diff options
author | melifaro <melifaro@FreeBSD.org> | 2014-10-04 12:42:37 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2014-10-04 12:42:37 +0000 |
commit | e8d559896cc84e0dd02a5419f74cb26abcb262e9 (patch) | |
tree | ede07b25dfc0e3d156d39f6fbfab305c429361d2 /contrib/netbsd-tests/lib | |
parent | 08c555cee75f59926d8d61bdc95449631fedce4c (diff) | |
parent | 1db3c5c0a6d331d775feb5b779ff5064c3e51a11 (diff) | |
download | FreeBSD-src-e8d559896cc84e0dd02a5419f74cb26abcb262e9.zip FreeBSD-src-e8d559896cc84e0dd02a5419f74cb26abcb262e9.tar.gz |
Sync to HEAD@r272516.
Diffstat (limited to 'contrib/netbsd-tests/lib')
547 files changed, 83848 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S new file mode 100644 index 0000000..b4382c1 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S @@ -0,0 +1,16 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:55 matt Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:55 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +LEAF_NOPROFILE(check_stack_alignment, 0) + ldiq v0, 0 + and sp, 7, t0 + cmoveq t0, 1, v0 + ret +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S new file mode 100644 index 0000000..2abc56f --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S @@ -0,0 +1,20 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +ARM_ENTRY(check_stack_alignment) +#ifdef __ARM_EABI__ + tst sp, #7 +#else + tst sp, #3 +#endif + movne r0, #0 + moveq r0, #1 + RET +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S new file mode 100644 index 0000000..c297e90 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S @@ -0,0 +1,12 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/11/15 11:48:30 skrll Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/11/15 11:48:30 skrll Exp $") + +LEAF_ENTRY(check_stack_alignment) + extru %sp,31,6,%ret0 + comiclr,<> 0, %ret0, %ret0 + ldi 1,%ret0 + bv,n %r0(%r2) +EXIT(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S new file mode 100644 index 0000000..e212989 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S @@ -0,0 +1,12 @@ +/* $NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $") + +_ENTRY(check_stack_alignment) + movl %esp, %eax + andl $3, %eax + setz %al + movzbl %al, %eax + ret diff --git a/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S new file mode 100644 index 0000000..f7612a8 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S @@ -0,0 +1,37 @@ +/* $NetBSD: h_initfini_align.S,v 1.2 2014/03/16 09:27:04 cherry Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.2 2014/03/16 09:27:04 cherry Exp $") + +ENTRY(check_stack_alignment, 0) + .prologue + .regstk 0, 2, 0, 0 + + alloc loc0 = ar.pfs, 0, 2, 0, 0 + + .body + mov ret0 = 1 + ;; + + /* ar.bsp has an 8-byte alignment requirement */ + mov loc1 = ar.bsp + ;; + + and loc1 = 7, loc1 + ;; + + cmp.eq p1, p0 = 0, loc1 + (p0) mov ret0 = 0 + ;; + + /* sp has a 16-byte alignment requirement */ + (p1) mov loc1 = sp + ;; + (p1) and loc1 = 15, loc1 + ;; + + (p1) cmp.eq p1, p0 = 0, loc1 + (p0) mov ret0 = 0 + + br.ret.sptk.few rp diff --git a/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S new file mode 100644 index 0000000..d6782ac --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S @@ -0,0 +1,19 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +LEAF_NOPROFILE(check_stack_alignment) +#ifdef __mips_o32 + andi v1,sp,3 +#else + andi v1,sp,7 +#endif + sltiu v0,v1,1 + jr ra +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S new file mode 100644 index 0000000..7abd9ea --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S @@ -0,0 +1,17 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +_ENTRY(check_stack_alignment) + li %r3,0 + andis. %r0,%r1,15 + bnelr %cr0 + li %r3,1 + blr +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S new file mode 100644 index 0000000..a770d39 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S @@ -0,0 +1,10 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/12 11:22:26 martin Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/12 11:22:26 martin Exp $") + +_ENTRY(check_stack_alignment) + and %sp, 7, %o1 + retl + not %o1, %o0 diff --git a/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S new file mode 100644 index 0000000..402ceb3 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S @@ -0,0 +1,11 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/11/15 20:00:20 martin Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/11/15 20:00:20 martin Exp $") + +_ENTRY(check_stack_alignment) + add %sp, BIAS, %o1 + and %o1, 15, %o2 + retl + not %o2, %o0 diff --git a/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S new file mode 100644 index 0000000..a751e1f --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S @@ -0,0 +1,17 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +_ENTRY(check_stack_alignment, 0) + clrl %r0 + bitl $3,%sp + bneq 1f + incl %r0 +1: ret +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S new file mode 100644 index 0000000..fbc1e56 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S @@ -0,0 +1,13 @@ +/* $NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $") + +_ENTRY(check_stack_alignment) + movl %esp, %eax + andl $15, %eax + subl $8, %eax + sete %al + movzbl %al, %eax + ret diff --git a/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx b/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx new file mode 100644 index 0000000..ff90ce6 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx @@ -0,0 +1,37 @@ +#include <unistd.h> + +#ifdef CHECK_STACK_ALIGNMENT +#include <stdlib.h> + +extern "C" int check_stack_alignment(void); +#endif + +class Test2 { +public: + Test2() + { + static const char msg[] = "constructor2 executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } + ~Test2() + { + static const char msg[] = "destructor2 executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } +}; + +Test2 test2; diff --git a/contrib/netbsd-tests/lib/csu/h_initfini1.cxx b/contrib/netbsd-tests/lib/csu/h_initfini1.cxx new file mode 100644 index 0000000..d410f70 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/h_initfini1.cxx @@ -0,0 +1,9 @@ +#include <unistd.h> + +int +main(void) +{ + static const char msg[] = "main executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); + return 0; +} diff --git a/contrib/netbsd-tests/lib/csu/h_initfini3.cxx b/contrib/netbsd-tests/lib/csu/h_initfini3.cxx new file mode 100644 index 0000000..13f54ce --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/h_initfini3.cxx @@ -0,0 +1,22 @@ +#include <dlfcn.h> +#include <err.h> +#include <unistd.h> + +int +main(void) +{ + static const char msg1[] = "main started\n"; + static const char msg2[] = "main after dlopen\n"; + static const char msg3[] = "main terminated\n"; + + void *handle; + + write(STDOUT_FILENO, msg1, sizeof(msg1) - 1); + handle = dlopen("h_initfini3_dso.so", RTLD_NOW | RTLD_LOCAL); + if (handle == NULL) + err(1, "dlopen"); + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + dlclose(handle); + write(STDOUT_FILENO, msg3, sizeof(msg3) - 1); + return 0; +} diff --git a/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx b/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx new file mode 100644 index 0000000..dd34983 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx @@ -0,0 +1,37 @@ +#include <unistd.h> + +#ifdef CHECK_STACK_ALIGNMENT +#include <stdlib.h> + +extern "C" int check_stack_alignment(void); +#endif + +class Test { +public: + Test() + { + static const char msg[] = "constructor executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } + ~Test() + { + static const char msg[] = "destructor executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } +}; + +Test test; diff --git a/contrib/netbsd-tests/lib/csu/t_crt0.sh b/contrib/netbsd-tests/lib/csu/t_crt0.sh new file mode 100755 index 0000000..a36a9b7 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/t_crt0.sh @@ -0,0 +1,104 @@ +# $NetBSD: t_crt0.sh,v 1.4 2011/12/11 14:57:07 joerg Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case initfini1 +initfini1_head() +{ + atf_set "descr" "Checks support for init/fini sections" +} +initfini1_body() +{ + cat >expout <<EOF +constructor executed +main executed +destructor executed +EOF + + atf_check -o file:expout "$(atf_get_srcdir)/h_initfini1" +} + +atf_test_case initfini2 +initfini2_head() +{ + atf_set "descr" "Checks support for init/fini sections in static binaries" +} +initfini2_body() +{ + cat >expout <<EOF +constructor executed +main executed +destructor executed +EOF + + atf_check -o file:expout "$(atf_get_srcdir)/h_initfini2" +} + +atf_test_case initfini3 +initfini3_head() +{ + atf_set "descr" "Checks support for init/fini sections in dlopen" +} +initfini3_body() +{ + cat >expout <<EOF +constructor executed +main started +constructor2 executed +main after dlopen +destructor2 executed +main terminated +destructor executed +EOF + + atf_check -o file:expout "$(atf_get_srcdir)/h_initfini3" +} + +atf_test_case initfini4 +initfini4_head() +{ + atf_set "descr" "Checks support for init/fini sections in LD_PRELOAD" +} +initfini4_body() +{ + cat >expout <<EOF +constructor2 executed +constructor executed +main executed +destructor executed +destructor2 executed +EOF + + atf_check -o file:expout -x "env LD_PRELOAD=$(atf_get_srcdir)/h_initfini3_dso.so $(atf_get_srcdir)/h_initfini1" +} + +atf_init_test_cases() +{ + atf_add_test_case initfini1 + atf_add_test_case initfini2 + atf_add_test_case initfini3 + atf_add_test_case initfini4 +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_bluetooth.c b/contrib/netbsd-tests/lib/libbluetooth/t_bluetooth.c new file mode 100644 index 0000000..066f8d9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_bluetooth.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_bluetooth.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <bluetooth.h> +#include <string.h> + +ATF_TC(check_bt_aton); + +ATF_TC_HEAD(check_bt_aton, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test bt_aton results"); +} + +ATF_TC_BODY(check_bt_aton, tc) +{ + bdaddr_t bdaddr; + + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d0:0e:0f", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e:0f:00", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e:0f\n", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton(" 0a:0b:0c:0d:0e:0f", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0x:0d:0e:0f", &bdaddr), 0); + + ATF_REQUIRE(bt_aton("0a:0b:0c:0d:0e:0f", &bdaddr)); + ATF_CHECK_EQ(bdaddr.b[0], 0x0f); + ATF_CHECK_EQ(bdaddr.b[1], 0x0e); + ATF_CHECK_EQ(bdaddr.b[2], 0x0d); + ATF_CHECK_EQ(bdaddr.b[3], 0x0c); + ATF_CHECK_EQ(bdaddr.b[4], 0x0b); + ATF_CHECK_EQ(bdaddr.b[5], 0x0a); +} + +ATF_TC(check_bt_ntoa); + +ATF_TC_HEAD(check_bt_ntoa, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test bt_ntoa results"); +} + +ATF_TC_BODY(check_bt_ntoa, tc) +{ + bdaddr_t bdaddr = { { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 } }; + + ATF_CHECK_STREQ(bt_ntoa(&bdaddr, NULL), "55:44:33:22:11:00"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_bt_aton); + ATF_TP_ADD_TC(tp, check_bt_ntoa); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c new file mode 100644 index 0000000..cff6627 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_sdp_data.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <sdp.h> + +ATF_TC(check_sdp_data_type); + +ATF_TC_HEAD(check_sdp_data_type, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_data_type results"); +} + +ATF_TC_BODY(check_sdp_data_type, tc) +{ + uint8_t data[] = { + 0x00, // nil + 0x08, 0x00, // uint8 0x00 + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT8); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_data_size); + +ATF_TC_HEAD(check_sdp_data_size, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_data_size results"); +} + +ATF_TC_BODY(check_sdp_data_size, tc) +{ + uint8_t data[] = { + 0x00, // nil + 0x08, 0x00, // uint8 + 0x11, 0x00, 0x00, // int16 + 0x1a, 0x00, 0x00, 0x00, // uuid32 + 0x00, + 0x28, 0x00, // bool + 0x25, 0x00, // str8(0) + 0x25, 0x02, 0x00, 0x00, // str8(2) + 0x36, 0x00, 0x00, // seq16(0) + 0x3e, 0x00, 0x05, 0x00, // alt16(5) + 0x00, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, // seq32(0) + 0x00, + 0x47, 0x00, 0x00, 0x00, // url32(7) + 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 1); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 5); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 4); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 8); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 5); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 12); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_data_type); + ATF_TP_ADD_TC(tp, check_sdp_data_size); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c new file mode 100644 index 0000000..3ad8070 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c @@ -0,0 +1,643 @@ +/* $NetBSD: t_sdp_get.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <limits.h> +#include <sdp.h> +#include <string.h> + +ATF_TC(check_sdp_get_data); + +ATF_TC_HEAD(check_sdp_get_data, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_data results"); +} + +ATF_TC_BODY(check_sdp_get_data, tc) +{ + uint8_t data[] = { + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x35, 0x05, // seq8(5) + 0x19, 0x00, 0x00, // uuid16 0x0000 + 0x08, 0x00, // uint8 0x00 + 0x36, 0x00, 0x01, // seq16(1) + 0x19, // uint16 /* invalid */ + 0x25, 0x04, 0x54, 0x45, // str8(4) "TEST" + 0x53, 0x54, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value, seq; + + /* + * sdp_get_data constructs a new sdp_data_t containing + * the next data element, advancing test if successful + */ + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT16); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ8); + ATF_CHECK_EQ(sdp_data_size(&value), 7); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ16); + ATF_CHECK_EQ(sdp_data_size(&value), 4); + ATF_REQUIRE_EQ(sdp_get_seq(&value, &seq), true); + ATF_REQUIRE_EQ(sdp_get_data(&seq, &value), false); /* invalid */ + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_STR8); + ATF_CHECK_EQ(sdp_data_size(&value), 6); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_attr); + +ATF_TC_HEAD(check_sdp_get_attr, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_attr results"); +} + +ATF_TC_BODY(check_sdp_get_attr, tc) +{ + uint8_t data[] = { + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x35, 0x05, // seq8(5) + 0x19, 0x00, 0x00, // uuid16 0x0000 + 0x08, 0x00, // uint8 0x00 + 0x08, 0x00, // uint8 0x00 + 0x09, 0x00, 0x01, // uint16 0x0001 + 0x19, 0x12, 0x34, // uuid16 0x1234 + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + uint16_t attr; + + /* + * sdp_get_attr expects a UINT16 followed by any data item + * and advances test if successful + */ + ATF_REQUIRE(sdp_get_attr(&test, &attr, &value)); + ATF_CHECK_EQ(attr, 0x0000); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ8); + ATF_CHECK_EQ(sdp_data_size(&value), 7); + + ATF_REQUIRE_EQ(sdp_get_attr(&test, &attr, &value), false); + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT8); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_attr(&test, &attr, &value)); + ATF_CHECK_EQ(attr, 0x0001); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UUID16); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_uuid); + +ATF_TC_HEAD(check_sdp_get_uuid, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_uuid results"); +} + +ATF_TC_BODY(check_sdp_get_uuid, tc) +{ + uint8_t data[] = { + 0x19, 0x12, 0x34, // uuid16 0x1234 + 0x1a, 0x11, 0x22, 0x33, // uuid32 0x11223344 + 0x44, + 0x00, // nil + 0x1c, // uuid128 0x00112233-4444--5555-6666-778899aabbcc + 0x00, 0x11, 0x22, 0x33, + 0x44, 0x44, 0x55, 0x55, + 0x66, 0x66, 0x77, 0x88, + 0x99, 0xaa, 0xbb, 0xcc, + }; + sdp_data_t test = { data, data + sizeof(data) }; + uuid_t u16 = { + 0x00001234, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + uuid_t u32 = { + 0x11223344, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + uuid_t u128 = { + 0x00112233, + 0x4444, + 0x5555, + 0x66, + 0x66, + { 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc } + }; + sdp_data_t nil; + uuid_t value; + + /* + * sdp_get_uuid expects any UUID type returns the full uuid + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_uuid(&test, &value)); + ATF_CHECK(uuid_equal(&value, &u16, NULL)); + + ATF_REQUIRE(sdp_get_uuid(&test, &value)); + ATF_CHECK(uuid_equal(&value, &u32, NULL)); + + ATF_REQUIRE_EQ(sdp_get_uuid(&test, &value), false); /* not uuid */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_uuid(&test, &value)); + ATF_CHECK(uuid_equal(&value, &u128, NULL)); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_bool); + +ATF_TC_HEAD(check_sdp_get_bool, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_bool results"); +} + +ATF_TC_BODY(check_sdp_get_bool, tc) +{ + uint8_t data[] = { + 0x28, 0x00, // bool false + 0x00, // nil + 0x28, 0x01, // bool true + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + bool value; + + /* + * sdp_get_bool expects a BOOL type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_bool(&test, &value)); + ATF_CHECK_EQ(value, false); + + ATF_REQUIRE_EQ(sdp_get_bool(&test, &value), false); /* not bool */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_bool(&test, &value)); + ATF_CHECK_EQ(value, true); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_uint); + +ATF_TC_HEAD(check_sdp_get_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_uint results"); +} + +ATF_TC_BODY(check_sdp_get_uint, tc) +{ + uint8_t data[] = { + 0x08, 0x00, // uint8 0x00 + 0x08, 0xff, // uint8 0xff + 0x09, 0x01, 0x02, // uint16 0x0102 + 0x09, 0xff, 0xff, // uint16 0xffff + 0x00, // nil + 0x0a, 0x01, 0x02, 0x03, // uint32 0x01020304 + 0x04, + 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff + 0xff, + 0x0b, 0x01, 0x02, 0x03, // uint64 0x0102030405060708 + 0x04, 0x05, 0x06, 0x07, + 0x08, + 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x00000000000000000000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x00000000000000010000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x0000000000000000ffffffffffffffff + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + uintmax_t value; + + /* + * sdp_get_uint expects any UINT type, advancing test if successful + */ + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x00); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT8_MAX); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x0102); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT16_MAX); + + ATF_REQUIRE_EQ(sdp_get_uint(&test, &value), false); /* not uint */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x01020304); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT32_MAX); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x0102030405060708); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT64_MAX); + + /* + * expected failure is that we cannot decode UINT128 values larger than UINT64 + */ + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x00000000000000000000000000000000); + + ATF_REQUIRE_EQ(sdp_get_uint(&test, &value), false); /* overflow */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_UINT128); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT64_MAX); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_int); + +ATF_TC_HEAD(check_sdp_get_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_int results"); +} + +ATF_TC_BODY(check_sdp_get_int, tc) +{ + uint8_t data[] = { + 0x10, 0x00, // int8 0x00 + 0x10, 0x7f, // int8 0x7f + 0x10, 0x80, // int8 0x80 + 0x11, 0x01, 0x02, // int16 0x0102 + 0x11, 0x7f, 0xff, // int16 0x7fff + 0x11, 0x80, 0x00, // int16 0x8000 + 0x00, // nil + 0x12, 0x01, 0x02, 0x03, // int32 0x01020304 + 0x04, + 0x12, 0x7f, 0xff, 0xff, // int32 0x7fffffff + 0xff, + 0x12, 0x80, 0x00, 0x00, // int32 0x80000000 + 0x00, + 0x13, 0x01, 0x02, 0x03, // int64 0x0102030405060708 + 0x04, 0x05, 0x06, 0x07, + 0x08, + 0x13, 0x7f, 0xff, 0xff, // int64 0x7fffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x13, 0x80, 0x00, 0x00, // int64 0x8000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000000000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000007fffffffffffffff + 0x00, 0x00, 0x00, 0x00, // (INT64_MAX) + 0x00, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000008000000000000000 + 0x00, 0x00, 0x00, 0x00, // (INT64_MAX + 1) + 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0xff, 0xff, 0xff, // int128 0xffffffffffffffff8000000000000000 + 0xff, 0xff, 0xff, 0xff, // (INT64_MIN) + 0xff, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0xff, 0xff, 0xff, // int128 0xffffffffffffffff7fffffffffffffff + 0xff, 0xff, 0xff, 0xff, // (INT64_MIN - 1) + 0xff, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + intmax_t value; + + /* + * sdp_get_int expects any INT type, advancing test if successful + */ + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT8_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT8_MIN); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0x0102); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT16_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT16_MIN); + + ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* not int */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0x01020304); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT32_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT32_MIN); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0x0102030405060708); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MIN); + + /* + * expected failure is that we cannot decode INT128 values larger than INT64 + */ + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MAX); + + ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* overflow */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_INT128); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MIN); + + ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* underflow */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_INT128); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_seq); + +ATF_TC_HEAD(check_sdp_get_seq, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_seq results"); +} + +ATF_TC_BODY(check_sdp_get_seq, tc) +{ + uint8_t data[] = { + 0x35, 0x00, // seq8(0) + 0x00, // nil + 0x36, 0x00, 0x00, // seq16(0) + 0x37, 0x00, 0x00, 0x00, // seq32(0) + 0x00, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + /* + * sdp_get_seq expects a SEQ type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_seq(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE_EQ(sdp_get_seq(&test, &value), false); /* not seq */ + ATF_REQUIRE(sdp_get_data(&test, &value)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_seq(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE(sdp_get_seq(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_alt); + +ATF_TC_HEAD(check_sdp_get_alt, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_alt results"); +} + +ATF_TC_BODY(check_sdp_get_alt, tc) +{ + uint8_t data[] = { + 0x3d, 0x00, // alt8(0) + 0x00, // nil + 0x3e, 0x00, 0x00, // alt16(0) + 0x3f, 0x00, 0x00, 0x00, // alt32(0) + 0x00, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + /* + * sdp_get_alt expects a ALT type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_alt(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE_EQ(sdp_get_alt(&test, &value), false); /* not alt */ + ATF_REQUIRE(sdp_get_data(&test, &value)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_alt(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE(sdp_get_alt(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_str); + +ATF_TC_HEAD(check_sdp_get_str, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_str results"); +} + +ATF_TC_BODY(check_sdp_get_str, tc) +{ + uint8_t data[] = { + 0x25, 0x04, 0x53, 0x54, // str8(4) "STR8" + 0x52, 0x38, + 0x00, // nil + 0x26, 0x00, 0x05, 0x53, // str16(5) "STR16" + 0x54, 0x52, 0x31, 0x36, + 0x27, 0x00, 0x00, 0x00, // str32(5) "STR32" + 0x05, 0x53, 0x54, 0x52, + 0x33, 0x32, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + char *str; + size_t len; + + /* + * sdp_get_str expects a STR type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_str(&test, &str, &len)); + ATF_CHECK(len == 4 && strncmp(str, "STR8", 4) == 0); + + ATF_REQUIRE_EQ(sdp_get_str(&test, &str, &len), false); /* not str */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_str(&test, &str, &len)); + ATF_CHECK(len == 5 && strncmp(str, "STR16", 5) == 0); + + ATF_REQUIRE(sdp_get_str(&test, &str, &len)); + ATF_CHECK(len == 5 && strncmp(str, "STR32", 5) == 0); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_url); + +ATF_TC_HEAD(check_sdp_get_url, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_url results"); +} + +ATF_TC_BODY(check_sdp_get_url, tc) +{ + uint8_t data[] = { + 0x45, 0x04, 0x55, 0x52, // url8(4) "URL8" + 0x4c, 0x38, + 0x00, // nil + 0x46, 0x00, 0x05, 0x55, // url16(5) "URL16" + 0x52, 0x4c, 0x31, 0x36, + 0x47, 0x00, 0x00, 0x00, // url32(5) "URL32" + 0x05, 0x55, 0x52, 0x4c, + 0x33, 0x32, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + char *url; + size_t len; + + /* + * sdp_get_url expects a URL type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_url(&test, &url, &len)); + ATF_CHECK(len == 4 && strncmp(url, "URL8", 4) == 0); + + ATF_REQUIRE_EQ(sdp_get_url(&test, &url, &len), false); /* not url */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_url(&test, &url, &len)); + ATF_CHECK(len == 5 && strncmp(url, "URL16", 5) == 0); + + ATF_REQUIRE(sdp_get_url(&test, &url, &len)); + ATF_CHECK(len == 5 && strncmp(url, "URL32", 5) == 0); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_get_data); + ATF_TP_ADD_TC(tp, check_sdp_get_attr); + ATF_TP_ADD_TC(tp, check_sdp_get_uuid); + ATF_TP_ADD_TC(tp, check_sdp_get_bool); + ATF_TP_ADD_TC(tp, check_sdp_get_uint); + ATF_TP_ADD_TC(tp, check_sdp_get_int); + ATF_TP_ADD_TC(tp, check_sdp_get_seq); + ATF_TP_ADD_TC(tp, check_sdp_get_alt); + ATF_TP_ADD_TC(tp, check_sdp_get_str); + ATF_TP_ADD_TC(tp, check_sdp_get_url); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c new file mode 100644 index 0000000..54a5bd5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_sdp_match.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <sdp.h> + +ATF_TC(check_sdp_match_uuid16); + +ATF_TC_HEAD(check_sdp_match_uuid16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_match_uuid16 results"); +} + +ATF_TC_BODY(check_sdp_match_uuid16, tc) +{ + uint8_t data[] = { + 0x19, 0x11, 0x11, // uuid16 0x1111 + 0x00, // nil + 0x19, 0x12, 0x34, // uuid16 0x1234 + 0x1a, 0x00, 0x00, 0x34, // uuid32 0x00003456 + 0x56, + 0x1c, 0x00, 0x00, 0x43, // uuid128 00004321-0000-1000-8000-00805f9b34fb + 0x21, 0x00, 0x00, 0x10, + 0x00, 0x80, 0x00, 0x00, + 0x80, 0x5f, 0x9b, 0x34, + 0xfb, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + + /* + * sdp_match_uuid16 advances if the UUID matches the 16-bit short alias given + */ + + ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1100), false); /* mismatch */ + ATF_REQUIRE(sdp_match_uuid16(&test, 0x1111)); + + ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1234), false); /* not uuid */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + ATF_REQUIRE(sdp_match_uuid16(&test, 0x1234)); + + ATF_REQUIRE(sdp_match_uuid16(&test, 0x3456)); + + ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1234), false); /* mismatch */ + ATF_REQUIRE(sdp_match_uuid16(&test, 0x4321)); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_match_uuid16); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c new file mode 100644 index 0000000..fff4119 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c @@ -0,0 +1,875 @@ +/* $NetBSD: t_sdp_put.c,v 1.3 2011/04/16 07:32:27 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <limits.h> +#include <sdp.h> +#include <string.h> + +ATF_TC(check_sdp_put_data); + +ATF_TC_HEAD(check_sdp_put_data, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_data results"); +} + +ATF_TC_BODY(check_sdp_put_data, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + uint8_t data[] = { + 0x35, 0x05, // seq8(5) + 0x08, 0x00, // uint8 0x00 + 0x09, 0x12, 0x34, // uint16 0x1234 + }; + sdp_data_t value = { data, data + sizeof(data) }; + + ATF_REQUIRE(sdp_put_data(&test, &value)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x35, 0x05, // seq8(5) + 0x08, 0x00, // uint8 0x00 + 0x09, 0x12, 0x34, // uint16 0x1234 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_attr); + +ATF_TC_HEAD(check_sdp_put_attr, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_attr results"); +} + +ATF_TC_BODY(check_sdp_put_attr, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + uint8_t data[] = { + 0x00, // nil + 0x19, 0x33, 0x44, // uuid16 0x3344 + }; + sdp_data_t value = { data, data + sizeof(data) }; + + ATF_REQUIRE_EQ(sdp_put_attr(&test, 0xabcd, &value), false); + value.next += 1; // skip "nil" + ATF_REQUIRE(sdp_put_attr(&test, 0x1337, &value)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x09, 0x13, 0x37, // uint16 0x1337 + 0x19, 0x33, 0x44, // uuid16 0x3344 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid); + +ATF_TC_HEAD(check_sdp_put_uuid, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid results"); +} + +ATF_TC_BODY(check_sdp_put_uuid, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + const uuid_t u16 = { + 0x00001234, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + const uuid_t u32 = { + 0x12345678, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + const uuid_t u128 = { + 0x00112233, + 0x4444, + 0x5555, + 0x66, + 0x77, + { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd } + }; + + ATF_REQUIRE(sdp_put_uuid(&test, &u16)); + ATF_REQUIRE(sdp_put_uuid(&test, &u32)); + ATF_REQUIRE(sdp_put_uuid(&test, &u128)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x19, 0x12, 0x34, // uuid16 0x1234 + 0x1a, 0x12, 0x34, 0x56, // uuid32 0x12345678 + 0x78, + 0x1c, 0x00, 0x11, 0x22, // uuid128 00112233-4444-5555-6677-8899aabbccdd + 0x33, 0x44, 0x44, 0x55, + 0x55, 0x66, 0x77, 0x88, + 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid16); + +ATF_TC_HEAD(check_sdp_put_uuid16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid16 results"); +} + +ATF_TC_BODY(check_sdp_put_uuid16, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uuid16(&test, 0x4567)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x19, 0x45, 0x67, // uuid16 0x4567 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid32); + +ATF_TC_HEAD(check_sdp_put_uuid32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid32 results"); +} + +ATF_TC_BODY(check_sdp_put_uuid32, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uuid32(&test, 0xabcdef00)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x1a, 0xab, 0xcd, 0xef, // uuid32 0xabcdef00 + 0x00, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid128); + +ATF_TC_HEAD(check_sdp_put_uuid128, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid128 results"); +} + +ATF_TC_BODY(check_sdp_put_uuid128, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + uuid_t value = { + 0x00000100, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + + ATF_REQUIRE(sdp_put_uuid128(&test, &value)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x1c, 0x00, 0x00, 0x01, // uuid128 0000100-0000-1000-8000-00805f9b34fb + 0x00, 0x00, 0x00, 0x10, // (L2CAP protocol) + 0x00, 0x80, 0x00, 0x00, + 0x80, 0x5f, 0x9b, 0x34, + 0xfb, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_bool); + +ATF_TC_HEAD(check_sdp_put_bool, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_bool results"); +} + +ATF_TC_BODY(check_sdp_put_bool, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_bool(&test, true)); + ATF_REQUIRE(sdp_put_bool(&test, false)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x28, 0x01, // bool true + 0x28, 0x00, // bool false + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint); + +ATF_TC_HEAD(check_sdp_put_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint results"); +} + +ATF_TC_BODY(check_sdp_put_uint, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)0)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT8_MAX + 1)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT16_MAX + 1)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT32_MAX)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT32_MAX + 1)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT64_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x08, 0x00, // uint8 0x00 + 0x08, 0xff, // uint8 0xff + 0x09, 0x01, 0x00, // uint16 0x0100 + 0x09, 0xff, 0xff, // uint16 0xffff + 0x0a, 0x00, 0x01, 0x00, // uint32 0x00010000 + 0x00, + 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff + 0xff, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000100000000 + 0x01, 0x00, 0x00, 0x00, + 0x00, + 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint8); + +ATF_TC_HEAD(check_sdp_put_uint8, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint8 results"); +} + +ATF_TC_BODY(check_sdp_put_uint8, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint8(&test, (uint8_t)0)); + ATF_REQUIRE(sdp_put_uint8(&test, (uint8_t)UINT8_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x08, 0x00, // uint8 0x00 + 0x08, 0xff, // uint8 0xff + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint16); + +ATF_TC_HEAD(check_sdp_put_uint16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint16 results"); +} + +ATF_TC_BODY(check_sdp_put_uint16, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)0)); + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)0xabcd)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x09, 0x00, 0xff, // uint16 0x00ff + 0x09, 0xff, 0xff, // uint16 0xffff + 0x09, 0xab, 0xcd, // uint16 0xabcd + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint32); + +ATF_TC_HEAD(check_sdp_put_uint32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint32 results"); +} + +ATF_TC_BODY(check_sdp_put_uint32, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)0)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT32_MAX)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)0xdeadbeef)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000 + 0x00, + 0x0a, 0x00, 0x00, 0x00, // uint32 0x000000ff + 0xff, + 0x0a, 0x00, 0x00, 0xff, // uint32 0x0000ffff + 0xff, + 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff + 0xff, + 0x0a, 0xde, 0xad, 0xbe, // uint32 0xdeadbeef + 0xef, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint64); + +ATF_TC_HEAD(check_sdp_put_uint64, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint64 results"); +} + +ATF_TC_BODY(check_sdp_put_uint64, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)0)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT32_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT64_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)0xc0ffeecafec0ffee)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x00000000000000ff + 0x00, 0x00, 0x00, 0x00, + 0xff, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x000000000000ffff + 0x00, 0x00, 0x00, 0xff, + 0xff, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x00000000ffffffff + 0x00, 0xff, 0xff, 0xff, + 0xff, + 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x0b, 0xc0, 0xff, 0xee, // uint64 0xc0ffeecafec0ffee + 0xca, 0xfe, 0xc0, 0xff, + 0xee, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int); + +ATF_TC_HEAD(check_sdp_put_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int results"); +} + +ATF_TC_BODY(check_sdp_put_int, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)0)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MIN - 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MAX + 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MAX)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MIN - 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MAX + 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MAX)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MIN - 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MAX + 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT64_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT64_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x10, 0x00, // int8 0 + 0x10, 0x80, // int8 -128 + 0x10, 0x7f, // int8 127 + 0x11, 0xff, 0x7f, // int16 -129 + 0x11, 0x00, 0x80, // int16 128 + 0x11, 0x80, 0x00, // int16 -32768 + 0x11, 0x7f, 0xff, // int16 32767 + 0x12, 0xff, 0xff, 0x7f, // int32 -32769 + 0xff, + 0x12, 0x00, 0x00, 0x80, // int32 32768 + 0x00, + 0x12, 0x80, 0x00, 0x00, // int32 -2147483648 + 0x00, + 0x12, 0x7f, 0xff, 0xff, // int32 2147483647 + 0xff, + 0x13, 0xff, 0xff, 0xff, // int64 -2147483649 + 0xff, 0x7f, 0xff, 0xff, + 0xff, + 0x13, 0x00, 0x00, 0x00, // int64 2147483648 + 0x00, 0x80, 0x00, 0x00, + 0x00, + 0x13, 0x80, 0x00, 0x00, // int64 -9223372036854775808 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x13, 0x7f, 0xff, 0xff, // int64 9223372036854775807 + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int8); + +ATF_TC_HEAD(check_sdp_put_int8, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int8 results"); +} + +ATF_TC_BODY(check_sdp_put_int8, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int8(&test, (int8_t)0)); + ATF_REQUIRE(sdp_put_int8(&test, (int8_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int8(&test, (int8_t)INT8_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x10, 0x00, // int8 0 + 0x10, 0x80, // int8 -128 + 0x10, 0x7f, // int8 127 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int16); + +ATF_TC_HEAD(check_sdp_put_int16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int16 results"); +} + +ATF_TC_BODY(check_sdp_put_int16, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)0)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT16_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x11, 0x00, 0x00, // int16 0 + 0x11, 0xff, 0x80, // int16 -128 + 0x11, 0x00, 0x7f, // int16 127 + 0x11, 0x80, 0x00, // int16 -32768 + 0x11, 0x7f, 0xff, // int16 32767 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int32); + +ATF_TC_HEAD(check_sdp_put_int32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int32 results"); +} + +ATF_TC_BODY(check_sdp_put_int32, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)0)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT16_MAX)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT32_MIN)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT32_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x12, 0x00, 0x00, 0x00, // int32 0 + 0x00, + 0x12, 0xff, 0xff, 0xff, // int32 -128 + 0x80, + 0x12, 0x00, 0x00, 0x00, // int32 127 + 0x7f, + 0x12, 0xff, 0xff, 0x80, // int32 -32768 + 0x00, + 0x12, 0x00, 0x00, 0x7f, // int32 32767 + 0xff, + 0x12, 0x80, 0x00, 0x00, // int32 -2147483648 + 0x00, + 0x12, 0x7f, 0xff, 0xff, // int32 2147483647 + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int64); + +ATF_TC_HEAD(check_sdp_put_int64, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int64 results"); +} + +ATF_TC_BODY(check_sdp_put_int64, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)0)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT16_MAX)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT32_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT32_MAX)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT64_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT64_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x13, 0x00, 0x00, 0x00, // int64 0 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x13, 0xff, 0xff, 0xff, // int64 -128 + 0xff, 0xff, 0xff, 0xff, + 0x80, + 0x13, 0x00, 0x00, 0x00, // int64 127 + 0x00, 0x00, 0x00, 0x00, + 0x7f, + 0x13, 0xff, 0xff, 0xff, // int64 -32768 + 0xff, 0xff, 0xff, 0x80, + 0x00, + 0x13, 0x00, 0x00, 0x00, // int64 32767 + 0x00, 0x00, 0x00, 0x7f, + 0xff, + 0x13, 0xff, 0xff, 0xff, // int64 -2147483648 + 0xff, 0x80, 0x00, 0x00, + 0x00, + 0x13, 0x00, 0x00, 0x00, // int64 2147483647 + 0x00, 0x7f, 0xff, 0xff, + 0xff, + 0x13, 0x80, 0x00, 0x00, // int64 -9223372036854775808 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x13, 0x7f, 0xff, 0xff, // int64 9223372036854775807 + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_seq); + +ATF_TC_HEAD(check_sdp_put_seq, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_seq results"); +} + +ATF_TC_BODY(check_sdp_put_seq, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)0)); + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)UINT8_MAX + 1)); + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)-1)); + ATF_CHECK_EQ(sdp_put_seq(&test, (ssize_t)UINT16_MAX), false); /* no room */ + ATF_CHECK_EQ(sdp_put_seq(&test, (ssize_t)SSIZE_MAX), false); /* no room */ + test.end = test.next; + test.next = buf; + + /* (not a valid element list) */ + const uint8_t expect[] = { + 0x35, 0x00, // seq8(0) + 0x35, 0xff, // seq8(255) + 0x36, 0x01, 0x00, // seq16(256) + 0x36, 0x01, 0xf6, // seq16(502) <- sizeof(buf) - 7 - 3 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_alt); + +ATF_TC_HEAD(check_sdp_put_alt, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_alt results"); +} + +ATF_TC_BODY(check_sdp_put_alt, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)0)); + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)UINT8_MAX + 1)); + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)-1)); + ATF_CHECK_EQ(sdp_put_alt(&test, (ssize_t)UINT16_MAX), false); /* no room */ + ATF_CHECK_EQ(sdp_put_alt(&test, (ssize_t)SSIZE_MAX), false); /* no room */ + test.end = test.next; + test.next = buf; + + /* (not a valid element list) */ + const uint8_t expect[] = { + 0x3d, 0x00, // alt8(0) + 0x3d, 0xff, // alt8(255) + 0x3e, 0x01, 0x00, // alt16(256) + 0x3e, 0x01, 0xf6, // alt16(502) <- sizeof(buf) - 7 - 3 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_str); + +ATF_TC_HEAD(check_sdp_put_str, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_str results"); +} + +ATF_TC_BODY(check_sdp_put_str, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + /* + * this does not test str16 or str32, but that is + * handled by the same code as sdp_put_seq above.. + */ + + ATF_REQUIRE(sdp_put_str(&test, "Hello World!", 5)); + ATF_REQUIRE(sdp_put_str(&test, "Hello\0World", 11)); + ATF_REQUIRE(sdp_put_str(&test, "Hello World!", -1)); + ATF_REQUIRE(sdp_put_str(&test, "Hello\0World", -1)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x25, 0x05, 0x48, 0x65, // str8 "Hello" + 0x6c, 0x6c, 0x6f, + 0x25, 0x0b, 0x48, 0x65, // str8 "Hello\0World" + 0x6c, 0x6c, 0x6f, 0x00, + 0x57, 0x6f, 0x72, 0x6c, + 0x64, + 0x25, 0x0c, 0x48, 0x65, // str8 "Hello World!" + 0x6c, 0x6c, 0x6f, 0x20, + 0x57, 0x6f, 0x72, 0x6c, + 0x64, 0x21, + 0x25, 0x05, 0x48, 0x65, // str8 "Hello" + 0x6c, 0x6c, 0x6f, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_url); + +ATF_TC_HEAD(check_sdp_put_url, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_url results"); +} + +ATF_TC_BODY(check_sdp_put_url, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + /* + * this does not test url16 or url32, but that is + * handled by the same code as sdp_put_seq above.. + */ + + ATF_REQUIRE(sdp_put_url(&test, "http://www.netbsd.org/", 21)); + ATF_REQUIRE(sdp_put_url(&test, "http://www.netbsd.org/", -1)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x45, 0x15, 0x68, 0x74, // url8 "http://www.netbsd.org" + 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x6e, 0x65, 0x74, + 0x62, 0x73, 0x64, 0x2e, + 0x6f, 0x72, 0x67, + 0x45, 0x16, 0x68, 0x74, // url8 "http://www.netbsd.org/" + 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x6e, 0x65, 0x74, + 0x62, 0x73, 0x64, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_put_data); + ATF_TP_ADD_TC(tp, check_sdp_put_attr); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid16); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid32); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid128); + ATF_TP_ADD_TC(tp, check_sdp_put_bool); + ATF_TP_ADD_TC(tp, check_sdp_put_uint); + ATF_TP_ADD_TC(tp, check_sdp_put_uint8); + ATF_TP_ADD_TC(tp, check_sdp_put_uint16); + ATF_TP_ADD_TC(tp, check_sdp_put_uint32); + ATF_TP_ADD_TC(tp, check_sdp_put_uint64); + ATF_TP_ADD_TC(tp, check_sdp_put_int); + ATF_TP_ADD_TC(tp, check_sdp_put_int8); + ATF_TP_ADD_TC(tp, check_sdp_put_int16); + ATF_TP_ADD_TC(tp, check_sdp_put_int32); + ATF_TP_ADD_TC(tp, check_sdp_put_int64); + ATF_TP_ADD_TC(tp, check_sdp_put_seq); + ATF_TP_ADD_TC(tp, check_sdp_put_alt); + ATF_TP_ADD_TC(tp, check_sdp_put_str); + ATF_TP_ADD_TC(tp, check_sdp_put_url); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c new file mode 100644 index 0000000..be5d953 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c @@ -0,0 +1,359 @@ +/* $NetBSD: t_sdp_set.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <limits.h> +#include <sdp.h> +#include <string.h> + +ATF_TC(check_sdp_set_bool); + +ATF_TC_HEAD(check_sdp_set_bool, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_bool results"); +} + +ATF_TC_BODY(check_sdp_set_bool, tc) +{ + uint8_t data[] = { + 0x28, 0x00, // bool false + 0x00, // nil + 0x28, // bool <invalid> + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_BOOL); + ATF_REQUIRE(sdp_set_bool(&test, true)); + ATF_CHECK_EQ(test.next[1], 0x01); + ATF_REQUIRE(sdp_set_bool(&test, false)); + ATF_CHECK_EQ(test.next[1], 0x00); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL); + ATF_CHECK_EQ(sdp_set_bool(&test, true), false); /* not bool */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_BOOL); + ATF_CHECK_EQ(sdp_set_bool(&test, true), false); /* no value */ +} + +ATF_TC(check_sdp_set_uint); + +ATF_TC_HEAD(check_sdp_set_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_uint results"); +} + +ATF_TC_BODY(check_sdp_set_uint, tc) +{ + uint8_t data[] = { + 0x08, 0x00, // uint8 0x00 + 0x00, // nil + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000 + 0x00, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0c, 0x00, 0x44, 0x00, // uint128 0x00440044004400440044004400440044 + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x00, + 0x09, 0x00, // uint16 <invalid> + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT8); + ATF_REQUIRE(sdp_set_uint(&test, 0x44)); + ATF_CHECK_EQ(sdp_set_uint(&test, UINT8_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL); + ATF_CHECK_EQ(sdp_set_uint(&test, 0x00), false); /* not uint */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT16); + ATF_REQUIRE(sdp_set_uint(&test, 0xabcd)); + ATF_CHECK_EQ(sdp_set_uint(&test, UINT16_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT32); + ATF_REQUIRE(sdp_set_uint(&test, 0xdeadbeef)); + ATF_CHECK_EQ(sdp_set_uint(&test, (uintmax_t)UINT32_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT64); + ATF_REQUIRE(sdp_set_uint(&test, 0xc0ffeecafec0ffee)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT128); + ATF_REQUIRE(sdp_set_uint(&test, 0xabcdef0123456789)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT16); + ATF_CHECK_EQ(sdp_set_uint(&test, 0x3344), false); /* no value */ + + const uint8_t expect[] = { + 0x08, 0x44, // uint8 0x44 + 0x00, // nil + 0x09, 0xab, 0xcd, // uint16 0xabcd + 0x0a, 0xde, 0xad, 0xbe, // uint32 0xdeadbeef + 0xef, + 0x0b, 0xc0, 0xff, 0xee, // uint64 0xc0ffeecafec0ffee + 0xca, 0xfe, 0xc0, 0xff, + 0xee, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x0000000000000000abcdef0123456789 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, + 0x89, + 0x09, 0x00, // uint16 <invalid> + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_set_int); + +ATF_TC_HEAD(check_sdp_set_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_int results"); +} + +ATF_TC_BODY(check_sdp_set_int, tc) +{ + uint8_t data[] = { + 0x10, 0x00, // int8 0 + 0x00, // nil + 0x11, 0x00, 0x00, // int16 0 + 0x12, 0x00, 0x00, 0x00, // int32 0 + 0x00, + 0x13, 0x00, 0x00, 0x00, // int64 0 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0x00, 0x44, 0x00, // int128 0x00440044004400440044004400440044 + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x00, + 0x11, 0x00, // int16 <invalid> + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT8); + ATF_REQUIRE(sdp_set_int(&test, -1)); + ATF_CHECK_EQ(sdp_set_int(&test, INT8_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL); + ATF_CHECK_EQ(sdp_set_int(&test, 33), false); /* not int */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_REQUIRE(sdp_set_int(&test, 789)); + ATF_CHECK_EQ(sdp_set_int(&test, INT16_MIN - 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT32); + ATF_REQUIRE(sdp_set_int(&test, -4567)); + ATF_CHECK_EQ(sdp_set_int(&test, (intmax_t)INT32_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT64); + ATF_REQUIRE(sdp_set_int(&test, -3483738234)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT128); + ATF_REQUIRE(sdp_set_int(&test, 3423489463464)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_CHECK_EQ(sdp_set_int(&test, 1234), false); /* no value */ + + const uint8_t expect[] = { + 0x10, 0xff, // int8 -1 + 0x00, // nil + 0x11, 0x03, 0x15, // int16 789 + 0x12, 0xff, 0xff, 0xee, // int32 -4567 + 0x29, + 0x13, 0xff, 0xff, 0xff, // int64 -3483738234 + 0xff, 0x30, 0x5a, 0x5f, + 0x86, + 0x14, 0x00, 0x00, 0x00, // int128 3423489463464 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, + 0x1d, 0x17, 0xdf, 0x94, + 0xa8, + 0x11, 0x00, // int16 <invalid> + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_set_seq); + +ATF_TC_HEAD(check_sdp_set_seq, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_seq results"); +} + +ATF_TC_BODY(check_sdp_set_seq, tc) +{ + uint8_t data[] = { + 0x35, 0x03, // seq8(3) + 0x11, 0xff, 0xff, // int16 -1 + 0x36, 0x01, 0x00, // seq16(256) + 0x09, 0xff, 0xff, // uint16 0xffff + 0x37, 0x01, 0x02, 0x03, // seq32(16909060) + 0x04, + 0x36, 0x00, // seq16(<invalid>) + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ8); + ATF_REQUIRE(sdp_set_seq(&test, 0)); + ATF_CHECK_EQ(sdp_set_seq(&test, UINT8_MAX), false); /* data too big */ + ATF_CHECK_EQ(sdp_set_seq(&test, UINT16_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_CHECK_EQ(sdp_set_seq(&test, 33), false); /* not seq */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ16); + ATF_REQUIRE(sdp_set_seq(&test, 3)); + ATF_CHECK_EQ(sdp_set_seq(&test, SSIZE_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ32); + ATF_REQUIRE(sdp_set_seq(&test, 0)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ16); + ATF_CHECK_EQ(sdp_set_seq(&test, 22), false); /* no size */ + + const uint8_t expect[] = { + 0x35, 0x00, // seq8(0) + 0x11, 0xff, 0xff, // int16 -1 + 0x36, 0x00, 0x03, // seq16(3) + 0x09, 0xff, 0xff, // uint16 0xffff + 0x37, 0x00, 0x00, 0x00, // seq32(0) + 0x00, + 0x36, 0x00, // seq16(<invalid>) + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_set_alt); + +ATF_TC_HEAD(check_sdp_set_alt, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_alt results"); +} + +ATF_TC_BODY(check_sdp_set_alt, tc) +{ + uint8_t data[] = { + 0x3d, 0x06, // alt8(6) + 0x11, 0xff, 0xff, // int16 -1 + 0x3e, 0xff, 0xff, // alt16(65535) + 0x3f, 0x01, 0x02, 0x03, // alt32(16909060) + 0x04, + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000003 + 0x03, + 0x3e, 0x00, // alt16(<invalid>) + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT8); + ATF_REQUIRE(sdp_set_alt(&test, 0)); + ATF_CHECK_EQ(sdp_set_alt(&test, UINT8_MAX), false); /* data too big */ + ATF_CHECK_EQ(sdp_set_alt(&test, UINT16_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_CHECK_EQ(sdp_set_alt(&test, 27), false); /* not alt */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT16); + ATF_REQUIRE(sdp_set_alt(&test, 10)); + ATF_CHECK_EQ(sdp_set_alt(&test, SSIZE_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_alt(&test, &discard)); + ATF_CHECK_EQ(sdp_data_type(&discard), SDP_DATA_ALT32); + ATF_CHECK(sdp_set_alt(&discard, -1)); /* end of alt16 */ + ATF_CHECK_EQ(sdp_set_alt(&discard, 6), false); /* data too big */ + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT16); + ATF_CHECK_EQ(sdp_set_alt(&test, 22), false); /* no size */ + + const uint8_t expect[] = { + 0x3d, 0x00, // alt8(0) + 0x11, 0xff, 0xff, // int16 -1 + 0x3e, 0x00, 0x0a, // alt16(10) + 0x3f, 0x00, 0x00, 0x00, // alt32(5) + 0x05, + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000003 + 0x03, + 0x3e, 0x00, // alt16(<invalid>) + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_set_bool); + ATF_TP_ADD_TC(tp, check_sdp_set_uint); + ATF_TP_ADD_TC(tp, check_sdp_set_int); + ATF_TP_ADD_TC(tp, check_sdp_set_seq); + ATF_TP_ADD_TC(tp, check_sdp_set_alt); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c b/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c new file mode 100644 index 0000000..da67c1b3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c @@ -0,0 +1,3975 @@ +/* $NetBSD: t_bpfjit.c,v 1.6 2014/07/08 21:07:52 alnsn Exp $ */ + +/*- + * Copyright (c) 2011-2012, 2014 Alexander Nasonov. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_bpfjit.c,v 1.6 2014/07/08 21:07:52 alnsn Exp $"); + +#include <atf-c.h> +#include <stdint.h> +#include <string.h> + +#include <net/bpf.h> +#include <net/bpfjit.h> + +static uint8_t deadbeef_at_5[16] = { + 0, 0xf1, 2, 0xf3, 4, 0xde, 0xad, 0xbe, 0xef, 0xff +}; + +static inline +unsigned int jitcall(bpfjit_func_t fn, + const uint8_t *pkt, unsigned int wirelen, unsigned int buflen) +{ + bpf_args_t args; + + args.pkt = pkt; + args.wirelen = wirelen; + args.buflen = buflen; + + return fn(NULL, &args); +} + +ATF_TC(libbpfjit_empty); +ATF_TC_HEAD(libbpfjit_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that JIT compilation of an empty bpf program fails"); +} + +ATF_TC_BODY(libbpfjit_empty, tc) +{ + struct bpf_insn dummy; + + ATF_CHECK(bpfjit_generate_code(NULL, &dummy, 0) == NULL); +} + +ATF_TC(libbpfjit_alu_add_k); +ATF_TC_HEAD(libbpfjit_alu_add_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_add_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 5); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_sub_k); +ATF_TC_HEAD(libbpfjit_alu_sub_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_sub_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mul_k); +ATF_TC_HEAD(libbpfjit_alu_mul_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_mul_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0xfffffffd)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div0_k); +ATF_TC_HEAD(libbpfjit_alu_div0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_div0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + //ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div1_k); +ATF_TC_HEAD(libbpfjit_alu_div1_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=1"); +} + +ATF_TC_BODY(libbpfjit_alu_div1_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div2_k); +ATF_TC_HEAD(libbpfjit_alu_div2_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=2"); +} + +ATF_TC_BODY(libbpfjit_alu_div2_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div4_k); +ATF_TC_HEAD(libbpfjit_alu_div4_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=4"); +} + +ATF_TC_BODY(libbpfjit_alu_div4_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x3fffffff)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10_k); +ATF_TC_HEAD(libbpfjit_alu_div10_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10"); +} + +ATF_TC_BODY(libbpfjit_alu_div10_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484384)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10000_k); +ATF_TC_HEAD(libbpfjit_alu_div10000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10000"); +} + +ATF_TC_BODY(libbpfjit_alu_div10000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10000), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div7609801_k); +ATF_TC_HEAD(libbpfjit_alu_div7609801_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=7609801"); +} + +ATF_TC_BODY(libbpfjit_alu_div7609801_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(7609801)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 564); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div80000000_k); +ATF_TC_HEAD(libbpfjit_alu_div80000000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0x80000000"); +} + +ATF_TC_BODY(libbpfjit_alu_div80000000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0x80000000)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_and_k); +ATF_TC_HEAD(libbpfjit_alu_and_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_AND+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_and_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead), + BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xbeef), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == (0xdead&0xbeef)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_or_k); +ATF_TC_HEAD(libbpfjit_alu_or_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_OR+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_or_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000), + BPF_STMT(BPF_ALU+BPF_OR+BPF_K, 0x0000beef), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh_k); +ATF_TC_HEAD(libbpfjit_alu_lsh_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 16), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xbeef0000); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh0_k); +ATF_TC_HEAD(libbpfjit_alu_lsh0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh_k); +ATF_TC_HEAD(libbpfjit_alu_rsh_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 16), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0x0000dead); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh0_k); +ATF_TC_HEAD(libbpfjit_alu_rsh0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_modulo_k); +ATF_TC_HEAD(libbpfjit_alu_modulo_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_ALU+BPF_K operations"); +} + +ATF_TC_BODY(libbpfjit_alu_modulo_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + + /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x0fffff77)), + + /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */ + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 1), + + /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xdddddddd)), + + /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */ + BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, UINT32_C(0xffffffff)), + + /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */ + BPF_STMT(BPF_ALU+BPF_OR+BPF_K, UINT32_C(0x0000030c)), + + /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */ + BPF_STMT(BPF_ALU+BPF_NEG, 0), + + /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */ + BPF_STMT(BPF_ALU+BPF_AND+BPF_K, UINT32_C(0xffffff0f)), + + /* F000009A,42218C74 >> 3 = 1E000013,48443180 */ + /* 00000000,42218C74 >> 3 = 00000000,08443180 */ + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 3), + + /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x7fffff77)), + + /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */ + /* 00000000,93818280 / DEAD = 00000000,0000A994 */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0xdead)), + + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3)); + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994)); + + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_add_x); +ATF_TC_HEAD(libbpfjit_alu_add_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_add_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 5); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_sub_x); +ATF_TC_HEAD(libbpfjit_alu_sub_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_sub_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mul_x); +ATF_TC_HEAD(libbpfjit_alu_mul_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_mul_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0xfffffffd)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div0_x); +ATF_TC_HEAD(libbpfjit_alu_div0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0"); +} + +ATF_TC_BODY(libbpfjit_alu_div0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div1_x); +ATF_TC_HEAD(libbpfjit_alu_div1_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=1"); +} + +ATF_TC_BODY(libbpfjit_alu_div1_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div2_x); +ATF_TC_HEAD(libbpfjit_alu_div2_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=2"); +} + +ATF_TC_BODY(libbpfjit_alu_div2_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div4_x); +ATF_TC_HEAD(libbpfjit_alu_div4_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=4"); +} + +ATF_TC_BODY(libbpfjit_alu_div4_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x3fffffff)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10_x); +ATF_TC_HEAD(libbpfjit_alu_div10_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10"); +} + +ATF_TC_BODY(libbpfjit_alu_div10_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484384)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10000_x); +ATF_TC_HEAD(libbpfjit_alu_div10000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10000"); +} + +ATF_TC_BODY(libbpfjit_alu_div10000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div7609801_x); +ATF_TC_HEAD(libbpfjit_alu_div7609801_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=7609801"); +} + +ATF_TC_BODY(libbpfjit_alu_div7609801_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 564); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div80000000_x); +ATF_TC_HEAD(libbpfjit_alu_div80000000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0x80000000"); +} + +ATF_TC_BODY(libbpfjit_alu_div80000000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX - 33), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_and_x); +ATF_TC_HEAD(libbpfjit_alu_and_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_AND+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_and_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0xbeef), + BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == (0xdead&0xbeef)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_or_x); +ATF_TC_HEAD(libbpfjit_alu_or_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_OR+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_or_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000beef), + BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh_x); +ATF_TC_HEAD(libbpfjit_alu_lsh_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xbeef0000); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh0_x); +ATF_TC_HEAD(libbpfjit_alu_lsh0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh_x); +ATF_TC_HEAD(libbpfjit_alu_rsh_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0x0000dead); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh0_x); +ATF_TC_HEAD(libbpfjit_alu_rsh0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_modulo_x); +ATF_TC_HEAD(libbpfjit_alu_modulo_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_ALU+BPF_X operations"); +} + +ATF_TC_BODY(libbpfjit_alu_modulo_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + + /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0fffff77)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + + /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, 1), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + + /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdddddddd)), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + + /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0), + + /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0000030c)), + BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0), + + /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */ + BPF_STMT(BPF_ALU+BPF_NEG, 0), + + /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffff0f)), + BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0), + + /* F000009A,42218C74 >> 3 = 1E000013,48443180 */ + /* 00000000,42218C74 >> 3 = 00000000,08443180 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, 3), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + + /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x7fffff77)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + + /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */ + /* 00000000,93818280 / DEAD = 00000000,0000A994 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdead)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3)); + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994)); + + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_neg); +ATF_TC_HEAD(libbpfjit_alu_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_NEG"); +} + +ATF_TC_BODY(libbpfjit_alu_neg, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 777), + BPF_STMT(BPF_ALU+BPF_NEG, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0u-777u); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_ja); +ATF_TC_HEAD(libbpfjit_jmp_ja, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JA"); +} + +ATF_TC_BODY(libbpfjit_jmp_ja, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jgt_k); +ATF_TC_HEAD(libbpfjit_jmp_jgt_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jgt_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 7, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 2, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 9, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 4, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 5, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jge_k); +ATF_TC_HEAD(libbpfjit_jmp_jge_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jge_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 3, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 9, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 5, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 6, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 1, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jeq_k); +ATF_TC_HEAD(libbpfjit_jmp_jeq_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jeq_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 1, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 5, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 7, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 7); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jset_k); +ATF_TC_HEAD(libbpfjit_jmp_jset_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jset_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 4, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 3, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 1, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 7, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 5); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_modulo_k); +ATF_TC_HEAD(libbpfjit_jmp_modulo_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_JMP+BPF_K operations"); +} + +ATF_TC_BODY(libbpfjit_jmp_modulo_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 0, 3), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 1, 0), + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + + /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)), + + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 1, 0), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 0, 3), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 1, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jgt_x); +ATF_TC_HEAD(libbpfjit_jmp_jgt_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jgt_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jge_x); +ATF_TC_HEAD(libbpfjit_jmp_jge_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jge_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jeq_x); +ATF_TC_HEAD(libbpfjit_jmp_jeq_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jeq_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 1, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 7); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jset_x); +ATF_TC_HEAD(libbpfjit_jmp_jset_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jset_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 3, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 5); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_modulo_x); +ATF_TC_HEAD(libbpfjit_jmp_modulo_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations"); +} + +ATF_TC_BODY(libbpfjit_jmp_modulo_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + /* FFFFF770 << 4 = FFFFF770 */ + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4), + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0), + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + + /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)), + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_abs); +ATF_TC_HEAD(libbpfjit_ld_abs, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_ld_abs, tc) +{ + static struct bpf_insn insns[3][2] = { + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + } + }; + + static size_t lengths[3] = { 1, 2, 4 }; + static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef }; + + size_t i, l; + uint8_t *pkt = deadbeef_at_5; + size_t pktsize = sizeof(deadbeef_at_5); + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + for (l = 1; l < 5 + lengths[i]; l++) { + ATF_CHECK(jitcall(code, pkt, l, l) == 0); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0); + } + + l = 5 + lengths[i]; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]); + + l = pktsize; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_abs_k_overflow); +ATF_TC_HEAD(libbpfjit_ld_abs_k_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4"); +} + +ATF_TC_BODY(libbpfjit_ld_abs_k_overflow, tc) +{ + static struct bpf_insn insns[12][3] = { + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3), + BPF_STMT(BPF_RET+BPF_K, 1) + } + }; + + int i; + uint8_t pkt[8] = { 0 }; + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_ind); +ATF_TC_HEAD(libbpfjit_ld_ind, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_ld_ind, tc) +{ + static struct bpf_insn insns[6][3] = { + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + } + }; + + static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 }; + + static unsigned int expected[6] = { + 0xde, 0xdead, 0xdeadbeef, + 0xde, 0xdead, 0xdeadbeef + }; + + size_t i, l; + uint8_t *pkt = deadbeef_at_5; + size_t pktsize = sizeof(deadbeef_at_5); + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + for (l = 1; l < 5 + lengths[i]; l++) { + ATF_CHECK(jitcall(code, pkt, l, l) == 0); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0); + } + + l = 5 + lengths[i]; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]); + + l = pktsize; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_ind_k_overflow); +ATF_TC_HEAD(libbpfjit_ld_ind_k_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4"); +} + +ATF_TC_BODY(libbpfjit_ld_ind_k_overflow, tc) +{ + static struct bpf_insn insns[12][3] = { + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3), + BPF_STMT(BPF_RET+BPF_K, 1) + } + }; + + int i; + uint8_t pkt[8] = { 0 }; + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_ind_x_overflow1); +ATF_TC_HEAD(libbpfjit_ld_ind_x_overflow1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4"); +} + +ATF_TC_BODY(libbpfjit_ld_ind_x_overflow1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_MISC+BPF_TAX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) { + ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i); + ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_ind_x_overflow2); +ATF_TC_HEAD(libbpfjit_ld_ind_x_overflow2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4"); +} + +ATF_TC_BODY(libbpfjit_ld_ind_x_overflow2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ST, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) { + ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i); + ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_len); +ATF_TC_HEAD(libbpfjit_ld_len, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN"); +} + +ATF_TC_BODY(libbpfjit_ld_len, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[32]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, 1) == i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_imm); +ATF_TC_HEAD(libbpfjit_ld_imm, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IMM"); +} + +ATF_TC_BODY(libbpfjit_ld_imm, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_imm1); +ATF_TC_HEAD(libbpfjit_ldx_imm1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_IMM"); +} + +ATF_TC_BODY(libbpfjit_ldx_imm1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX - 5); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_imm2); +ATF_TC_HEAD(libbpfjit_ldx_imm2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_IMM"); +} + +ATF_TC_BODY(libbpfjit_ldx_imm2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_len1); +ATF_TC_HEAD(libbpfjit_ldx_len1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_LEN"); +} + +ATF_TC_BODY(libbpfjit_ldx_len1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[5]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i < sizeof(pkt); i++) { + ATF_CHECK(jitcall(code, pkt, i, 1) == i); + ATF_CHECK(jitcall(code, pkt, i + 1, i) == i + 1); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_len2); +ATF_TC_HEAD(libbpfjit_ldx_len2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_LEN"); +} + +ATF_TC_BODY(libbpfjit_ldx_len2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LD+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX) + }; + + bpfjit_func_t code; + uint8_t pkt[5]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 5, 1) == UINT32_MAX); + ATF_CHECK(jitcall(code, pkt, 6, 5) == 7); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_msh); +ATF_TC_HEAD(libbpfjit_ldx_msh, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_MSH"); +} + +ATF_TC_BODY(libbpfjit_ldx_msh, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2] = { 0, 0x7a }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 2, 2) == 40); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_misc_tax); +ATF_TC_HEAD(libbpfjit_misc_tax, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_MISC+BPF_TAX"); +} + +ATF_TC_BODY(libbpfjit_misc_tax, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_MISC+BPF_TAX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[] = { 0, 11, 22, 33, 44, 55 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, sizeof(pkt), sizeof(pkt)) == 55); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_misc_txa); +ATF_TC_HEAD(libbpfjit_misc_txa, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_MISC+BPF_TXA"); +} + +ATF_TC_BODY(libbpfjit_misc_txa, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 391); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st1); +ATF_TC_HEAD(libbpfjit_st1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st2); +ATF_TC_HEAD(libbpfjit_st2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st3); +ATF_TC_HEAD(libbpfjit_st3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0), + BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1), + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_REQUIRE(BPF_MEMWORDS > 1); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 102); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st4); +ATF_TC_HEAD(libbpfjit_st4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st4, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0), + BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1), + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_LD+BPF_MEM, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_REQUIRE(BPF_MEMWORDS > 6); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 102); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st5); +ATF_TC_HEAD(libbpfjit_st5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st5, tc) +{ + struct bpf_insn insns[5*BPF_MEMWORDS+2]; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + size_t k; + bpfjit_func_t code; + uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */ + + memset(insns, 0, sizeof(insns)); + + /* for each k do M[k] = k */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*k].code = BPF_LD+BPF_IMM; + insns[2*k].k = 3*k; + insns[2*k+1].code = BPF_ST; + insns[2*k+1].k = k; + } + + /* load wirelen into A */ + insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN; + + /* for each k, if (A == k + 1) return M[k] */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K; + insns[2*BPF_MEMWORDS+3*k+1].k = k+1; + insns[2*BPF_MEMWORDS+3*k+1].jt = 0; + insns[2*BPF_MEMWORDS+3*k+1].jf = 2; + insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM; + insns[2*BPF_MEMWORDS+3*k+2].k = k; + insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A; + insns[2*BPF_MEMWORDS+3*k+3].k = 0; + } + + insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K; + insns[5*BPF_MEMWORDS+1].k = UINT32_MAX; + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (k = 1; k <= sizeof(pkt); k++) + ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx1); +ATF_TC_HEAD(libbpfjit_stx1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx2); +ATF_TC_HEAD(libbpfjit_stx2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, BPF_MEMWORDS-1), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx3); +ATF_TC_HEAD(libbpfjit_stx3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, 5), + BPF_STMT(BPF_STX, 2), + BPF_STMT(BPF_STX, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == 3 * i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx4); +ATF_TC_HEAD(libbpfjit_stx4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx4, tc) +{ + struct bpf_insn insns[5*BPF_MEMWORDS+2]; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + size_t k; + bpfjit_func_t code; + uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */ + + memset(insns, 0, sizeof(insns)); + + /* for each k do M[k] = k */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*k].code = BPF_LDX+BPF_W+BPF_IMM; + insns[2*k].k = 3*k; + insns[2*k+1].code = BPF_STX; + insns[2*k+1].k = k; + } + + /* load wirelen into A */ + insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN; + + /* for each k, if (A == k + 1) return M[k] */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K; + insns[2*BPF_MEMWORDS+3*k+1].k = k+1; + insns[2*BPF_MEMWORDS+3*k+1].jt = 0; + insns[2*BPF_MEMWORDS+3*k+1].jf = 2; + insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM; + insns[2*BPF_MEMWORDS+3*k+2].k = k; + insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A; + insns[2*BPF_MEMWORDS+3*k+3].k = 0; + } + + insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K; + insns[5*BPF_MEMWORDS+1].k = UINT32_MAX; + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (k = 1; k <= sizeof(pkt); k++) + ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_abs_1); +ATF_TC_HEAD(libbpfjit_opt_ld_abs_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_abs_1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_abs_2); +ATF_TC_HEAD(libbpfjit_opt_ld_abs_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_abs_2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_abs_3); +ATF_TC_HEAD(libbpfjit_opt_ld_abs_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_abs_3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_1); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_2); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_3); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_4); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_4, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_abc_ja); +ATF_TC_HEAD(libbpfjit_abc_ja, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization with a single BPF_JMP+BPF_JA"); +} + +ATF_TC_BODY(libbpfjit_abc_ja, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */ + BPF_STMT(BPF_JMP+BPF_JA, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */ + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_abc_ja_over); +ATF_TC_HEAD(libbpfjit_abc_ja_over, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads"); +} + +ATF_TC_BODY(libbpfjit_abc_ja_over, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_abc_ld_chain); +ATF_TC_HEAD(libbpfjit_abc_ld_chain, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization of a chain of BPF_LD instructions " + "with exits leading to a single BPF_RET"); +} + +ATF_TC_BODY(libbpfjit_abc_ld_chain, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */ + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */ + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 123456789), + BPF_STMT(BPF_RET+BPF_K, 987654321), + }; + + bpfjit_func_t code; + uint8_t pkt[10] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + + /* !(pkt[3] == 8) => return 123456789 */ + ATF_CHECK(jitcall(code, pkt, 4, 4) == 123456789); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 123456789); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 123456789); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 123456789); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789); + + /* !(pkt[4:2] >= 7) => too short or return 123456789 */ + pkt[3] = 8; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789); + + /* !(pkt[6:4] > 6) => too short or return 987654321 */ + pkt[4] = pkt[5] = 1; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 987654321); + + /* (pkt[6:4] > 6) => too short or return 123456789 */ + pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 123456789); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_examples_1); +ATF_TC_HEAD(libbpfjit_examples_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the first example from bpf(4) - " + "accept Reverse ARP requests"); +} + +ATF_TC_BODY(libbpfjit_examples_1, tc) +{ + /* + * The following filter is taken from the Reverse ARP + * Daemon. It accepts only Reverse ARP requests. + */ + struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 42), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[22] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 0x80; pkt[13] = 0x35; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + /* Set RARP message type. */ + pkt[21] = 3; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 42); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + + /* Change RARP message type. */ + pkt[20] = 3; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_examples_2); +ATF_TC_HEAD(libbpfjit_examples_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the second example from bpf(4) - " + "accept IP packets between two specified hosts"); +} + +ATF_TC_BODY(libbpfjit_examples_2, tc) +{ + /* + * This filter accepts only IP packets between host 128.3.112.15 + * and 128.3.112.35. + */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[34] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + ATF_CHECK(jitcall(code, pkt, 31, 31) == 0); + ATF_CHECK(jitcall(code, pkt, 32, 32) == 0); + ATF_CHECK(jitcall(code, pkt, 33, 33) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 8; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35; + ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX); + + /* Swap the ip addresses. */ + pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15; + ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + ATF_CHECK(jitcall(code, pkt, 31, 31) == 0); + ATF_CHECK(jitcall(code, pkt, 32, 32) == 0); + ATF_CHECK(jitcall(code, pkt, 33, 33) == 0); + + /* Change the protocol field. */ + pkt[13] = 8; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_examples_3); +ATF_TC_HEAD(libbpfjit_examples_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the third example from bpf(4) - " + "accept TCP finger packets"); +} + +ATF_TC_BODY(libbpfjit_examples_3, tc) +{ + /* + * This filter returns only TCP finger packets. + */ + struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0), + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[30] = {}; + + /* Set IP fragment offset to non-zero. */ + pkt[20] = 1; pkt[21] = 1; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 8; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Get one step closer to the match. */ + pkt[23] = 6; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Set IP fragment offset to zero. */ + pkt[20] = 0x20; pkt[21] = 0; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Set IP header length to 12. */ + pkt[14] = 0xd3; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Match one branch of the program. */ + pkt[27] = 79; + ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX); + + /* Match the other branch of the program. */ + pkt[29] = 79; pkt[27] = 0; + ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + + /* Set IP header length to 16. Packet is too short. */ + pkt[14] = 4; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_no_ctx); +ATF_TC_HEAD(libbpfjit_cop_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COP " + "instruction can't be accepted without a context"); +} + +ATF_TC_BODY(libbpfjit_cop_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_copx_no_ctx); +ATF_TC_HEAD(libbpfjit_copx_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COPX " + "instruction can't be accepted without a context"); +} + +ATF_TC_BODY(libbpfjit_copx_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpfjit/t_bpfjit.c + */ + ATF_TP_ADD_TC(tp, libbpfjit_empty); + ATF_TP_ADD_TC(tp, libbpfjit_alu_add_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_sub_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mul_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div0_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div1_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div2_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div4_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10000_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div7609801_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div80000000_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_and_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_or_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh0_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh0_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_modulo_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_add_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_sub_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mul_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div0_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div1_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div2_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div4_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10000_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div7609801_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div80000000_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_and_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_or_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh0_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh0_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_modulo_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_neg); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_ja); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jgt_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jge_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jset_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_modulo_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jgt_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jge_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jset_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_modulo_x); + ATF_TP_ADD_TC(tp, libbpfjit_ld_abs); + ATF_TP_ADD_TC(tp, libbpfjit_ld_abs_k_overflow); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_k_overflow); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_x_overflow1); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_x_overflow2); + ATF_TP_ADD_TC(tp, libbpfjit_ld_len); + ATF_TP_ADD_TC(tp, libbpfjit_ld_imm); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_imm1); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_imm2); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_len1); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_len2); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_msh); + ATF_TP_ADD_TC(tp, libbpfjit_misc_tax); + ATF_TP_ADD_TC(tp, libbpfjit_misc_txa); + ATF_TP_ADD_TC(tp, libbpfjit_st1); + ATF_TP_ADD_TC(tp, libbpfjit_st2); + ATF_TP_ADD_TC(tp, libbpfjit_st3); + ATF_TP_ADD_TC(tp, libbpfjit_st4); + ATF_TP_ADD_TC(tp, libbpfjit_st5); + ATF_TP_ADD_TC(tp, libbpfjit_stx1); + ATF_TP_ADD_TC(tp, libbpfjit_stx2); + ATF_TP_ADD_TC(tp, libbpfjit_stx3); + ATF_TP_ADD_TC(tp, libbpfjit_stx4); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_1); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_2); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_3); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_1); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_2); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_3); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_4); + ATF_TP_ADD_TC(tp, libbpfjit_abc_ja); + ATF_TP_ADD_TC(tp, libbpfjit_abc_ja_over); + ATF_TP_ADD_TC(tp, libbpfjit_abc_ld_chain); + ATF_TP_ADD_TC(tp, libbpfjit_examples_1); + ATF_TP_ADD_TC(tp, libbpfjit_examples_2); + ATF_TP_ADD_TC(tp, libbpfjit_examples_3); + ATF_TP_ADD_TC(tp, libbpfjit_cop_no_ctx); + ATF_TP_ADD_TC(tp, libbpfjit_copx_no_ctx); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_cop.c b/contrib/netbsd-tests/lib/libbpfjit/t_cop.c new file mode 100644 index 0000000..7b3b086 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbpfjit/t_cop.c @@ -0,0 +1,657 @@ +/* $NetBSD: t_cop.c,v 1.4 2014/07/13 21:35:33 alnsn Exp $ */ + +/*- + * Copyright (c) 2013-2014 Alexander Nasonov. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_cop.c,v 1.4 2014/07/13 21:35:33 alnsn Exp $"); + +#include <atf-c.h> +#include <stdint.h> +#include <string.h> + +#define __BPF_PRIVATE +#include <net/bpf.h> +#include <net/bpfjit.h> + +static uint32_t retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); + +static const bpf_copfunc_t copfuncs[] = { + &retA, + &retBL, + &retWL, + &retNF, + &setARG +}; + +static const bpf_ctx_t ctx = { + .copfuncs = copfuncs, + .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]), + .extwords = 0 +}; + +static uint32_t +retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return A; +} + +static uint32_t +retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->buflen; +} + +static uint32_t +retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->wirelen; +} + +static uint32_t +retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return bc->nfuncs; +} + +/* + * COP function with a side effect. + */ +static uint32_t +setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + bool *arg = (bool *)args->arg; + bool old = *arg; + + *arg = true; + return old; +} + +ATF_TC(libbpfjit_cop_no_ctx); +ATF_TC_HEAD(libbpfjit_cop_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COP " + "instruction isn't valid without a context"); +} + +ATF_TC_BODY(libbpfjit_cop_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_CHECK(code == NULL); +} + +ATF_TC(libbpfjit_cop_ret_A); +ATF_TC_HEAD(libbpfjit_cop_ret_A, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of the A register"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_A, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retA + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_buflen); +ATF_TC_HEAD(libbpfjit_cop_ret_buflen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the buflen argument"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_buflen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 1), // retBL + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_wirelen); +ATF_TC_HEAD(libbpfjit_cop_ret_wirelen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the wirelen argument"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_wirelen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 2), // retWL + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_nfuncs); +ATF_TC_HEAD(libbpfjit_cop_ret_nfuncs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns nfuncs member of the context argument"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_nfuncs, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 3), // retNF + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_side_effect); +ATF_TC_HEAD(libbpfjit_cop_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that ABC optimization doesn't skip BPF_COP call"); +} + +ATF_TC_BODY(libbpfjit_cop_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), + BPF_STMT(BPF_MISC+BPF_COP, 4), // setARG + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + bool arg = false; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = NULL, + .arg = &arg + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + ATF_CHECK(arg == true); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_copx); +ATF_TC_HEAD(libbpfjit_cop_copx, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_COP call followed by BPF_COPX call"); +} + +ATF_TC_BODY(libbpfjit_cop_copx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + BPF_STMT(BPF_MISC+BPF_COP, 0), /* retA */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retNF */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 2 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3 + ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_invalid_index); +ATF_TC_HEAD(libbpfjit_cop_invalid_index, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that out-of-range coprocessor function fails validation"); +} + +ATF_TC_BODY(libbpfjit_cop_invalid_index, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 6), // invalid index + BPF_STMT(BPF_RET+BPF_K, 27) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_copx_no_ctx); +ATF_TC_HEAD(libbpfjit_copx_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COPX " + "instruction isn't valid without a context"); +} + +ATF_TC_BODY(libbpfjit_copx_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_CHECK(code == NULL); +} + +ATF_TC(libbpfjit_copx_ret_A); +ATF_TC_HEAD(libbpfjit_copx_ret_A, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of the A register"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_A, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retA + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_buflen); +ATF_TC_HEAD(libbpfjit_copx_ret_buflen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the buflen argument"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_buflen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 1), // retBL + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_wirelen); +ATF_TC_HEAD(libbpfjit_copx_ret_wirelen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the wirelen argument"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_wirelen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 2), // retWL + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_nfuncs); +ATF_TC_HEAD(libbpfjit_copx_ret_nfuncs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns nfuncs member of the context argument"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_nfuncs, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 3), // retNF + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_side_effect); +ATF_TC_HEAD(libbpfjit_copx_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that ABC optimization doesn't skip BPF_COPX call"); +} + +ATF_TC_BODY(libbpfjit_copx_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), + BPF_STMT(BPF_LDX+BPF_IMM, 4), // setARG + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + bool arg = false; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = NULL, + .arg = &arg + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + ATF_CHECK(arg == true); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_cop); +ATF_TC_HEAD(libbpfjit_copx_cop, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_COPX call followed by BPF_COP call"); +} + +ATF_TC_BODY(libbpfjit_copx_cop, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retWL */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_MISC+BPF_COP, 3), /* retNF */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 2 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 5 + ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_invalid_index); +ATF_TC_HEAD(libbpfjit_copx_invalid_index, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that out-of-range BPF_COPX call fails at runtime"); +} + +ATF_TC_BODY(libbpfjit_copx_invalid_index, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 5), // invalid index + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_K, 27) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + bpfjit_free_code(code); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpfjit/t_cop.c + */ + ATF_TP_ADD_TC(tp, libbpfjit_cop_no_ctx); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_A); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_buflen); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_wirelen); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_nfuncs); + ATF_TP_ADD_TC(tp, libbpfjit_cop_side_effect); + ATF_TP_ADD_TC(tp, libbpfjit_cop_copx); + ATF_TP_ADD_TC(tp, libbpfjit_cop_invalid_index); + + ATF_TP_ADD_TC(tp, libbpfjit_copx_no_ctx); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_A); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_buflen); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_wirelen); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_nfuncs); + ATF_TP_ADD_TC(tp, libbpfjit_copx_side_effect); + ATF_TP_ADD_TC(tp, libbpfjit_copx_cop); + ATF_TP_ADD_TC(tp, libbpfjit_copx_invalid_index); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c b/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c new file mode 100644 index 0000000..ab6ea88 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c @@ -0,0 +1,483 @@ +/* $NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $ */ + +/*- + * Copyright (c) 2014 Alexander Nasonov. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $"); + +#include <atf-c.h> +#include <stdint.h> +#include <string.h> + +#define __BPF_PRIVATE +#include <net/bpf.h> +#include <net/bpfjit.h> + +static uint32_t retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); + +static const bpf_copfunc_t copfuncs[] = { + &retM +}; + +static const bpf_ctx_t ctx = { + .copfuncs = copfuncs, + .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]), + .extwords = 4, + .preinited = BPF_MEMWORD_INIT(0) | BPF_MEMWORD_INIT(3), +}; + +static uint32_t +retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->mem[(uintptr_t)args->arg]; +} + + +ATF_TC(libbpfjit_extmem_load_default); +ATF_TC_HEAD(libbpfjit_extmem_load_default, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that external memory " + "is zero initialized by default"); +} + +ATF_TC_BODY(libbpfjit_extmem_load_default, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 1), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_extmem_load_preinited); +ATF_TC_HEAD(libbpfjit_extmem_load_preinited, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test a load of external " + "pre-initialized memory"); +} + +ATF_TC_BODY(libbpfjit_extmem_load_preinited, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 3), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_extmem_invalid_load); +ATF_TC_HEAD(libbpfjit_extmem_invalid_load, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that out-of-range load " + "fails validation"); +} + +ATF_TC_BODY(libbpfjit_extmem_invalid_load, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_extmem_store); +ATF_TC_HEAD(libbpfjit_extmem_store, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stores to external memory"); +} + +ATF_TC_BODY(libbpfjit_extmem_store, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_ST, 1), /* M[1] <- A */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_STX, 2), /* M[2] <- X */ + BPF_STMT(BPF_ST, 3), /* M[3] <- A */ + BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */ + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 7; + + mem[1] = mem[2] = 0xdeadbeef; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); + + ATF_CHECK(mem[0] == 0); + ATF_CHECK(mem[1] == 1); + ATF_CHECK(mem[2] == 2); + ATF_CHECK(mem[3] == 3); +} + +ATF_TC(libbpfjit_extmem_side_effect); +ATF_TC_HEAD(libbpfjit_extmem_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that ABC optimization doesn\'t " + "skip stores to external memory"); +} + +ATF_TC_BODY(libbpfjit_extmem_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_ST, 1), /* M[1] <- A */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_STX, 2), /* M[2] <- X */ + BPF_STMT(BPF_ST, 3), /* M[3] <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */ + BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */ + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 1 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 7; + + mem[1] = mem[2] = 0xdeadbeef; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + bpfjit_free_code(code); + + ATF_CHECK(mem[0] == 0); + ATF_CHECK(mem[1] == 1); + ATF_CHECK(mem[2] == 2); + ATF_CHECK(mem[3] == 3); +} + +ATF_TC(libbpfjit_extmem_invalid_store); +ATF_TC_HEAD(libbpfjit_extmem_invalid_store, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that out-of-range store " + "fails validation"); +} + +ATF_TC_BODY(libbpfjit_extmem_invalid_store, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ST, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_cop_ret_mem); +ATF_TC_HEAD(libbpfjit_cop_ret_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of external memory word"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retM + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)2; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_preinited_mem); +ATF_TC_HEAD(libbpfjit_cop_ret_preinited_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function that " + "returns a content of external pre-initialized memory word"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_preinited_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retM + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)3; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_mem); +ATF_TC_HEAD(libbpfjit_copx_ret_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of external memory word"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)2; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_preinited_mem); +ATF_TC_HEAD(libbpfjit_copx_ret_preinited_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function that " + "returns a content of external pre-initialized memory word"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_preinited_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)3; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpfjit/t_extmem.c + */ + ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_default); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_preinited); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_load); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_store); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_side_effect); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_store); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_mem); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_preinited_mem); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_mem); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_preinited_mem); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c new file mode 100644 index 0000000..56a1be8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S new file mode 100644 index 0000000..d237982 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2014/08/10 05:47:38 matt Exp $ */ + +#include <machine/asm.h> + +ENTRY_NP(return_one) + mov x0, #1 + ret + .globl return_one_end +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S new file mode 100644 index 0000000..18800e2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2014/01/26 20:42:06 matt Exp $ */ + +#include <machine/asm.h> + +ENTRY_NP(return_one) + mov r0, #1 + RET + .align 0 + .globl return_one_end +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c new file mode 100644 index 0000000..11a20f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c @@ -0,0 +1,65 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include <stdlib.h> +#include <sys/sysctl.h> + +#include "../../common/exec_prot.h" + +/* + * Support for executable space protection has always been erratic under i386. + * Originally IA-32 can't do per-page execute permission, so it is + * implemented using different executable segments for %cs (code segment). + * This only allows coarse grained protection, especially when memory starts + * being fragmented. + * Later, PAE was introduced together with a NX/XD bit in the page table + * entry to offer per-page permission. + */ +int +exec_prot_support(void) +{ + int pae; + size_t pae_len = sizeof(pae); + + if (sysctlbyname("machdep.pae", &pae, &pae_len, NULL, 0) == -1) + return PARTIAL_XP; + + if (pae == 1) { + if (system("cpuctl identify 0 | grep -q NOX") == 0 || + system("cpuctl identify 0 | grep -q XD") == 0) + return PERPAGE_XP; + } + + return PARTIAL_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S new file mode 100644 index 0000000..f80fd74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +_ENTRY(return_one) + movl $0x1,%eax + ret +LABEL(return_one_end) diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c new file mode 100644 index 0000000..623456b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return PERPAGE_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S new file mode 100644 index 0000000..ba3d678 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S @@ -0,0 +1,12 @@ +/* $NetBSD: return_one.S,v 1.1 2014/09/03 19:34:26 matt Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end + +ENTRY_NP(return_one) + l.addi r11, r0, 1 + l.jr lr + l.nop +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c new file mode 100644 index 0000000..81c1d86 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c @@ -0,0 +1,52 @@ +/* $NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $"); + +#include "../../common/exec_prot.h" + +#include <sys/sysctl.h> + +int +exec_prot_support(void) +{ + int execprot = 0; + size_t len = sizeof(execprot); + + if (sysctlbyname("machdep.execprot", &execprot, &len, NULL, 0) < 0) + return NOTIMPL; + + if (execprot) + return PERPAGE_XP; + + return NO_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S new file mode 100644 index 0000000..d40298e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2012/03/16 08:51:47 matt Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end + +_ENTRY(return_one) + li %r3, 1 + blr +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c new file mode 100644 index 0000000..91c5ff4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return PERPAGE_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S new file mode 100644 index 0000000..43ddd2c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.1 2014/09/19 17:36:26 matt Exp $ */ + +#include <machine/asm.h> + + .globl return_one_end + +ENTRY_NP(return_one) + li v0, 1 + ret +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c new file mode 100644 index 0000000..2d8363d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c @@ -0,0 +1,50 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $"); + +#include <stdlib.h> + +#include "../../common/exec_prot.h" + +/* + * When the NX/XD flag is present, the protection should be enabled. + */ +int +exec_prot_support(void) +{ + if (system("cpuctl identify 0 | grep -q NOX") == 0 || + system("cpuctl identify 0 | grep -q XD") == 0) + return PERPAGE_XP; + + return NO_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S new file mode 100644 index 0000000..0903001 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $"); + +_ENTRY(return_one) + movq $0x1, %rax + retq +LABEL(return_one_end) diff --git a/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c new file mode 100644 index 0000000..c9e0cc8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c @@ -0,0 +1,185 @@ +/* $NetBSD: t_faccessat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_faccessat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/faccessat" +#define BASEFILE "faccessat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/faccessaterr" + +ATF_TC(faccessat_fd); +ATF_TC_HEAD(faccessat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat works with fd"); +} +ATF_TC_BODY(faccessat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fdcwd); +ATF_TC_HEAD(faccessat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that faccessat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(faccessat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(faccessat(AT_FDCWD, BASEFILE, F_OK, 0) == 0); +} + +ATF_TC(faccessat_fdcwderr); +ATF_TC_HEAD(faccessat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that faccessat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(faccessat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(faccessat(AT_FDCWD, FILEERR, F_OK, 0) == -1); +} + +ATF_TC(faccessat_fderr1); +ATF_TC_HEAD(faccessat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fail with bad path"); +} +ATF_TC_BODY(faccessat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, FILEERR, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fderr2); +ATF_TC_HEAD(faccessat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fails with bad fdat"); +} +ATF_TC_BODY(faccessat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fderr3); +ATF_TC_HEAD(faccessat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fails with fd as -1"); +} +ATF_TC_BODY(faccessat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(faccessat(-1, FILE, F_OK, 0) == -1); +} + +ATF_TC(faccessat_fdlink); +ATF_TC_HEAD(faccessat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat works on symlink"); +} +ATF_TC_BODY(faccessat_fdlink, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, faccessat_fd); + ATF_TP_ADD_TC(tp, faccessat_fdcwd); + ATF_TP_ADD_TC(tp, faccessat_fdcwderr); + ATF_TP_ADD_TC(tp, faccessat_fderr1); + ATF_TP_ADD_TC(tp, faccessat_fderr2); + ATF_TP_ADD_TC(tp, faccessat_fderr3); + ATF_TP_ADD_TC(tp, faccessat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c new file mode 100644 index 0000000..462d53d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c @@ -0,0 +1,197 @@ +/* $NetBSD: t_fchmodat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fchmodat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/fchmodat" +#define BASEFILE "fchmodat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/fchmodaterr" + +ATF_TC(fchmodat_fd); +ATF_TC_HEAD(fchmodat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat works with fd"); +} +ATF_TC_BODY(fchmodat_fd, tc) +{ + int dfd; + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TC(fchmodat_fdcwd); +ATF_TC_HEAD(fchmodat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchmodat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(fchmodat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fchmodat(AT_FDCWD, BASEFILE, 0600, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TC(fchmodat_fdcwderr); +ATF_TC_HEAD(fchmodat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchmodat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(fchmodat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fchmodat(AT_FDCWD, FILEERR, 0600, 0) == -1); +} + +ATF_TC(fchmodat_fderr1); +ATF_TC_HEAD(fchmodat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fail with bad path"); +} +ATF_TC_BODY(fchmodat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, FILEERR, 0600, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchmodat_fderr2); +ATF_TC_HEAD(fchmodat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with bad fdat"); +} +ATF_TC_BODY(fchmodat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchmodat_fderr3); +ATF_TC_HEAD(fchmodat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with fd as -1"); +} +ATF_TC_BODY(fchmodat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmodat(-1, FILE, 0600, 0) == -1); +} + +ATF_TC(fchmodat_fdlink); +ATF_TC_HEAD(fchmodat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat works on symlink"); +} +ATF_TC_BODY(fchmodat_fdlink, tc) +{ + int dfdlink; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE((dfdlink = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, 0) == -1); + ATF_REQUIRE(errno = ENOENT); + + ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfdlink) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fchmodat_fd); + ATF_TP_ADD_TC(tp, fchmodat_fdcwd); + ATF_TP_ADD_TC(tp, fchmodat_fdcwderr); + ATF_TP_ADD_TC(tp, fchmodat_fderr1); + ATF_TP_ADD_TC(tp, fchmodat_fderr2); + ATF_TP_ADD_TC(tp, fchmodat_fderr3); + ATF_TP_ADD_TC(tp, fchmodat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c new file mode 100644 index 0000000..80c7606 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c @@ -0,0 +1,247 @@ +/* $NetBSD: t_fchownat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fchownat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/fchownat" +#define BASEFILE "fchownat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/fchownaterr" +#define USER "nobody" + +static int getuser(uid_t *, gid_t *); + +static int getuser(uid_t *uid, gid_t *gid) +{ + struct passwd *pw; + + if ((pw = getpwnam(USER)) == NULL) + return -1; + + *uid = pw->pw_uid; + *gid = pw->pw_gid; + + return 0; +} + +ATF_TC(fchownat_fd); +ATF_TC_HEAD(fchownat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat works with fd"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fd, tc) +{ + int dfd; + int fd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TC(fchownat_fdcwd); +ATF_TC_HEAD(fchownat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchownat works with fd as AT_FDCWD"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdcwd, tc) +{ + int fd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fchownat(AT_FDCWD, BASEFILE, uid, gid, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TC(fchownat_fdcwderr); +ATF_TC_HEAD(fchownat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchownat fails with fd as AT_FDCWD and bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdcwderr, tc) +{ + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fchownat(AT_FDCWD, FILEERR, uid, gid, 0) == -1); +} + +ATF_TC(fchownat_fderr1); +ATF_TC_HEAD(fchownat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fail with bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr1, tc) +{ + int dfd; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, FILEERR, uid, gid, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchownat_fderr2); +ATF_TC_HEAD(fchownat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fails with bad fdat"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchownat_fderr3); +ATF_TC_HEAD(fchownat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fails with fd as -1"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr3, tc) +{ + int fd; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchownat(-1, FILE, uid, gid, 0) == -1); +} + +ATF_TC(fchownat_fdlink); +ATF_TC_HEAD(fchownat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat works on symlink"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdlink, tc) +{ + int dfd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* Target does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid, + AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fchownat_fd); + ATF_TP_ADD_TC(tp, fchownat_fdcwd); + ATF_TP_ADD_TC(tp, fchownat_fdcwderr); + ATF_TP_ADD_TC(tp, fchownat_fderr1); + ATF_TP_ADD_TC(tp, fchownat_fderr2); + ATF_TP_ADD_TC(tp, fchownat_fderr3); + ATF_TP_ADD_TC(tp, fchownat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c new file mode 100644 index 0000000..d557b00 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c @@ -0,0 +1,94 @@ +/* $NetBSD: t_fexecve.c,v 1.2 2013/03/17 04:35:59 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fexecve.c,v 1.2 2013/03/17 04:35:59 jmmv Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +ATF_TC(fexecve); +ATF_TC_HEAD(fexecve, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fexecve works"); +} +ATF_TC_BODY(fexecve, tc) +{ + int status; + pid_t pid; + const char *const argv[] = { "touch", "test", NULL }; + const char *const envp[] = { NULL }; + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + int fd; + + if ((fd = open("/usr/bin/touch", O_RDONLY, 0)) == -1) + err(EXIT_FAILURE, "open /usr/bin/touch"); + + if (fexecve(fd, __UNCONST(argv), __UNCONST(envp)) == -1) { + int error; + if (errno == ENOSYS) + error = 76; + else + error = EXIT_FAILURE; + err(error, "fexecve"); + } + } + + ATF_REQUIRE(waitpid(pid, &status, 0) != -1); + if (!WIFEXITED(status)) + atf_tc_fail("child process did not exit cleanly"); + if (WEXITSTATUS(status) == 76) + atf_tc_expect_fail("fexecve not implemented"); + else + ATF_REQUIRE(WEXITSTATUS(status) == EXIT_SUCCESS); + + ATF_REQUIRE(access("test", F_OK) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fexecve); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c new file mode 100644 index 0000000..a48cd57 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c @@ -0,0 +1,196 @@ +/* $NetBSD: t_fstatat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fstatat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/fstatat" +#define BASEFILE "fstatat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/symlink" + +ATF_TC(fstatat_fd); +ATF_TC_HEAD(fstatat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat works with fd"); +} +ATF_TC_BODY(fstatat_fd, tc) +{ + int dfd; + int fd; + struct stat st1, st2; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, BASEFILE, &st1, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st2) == 0); + ATF_REQUIRE(memcmp(&st1, &st2, sizeof(st1)) == 0); +} + +ATF_TC(fstatat_fdcwd); +ATF_TC_HEAD(fstatat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fstatat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(fstatat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fstatat(AT_FDCWD, BASEFILE, &st, 0) == 0); +} + +ATF_TC(fstatat_fdcwderr); +ATF_TC_HEAD(fstatat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fstatat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(fstatat_fdcwderr, tc) +{ + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fstatat(AT_FDCWD, FILEERR, &st, 0) == -1); +} + +ATF_TC(fstatat_fderr1); +ATF_TC_HEAD(fstatat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fail with bad path"); +} +ATF_TC_BODY(fstatat_fderr1, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, FILEERR, &st, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fstatat_fderr2); +ATF_TC_HEAD(fstatat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fails with bad fdat"); +} +ATF_TC_BODY(fstatat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, BASEFILE, &st, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fstatat_fderr3); +ATF_TC_HEAD(fstatat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fails with fd as -1"); +} +ATF_TC_BODY(fstatat_fderr3, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fstatat(-1, FILE, &st, 0) == -1); +} + +ATF_TC(fstatat_fdlink); +ATF_TC_HEAD(fstatat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat works on symlink"); +} +ATF_TC_BODY(fstatat_fdlink, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* target does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fstatat(dfd, BASELINK, &st, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(fstatat(dfd, BASELINK, &st, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fstatat_fd); + ATF_TP_ADD_TC(tp, fstatat_fdcwd); + ATF_TP_ADD_TC(tp, fstatat_fdcwderr); + ATF_TP_ADD_TC(tp, fstatat_fderr1); + ATF_TP_ADD_TC(tp, fstatat_fderr2); + ATF_TP_ADD_TC(tp, fstatat_fderr3); + ATF_TP_ADD_TC(tp, fstatat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_linkat.c b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c new file mode 100644 index 0000000..b49a3f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c @@ -0,0 +1,217 @@ +/* $NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define TARGET "newdir/new" +#define BASETARGET "new" +#define LINK "olddir/symlink" +#define BASELINK "symlink" +#define FILEERR "olddir/olderr" + +ATF_TC(linkat_fd); +ATF_TC_HEAD(linkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works with fd"); +} +ATF_TC_BODY(linkat_fd, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASEFILE, nfd, BASETARGET, 0) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(linkat_fdcwd); +ATF_TC_HEAD(linkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that linkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(linkat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(AT_FDCWD, FILE, AT_FDCWD, TARGET, 0) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(linkat_fdcwderr); +ATF_TC_HEAD(linkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that linkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(linkat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET, 0) == -1); +} + +ATF_TC(linkat_fderr); +ATF_TC_HEAD(linkat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat fails with fd as -1"); +} +ATF_TC_BODY(linkat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(-1, FILE, AT_FDCWD, TARGET, 0) == -1); + ATF_REQUIRE(linkat(AT_FDCWD, FILE, -1, TARGET, 0) == -1); + ATF_REQUIRE(linkat(-1, FILE, -1, TARGET, 0) == -1); +} + +ATF_TC(linkat_fdlink1); +ATF_TC_HEAD(linkat_fdlink1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink target"); +} +ATF_TC_BODY(linkat_fdlink1, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + ATF_REQUIRE(symlink(RELFILE, LINK) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET, + AT_SYMLINK_FOLLOW) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(lstat(LINK, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino != nst.st_ino); + + ATF_REQUIRE(lstat(FILE, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + + +ATF_TC(linkat_fdlink2); +ATF_TC_HEAD(linkat_fdlink2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink source"); +} +ATF_TC_BODY(linkat_fdlink2, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + ATF_REQUIRE(symlink(RELFILE, LINK) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET, 0) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(lstat(LINK, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); + + ATF_REQUIRE(lstat(FILE, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino != nst.st_ino); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, linkat_fd); + ATF_TP_ADD_TC(tp, linkat_fdcwd); + ATF_TP_ADD_TC(tp, linkat_fdcwderr); + ATF_TP_ADD_TC(tp, linkat_fderr); + ATF_TP_ADD_TC(tp, linkat_fdlink1); + ATF_TP_ADD_TC(tp, linkat_fdlink2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c new file mode 100644 index 0000000..23c53d7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define DIR "dir" +#define SDIR "dir/openat" +#define BASESDIR "openat" +#define SDIRERR "dir/openaterr" + +ATF_TC(mkdirat_fd); +ATF_TC_HEAD(mkdirat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkdirat works with fd"); +} +ATF_TC_BODY(mkdirat_fd, tc) +{ + int dfd; + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(mkdirat(dfd, BASESDIR, mode) != -1); + ATF_REQUIRE(close(dfd) == 0); + ATF_REQUIRE(access(SDIR, F_OK) == 0); +} + +ATF_TC(mkdirat_fdcwd); +ATF_TC_HEAD(mkdirat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkdirat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(mkdirat_fdcwd, tc) +{ + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(mkdirat(AT_FDCWD, SDIR, mode) != -1); + ATF_REQUIRE(access(SDIR, F_OK) == 0); +} + +ATF_TC(mkdirat_fdcwderr); +ATF_TC_HEAD(mkdirat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkdirat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(mkdirat_fdcwderr, tc) +{ + mode_t mode = 0755; + + ATF_REQUIRE(mkdirat(AT_FDCWD, SDIRERR, mode) == -1); +} + +ATF_TC(mkdirat_fderr); +ATF_TC_HEAD(mkdirat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkdirat fails with fd as -1"); +} +ATF_TC_BODY(mkdirat_fderr, tc) +{ + int fd; + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(SDIR, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(mkdirat(-1, SDIR, mode) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkdirat_fd); + ATF_TP_ADD_TC(tp, mkdirat_fdcwd); + ATF_TP_ADD_TC(tp, mkdirat_fdcwderr); + ATF_TP_ADD_TC(tp, mkdirat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c new file mode 100644 index 0000000..1ae023c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c @@ -0,0 +1,124 @@ +/* $NetBSD: t_mkfifoat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mkfifoat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define DIR "dir" +#define FIFO "dir/openat" +#define BASEFIFO "openat" +#define FIFOERR "dir/openaterr" + +ATF_TC(mkfifoat_fd); +ATF_TC_HEAD(mkfifoat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkfifoat works with fd"); +} +ATF_TC_BODY(mkfifoat_fd, tc) +{ + int dfd; + int fd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = mkfifoat(dfd, BASEFIFO, mode)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FIFO, F_OK) == 0); +} + +ATF_TC(mkfifoat_fdcwd); +ATF_TC_HEAD(mkfifoat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkfifoat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(mkfifoat_fdcwd, tc) +{ + int fd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = mkfifoat(AT_FDCWD, FIFO, mode)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FIFO, F_OK) == 0); +} + +ATF_TC(mkfifoat_fdcwderr); +ATF_TC_HEAD(mkfifoat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkfifoat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(mkfifoat_fdcwderr, tc) +{ + int fd; + mode_t mode = 0600; + + ATF_REQUIRE((fd = mkfifoat(AT_FDCWD, FIFOERR, mode)) == -1); +} + +ATF_TC(mkfifoat_fderr); +ATF_TC_HEAD(mkfifoat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkfifoat fails with fd as -1"); +} +ATF_TC_BODY(mkfifoat_fderr, tc) +{ + int fd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FIFO, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE((fd = mkfifoat(-1, FIFO, mode)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkfifoat_fd); + ATF_TP_ADD_TC(tp, mkfifoat_fdcwd); + ATF_TP_ADD_TC(tp, mkfifoat_fdcwderr); + ATF_TP_ADD_TC(tp, mkfifoat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c new file mode 100644 index 0000000..b04a159 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_mknodat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mknodat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define DIR "dir" +#define FILE "dir/openat" +#define BASEFILE "openat" +#define FILEERR "dir/openaterr" + +static dev_t get_devnull(void); + +static dev_t +get_devnull(void) +{ + struct stat st; + + if (stat(_PATH_DEVNULL, &st) != 0) + return NODEV; + + return st.st_rdev; +} + + +ATF_TC(mknodat_fd); +ATF_TC_HEAD(mknodat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mknodat works with fd"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fd, tc) +{ + int dfd; + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = mknodat(dfd, BASEFILE, mode, dev)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FILE, F_OK) == 0); +} + +ATF_TC(mknodat_fdcwd); +ATF_TC_HEAD(mknodat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mknodat works with fd as AT_FDCWD"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fdcwd, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILE, mode, dev)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FILE, F_OK) == 0); +} + +ATF_TC(mknodat_fdcwderr); +ATF_TC_HEAD(mknodat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mknodat fails with fd as AT_FDCWD and bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fdcwderr, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILEERR, mode, dev)) == -1); +} + +ATF_TC(mknodat_fderr); +ATF_TC_HEAD(mknodat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mknodat fails with fd as -1"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fderr, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE((fd = mknodat(-1, FILE, mode, dev)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mknodat_fd); + ATF_TP_ADD_TC(tp, mknodat_fdcwd); + ATF_TP_ADD_TC(tp, mknodat_fdcwderr); + ATF_TP_ADD_TC(tp, mknodat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_o_search.c b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c new file mode 100644 index 0000000..d9dbe19 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c @@ -0,0 +1,278 @@ +/* $NetBSD: t_o_search.c,v 1.4 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_o_search.c,v 1.4 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> +#include <sys/param.h> + +/* + * dholland 20130112: disable tests that require O_SEARCH semantics + * until a decision is reached about the semantics of O_SEARCH and a + * non-broken implementation is available. + */ +#if (O_MASK & O_SEARCH) != 0 +#define USE_O_SEARCH +#endif + +#define DIR "dir" +#define FILE "dir/o_search" +#define BASEFILE "o_search" + + +ATF_TC(o_search_perm1); +ATF_TC_HEAD(o_search_perm1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat enforces search permission"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_perm1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1); + ATF_REQUIRE(errno == EACCES); + + ATF_REQUIRE(close(dfd) == 0); +} + +#ifdef USE_O_SEARCH + +ATF_TC(o_search_root_flag1); +ATF_TC_HEAD(o_search_root_flag1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that root openat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(o_search_root_flag1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(o_search_unpriv_flag1); +ATF_TC_HEAD(o_search_unpriv_flag1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_unpriv_flag1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + + ATF_REQUIRE(close(dfd) == 0); +} + +#endif /* USE_O_SEARCH */ + +ATF_TC(o_search_perm2); +ATF_TC_HEAD(o_search_perm2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat enforces search permission"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_perm2, tc) +{ + int dfd; + int fd; + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == -1); + ATF_REQUIRE(errno == EACCES); + + ATF_REQUIRE(close(dfd) == 0); +} + +#ifdef USE_O_SEARCH + +ATF_TC(o_search_root_flag2); +ATF_TC_HEAD(o_search_root_flag2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that root fstatat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(o_search_root_flag2, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(o_search_unpriv_flag2); +ATF_TC_HEAD(o_search_unpriv_flag2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_unpriv_flag2, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +#endif /* USE_O_SEARCH */ + + +ATF_TC(o_search_notdir); +ATF_TC_HEAD(o_search_notdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with non dir fd"); +} +ATF_TC_BODY(o_search_notdir, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(FILE, O_CREAT|O_RDWR|O_SEARCH, 0644)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1); + ATF_REQUIRE(errno == ENOTDIR); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, o_search_perm1); +#ifdef USE_O_SEARCH + ATF_TP_ADD_TC(tp, o_search_root_flag1); + ATF_TP_ADD_TC(tp, o_search_unpriv_flag1); +#endif + ATF_TP_ADD_TC(tp, o_search_perm2); +#ifdef USE_O_SEARCH + ATF_TP_ADD_TC(tp, o_search_root_flag2); + ATF_TP_ADD_TC(tp, o_search_unpriv_flag2); +#endif + ATF_TP_ADD_TC(tp, o_search_notdir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_openat.c b/contrib/netbsd-tests/lib/libc/c063/t_openat.c new file mode 100644 index 0000000..79b5f38 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_openat.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_openat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_openat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/openat" +#define BASEFILE "openat" +#define FILEERR "dir/openaterr" + +ATF_TC(openat_fd); +ATF_TC_HEAD(openat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat works with fd"); +} +ATF_TC_BODY(openat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) != -1); + ATF_REQUIRE(close(dfd) == 0); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(openat_fdcwd); +ATF_TC_HEAD(openat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that openat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(openat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE((fd = openat(AT_FDCWD, BASEFILE, O_RDONLY, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(openat_fdcwderr); +ATF_TC_HEAD(openat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that openat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(openat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = openat(AT_FDCWD, FILEERR, O_RDONLY, 0)) == -1); +} + +ATF_TC(openat_fderr1); +ATF_TC_HEAD(openat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fail with bad path"); +} +ATF_TC_BODY(openat_fderr1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, FILEERR, O_RDONLY, 0)) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(openat_fderr2); +ATF_TC_HEAD(openat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with bad fdat"); +} +ATF_TC_BODY(openat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(openat_fderr3); +ATF_TC_HEAD(openat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with fd as -1"); +} +ATF_TC_BODY(openat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((fd = openat(-1, FILE, O_RDONLY, 0)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, openat_fd); + ATF_TP_ADD_TC(tp, openat_fdcwd); + ATF_TP_ADD_TC(tp, openat_fdcwderr); + ATF_TP_ADD_TC(tp, openat_fderr1); + ATF_TP_ADD_TC(tp, openat_fderr2); + ATF_TP_ADD_TC(tp, openat_fderr3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c new file mode 100644 index 0000000..d354ff5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c @@ -0,0 +1,157 @@ +/* $NetBSD: t_readlinkat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_readlinkat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/readlinkat" +#define BASEFILE "readlinkat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/readlinkaterr" + +ATF_TC(readlinkat_fd); +ATF_TC_HEAD(readlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat works with fd"); +} +ATF_TC_BODY(readlinkat_fd, tc) +{ + int dfd; + int fd; + ssize_t len; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + len = readlinkat(dfd, BASELINK, buf, sizeof(buf)-1); + ATF_REQUIRE(len != -1); + buf[len] = 0; + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(strcmp(buf, FILE) == 0); +} + +ATF_TC(readlinkat_fdcwd); +ATF_TC_HEAD(readlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that readlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(readlinkat_fdcwd, tc) +{ + int fd; + ssize_t len; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + len = readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)-1); + ATF_REQUIRE(len != -1); + buf[len] = 0; + + ATF_REQUIRE(strcmp(buf, FILE) == 0); +} + +ATF_TC(readlinkat_fdcwderr); +ATF_TC_HEAD(readlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that readlinkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(readlinkat_fdcwderr, tc) +{ + char buf[MAXPATHLEN]; + + ATF_REQUIRE(readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)) == -1); +} + +ATF_TC(readlinkat_fderr1); +ATF_TC_HEAD(readlinkat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat fail with bad path"); +} +ATF_TC_BODY(readlinkat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(readlinkat(dfd, FILEERR, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(readlinkat_fderr2); +ATF_TC_HEAD(readlinkat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat fails with fd as -1"); +} +ATF_TC_BODY(readlinkat_fderr2, tc) +{ + int fd; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE(readlinkat(-1, LINK, buf, sizeof(buf)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, readlinkat_fd); + ATF_TP_ADD_TC(tp, readlinkat_fdcwd); + ATF_TP_ADD_TC(tp, readlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, readlinkat_fderr1); + ATF_TP_ADD_TC(tp, readlinkat_fderr2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_renameat.c b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c new file mode 100644 index 0000000..e297f2a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define TARGET "newdir/new" +#define BASETARGET "new" +#define FILEERR "olddir/olderr" + +ATF_TC(renameat_fd); +ATF_TC_HEAD(renameat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that renameat works with fd"); +} +ATF_TC_BODY(renameat_fd, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(renameat(ofd, BASEFILE, nfd, BASETARGET) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(renameat_fdcwd); +ATF_TC_HEAD(renameat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that renameat works with fd as AT_FDCWD"); +} + +ATF_TC_BODY(renameat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + + ATF_REQUIRE(renameat(AT_FDCWD, FILE, AT_FDCWD, TARGET) == 0); + + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(renameat_fdcwderr); +ATF_TC_HEAD(renameat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that renameat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(renameat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(renameat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET) == -1); +} + +ATF_TC(renameat_fderr); +ATF_TC_HEAD(renameat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that renameat fails with fd as -1"); +} +ATF_TC_BODY(renameat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(renameat(-1, FILE, AT_FDCWD, TARGET) == -1); + ATF_REQUIRE(renameat(AT_FDCWD, FILE, -1, TARGET) == -1); + ATF_REQUIRE(renameat(-1, FILE, -1, TARGET) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, renameat_fd); + ATF_TP_ADD_TC(tp, renameat_fdcwd); + ATF_TP_ADD_TC(tp, renameat_fdcwderr); + ATF_TP_ADD_TC(tp, renameat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c new file mode 100644 index 0000000..d62f289 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define LINK "newdir/symlink" +#define BASELINK "symlink" +#define FILEERR "olddir/olderr" + +ATF_TC(symlinkat_fd); +ATF_TC_HEAD(symlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that symlinkat works with fd"); +} +ATF_TC_BODY(symlinkat_fd, tc) +{ + int dfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE((dfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(symlinkat(RELFILE, dfd, BASELINK) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(LINK, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(symlinkat_fdcwd); +ATF_TC_HEAD(symlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that symlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(symlinkat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(RELFILE, AT_FDCWD, LINK) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(LINK, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(symlinkat_fdcwderr); +ATF_TC_HEAD(symlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that symlinkat works with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(symlinkat_fdcwderr, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(FILEERR, AT_FDCWD, LINK) == 0); + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(stat(LINK, &st) == -1); + ATF_REQUIRE(errno == ENOENT); + +} + +ATF_TC(symlinkat_fderr); +ATF_TC_HEAD(symlinkat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that symlinkat fails with fd as -1"); +} +ATF_TC_BODY(symlinkat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(RELFILE, -1, LINK) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, symlinkat_fd); + ATF_TP_ADD_TC(tp, symlinkat_fdcwd); + ATF_TP_ADD_TC(tp, symlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, symlinkat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c new file mode 100644 index 0000000..79aa7aa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c @@ -0,0 +1,176 @@ +/* $NetBSD: t_unlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_unlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/unlinkat" +#define BASEFILE "unlinkat" +#define FILEERR "dir/unlinkaterr" + +ATF_TC(unlinkat_fd); +ATF_TC_HEAD(unlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat works with fd"); +} +ATF_TC_BODY(unlinkat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fdcwd); +ATF_TC_HEAD(unlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(unlinkat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(unlinkat(AT_FDCWD, BASEFILE, 0) == 0); +} + +ATF_TC(unlinkat_fdcwderr); +ATF_TC_HEAD(unlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(unlinkat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(unlinkat(AT_FDCWD, FILEERR, 0) == -1); +} + +ATF_TC(unlinkat_fderr1); +ATF_TC_HEAD(unlinkat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fail with bad path"); +} +ATF_TC_BODY(unlinkat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, FILEERR, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fderr2); +ATF_TC_HEAD(unlinkat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with bad fdat"); +} +ATF_TC_BODY(unlinkat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fderr3); +ATF_TC_HEAD(unlinkat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with fd as -1"); +} +ATF_TC_BODY(unlinkat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(unlinkat(-1, FILE, 0) == -1); +} + +ATF_TC(unlinkat_dir); +ATF_TC_HEAD(unlinkat_dir, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat can remove directories"); +} +ATF_TC_BODY(unlinkat_dir, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + + ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, 0) == -1); + ATF_REQUIRE(errno == EPERM); + ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, AT_REMOVEDIR) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, unlinkat_fd); + ATF_TP_ADD_TC(tp, unlinkat_fdcwd); + ATF_TP_ADD_TC(tp, unlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, unlinkat_fderr1); + ATF_TP_ADD_TC(tp, unlinkat_fderr2); + ATF_TP_ADD_TC(tp, unlinkat_fderr3); + ATF_TP_ADD_TC(tp, unlinkat_dir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c new file mode 100644 index 0000000..9f21fd6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c @@ -0,0 +1,212 @@ +/* $NetBSD: t_utimensat.c,v 1.5 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_utimensat.c,v 1.5 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/time.h> + +#define DIR "dir" +#define FILE "dir/utimensat" +#define BASEFILE "utimensat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/symlink" + +const struct timespec tptr[] = { + { 0x12345678, 987654321 }, + { 0x15263748, 123456789 }, +}; + +ATF_TC(utimensat_fd); +ATF_TC_HEAD(utimensat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat works with fd"); +} +ATF_TC_BODY(utimensat_fd, tc) +{ + int dfd; + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TC(utimensat_fdcwd); +ATF_TC_HEAD(utimensat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that utimensat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(utimensat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(utimensat(AT_FDCWD, BASEFILE, tptr, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TC(utimensat_fdcwderr); +ATF_TC_HEAD(utimensat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that utimensat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(utimensat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(utimensat(AT_FDCWD, FILEERR, tptr, 0) == -1); +} + +ATF_TC(utimensat_fderr1); +ATF_TC_HEAD(utimensat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fail with bad path"); +} +ATF_TC_BODY(utimensat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, FILEERR, tptr, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(utimensat_fderr2); +ATF_TC_HEAD(utimensat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fails with bad fdat"); +} +ATF_TC_BODY(utimensat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(utimensat_fderr3); +ATF_TC_HEAD(utimensat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fails with fd as -1"); +} +ATF_TC_BODY(utimensat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(utimensat(-1, FILE, tptr, 0) == -1); +} + +ATF_TC(utimensat_fdlink); +ATF_TC_HEAD(utimensat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat works on symlink"); +} +ATF_TC_BODY(utimensat_fdlink, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, 0) == -1); + ATF_REQUIRE(errno = ENOENT); + + ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, utimensat_fd); + ATF_TP_ADD_TC(tp, utimensat_fdcwd); + ATF_TP_ADD_TC(tp, utimensat_fdcwderr); + ATF_TP_ADD_TC(tp, utimensat_fderr1); + ATF_TP_ADD_TC(tp, utimensat_fderr2); + ATF_TP_ADD_TC(tp, utimensat_fderr3); + ATF_TP_ADD_TC(tp, utimensat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/common/exec_prot.h b/contrib/netbsd-tests/lib/libc/common/exec_prot.h new file mode 100644 index 0000000..6e17f97 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/common/exec_prot.h @@ -0,0 +1,61 @@ +/* $NetBSD: exec_prot.h,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TESTS_EXEC_PROT_H_ +#define _TESTS_EXEC_PROT_H_ + +/* + * Prototype definitions of external helper functions for executable + * mapping tests. + */ + +/* + * Trivial MD shellcode that justs returns 1. + */ +int return_one(void); /* begin marker -- shellcode entry */ +int return_one_end(void); /* end marker */ + +/* + * MD callback to verify whether host offers executable space protection. + * Returns execute protection level. + */ +int exec_prot_support(void); + +/* execute protection level */ +enum { + NOTIMPL = -1, /* callback not implemented */ + NO_XP, /* no execute protection */ + PERPAGE_XP, /* per-page execute protection */ + PARTIAL_XP /* partial execute protection. Depending on where the + page is located in virtual memory, executable space + protection may be enforced or not. */ +}; +#endif diff --git a/contrib/netbsd-tests/lib/libc/db/README b/contrib/netbsd-tests/lib/libc/db/README new file mode 100644 index 0000000..68f0ec7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/README @@ -0,0 +1,66 @@ +# $NetBSD: README,v 1.1 2011/01/07 15:05:58 pgoyette Exp $ +# @(#)README 8.8 (Berkeley) 7/31/94 + +Fairly large files (the command files) are built in this directory during +the test runs, and even larger files (the database files) are created in +"/var/tmp". If the latter directory doesn't exist, set the environmental +variable TMPDIR to a directory where the files can be built. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +The script file consists of lines with an initial character which is +the command for that line, or an initial character indicating a key +or data entry for a previous command. + +Legal command characters are as follows: + +c: compare a record + + must be followed by [kK][dD]; the data value in the database + associated with the specified key is compared to the specified + data value. +e: echo a string + + writes out the rest of the line into the output file; if the + last character is not a carriage-return, a newline is appended. +f: set the flags for the next command + + no value zero's the flags +g: do a get command + + must be followed by [kK] + + writes out the retrieved data DBT. +o [r]: dump [reverse] + + dump the database out, if 'r' is set, in reverse order. +p: do a put command + + must be followed by [kK][dD] +r: do a del command + + must be followed by [kK] unless R_CURSOR flag set. +S: sync the database +s: do a seq command + + must be followed by [kK] if R_CURSOR flag set. + + writes out the retrieved data DBT. + +Legal key/data characters are as follows: + +D [file]: data file + + set the current data value to the contents of the file +d [data]: + + set the current key value to the contents of the line. +K [file]: key file + + set the current key value to the contents of the file +k [data]: + + set the current key value to the contents of the line. + +Blank lines, lines with leading white space, and lines with leading +hash marks (#) are ignored. + +Options to dbtest are as follows: + + -d: Set the DB_LOCK flag. + -f: Use the file argument as the database file. + -i: Use the rest of the argument to set elements in the info + structure. If the type is btree, then "-i cachesize=10240" + will set BTREEINFO.cachesize to 10240. + -o: The rest of the argument is the output file instead of + using stdout. + -s: Don't delete the database file before opening it, i.e. + use the database file from a previous run. + +Dbtest requires two arguments, the type of access "hash", "recno" +or "btree", and the script name or "-" to indicate stdin. diff --git a/contrib/netbsd-tests/lib/libc/db/h_db.c b/contrib/netbsd-tests/lib/libc/db/h_db.c new file mode 100644 index 0000000..dfb1385 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/h_db.c @@ -0,0 +1,731 @@ +/* $NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $ */ + +/*- + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; +#else +__RCSID("$NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $"); +#endif +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/stat.h> + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <unistd.h> +#include <err.h> +#include <db.h> + +enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; + +static void compare(DBT *, DBT *); +static DBTYPE dbtype(const char *); +static void dump(DB *, int); +static void get(DB *, DBT *); +static void getdata(DB *, DBT *, DBT *); +static void put(DB *, DBT *, DBT *); +static void rem(DB *, DBT *); +static const char *sflags(int); +static void synk(DB *); +static void *rfile(char *, size_t *); +static void seq(DB *, DBT *); +static u_int setflags(char *); +static void *setinfo(DBTYPE, char *); +static void usage(void) __attribute__((__noreturn__)); +static void *xcopy(void *, size_t); +static void chkcmd(enum S); +static void chkdata(enum S); +static void chkkey(enum S); + +#ifdef STATISTICS +extern void __bt_stat(DB *); +#endif + +static DBTYPE type; /* Database type. */ +static void *infop; /* Iflags. */ +static size_t lineno; /* Current line in test script. */ +static u_int flags; /* Current DB flags. */ +static int ofd = STDOUT_FILENO; /* Standard output fd. */ + +static DB *XXdbp; /* Global for gdb. */ +static size_t XXlineno; /* Fast breakpoint for gdb. */ + +int +main(int argc, char *argv[]) +{ + extern int optind; + extern char *optarg; + enum S command = COMMAND, state; + DB *dbp; + DBT data, key, keydata; + size_t len; + int ch, oflags, sflag; + char *fname, *infoarg, *p, *t, buf[8 * 1024]; + bool unlink_dbfile; + + infoarg = NULL; + fname = NULL; + unlink_dbfile = false; + oflags = O_CREAT | O_RDWR; + sflag = 0; + while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) + switch (ch) { + case 'f': + fname = optarg; + break; + case 'i': + infoarg = optarg; + break; + case 'l': + oflags |= DB_LOCK; + break; + case 'o': + if ((ofd = open(optarg, + O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) + err(1, "Cannot create `%s'", optarg); + break; + case 's': + sflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + /* Set the type. */ + type = dbtype(*argv++); + + /* Open the descriptor file. */ + if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) + err(1, "Cannot reopen `%s'", *argv); + + /* Set up the db structure as necessary. */ + if (infoarg == NULL) + infop = NULL; + else + for (p = strtok(infoarg, ",\t "); p != NULL; + p = strtok(0, ",\t ")) + if (*p != '\0') + infop = setinfo(type, p); + + /* + * Open the DB. Delete any preexisting copy, you almost never + * want it around, and it often screws up tests. + */ + if (fname == NULL) { + const char *q = getenv("TMPDIR"); + if (q == NULL) + q = "/var/tmp"; + (void)snprintf(buf, sizeof(buf), "%s/__dbtest", q); + fname = buf; + (void)unlink(buf); + unlink_dbfile = true; + } else if (!sflag) + (void)unlink(fname); + + if ((dbp = dbopen(fname, + oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) + err(1, "Cannot dbopen `%s'", fname); + XXdbp = dbp; + if (unlink_dbfile) + (void)unlink(fname); + + state = COMMAND; + for (lineno = 1; + (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { + /* Delete the newline, displaying the key/data is easier. */ + if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) + *t = '\0'; + if ((len = strlen(buf)) == 0 || isspace((unsigned char)*p) || + *p == '#') + continue; + + /* Convenient gdb break point. */ + if (XXlineno == lineno) + XXlineno = 1; + switch (*p) { + case 'c': /* compare */ + chkcmd(state); + state = KEY; + command = COMPARE; + break; + case 'e': /* echo */ + chkcmd(state); + /* Don't display the newline, if CR at EOL. */ + if (p[len - 2] == '\r') + --len; + if (write(ofd, p + 1, len - 1) != (ssize_t)len - 1 || + write(ofd, "\n", 1) != 1) + err(1, "write failed"); + break; + case 'g': /* get */ + chkcmd(state); + state = KEY; + command = GET; + break; + case 'p': /* put */ + chkcmd(state); + state = KEY; + command = PUT; + break; + case 'r': /* remove */ + chkcmd(state); + if (flags == R_CURSOR) { + rem(dbp, &key); + state = COMMAND; + } else { + state = KEY; + command = REMOVE; + } + break; + case 'S': /* sync */ + chkcmd(state); + synk(dbp); + state = COMMAND; + break; + case 's': /* seq */ + chkcmd(state); + if (flags == R_CURSOR) { + state = KEY; + command = SEQ; + } else + seq(dbp, &key); + break; + case 'f': + flags = setflags(p + 1); + break; + case 'D': /* data file */ + chkdata(state); + data.data = rfile(p + 1, &data.size); + goto ldata; + case 'd': /* data */ + chkdata(state); + data.data = xcopy(p + 1, len - 1); + data.size = len - 1; +ldata: switch (command) { + case COMPARE: + compare(&keydata, &data); + break; + case PUT: + put(dbp, &key, &data); + break; + default: + errx(1, "line %zu: command doesn't take data", + lineno); + } + if (type != DB_RECNO) + free(key.data); + free(data.data); + state = COMMAND; + break; + case 'K': /* key file */ + chkkey(state); + if (type == DB_RECNO) + errx(1, "line %zu: 'K' not available for recno", + lineno); + key.data = rfile(p + 1, &key.size); + goto lkey; + case 'k': /* key */ + chkkey(state); + if (type == DB_RECNO) { + static recno_t recno; + recno = atoi(p + 1); + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = xcopy(p + 1, len - 1); + key.size = len - 1; + } +lkey: switch (command) { + case COMPARE: + getdata(dbp, &key, &keydata); + state = DATA; + break; + case GET: + get(dbp, &key); + if (type != DB_RECNO) + free(key.data); + state = COMMAND; + break; + case PUT: + state = DATA; + break; + case REMOVE: + rem(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + case SEQ: + seq(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + default: + errx(1, "line %zu: command doesn't take a key", + lineno); + } + break; + case 'o': + dump(dbp, p[1] == 'r'); + break; + default: + errx(1, "line %zu: %s: unknown command character", + lineno, p); + } + } +#ifdef STATISTICS + /* + * -l must be used (DB_LOCK must be set) for this to be + * used, otherwise a page will be locked and it will fail. + */ + if (type == DB_BTREE && oflags & DB_LOCK) + __bt_stat(dbp); +#endif + if ((*dbp->close)(dbp)) + err(1, "db->close failed"); + (void)close(ofd); + return 0; +} + +#define NOOVERWRITE "put failed, would overwrite key\n" + +static void +compare(DBT *db1, DBT *db2) +{ + size_t len; + u_char *p1, *p2; + + if (db1->size != db2->size) + printf("compare failed: key->data len %zu != data len %zu\n", + db1->size, db2->size); + + len = MIN(db1->size, db2->size); + for (p1 = db1->data, p2 = db2->data; len--;) + if (*p1++ != *p2++) { + printf("compare failed at offset %lu\n", + (unsigned long)(p1 - (u_char *)db1->data)); + break; + } +} + +static void +get(DB *dbp, DBT *kp) +{ + DBT data; + + switch ((*dbp->get)(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err(1, "line %zu: get failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "get failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, + NOSUCHKEY); +#undef NOSUCHKEY + break; + } +} + +static void +getdata(DB *dbp, DBT *kp, DBT *dp) +{ + switch ((*dbp->get)(dbp, kp, dp, flags)) { + case 0: + return; + case -1: + err(1, "line %zu: getdata failed", lineno); + /* NOTREACHED */ + case 1: + errx(1, "line %zu: getdata failed, no such key", lineno); + /* NOTREACHED */ + } +} + +static void +put(DB *dbp, DBT *kp, DBT *dp) +{ + switch ((*dbp->put)(dbp, kp, dp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: put failed", lineno); + /* NOTREACHED */ + case 1: + (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); + break; + } +} + +static void +rem(DB *dbp, DBT *kp) +{ + switch ((*dbp->del)(dbp, kp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: rem failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "rem failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags != R_CURSOR) + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%zu: rem of cursor failed\n", lineno); +#undef NOSUCHKEY + break; + } +} + +static void +synk(DB *dbp) +{ + switch ((*dbp->sync)(dbp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: synk failed", lineno); + /* NOTREACHED */ + } +} + +static void +seq(DB *dbp, DBT *kp) +{ + DBT data; + + switch (dbp->seq(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err(1, "line %zu: seq failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "seq failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags == R_CURSOR) + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%zu: seq (%s) failed\n", lineno, sflags(flags)); +#undef NOSUCHKEY + break; + } +} + +static void +dump(DB *dbp, int rev) +{ + DBT key, data; + int xflags, nflags; + + if (rev) { + xflags = R_LAST; + nflags = R_PREV; + } else { + xflags = R_FIRST; + nflags = R_NEXT; + } + for (;; xflags = nflags) + switch (dbp->seq(dbp, &key, &data, xflags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case 1: + goto done; + case -1: + err(1, "line %zu: (dump) seq failed", lineno); + /* NOTREACHED */ + } +done: return; +} + +static u_int +setflags(char *s) +{ + char *p; + + for (; isspace((unsigned char)*s); ++s); + if (*s == '\n' || *s == '\0') + return 0; + if ((p = strchr(s, '\n')) != NULL) + *p = '\0'; + if (!strcmp(s, "R_CURSOR")) return R_CURSOR; + if (!strcmp(s, "R_FIRST")) return R_FIRST; + if (!strcmp(s, "R_IAFTER")) return R_IAFTER; + if (!strcmp(s, "R_IBEFORE")) return R_IBEFORE; + if (!strcmp(s, "R_LAST")) return R_LAST; + if (!strcmp(s, "R_NEXT")) return R_NEXT; + if (!strcmp(s, "R_NOOVERWRITE")) return R_NOOVERWRITE; + if (!strcmp(s, "R_PREV")) return R_PREV; + if (!strcmp(s, "R_SETCURSOR")) return R_SETCURSOR; + + errx(1, "line %zu: %s: unknown flag", lineno, s); + /* NOTREACHED */ +} + +static const char * +sflags(int xflags) +{ + switch (xflags) { + case R_CURSOR: return "R_CURSOR"; + case R_FIRST: return "R_FIRST"; + case R_IAFTER: return "R_IAFTER"; + case R_IBEFORE: return "R_IBEFORE"; + case R_LAST: return "R_LAST"; + case R_NEXT: return "R_NEXT"; + case R_NOOVERWRITE: return "R_NOOVERWRITE"; + case R_PREV: return "R_PREV"; + case R_SETCURSOR: return "R_SETCURSOR"; + } + + return "UNKNOWN!"; +} + +static DBTYPE +dbtype(const char *s) +{ + if (!strcmp(s, "btree")) + return DB_BTREE; + if (!strcmp(s, "hash")) + return DB_HASH; + if (!strcmp(s, "recno")) + return DB_RECNO; + errx(1, "%s: unknown type (use btree, hash or recno)", s); + /* NOTREACHED */ +} + +static void * +setinfo(DBTYPE dtype, char *s) +{ + static BTREEINFO ib; + static HASHINFO ih; + static RECNOINFO rh; + char *eq; + + if ((eq = strchr(s, '=')) == NULL) + errx(1, "%s: illegal structure set statement", s); + *eq++ = '\0'; + if (!isdigit((unsigned char)*eq)) + errx(1, "%s: structure set statement must be a number", s); + + switch (dtype) { + case DB_BTREE: + if (!strcmp("flags", s)) { + ib.flags = atoi(eq); + return &ib; + } + if (!strcmp("cachesize", s)) { + ib.cachesize = atoi(eq); + return &ib; + } + if (!strcmp("maxkeypage", s)) { + ib.maxkeypage = atoi(eq); + return &ib; + } + if (!strcmp("minkeypage", s)) { + ib.minkeypage = atoi(eq); + return &ib; + } + if (!strcmp("lorder", s)) { + ib.lorder = atoi(eq); + return &ib; + } + if (!strcmp("psize", s)) { + ib.psize = atoi(eq); + return &ib; + } + break; + case DB_HASH: + if (!strcmp("bsize", s)) { + ih.bsize = atoi(eq); + return &ih; + } + if (!strcmp("ffactor", s)) { + ih.ffactor = atoi(eq); + return &ih; + } + if (!strcmp("nelem", s)) { + ih.nelem = atoi(eq); + return &ih; + } + if (!strcmp("cachesize", s)) { + ih.cachesize = atoi(eq); + return &ih; + } + if (!strcmp("lorder", s)) { + ih.lorder = atoi(eq); + return &ih; + } + break; + case DB_RECNO: + if (!strcmp("flags", s)) { + rh.flags = atoi(eq); + return &rh; + } + if (!strcmp("cachesize", s)) { + rh.cachesize = atoi(eq); + return &rh; + } + if (!strcmp("lorder", s)) { + rh.lorder = atoi(eq); + return &rh; + } + if (!strcmp("reclen", s)) { + rh.reclen = atoi(eq); + return &rh; + } + if (!strcmp("bval", s)) { + rh.bval = atoi(eq); + return &rh; + } + if (!strcmp("psize", s)) { + rh.psize = atoi(eq); + return &rh; + } + break; + } + errx(1, "%s: unknown structure value", s); + /* NOTREACHED */ +} + +static void * +rfile(char *name, size_t *lenp) +{ + struct stat sb; + void *p; + int fd; + char *np; + + for (; isspace((unsigned char)*name); ++name) + continue; + if ((np = strchr(name, '\n')) != NULL) + *np = '\0'; + if ((fd = open(name, O_RDONLY, 0)) == -1 || fstat(fd, &sb) == -1) + err(1, "Cannot open `%s'", name); +#ifdef NOT_PORTABLE + if (sb.st_size > (off_t)SIZE_T_MAX) { + errno = E2BIG; + err("Cannot process `%s'", name); + } +#endif + if ((p = malloc((size_t)sb.st_size)) == NULL) + err(1, "Cannot allocate %zu bytes", (size_t)sb.st_size); + if (read(fd, p, (ssize_t)sb.st_size) != (ssize_t)sb.st_size) + err(1, "read failed"); + *lenp = (size_t)sb.st_size; + (void)close(fd); + return p; +} + +static void * +xcopy(void *text, size_t len) +{ + void *p; + + if ((p = malloc(len)) == NULL) + err(1, "Cannot allocate %zu bytes", len); + (void)memmove(p, text, len); + return p; +} + +static void +chkcmd(enum S state) +{ + if (state != COMMAND) + errx(1, "line %zu: not expecting command", lineno); +} + +static void +chkdata(enum S state) +{ + if (state != DATA) + errx(1, "line %zu: not expecting data", lineno); +} + +static void +chkkey(enum S state) +{ + if (state != KEY) + errx(1, "line %zu: not expecting a key", lineno); +} + +static void +usage(void) +{ + (void)fprintf(stderr, + "Usage: %s [-l] [-f file] [-i info] [-o file] type script\n", + getprogname()); + exit(1); +} diff --git a/contrib/netbsd-tests/lib/libc/db/t_db.sh b/contrib/netbsd-tests/lib/libc/db/t_db.sh new file mode 100755 index 0000000..52244e3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/t_db.sh @@ -0,0 +1,920 @@ +# $NetBSD: t_db.sh,v 1.4 2013/07/29 10:43:15 skrll Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +prog() +{ + echo $(atf_get_srcdir)/h_db +} + +dict() +{ + if [ -f /usr/share/dict/words ]; then + echo /usr/share/dict/words + elif [ -f /usr/dict/words ]; then + echo /usr/dict/words + else + atf_fail "no dictionary found" + fi +} + +SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg" + +atf_test_case small_btree +small_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." +} +small_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + for i in `sed 200q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" btree in +} + +atf_test_case small_hash +small_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." +} +small_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + for i in `sed 200q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" hash in +} + +atf_test_case small_recno +small_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." +} +small_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + sed 200q $(dict) | + awk '{ + ++i; + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case medium_btree +medium_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." +} +medium_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + for i in $(sed 200q $(dict)); do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" btree in +} + +atf_test_case medium_hash +medium_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." +} +medium_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + for i in $(sed 200q $(dict)); do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" hash in +} + +atf_test_case medium_recno +medium_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." +} +medium_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case big_btree +big_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + for psize in 512 16384 65536; do + echo "checking page size: $psize" + + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done >in + + atf_check "$(prog)" -o out btree in + cmp -s exp out || atf_fail "test failed for page size: $psize" + done +} + +atf_test_case big_hash +big_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done >in + + atf_check "$(prog)" -o out hash in + cmp -s exp out || atf_fail "test failed" +} + +atf_test_case big_recno +big_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + find /bin -type f -print | + awk '{ + ++i; + printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i); + }' >in + + for psize in 512 16384 65536; do + echo "checking page size: $psize" + + atf_check "$(prog)" -o out recno in + cmp -s exp out || atf_fail "test failed for page size: $psize" + done +} + +atf_test_case random_recno +random_recno_head() +{ + atf_set "descr" "Checks recno database using random entries" +} +random_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 37; i <= 37 + 88 * 17; i += 17) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 1; i <= 15; ++i) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 19234; i <= 19234 + 61 * 27; i += 27) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit + }' >exp + + cat exp | + awk 'BEGIN { + i = 37; + incr = 17; + } + { + printf("p\nk%d\nd%s\n", i, $0); + if (i == 19234 + 61 * 27) + exit; + if (i == 37 + 88 * 17) { + i = 1; + incr = 1; + } else if (i == 15) { + i = 19234; + incr = 27; + } else + i += incr; + } + END { + for (i = 37; i <= 37 + 88 * 17; i += 17) + printf("g\nk%d\n", i); + for (i = 1; i <= 15; ++i) + printf("g\nk%d\n", i); + for (i = 19234; i <= 19234 + 61 * 27; i += 27) + printf("g\nk%d\n", i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case reverse_recno +reverse_recno_head() +{ + atf_set "descr" "Checks recno database using reverse order entries" +} +reverse_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk ' { + for (i = 1500; i; --i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' >exp + + cat exp | + awk 'BEGIN { + i = 1500; + } + { + printf("p\nk%d\nd%s\n", i, $0); + --i; + } + END { + for (i = 1500; i; --i) + printf("g\nk%d\n", i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case alternate_recno +alternate_recno_head() +{ + atf_set "descr" "Checks recno database using alternating order entries" +} +alternate_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk ' { + for (i = 1; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 2; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' >exp + + cat exp | + awk 'BEGIN { + i = 1; + even = 0; + } + { + printf("p\nk%d\nd%s\n", i, $0); + i += 2; + if (i >= 1200) { + if (even == 1) + exit; + even = 1; + i = 2; + } + } + END { + for (i = 1; i < 1200; ++i) + printf("g\nk%d\n", i); + }' >in + + atf_check "$(prog)" -o out recno in + + sort -o exp exp + sort -o out out + + cmp -s exp out || atf_fail "test failed" +} + +h_delete() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 120; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + }' >exp + + cat exp | + awk '{ + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_NEXT\n"); + for (i = 1; i <= 120; ++i) + printf("s\n"); + printf("fR_CURSOR\ns\nkXX\n"); + printf("r\n"); + printf("fR_NEXT\ns\n"); + printf("fR_CURSOR\ns\nk1\n"); + printf("r\n"); + printf("fR_FIRST\ns\n"); + }' >in + + # For btree, the records are ordered by the string representation + # of the key value. So sort the expected output file accordingly, + # and set the seek_last key to the last expected key value. + + if [ "$type" = "btree" ] ; then + sed -e 's/kXX/k99/' < in > tmp + mv tmp in + sort -d -k4 < exp > tmp + mv tmp exp + echo $SEVEN_SEVEN | + awk '{ + printf("%05d: input key %d: %s\n", 99, 99, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 10, 10, $0); + exit; + }' >> exp + else + # For recno, records are ordered by numerical key value. No sort + # is needed, but still need to set proper seek_last key value. + sed -e 's/kXX/k120/' < in > tmp + mv tmp in + echo $SEVEN_SEVEN | + awk '{ + printf("%05d: input key %d: %s\n", 120, 120, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 2, 2, $0); + exit; + }' >> exp + fi + + atf_check "$(prog)" -o out $type in + atf_check -o file:exp cat out +} + +atf_test_case delete_btree +delete_btree_head() +{ + atf_set "descr" "Checks removing records in btree database" +} +delete_btree_body() +{ + h_delete btree +} + +atf_test_case delete_recno +delete_recno_head() +{ + atf_set "descr" "Checks removing records in recno database" +} +delete_recno_body() +{ + h_delete recno +} + +h_repeated() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo "" | + awk 'BEGIN { + for (i = 1; i <= 10; ++i) { + printf("p\nkkey1\nD/bin/sh\n"); + printf("p\nkkey2\nD/bin/csh\n"); + if (i % 8 == 0) { + printf("c\nkkey2\nD/bin/csh\n"); + printf("c\nkkey1\nD/bin/sh\n"); + printf("e\t%d of 10 (comparison)\n", i); + } else + printf("e\t%d of 10 \n", i); + printf("r\nkkey1\nr\nkkey2\n"); + } + }' >in + + $(prog) btree in +} + +atf_test_case repeated_btree +repeated_btree_head() +{ + atf_set "descr" \ + "Checks btree database with repeated small keys and" \ + "big data pairs. Makes sure that overflow pages are reused" +} +repeated_btree_body() +{ + h_repeated btree +} + +atf_test_case repeated_hash +repeated_hash_head() +{ + atf_set "descr" \ + "Checks hash database with repeated small keys and" \ + "big data pairs. Makes sure that overflow pages are reused" +} +repeated_hash_body() +{ + h_repeated hash +} + +atf_test_case duplicate_btree +duplicate_btree_head() +{ + atf_set "descr" "Checks btree database with duplicate keys" +} +duplicate_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 543; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + cat exp | + awk '{ + if (i++ % 2) + printf("p\nkduplicatekey\nd%s\n", $0); + else + printf("p\nkunique%dkey\nd%s\n", i, $0); + } + END { + printf("o\n"); + }' >in + + atf_check -o file:exp -x "$(prog) -iflags=1 btree in | sort" +} + +h_cursor_flags() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 20; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + # Test that R_CURSOR doesn't succeed before cursor initialized + cat exp | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\nr\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' >in + + atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in + atf_check -s ne:0 test -s out + + cat exp | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\np\nk1\ndsome data\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' >in + + atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in + atf_check -s ne:0 test -s out +} + +atf_test_case cursor_flags_btree +cursor_flags_btree_head() +{ + atf_set "descr" \ + "Checks use of cursor flags without initialization in btree database" +} +cursor_flags_btree_body() +{ + h_cursor_flags btree +} + +atf_test_case cursor_flags_recno +cursor_flags_recno_head() +{ + atf_set "descr" \ + "Checks use of cursor flags without initialization in recno database" +} +cursor_flags_recno_body() +{ + h_cursor_flags recno +} + +atf_test_case reverse_order_recno +reverse_order_recno_head() +{ + atf_set "descr" "Checks reverse order inserts in recno database" +} +reverse_order_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 779; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + cat exp | + awk '{ + if (i == 0) { + i = 1; + printf("p\nk1\nd%s\n", $0); + printf("%s\n", "fR_IBEFORE"); + } else + printf("p\nk1\nd%s\n", $0); + } + END { + printf("or\n"); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case small_page_btree +small_page_btree_head() +{ + atf_set "descr" \ + "Checks btree database with lots of keys and small page" \ + "size: takes the first 20000 entries in the dictionary," \ + "reverses them, and gives them each a small size data" \ + "entry. Uses a small page size to make sure the btree" \ + "split code gets hammered." +} +small_page_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxy + echo $mdata | + awk '{ for (i = 1; i < 20001; ++i) print $0 }' >exp + + for i in `sed 20000q $(dict) | rev`; do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" -i psize=512 btree in +} + +h_byte_orders() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + sed 50q $(dict) >exp + for order in 1234 4321; do + for i in `sed 50q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" -ilorder=$order -f byte.file $type in + + for i in `sed 50q $(dict)`; do + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" -s -ilorder=$order -f byte.file $type in + done +} + +atf_test_case byte_orders_btree +byte_orders_btree_head() +{ + atf_set "descr" "Checks btree database using differing byte orders" +} +byte_orders_btree_body() +{ + h_byte_orders btree +} + +atf_test_case byte_orders_hash +byte_orders_hash_head() +{ + atf_set "descr" "Checks hash database using differing byte orders" +} +byte_orders_hash_body() +{ + h_byte_orders hash +} + +h_bsize_ffactor() +{ + bsize=$1 + ffactor=$2 + + echo "bucketsize $bsize, fill factor $ffactor" + atf_check -o file:exp "$(prog)" "-ibsize=$bsize,\ +ffactor=$ffactor,nelem=25000,cachesize=65536" hash in +} + +atf_test_case bsize_ffactor +bsize_ffactor_head() +{ + atf_set "timeout" "480" + atf_set "descr" "Checks hash database with various" \ + "bucketsizes and fill factors" +} +bsize_ffactor_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 10000; ++i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("%s\n", s); + } + exit; + + }' >exp + + sed 10000q $(dict) | + awk 'BEGIN { + ds="'$SEVEN_SEVEN'" + } + { + if (++i % 34) + s = substr(ds, 1, i % 34); + else + s = substr(ds, 1); + printf("p\nk%s\nd%s\n", $0, s); + }' >in + + sed 10000q $(dict) | + awk '{ + ++i; + printf("g\nk%s\n", $0); + }' >>in + + h_bsize_ffactor 256 11 + h_bsize_ffactor 256 14 + h_bsize_ffactor 256 21 + + h_bsize_ffactor 512 21 + h_bsize_ffactor 512 28 + h_bsize_ffactor 512 43 + + h_bsize_ffactor 1024 43 + h_bsize_ffactor 1024 57 + h_bsize_ffactor 1024 85 + + h_bsize_ffactor 2048 85 + h_bsize_ffactor 2048 114 + h_bsize_ffactor 2048 171 + + h_bsize_ffactor 4096 171 + h_bsize_ffactor 4096 228 + h_bsize_ffactor 4096 341 + + h_bsize_ffactor 8192 341 + h_bsize_ffactor 8192 455 + h_bsize_ffactor 8192 683 +} + +# FIXME: what does it test? +atf_test_case four_char_hash +four_char_hash_head() +{ + atf_set "descr" \ + "Checks hash database with 4 char key and" \ + "value insert on a 65536 bucket size" +} +four_char_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + cat >in <<EOF +p +k1234 +d1234 +r +k1234 +EOF + + atf_check "$(prog)" -i bsize=65536 hash in +} + +atf_init_test_cases() +{ + atf_add_test_case small_btree + atf_add_test_case small_hash + atf_add_test_case small_recno + atf_add_test_case medium_btree + atf_add_test_case medium_hash + atf_add_test_case medium_recno + atf_add_test_case big_btree + atf_add_test_case big_hash + atf_add_test_case big_recno + atf_add_test_case random_recno + atf_add_test_case reverse_recno + atf_add_test_case alternate_recno + atf_add_test_case delete_btree + atf_add_test_case delete_recno + atf_add_test_case repeated_btree + atf_add_test_case repeated_hash + atf_add_test_case duplicate_btree + atf_add_test_case cursor_flags_btree + atf_add_test_case cursor_flags_recno + atf_add_test_case reverse_order_recno + atf_add_test_case small_page_btree + atf_add_test_case byte_orders_btree + atf_add_test_case byte_orders_hash + atf_add_test_case bsize_ffactor + atf_add_test_case four_char_hash +} diff --git a/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c new file mode 100644 index 0000000..32de6e7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_execve.c,v 1.1 2014/04/29 06:29:02 uebayasi Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> + +ATF_TC(t_execve_null); + +ATF_TC_HEAD(t_execve_null, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests an empty execve(2) executing"); +} + +ATF_TC_BODY(t_execve_null, tc) +{ + int err; + + err = execve(NULL, NULL, NULL); + ATF_REQUIRE(err == -1); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_execve_null); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/isqemu.h b/contrib/netbsd-tests/lib/libc/gen/isqemu.h new file mode 100644 index 0000000..7d73a22 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/isqemu.h @@ -0,0 +1,63 @@ +/* $NetBSD: isqemu.h,v 1.3 2013/04/14 12:46:29 martin Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/sysctl.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> +#include <err.h> + +static __inline bool +isQEMU(void) { +#if defined(__i386__) || defined(__x86_64__) + char name[1024]; + size_t len = sizeof(name); + + if (sysctlbyname("machdep.cpu_brand", name, &len, NULL, 0) == -1) { + if (errno == ENOENT) + return false; + err(EXIT_FAILURE, "sysctl"); + } + return strstr(name, "QEMU") != NULL; +#else + return false; +#endif +} + +#ifdef TEST +int +main(void) { + return isQEMU(); +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c new file mode 100644 index 0000000..d923370 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c @@ -0,0 +1,104 @@ +/* $NetBSD: h_fileactions.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <sys/stat.h> + +#define BUFSIZE 16 + +/* + * This checks (hardcoded) the assumptions that are setup from the + * main test program via posix spawn file actions. + * Program exits with EXIT_SUCCESS or EXIT_FAILURE accordingly + * (and does some stderr diagnostics in case of errors). + */ +int +main(int argc, char **argv) +{ + int res = EXIT_SUCCESS; + char buf[BUFSIZE]; + struct stat sb0, sb1; + + strcpy(buf, "test..."); + /* file desc 3 should be closed via addclose */ + if (read(3, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 3 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 4 should be closed via closeonexec */ + if (read(4, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 4 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 5 remains open */ + if (write(5, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 5\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 6 should be open (via addopen) */ + if (write(6, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 6\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 7 should refer to stdout */ + fflush(stdout); + if (fstat(fileno(stdout), &sb0) != 0) { + fprintf(stderr, "%s: could not fstat stdout\n", + getprogname()); + res = EXIT_FAILURE; + } + if (fstat(7, &sb1) != 0) { + fprintf(stderr, "%s: could not fstat filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (write(7, buf, strlen(buf)) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (memcmp(&sb0, &sb1, sizeof sb0) != 0) { + fprintf(stderr, "%s: stat results differ\n", getprogname()); + res = EXIT_FAILURE; + } + + return res; +} + diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh new file mode 100755 index 0000000..deee6fe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh @@ -0,0 +1,3 @@ +#! /nonexistent + +# this is just a dummy script, trying to be non-executable diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c new file mode 100644 index 0000000..dbf5da5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c @@ -0,0 +1,50 @@ +/* $NetBSD: h_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char **argv) +{ + unsigned long ret; + char *endp; + + if (argc < 2) { + fprintf(stderr, "usage:\n\t%s (retcode)\n", getprogname()); + exit(255); + } + ret = strtoul(argv[1], &endp, 10); + + fprintf(stderr, "%s exiting with status %lu\n", getprogname(), ret); + return ret; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c new file mode 100644 index 0000000..1f13c54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c @@ -0,0 +1,90 @@ +/* $NetBSD: h_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +/* + * Helper to test the hardcoded assumptions from t_spawnattr.c + * Exit with apropriate exit status and print diagnostics to + * stderr explaining what is wrong. + */ +int +main(int argc, char **argv) +{ + int parent_pipe, res = EXIT_SUCCESS; + sigset_t sig; + struct sigaction act; + ssize_t rd; + char tmp; + + sigemptyset(&sig); + if (sigprocmask(0, NULL, &sig) < 0) { + fprintf(stderr, "%s: sigprocmask error\n", getprogname()); + res = EXIT_FAILURE; + } + if (!sigismember(&sig, SIGUSR1)) { + fprintf(stderr, "%s: SIGUSR not in procmask\n", getprogname()); + res = EXIT_FAILURE; + } + if (sigaction(SIGUSR1, NULL, &act) < 0) { + fprintf(stderr, "%s: sigaction error\n", getprogname()); + res = EXIT_FAILURE; + } + if (act.sa_sigaction != (void *)SIG_DFL) { + fprintf(stderr, "%s: SIGUSR1 action != SIG_DFL\n", + getprogname()); + res = EXIT_FAILURE; + } + + if (argc >= 2) { + parent_pipe = atoi(argv[1]); + if (parent_pipe > 2) { + printf("%s: waiting for command from parent on pipe " + "%d\n", getprogname(), parent_pipe); + rd = read(parent_pipe, &tmp, 1); + if (rd == 1) { + printf("%s: got command %c from parent\n", + getprogname(), tmp); + } else if (rd == -1) { + printf("%s: %d is no pipe, errno %d\n", + getprogname(), parent_pipe, errno); + res = EXIT_FAILURE; + } + } + } + + return res; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c new file mode 100644 index 0000000..1cf6433 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c @@ -0,0 +1,385 @@ +/* $NetBSD: t_fileactions.c,v 1.5 2012/04/09 19:42:07 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <spawn.h> +#include <unistd.h> +#include <sys/wait.h> + + +ATF_TC(t_spawn_openmode); + +ATF_TC_HEAD(t_spawn_openmode, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the proper handling of 'mode' for 'open' fileactions"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +static off_t +filesize(const char * restrict fname) +{ + struct stat st; + int err; + + err = stat(fname, &st); + ATF_REQUIRE(err == 0); + return st.st_size; +} + +#define TESTFILE "./the_input_data" +#define CHECKFILE "./the_output_data" +#define TESTCONTENT "marry has a little lamb" + +static void +make_testfile(const char *restrict file) +{ + FILE *f; + size_t written; + + f = fopen(file, "w"); + ATF_REQUIRE(f != NULL); + written = fwrite(TESTCONTENT, 1, strlen(TESTCONTENT), f); + fclose(f); + ATF_REQUIRE(written == strlen(TESTCONTENT)); +} + +static void +empty_outfile(const char *restrict filename) +{ + FILE *f; + + f = fopen(filename, "w"); + ATF_REQUIRE(f != NULL); + fclose(f); +} + +ATF_TC_BODY(t_spawn_openmode, tc) +{ + int status, err; + pid_t pid; + size_t insize, outsize; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * try a "cat < testfile > checkfile" + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_CREAT, 0600); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); + + /* + * try a "cat < testfile >> checkfile" + */ + make_testfile(TESTFILE); + make_testfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_APPEND, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that output is twice as long as input */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize*2 == outsize); + + /* + * try a "cat < testfile > checkfile" with input and output swapped + */ + make_testfile(TESTFILE); + empty_outfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + CHECKFILE, O_WRONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_FAILURE); + + /* now check that input and output are still the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(outsize == 0); +} + +ATF_TC(t_spawn_reopen); + +ATF_TC_HEAD(t_spawn_reopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "an open filehandle can be replaced by a 'open' fileaction"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_reopen, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * make sure stdin is open in the parent + */ + freopen("/dev/zero", "r", stdin); + /* + * now request an open for this fd again in the child + */ + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + "/dev/null", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_open_nonexistent); + +ATF_TC_HEAD(t_spawn_open_nonexistent, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent, tc) +{ + int err, status; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + if (err == 0) { + /* + * The child has been created - it should fail and + * return exit code 127 + */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 127); + } else { + /* + * The error has been noticed early enough, no child has + * been run + */ + ATF_REQUIRE(err == ENOENT); + } + posix_spawn_file_actions_destroy(&fa); +} + +ATF_TC(t_spawn_open_nonexistent_diag); + +ATF_TC_HEAD(t_spawn_open_nonexistent_diag, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist " + "and delivers proper diagnostic"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent_diag, tc) +{ + int err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawnattr_t attr; + posix_spawn_file_actions_t fa; + + posix_spawnattr_init(&attr); + /* + * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that + * will cause a "proper" return value from posix_spawn(2) + * instead of a (potential) success there and a 127 exit + * status from the child process (c.f. the non-diag variant + * of this test). + */ + posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, &attr, args, NULL); + ATF_REQUIRE(err == ENOENT); + posix_spawn_file_actions_destroy(&fa); + posix_spawnattr_destroy(&attr); +} + +ATF_TC(t_spawn_fileactions); + +ATF_TC_HEAD(t_spawn_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests various complex fileactions"); +} + +ATF_TC_BODY(t_spawn_fileactions, tc) +{ + int fd1, fd2, fd3, status, err; + pid_t pid; + char * const args[2] = { __UNCONST("h_fileactions"), NULL }; + char helper[FILENAME_MAX]; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + + closefrom(fileno(stderr)+1); + + fd1 = open("/dev/null", O_RDONLY); + ATF_REQUIRE(fd1 == 3); + + fd2 = open("/dev/null", O_WRONLY, O_CLOEXEC); + ATF_REQUIRE(fd2 == 4); + + fd3 = open("/dev/null", O_WRONLY); + ATF_REQUIRE(fd3 == 5); + + posix_spawn_file_actions_addclose(&fa, fd1); + posix_spawn_file_actions_addopen(&fa, 6, "/dev/null", O_RDWR, 0); + posix_spawn_file_actions_adddup2(&fa, 1, 7); + + snprintf(helper, sizeof helper, "%s/h_fileactions", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(&pid, helper, &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_empty_fileactions); + +ATF_TC_HEAD(t_spawn_empty_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn with empty fileactions (PR kern/46038)"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_empty_fileactions, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + size_t insize, outsize; + + /* + * try a "cat < testfile > checkfile", but set up stdin/stdout + * already in the parent and pass empty file actions to the child. + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + freopen(TESTFILE, "r", stdin); + freopen(CHECKFILE, "w", stdout); + + posix_spawn_file_actions_init(&fa); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_fileactions); + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent); + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag); + ATF_TP_ADD_TC(tp, t_spawn_reopen); + ATF_TP_ADD_TC(tp, t_spawn_openmode); + ATF_TP_ADD_TC(tp, t_spawn_empty_fileactions); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c new file mode 100644 index 0000000..178374b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c @@ -0,0 +1,184 @@ +/* $NetBSD: t_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include <atf-c.h> +#include <spawn.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/wait.h> + +ATF_TC(t_spawn_ls); + +ATF_TC_HEAD(t_spawn_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawn executing /bin/ls"); +} + +ATF_TC_BODY(t_spawn_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawnp_ls); + +ATF_TC_HEAD(t_spawnp_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawnp executing ls via $PATH"); +} + +ATF_TC_BODY(t_spawnp_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawn_zero); + +ATF_TC_HEAD(t_spawn_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn an invalid binary"); +} + +ATF_TC_BODY(t_spawn_zero, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_zero"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf); +} + +ATF_TC(t_spawn_missing); + +ATF_TC_HEAD(t_spawn_missing, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a non existant binary"); +} + +ATF_TC_BODY(t_spawn_missing, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexist"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexist", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_nonexec); + +ATF_TC_HEAD(t_spawn_nonexec, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a script with non existing interpreter"); +} + +ATF_TC_BODY(t_spawn_nonexec, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexec"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexec", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_child); + +ATF_TC_HEAD(t_spawn_child, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a child and get it's return code"); +} + +ATF_TC_BODY(t_spawn_child, tc) +{ + char buf[FILENAME_MAX]; + char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL }; + char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL }; + char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL }; + int err, status; + pid_t pid; + + snprintf(buf, sizeof buf, "%s/h_spawn", + atf_tc_get_config_var(tc, "srcdir")); + + err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); + + err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1); + + err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_ls); + ATF_TP_ADD_TC(tp, t_spawnp_ls); + ATF_TP_ADD_TC(tp, t_spawn_zero); + ATF_TP_ADD_TC(tp, t_spawn_missing); + ATF_TP_ADD_TC(tp, t_spawn_nonexec); + ATF_TP_ADD_TC(tp, t_spawn_child); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c new file mode 100644 index 0000000..eb99c41 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c @@ -0,0 +1,173 @@ +/* $NetBSD: t_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <sched.h> +#include <signal.h> +#include <spawn.h> +#include <unistd.h> +#include <sys/wait.h> + +#define MAX(a, b) (a) > (b) ? (a) : (b) +#define MIN(a, b) (a) > (b) ? (b) : (a) + +static int get_different_scheduler(void); +static int get_different_priority(void); + +static int +get_different_scheduler() +{ + int scheduler, max, min, new; + + max = MAX(MAX(SCHED_FIFO, SCHED_OTHER), SCHED_RR); + min = MIN(MIN(SCHED_FIFO, SCHED_OTHER), SCHED_RR); + + /* get current schedule policy */ + scheduler = sched_getscheduler(0); + + /* new scheduler */ + new = (scheduler + 1); + if (new > max) + new = min; + + return new; +} + +static int +get_different_priority() +{ + int scheduler, max, min, new, priority; + struct sched_param param; + + /* get current schedule policy */ + scheduler = sched_getscheduler(0); + + max = sched_get_priority_max(scheduler); + min = sched_get_priority_min(scheduler); + + sched_getparam(0, ¶m); + priority = param.sched_priority; + + /* new schedule policy */ + new = (priority + 1); + if (new > max) + new = min; + + return new; +} + +ATF_TC(t_spawnattr); + +ATF_TC_HEAD(t_spawnattr, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Tests posix_spawn with scheduler attributes"); +} + +ATF_TC_BODY(t_spawnattr, tc) +{ + int pid, scheduler, child_scheduler, priority, status, err, pfd[2]; + char helper_arg[128]; + char * const args[] = { __UNCONST("h_spawnattr"), helper_arg, NULL }; + struct sched_param sp, child_sp; + sigset_t sig; + posix_spawnattr_t attr; + char helper[FILENAME_MAX]; + + /* + * create a pipe to controll the child + */ + err = pipe(pfd); + ATF_REQUIRE_MSG(err == 0, "could not create pipe, errno %d", errno); + sprintf(helper_arg, "%d", pfd[0]); + + posix_spawnattr_init(&attr); + + scheduler = get_different_scheduler(); + priority = get_different_priority(); + sp.sched_priority = priority; + + sigemptyset(&sig); + sigaddset(&sig, SIGUSR1); + + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDULER | + POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETPGROUP | + POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF | + POSIX_SPAWN_SETSIGDEF); + posix_spawnattr_setpgroup(&attr, 0); + posix_spawnattr_setschedparam(&attr, &sp); + posix_spawnattr_setschedpolicy(&attr, scheduler); + posix_spawnattr_setsigmask(&attr, &sig); + posix_spawnattr_setsigdefault(&attr, &sig); + + sprintf(helper, "%s/h_spawnattr", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(&pid, helper, NULL, &attr, args, NULL); + ATF_REQUIRE_MSG(err == 0, "error %d", err); + + child_scheduler = sched_getscheduler(pid); + ATF_REQUIRE_MSG(scheduler == child_scheduler, + "scheduler = %d, child_scheduler = %d, pid %d, errno %d", + scheduler, child_scheduler, pid, errno); + + sched_getparam(pid, &child_sp); + ATF_REQUIRE_MSG(child_sp.sched_priority == sp.sched_priority, + "priority is: %d, but we requested: %d", + child_sp.sched_priority, sp.sched_priority); + + ATF_REQUIRE_MSG(pid == getpgid(pid), "child pid: %d, child pgid: %d", + pid, getpgid(pid)); + + /* ready, let child go */ + write(pfd[1], "q", 1); + close(pfd[0]); + close(pfd[1]); + + /* wait and check result from child */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + posix_spawnattr_destroy(&attr); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawnattr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_alarm.c b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c new file mode 100644 index 0000000..d9e903d1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +static bool fail; +static void handler(int); + +static void +handler(int signo) +{ + + if (signo == SIGALRM) + fail = false; +} + +ATF_TC(alarm_basic); +ATF_TC_HEAD(alarm_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of alarm(3)"); +} + +ATF_TC_BODY(alarm_basic, tc) +{ + + ATF_REQUIRE(signal(SIGALRM, handler) == 0); + + fail = true; + + (void)alarm(1); + (void)sleep(2); + + if (fail != false) + atf_tc_fail("alarm(3) failed to deliver signal"); +} + +ATF_TC(alarm_fork); +ATF_TC_HEAD(alarm_fork, tc) +{ + atf_tc_set_md_var(tc, "descr", "Does fork(2) clear a pending alarm?"); +} + +ATF_TC_BODY(alarm_fork, tc) +{ + unsigned int rv; + pid_t pid; + int sta; + + /* + * Any pending alarms should be + * cleared in the child process. + */ + (void)alarm(60); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = alarm(0); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)alarm(0); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("pending alarm was not cleared for child"); +} + +ATF_TC(alarm_previous); +ATF_TC_HEAD(alarm_previous, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test return value from alarm(3)"); +} + +ATF_TC_BODY(alarm_previous, tc) +{ + unsigned int rv; + + /* + * See that alarm(3) returns the amount + * left on the timer from the previous call. + */ + rv = alarm(60); + + if (rv != 0) + goto fail; + + rv = alarm(0); + + if (rv < 50) + goto fail; + + (void)alarm(0); + + return; + +fail: + atf_tc_fail("invalid return value from alarm(3)"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, alarm_basic); + ATF_TP_ADD_TC(tp, alarm_fork); + ATF_TP_ADD_TC(tp, alarm_previous); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_assert.c b/contrib/netbsd-tests/lib/libc/gen/t_assert.c new file mode 100644 index 0000000..140417a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_assert.c @@ -0,0 +1,132 @@ +/* $NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $"); + +#include <sys/wait.h> + +#include <assert.h> +#include <atf-c.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static void handler(int); + +static void +handler(int signo) +{ + /* Nothing. */ +} + +ATF_TC(assert_false); +ATF_TC_HEAD(assert_false, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #1"); +} + +ATF_TC_BODY(assert_false, tc) +{ + struct sigaction sa; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)closefrom(0); + (void)memset(&sa, 0, sizeof(struct sigaction)); + + sa.sa_flags = 0; + sa.sa_handler = handler; + + (void)sigemptyset(&sa.sa_mask); + (void)sigaction(SIGABRT, &sa, 0); + + assert(1 == 1); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WIFEXITED(sta) == 0) + atf_tc_fail("assert(3) fired haphazardly"); +} + +ATF_TC(assert_true); +ATF_TC_HEAD(assert_true, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #2"); +} + +ATF_TC_BODY(assert_true, tc) +{ + struct sigaction sa; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)closefrom(0); + (void)memset(&sa, 0, sizeof(struct sigaction)); + + sa.sa_flags = 0; + sa.sa_handler = handler; + + (void)sigemptyset(&sa.sa_mask); + (void)sigaction(SIGABRT, &sa, 0); + + assert(1 == 2); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGABRT) + atf_tc_fail("assert(3) did not fire"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, assert_false); + ATF_TP_ADD_TC(tp, assert_true); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c new file mode 100644 index 0000000..6c82cb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c @@ -0,0 +1,200 @@ +/* $NetBSD: t_basedirname.c,v 1.2 2011/07/07 09:49:59 jruoho Exp $ */ + +/* + * Regression test for basename(3). + * + * Written by Jason R. Thorpe <thorpej@NetBSD.org>, Oct. 2002. + * Public domain. + */ + +#include <atf-c.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <libgen.h> + +struct { + const char *input; + const char *output; +} test_basename_table[] = { +/* + * The following are taken from the "Sample Input and Output Strings + * for basename()" table in IEEE Std 1003.1-2001. + */ + { "/usr/lib", "lib" }, + { "/usr/", "usr" }, + { "/", "/" }, + { "///", "/" }, + { "//usr//lib//", "lib" }, +/* + * IEEE Std 1003.1-2001: + * + * If path is a null pointer or points to an empty string, + * basename() shall return a pointer to the string "." . + */ + { "", "." }, + { NULL, "." }, +/* + * IEEE Std 1003.1-2001: + * + * If the string is exactly "//", it is implementation-defined + * whether "/" or "//" is returned. + * + * The NetBSD implementation returns "/". + */ + { "//", "/" }, + + { NULL, NULL } +}; + +struct { + const char *input; + const char *output; +} test_dirname_table[] = { +/* + * The following are taken from the "Sample Input and Output Strings + * for dirname()" table in IEEE Std 1003.1-2001. + */ + { "/usr/lib", "/usr" }, + { "/usr/", "/" }, + { "usr", "." }, + { "/", "/" }, + { ".", "." }, + { "..", "." }, +/* + * IEEE Std 1003.1-2001: + * + * If path is a null pointer or points to an empty string, + * dirname() shall return a pointer to the string "." . + */ + { "", "." }, + { NULL, "." }, +/* + * IEEE Std 1003.1-2001: + * + * Since the meaning of the leading "//" is implementation-defined, + * dirname("//foo") may return either "//" or "/" (but nothing else). + * + * The NetBSD implementation returns "/". + */ + { "//foo", "/" }, +/* + * Make sure the trailing slashes after the directory name component + * get trimmed. The Std does not talk about this, but this is what + * Solaris 8's dirname(3) does. + */ + { "/usr///lib", "/usr" }, + + { NULL, NULL } +}; + +ATF_TC(basename_posix); +ATF_TC_HEAD(basename_posix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test basename(3) with POSIX examples"); +} + +ATF_TC_BODY(basename_posix, tc) +{ + char testbuf[32], *base; + int i; + + for (i = 0; test_basename_table[i].output != NULL; i++) { + if (test_basename_table[i].input != NULL) { + if (strlen(test_basename_table[i].input) >= + sizeof(testbuf)) + atf_tc_skip("Testbuf too small!"); + strcpy(testbuf, test_basename_table[i].input); + base = basename(testbuf); + } else + base = basename(NULL); + + /* + * basename(3) is allowed to modify the input buffer. + * However, that is considered hostile by some programs, + * and so we elect to consider this an error. + * + * This is not a problem, as basename(3) is also allowed + * to return a pointer to a statically-allocated buffer + * (it is explicitly not required to be reentrant). + */ + if (test_basename_table[i].input != NULL && + strcmp(test_basename_table[i].input, testbuf) != 0) { + fprintf(stderr, + "Input buffer for \"%s\" was modified\n", + test_basename_table[i].input); + atf_tc_fail("Input buffer was modified."); + } + + /* Make sure the result is correct. */ + if (strcmp(test_basename_table[i].output, base) != 0) { + fprintf(stderr, + "Input \"%s\", output \"%s\", expected \"%s\"\n", + test_basename_table[i].input == + NULL ? "(null)" : test_basename_table[i].input, + base, test_basename_table[i].output); + atf_tc_fail("Output does not match expected value."); + } + } +} + + +ATF_TC(dirname_posix); +ATF_TC_HEAD(dirname_posix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dirname(3) with POSIX examples"); +} + +ATF_TC_BODY(dirname_posix, tc) +{ + char testbuf[32], *base; + int i; + + for (i = 0; test_dirname_table[i].output != NULL; i++) { + if (test_dirname_table[i].input != NULL) { + if (strlen(test_dirname_table[i].input) >= + sizeof(testbuf)) + atf_tc_skip("Testbuf too small!"); + strcpy(testbuf, test_dirname_table[i].input); + base = dirname(testbuf); + } else + base = dirname(NULL); + + /* + * dirname(3) is allowed to modify the input buffer. + * However, that is considered hostile by some programs, + * and so we elect to consider this an error. + * + * This is not a problem, as dirname(3) is also allowed + * to return a pointer to a statically-allocated buffer + * (it is explicitly not required to be reentrant). + */ + if (test_dirname_table[i].input != NULL && + strcmp(test_dirname_table[i].input, testbuf) != 0) { + fprintf(stderr, + "Input buffer for \"%s\" was modified\n", + test_dirname_table[i].input); + atf_tc_fail("Input buffer was modified."); + } + + /* Make sure the result is correct. */ + if (strcmp(test_dirname_table[i].output, base) != 0) { + fprintf(stderr, + "Input \"%s\", output \"%s\", expected \"%s\"\n", + test_dirname_table[i].input == + NULL ? "(null)" : test_dirname_table[i].input, + base, test_dirname_table[i].output); + atf_tc_fail("Output does not match expected value."); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, basename_posix); + ATF_TP_ADD_TC(tp, dirname_posix); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c new file mode 100644 index 0000000..75ebabb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c @@ -0,0 +1,173 @@ +/* $NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <unistd.h> + +static const char path[] = "closefrom"; + +ATF_TC_WITH_CLEANUP(closefrom_basic); +ATF_TC_HEAD(closefrom_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #1"); +} + +ATF_TC_BODY(closefrom_basic, tc) +{ + int fd, cur1, cur2; + + (void)closefrom(STDERR_FILENO + 1); + + fd = open(path, O_RDONLY | O_CREAT, 0400); + ATF_REQUIRE(fd >= 0); + + cur1 = fcntl(0, F_MAXFD); + + ATF_REQUIRE(cur1 == STDERR_FILENO + 1); + ATF_REQUIRE(closefrom(cur1) == 0); + + cur2 = fcntl(0, F_MAXFD); + + ATF_REQUIRE(cur1 - 1 == cur2); + ATF_REQUIRE(close(fd) == -1); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(closefrom_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(closefrom_buffer); +ATF_TC_HEAD(closefrom_buffer, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #2"); +} + +ATF_TC_BODY(closefrom_buffer, tc) +{ + int buf[16], cur, half; + size_t i; + + /* + * Open a buffer of descriptors, close the half of + * these and verify that the result is consistent. + */ + ATF_REQUIRE(closefrom(STDERR_FILENO + 1) == 0); + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == STDERR_FILENO); + + for (i = 0; i < __arraycount(buf); i++) { + buf[i] = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(buf[i] >= 0); + } + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == __arraycount(buf) + STDERR_FILENO); + + half = STDERR_FILENO + __arraycount(buf) / 2; + ATF_REQUIRE(closefrom(half) == 0); + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == half - 1); + + for (i = 0; i < __arraycount(buf); i++) + (void)close(buf[i]); +} + +ATF_TC_CLEANUP(closefrom_buffer, tc) +{ + (void)unlink(path); +} + +ATF_TC(closefrom_err); +ATF_TC_HEAD(closefrom_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from closefrom(3)"); +} + +ATF_TC_BODY(closefrom_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, closefrom(-INT_MAX) == -1); +} + +ATF_TC(closefrom_one); +ATF_TC_HEAD(closefrom_one, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test closefrom(1)"); +} + +ATF_TC_BODY(closefrom_one, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (closefrom(1) != 0) + _exit(10); + + _exit(fcntl(0, F_MAXFD)); + } + + + (void)wait(&sta); + + /* + * STDIN_FILENO sould still be open; WEXITSTATUS(1) == 0. + */ + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != 0) + atf_tc_fail("not all descriptors were closed"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, closefrom_basic); + ATF_TP_ADD_TC(tp, closefrom_buffer); + ATF_TP_ADD_TC(tp, closefrom_err); + ATF_TP_ADD_TC(tp, closefrom_one); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c new file mode 100644 index 0000000..9eca03b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $"); + +#include <atf-c.h> +#include <limits.h> +#include <stdio.h> +#include <sched.h> + +ATF_TC(cpuset_err); +ATF_TC_HEAD(cpuset_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from cpuset(3)"); +} + +ATF_TC_BODY(cpuset_err, tc) +{ + cpuset_t *set; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + ATF_CHECK(cpuset_set(-1, set) == -1); + ATF_CHECK(cpuset_clr(-1, set) == -1); + ATF_CHECK(cpuset_isset(-1, set) == -1); + + ATF_CHECK(cpuset_set(INT_MAX, set) == -1); + ATF_CHECK(cpuset_clr(INT_MAX, set) == -1); + ATF_CHECK(cpuset_isset(INT_MAX, set) == -1); + + cpuset_destroy(set); +} + +ATF_TC(cpuset_set); +ATF_TC_HEAD(cpuset_set, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cpuset_set(3)"); +} + +ATF_TC_BODY(cpuset_set, tc) +{ + cpuset_t *set; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + ATF_REQUIRE(cpuset_set(0, set) == 0); + ATF_REQUIRE(cpuset_isset(0, set) > 0); + ATF_REQUIRE(cpuset_clr(0, set) == 0); + ATF_REQUIRE(cpuset_isset(0, set) == 0); + + cpuset_destroy(set); +} + +ATF_TC(cpuset_size); +ATF_TC_HEAD(cpuset_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test puset_size(3)"); +} + +ATF_TC_BODY(cpuset_size, tc) +{ + cpuset_t *set; + size_t size; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + size = cpuset_size(set); + + ATF_CHECK(cpuset_set((size * 8) - 1, set) == 0); + ATF_CHECK(cpuset_set((size * 8) + 1, set) == -1); + + cpuset_destroy(set); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cpuset_err); + ATF_TP_ADD_TC(tp, cpuset_set); + ATF_TP_ADD_TC(tp, cpuset_size); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_dir.c b/contrib/netbsd-tests/lib/libc/gen/t_dir.c new file mode 100644 index 0000000..81412c1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_dir.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_dir.c,v 1.6 2013/10/19 17:45:00 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <assert.h> +#include <dirent.h> +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/stat.h> + +ATF_TC(seekdir_basic); +ATF_TC_HEAD(seekdir_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check telldir(3) and seekdir(3) " + "for correct behavior (PR lib/24324)"); +} + +ATF_TC_BODY(seekdir_basic, tc) +{ + DIR *dp; + char *wasname; + struct dirent *entry; + long here; + + mkdir("t", 0755); + creat("t/a", 0600); + creat("t/b", 0600); + creat("t/c", 0600); + + dp = opendir("t"); + if ( dp == NULL) + atf_tc_fail("Could not open temp directory."); + + /* skip two for . and .. */ + entry = readdir(dp); + entry = readdir(dp); + + /* get first entry */ + entry = readdir(dp); + here = telldir(dp); + + /* get second entry */ + entry = readdir(dp); + wasname = strdup(entry->d_name); + if (wasname == NULL) + atf_tc_fail("cannot allocate memory"); + + /* get third entry */ + entry = readdir(dp); + + /* try to return to the position after the first entry */ + seekdir(dp, here); + entry = readdir(dp); + + if (entry == NULL) + atf_tc_fail("entry 1 not found"); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("1st seekdir found wrong name"); + + /* try again, and throw in a telldir() for good measure */ + seekdir(dp, here); + here = telldir(dp); + entry = readdir(dp); + + if (entry == NULL) + atf_tc_fail("entry 2 not found"); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("2nd seekdir found wrong name"); + + /* One more time, to make sure that telldir() doesn't affect result */ + seekdir(dp, here); + entry = readdir(dp); + + if (entry == NULL) + atf_tc_fail("entry 3 not found"); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("3rd seekdir found wrong name"); + + closedir(dp); +} + +ATF_TC(telldir_leak); +ATF_TC_HEAD(telldir_leak, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Check telldir(3) for memory leakage (PR lib/24324)"); +} + +ATF_TC_BODY(telldir_leak, tc) +{ + DIR *dp; + char *memused; + int i; + int oktouse = 4096; + + dp = opendir("."); + if (dp == NULL) + atf_tc_fail("Could not open current directory"); + + (void)telldir(dp); + memused = sbrk(0); + closedir(dp); + + for (i = 0; i < 1000; i++) { + dp = opendir("."); + if (dp == NULL) + atf_tc_fail("Could not open current directory"); + + (void)telldir(dp); + closedir(dp); + + if ((char *)sbrk(0) - memused > oktouse) { + (void)printf("Used %td extra bytes for %d telldir " + "calls", ((char *)sbrk(0) - memused), i); + oktouse = (char *)sbrk(0) - memused; + } + } + if (oktouse > 4096) { + atf_tc_fail("Failure: leaked %d bytes", oktouse); + } else { + (void)printf("OK: used %td bytes\n", (char *)(sbrk(0))-memused); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, seekdir_basic); + ATF_TP_ADD_TC(tp, telldir_leak); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c new file mode 100644 index 0000000..9561a3c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_floatunditf.c,v 1.5 2014/02/02 08:16:22 martin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <atf-c/config.h> +#include <inttypes.h> +#include <math.h> + +#ifdef __HAVE_LONG_DOUBLE +static const struct { + uint64_t u64; + long double ld; +} testcases[] = { + { 0xffffffffffffffffULL, 0xf.fffffffffffffffp+60L }, + { 0xfffffffffffffffeULL, 0xf.ffffffffffffffep+60L }, + { 0xfffffffffffffffdULL, 0xf.ffffffffffffffdp+60L }, + { 0xfffffffffffffffcULL, 0xf.ffffffffffffffcp+60L }, + { 0x7fffffffffffffffULL, 0xf.ffffffffffffffep+59L }, + { 0x3fffffffffffffffULL, 0xf.ffffffffffffffcp+58L }, + { 0x1fffffffffffffffULL, 0xf.ffffffffffffff8p+57L }, + { 0xfffffffffffffffULL, 0xf.ffffffffffffffp+56L }, + { 0x7ffffffffffffffULL, 0xf.fffffffffffffep+55L }, + { 0x3ffffffffffffffULL, 0xf.fffffffffffffcp+54L }, + { 0x1ffffffffffffffULL, 0xf.fffffffffffff8p+53L }, + { 0xffffffffffffffULL, 0xf.fffffffffffffp+52L }, + { 0x7fffffffffffffULL, 0xf.ffffffffffffep+51L }, + { 0x3fffffffffffffULL, 0xf.ffffffffffffcp+50L }, + { 0x1fffffffffffffULL, 0xf.ffffffffffff8p+49L }, + { 0xfffffffffffffULL, 0xf.ffffffffffffp+48L }, + { 0x7ffffffffffffULL, 0xf.fffffffffffep+47L }, + { 0x3ffffffffffffULL, 0xf.fffffffffffcp+46L }, + { 0x1ffffffffffffULL, 0xf.fffffffffff8p+45L }, + { 0xffffffffffffULL, 0xf.fffffffffffp+44L }, + { 0x7fffffffffffULL, 0xf.ffffffffffep+43L }, + { 0x3fffffffffffULL, 0xf.ffffffffffcp+42L }, + { 0x1fffffffffffULL, 0xf.ffffffffff8p+41L }, + { 0xfffffffffffULL, 0xf.ffffffffffp+40L }, + { 0x7ffffffffffULL, 0xf.fffffffffep+39L }, + { 0x3ffffffffffULL, 0xf.fffffffffcp+38L }, + { 0x1ffffffffffULL, 0xf.fffffffff8p+37L }, + { 0xffffffffffULL, 0xf.fffffffffp+36L }, + { 0x7fffffffffULL, 0xf.ffffffffep+35L }, + { 0x3fffffffffULL, 0xf.ffffffffcp+34L }, + { 0x1fffffffffULL, 0xf.ffffffff8p+33L }, + { 0xfffffffffULL, 0xf.ffffffffp+32L }, + { 0x7ffffffffULL, 0xf.fffffffep+31L }, + { 0x3ffffffffULL, 0xf.fffffffcp+30L }, + { 0x1ffffffffULL, 0xf.fffffff8p+29L }, + { 0xffffffffULL, 0xf.fffffffp+28L }, + { 0x7fffffffULL, 0xf.ffffffep+27L }, + { 0x3fffffffULL, 0xf.ffffffcp+26L }, + { 0x1fffffffULL, 0xf.ffffff8p+25L }, + { 0xfffffffULL, 0xf.ffffffp+24L }, + { 0x7ffffffULL, 0xf.fffffep+23L }, + { 0x3ffffffULL, 0xf.fffffcp+22L }, + { 0x1ffffffULL, 0xf.fffff8p+21L }, + { 0xffffffULL, 0xf.fffffp+20L }, + { 0x7fffffULL, 0xf.ffffep+19L }, + { 0x3fffffULL, 0xf.ffffcp+18L }, + { 0x1fffffULL, 0xf.ffff8p+17L }, + { 0xfffffULL, 0xf.ffffp+16L }, + { 0x7ffffULL, 0xf.fffep+15L }, + { 0x3ffffULL, 0xf.fffcp+14L }, + { 0x1ffffULL, 0xf.fff8p+13L }, + { 0xffffULL, 0xf.fffp+12L }, + { 0x7fffULL, 0xf.ffep+11L }, + { 0x3fffULL, 0xf.ffcp+10L }, + { 0x1fffULL, 0xf.ff8p+9L }, + { 0xfffULL, 0xf.ffp+8L }, + { 0x7ffULL, 0xf.fep+7L }, + { 0x3ffULL, 0xf.fcp+6L }, + { 0x1ffULL, 0xf.f8p+5L }, + { 0xffULL, 0xf.fp+4L }, + { 0x7fULL, 0xf.ep+3L }, + { 0x3fULL, 0xf.cp+2L }, + { 0x1fULL, 0xf.8p+1L }, + { 0xfULL, 0xfp+0L }, + { 0x7ULL, 0xep-1L }, + { 0x3ULL, 0xcp-2L }, + { 0x1ULL, 0x8p-3L }, +}; +#endif + +ATF_TC(floatunditf); +ATF_TC_HEAD(floatunditf, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that uint64 -> long double conversion works"); +} + +ATF_TC_BODY(floatunditf, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + size_t i; + + for (i = 0; i < __arraycount(testcases); ++i) + ATF_CHECK_MSG( + testcases[i].ld == (long double)testcases[i].u64, + "#%zu: expected %.20Lf, got %.20Lf\n", i, + testcases[i].ld, + (long double)testcases[i].u64); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, floatunditf); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c new file mode 100644 index 0000000..ab95400 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_fmtcheck.c,v 1.3 2014/06/14 08:19:02 apb Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Allen Briggs. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> + +const char *fmtcheck(const char *f1, const char *f2) + __attribute__((__format_arg__(2))); + +#include <err.h> + +struct test_fmt { + const char *fmt1; + const char *fmt2; + int correct; +} test_fmts[] = { + { "%d", "%d", 1 }, + { "%2d", "%2.2d", 1 }, + { "%x", "%d", 1 }, + { "%u", "%d", 1 }, + { "%03d", "%d", 1 }, + { "%-2d", "%d", 1 }, + { "%d", "%-12.1d", 1 }, + { "%d", "%-01.3d", 1 }, + { "%X", "%-01.3d", 1 }, + { "%D", "%ld", 1 }, + { "%s", "%s", 1 }, + { "%s", "This is a %s test", 1 }, + { "Hi, there. This is a %s test", "%s", 1 }, + { "%d", "%s", 2 }, + { "%e", "%s", 2 }, + { "%r", "%d", 2 }, + { "%*.2d", "%*d", 1 }, + { "%2.*d", "%*d", 2 }, + { "%*d", "%*d", 1 }, + { "%-3", "%d", 2 }, + { "%d %s", "%d", 2 }, + { "%*.*.*d", "%*.*.*d", 2 }, + { "%d", "%d %s", 1 }, + { "%40s", "%20s", 1 }, + { "%x %x %x", "%o %u %d", 1 }, + { "%o %u %d", "%x %x %X", 1 }, + { "%#o %u %#-d", "%x %#x %X", 1 }, + { "%qd", "%llx", 1 }, + { "%%", "%llx", 1 }, + { "%ld %30s %#llx %-10.*e", "This number %lu%% and string %s has %qd numbers and %.*g floats", 1 }, + { "%o", "%lx", 2 }, + { "%p", "%lu", 2 }, +}; + +ATF_TC(fmtcheck_basic); +ATF_TC_HEAD(fmtcheck_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test fmtcheck(3)"); +} + +ATF_TC_BODY(fmtcheck_basic, tc) +{ + unsigned int i, r; + const char *f, *cf, *f1, *f2; + + r = 0; + for (i = 0 ; i < __arraycount(test_fmts); i++) { + f1 = test_fmts[i].fmt1; + f2 = test_fmts[i].fmt2; + f = fmtcheck(f1, f2); + if (test_fmts[i].correct == 1) { + cf = f1; + } else { + cf = f2; + } + if (f != cf) { + r++; + atf_tc_fail_nonfatal("Test %d: (%s) vs. (%s) failed " + "(should have returned %s)", i, f1, f2, + (test_fmts[i].correct == 1) ? "1st" : "2nd"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fmtcheck_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c new file mode 100644 index 0000000..f90d8cf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c @@ -0,0 +1,167 @@ +/* $NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $"); + +#include <atf-c.h> +#include <fnmatch.h> +#include <stdio.h> + +ATF_TC(fnmatch_backslashes); +ATF_TC_HEAD(fnmatch_backslashes, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test translation of '\\' with fnmatch(3) (PR lib/41558)"); +} + +ATF_TC_BODY(fnmatch_backslashes, tc) +{ + const int rv = fnmatch(/* pattern */ "\\", "\\", 0); + + if (rv != FNM_NOMATCH) + atf_tc_fail("fnmatch(3) did not translate '\\'"); +} + +ATF_TC(fnmatch_casefold); +ATF_TC_HEAD(fnmatch_casefold, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_CASEFOLD"); +} + +ATF_TC_BODY(fnmatch_casefold, tc) +{ + ATF_CHECK(fnmatch("xxx", "XXX", 0) != 0); + ATF_CHECK(fnmatch("XXX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("xxx", "XxX", 0) != 0); + ATF_CHECK(fnmatch("XxX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("x*x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("**x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("*?x", "XXX", 0) != 0); + + ATF_CHECK(fnmatch("xxx", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XXX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("xxx", "XxX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XxX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("x*x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("**x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("*?x", "XXX", FNM_CASEFOLD) == 0); +} + +ATF_TC(fnmatch_leadingdir); +ATF_TC_HEAD(fnmatch_leadingdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_LEADING_DIR"); +} + +ATF_TC_BODY(fnmatch_leadingdir, tc) +{ + ATF_CHECK(fnmatch("", "/*", 0) != 0); + ATF_CHECK(fnmatch(" ", " /*", 0) != 0); + ATF_CHECK(fnmatch("x", "x/*", 0) != 0); + ATF_CHECK(fnmatch("///", "////*", 0) != 0); + + ATF_CHECK(fnmatch("", "/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch(" ", " /*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("x", "x/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("///", "////*", FNM_LEADING_DIR) == 0); +} + +ATF_TC(fnmatch_noescape); +ATF_TC_HEAD(fnmatch_noescape, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_NOESCAPE"); +} + +ATF_TC_BODY(fnmatch_noescape, tc) +{ + ATF_CHECK(fnmatch(" \\x", " \\x", 0) != 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", 0) != 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", 0) != 0); + + ATF_CHECK(fnmatch(" \\x", " \\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", FNM_NOESCAPE) == 0); +} + +ATF_TC(fnmatch_pathname); +ATF_TC_HEAD(fnmatch_pathname, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PATHNAME"); +} + +ATF_TC_BODY(fnmatch_pathname, tc) +{ + ATF_CHECK(fnmatch("???x", "xxx/x", FNM_PATHNAME) != 0); + ATF_CHECK(fnmatch("***x", "xxx/x", FNM_PATHNAME) != 0); + + ATF_CHECK(fnmatch("???x", "xxxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("*/xxx", "/xxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("x/*.y", "x/z.y", FNM_PATHNAME) == 0); +} + +ATF_TC(fnmatch_period); +ATF_TC_HEAD(fnmatch_period, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PERIOD"); +} + +ATF_TC_BODY(fnmatch_period, tc) +{ + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD | FNM_CASEFOLD) == 0); + + ATF_CHECK(fnmatch("x?y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x*y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*.c", "x.c", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/?", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/*", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch(".*/?", ".x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/.?", "x/.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x[.]y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + + ATF_CHECK(fnmatch("?x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/?y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/*y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fnmatch_backslashes); + ATF_TP_ADD_TC(tp, fnmatch_casefold); + ATF_TP_ADD_TC(tp, fnmatch_leadingdir); + ATF_TP_ADD_TC(tp, fnmatch_noescape); + ATF_TP_ADD_TC(tp, fnmatch_pathname); + ATF_TP_ADD_TC(tp, fnmatch_period); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c new file mode 100644 index 0000000..21dea9e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c @@ -0,0 +1,206 @@ +/* $NetBSD: t_fpclassify.c,v 1.3 2011/10/01 21:47:08 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <float.h> +#include <math.h> +#include <stdio.h> +#include <string.h> + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + atf_tc_set_md_var(tc, "descr", "Dummy test"); +} + +ATF_TC_BODY(no_test,tc) +{ + atf_tc_skip("Test not available on this architecture"); +} + +#else /* defined(_FLOAT_IEEE754) */ + +ATF_TC(fpclassify_float); +ATF_TC_HEAD(fpclassify_float, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test float operations"); +} + +ATF_TC_BODY(fpclassify_float, tc) +{ + float d0, d1, d2, f, ip; + int e, i; + + d0 = FLT_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpf(d0, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < FLT_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpf(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modff(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +ATF_TC(fpclassify_double); +ATF_TC_HEAD(fpclassify_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test double operations"); +} + +ATF_TC_BODY(fpclassify_double, tc) +{ + double d0, d1, d2, f, ip; + int e, i; + + d0 = DBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexp(d0, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < DBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexp(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modf(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +/* + * XXX NetBSD doesn't have long-double flavors of frexp, ldexp, and modf, + * XXX so this test is disabled. + */ + +#ifdef TEST_LONG_DOUBLE + +ATF_TC(fpclassify_long_double); +ATF_TC_HEAD(fpclassify_long_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test long double operations"); +} + +ATF_TC_BODY(fpclassify_long_double, tc) +{ + long double d0, d1, d2, f, ip; + int e, i; + + d0 = LDBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpl(d0, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < LDBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpl(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modfl(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpclassify_float); + ATF_TP_ADD_TC(tp, fpclassify_double); +#ifdef TEST_LONG_DOUBLE + ATF_TP_ADD_TC(tp, fpclassify_long_double); +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c new file mode 100644 index 0000000..998eb85 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c @@ -0,0 +1,355 @@ +/* $NetBSD: t_fpsetmask.c,v 1.13 2014/02/09 21:26:07 jmmv Exp $ */ + +/*- + * Copyright (c) 1995 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <stdio.h> +#include <signal.h> +#include <float.h> +#include <setjmp.h> +#include <stdlib.h> +#include <string.h> + +#include "isqemu.h" + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Dummy test case"); +} + +ATF_TC_BODY(no_test, tc) +{ + + atf_tc_skip("Test not available on this architecture."); +} + +#else /* defined(_FLOAT_IEEE754) */ + +#include <ieeefp.h> + +const char *skip_mesg; +const char *skip_arch; + +void sigfpe(int, siginfo_t *, void *); + +volatile sig_atomic_t signal_caught; +volatile int sicode; + +static volatile const float f_one = 1.0; +static volatile const float f_zero = 0.0; +static volatile const double d_one = 1.0; +static volatile const double d_zero = 0.0; +static volatile const long double ld_one = 1.0; +static volatile const long double ld_zero = 0.0; + +static volatile const float f_huge = FLT_MAX; +static volatile const float f_tiny = FLT_MIN; +static volatile const double d_huge = DBL_MAX; +static volatile const double d_tiny = DBL_MIN; +static volatile const long double ld_huge = LDBL_MAX; +static volatile const long double ld_tiny = LDBL_MIN; + +static volatile float f_x; +static volatile double d_x; +static volatile long double ld_x; + +/* trip divide by zero */ +static void +f_dz(void) +{ + + f_x = f_one / f_zero; +} + +static void +d_dz(void) +{ + + d_x = d_one / d_zero; +} + +static void +ld_dz(void) +{ + + ld_x = ld_one / ld_zero; +} + +/* trip invalid operation */ +static void +d_inv(void) +{ + + d_x = d_zero / d_zero; +} + +static void +ld_inv(void) +{ + + ld_x = ld_zero / ld_zero; +} + +static void +f_inv(void) +{ + + f_x = f_zero / f_zero; +} + +/* trip overflow */ +static void +f_ofl(void) +{ + + f_x = f_huge * f_huge; +} + +static void +d_ofl(void) +{ + + d_x = d_huge * d_huge; +} + +static void +ld_ofl(void) +{ + + ld_x = ld_huge * ld_huge; +} + +/* trip underflow */ +static void +f_ufl(void) +{ + + f_x = f_tiny * f_tiny; +} + +static void +d_ufl(void) +{ + + d_x = d_tiny * d_tiny; +} + +static void +ld_ufl(void) +{ + + ld_x = ld_tiny * ld_tiny; +} + +struct ops { + void (*op)(void); + fp_except mask; + int sicode; +}; + +static const struct ops float_ops[] = { + { f_dz, FP_X_DZ, FPE_FLTDIV }, + { f_inv, FP_X_INV, FPE_FLTINV }, + { f_ofl, FP_X_OFL, FPE_FLTOVF }, + { f_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops double_ops[] = { + { d_dz, FP_X_DZ, FPE_FLTDIV }, + { d_inv, FP_X_INV, FPE_FLTINV }, + { d_ofl, FP_X_OFL, FPE_FLTOVF }, + { d_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops long_double_ops[] = { + { ld_dz, FP_X_DZ, FPE_FLTDIV }, + { ld_inv, FP_X_INV, FPE_FLTINV }, + { ld_ofl, FP_X_OFL, FPE_FLTOVF }, + { ld_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static sigjmp_buf b; + +static void +fpsetmask_masked(const struct ops *test_ops) +{ + struct sigaction sa; + fp_except ex1, ex2; + const struct ops *t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exceptions masked, check whether "sticky" bits are set correctly + */ + for (t = test_ops; t->op != NULL; t++) { + (*t->op)(); + ex1 = fpgetsticky(); + ATF_CHECK_EQ(ex1 & t->mask, t->mask); + ATF_CHECK_EQ(signal_caught, 0); + + /* check correct fpsetsticky() behaviour */ + ex2 = fpsetsticky(0); + ATF_CHECK_EQ(fpgetsticky(), 0); + ATF_CHECK_EQ(ex1, ex2); + } +} + +/* force delayed exceptions to be delivered */ +#define BARRIER() fpsetmask(0); f_x = f_one * f_one + +static void +fpsetmask_unmasked(const struct ops *test_ops) +{ + struct sigaction sa; + int r; + const struct ops *volatile t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exception unmasked, check SIGFPE delivery and correct siginfo + */ + for (t = test_ops; t->op != NULL; t++) { + fpsetmask(t->mask); + r = sigsetjmp(b, 1); + if (!r) { + (*t->op)(); + BARRIER(); + } + ATF_CHECK_EQ(signal_caught, 1); + ATF_CHECK_EQ(sicode, t->sicode); + signal_caught = 0; + } +} + +void +sigfpe(int s, siginfo_t *si, void *c) +{ + signal_caught = 1; + sicode = si->si_code; + siglongjmp(b, 1); +} + +#define TEST(m, t) \ + ATF_TC(m##_##t); \ + \ + ATF_TC_HEAD(m##_##t, tc) \ + { \ + \ + atf_tc_set_md_var(tc, "descr", \ + "Test " ___STRING(m) " exceptions for " \ + ___STRING(t) "values"); \ + } \ + \ + ATF_TC_BODY(m##_##t, tc) \ + { \ + if (strcmp(MACHINE, "macppc") == 0) \ + atf_tc_expect_fail("PR port-macppc/46319"); \ + \ + if (isQEMU()) \ + atf_tc_expect_fail("PR misc/44767"); \ + \ + m(t##_ops); \ + } + +TEST(fpsetmask_masked, float) +TEST(fpsetmask_masked, double) +TEST(fpsetmask_masked, long_double) +TEST(fpsetmask_unmasked, float) +TEST(fpsetmask_unmasked, double) +TEST(fpsetmask_unmasked, long_double) + +ATF_TC(fpsetmask_basic); +ATF_TC_HEAD(fpsetmask_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fpsetmask(3)"); +} + +ATF_TC_BODY(fpsetmask_basic, tc) +{ + size_t i; + fp_except_t msk, lst[] = { FP_X_INV, FP_X_DZ, FP_X_OFL, FP_X_UFL }; + + msk = fpgetmask(); + for (i = 0; i < __arraycount(lst); i++) { + fpsetmask(msk | lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) != 0); + fpsetmask(msk & lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) == 0); + } + +} + +#endif /* defined(_FLOAT_IEEE754) */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpsetmask_basic); + ATF_TP_ADD_TC(tp, fpsetmask_masked_float); + ATF_TP_ADD_TC(tp, fpsetmask_masked_double); + ATF_TP_ADD_TC(tp, fpsetmask_masked_long_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_float); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_long_double); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c new file mode 100644 index 0000000..0f23e74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $"); + +#include <float.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <atf-c.h> + +ATF_TC(fpsetround_basic); +ATF_TC_HEAD(fpsetround_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Minimal testing of fpgetround(3) and fpsetround(3)"); +} + +#ifdef _FLOAT_IEEE754 +#include <ieeefp.h> + +static const struct { + const char *n; + int rm; + int rf; +} rnd[] = { + { "RN", FP_RN, 1 }, + { "RP", FP_RP, 2 }, + { "RM", FP_RM, 3 }, + { "RZ", FP_RZ, 0 }, + +}; + +static const struct { + const char *n; + int v[4]; +} tst[] = { /* RN RP RM RZ */ + { "1.1", { 1, 1, 2, 1 } }, + { "1.5", { 1, 2, 2, 1 } }, + { "1.9", { 1, 2, 2, 1 } }, + { "2.1", { 2, 2, 3, 2 } }, + { "2.5", { 2, 2, 3, 2 } }, + { "2.9", { 2, 3, 3, 2 } }, + { "-1.1", { -1, -1, -1, -2 } }, + { "-1.5", { -1, -2, -1, -2 } }, + { "-1.9", { -1, -2, -1, -2 } }, + { "-2.1", { -2, -2, -2, -3 } }, + { "-2.5", { -2, -2, -2, -3 } }, + { "-2.9", { -2, -3, -2, -3 } }, +}; + +static const char * +getname(int r) +{ + for (size_t i = 0; i < __arraycount(rnd); i++) + if (rnd[i].rm == r) + return rnd[i].n; + return "*unknown*"; +} + +static void +test(int r) +{ + int did = 0; + for (size_t i = 0; i < __arraycount(tst); i++) { + double d = strtod(tst[i].n, NULL); + int g = (int)rint(d); + int e = tst[i].v[r]; + ATF_CHECK_EQ(g, e); + if (g != e) { + if (!did) { + fprintf(stderr, "Mode Value Result Expected\n"); + did = 1; + } + fprintf(stderr, "%4.4s %-5.5s %6d %8d\n", rnd[r].n, + tst[i].n, (int)rint(d), tst[i].v[r]); + } + } +} +#endif + + +ATF_TC_BODY(fpsetround_basic, tc) +{ + +#ifndef _FLOAT_IEEE754 + atf_tc_skip("Test not applicable on this architecture."); +#else + int r; + + ATF_CHECK_EQ(r = fpgetround(), FP_RN); + if (FP_RN != r) + fprintf(stderr, "default expected=%s got=%s\n", getname(FP_RN), + getname(r)); + ATF_CHECK_EQ(FLT_ROUNDS, 1); + + for (size_t i = 0; i < __arraycount(rnd); i++) { + const size_t j = (i + 1) & 3; + const int o = rnd[i].rm; + const int n = rnd[j].rm; + + ATF_CHECK_EQ(r = fpsetround(n), o); + if (o != r) + fprintf(stderr, "set %s expected=%s got=%s\n", + getname(n), getname(o), getname(r)); + ATF_CHECK_EQ(r = fpgetround(), n); + if (n != r) + fprintf(stderr, "get expected=%s got=%s\n", getname(n), + getname(r)); + ATF_CHECK_EQ(r = FLT_ROUNDS, rnd[j].rf); + if (r != rnd[j].rf) + fprintf(stderr, "rounds expected=%x got=%x\n", + rnd[j].rf, r); + test(r); + } +#endif /* _FLOAT_IEEE754 */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fpsetround_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ftok.c b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c new file mode 100644 index 0000000..100bd1b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $"); + +#include <sys/types.h> +#include <sys/ipc.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <unistd.h> + +static const char *path = "ftok"; +static const char *hlnk = "hlnk"; +static const char *slnk = "slnk"; +static const int key = 123456789; + +ATF_TC(ftok_err); +ATF_TC_HEAD(ftok_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from ftok(3)"); +} + +ATF_TC_BODY(ftok_err, tc) +{ + ATF_REQUIRE(ftok("/a/b/c/d/e/f/g/h/i", key) == -1); +} + +ATF_TC_WITH_CLEANUP(ftok_link); +ATF_TC_HEAD(ftok_link, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that links return the same key"); +} + +ATF_TC_BODY(ftok_link, tc) +{ + key_t k1, k2, k3; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(link(path, hlnk) == 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + + k1 = ftok(path, key); + k2 = ftok(hlnk, key); + k3 = ftok(slnk, key); + + ATF_REQUIRE(k1 != -1); + ATF_REQUIRE(k2 != -1); + ATF_REQUIRE(k3 != -1); + + if (k1 != k2) + atf_tc_fail("ftok(3) gave different key for a hard link"); + + if (k1 != k3) + atf_tc_fail("ftok(3) gave different key for a symbolic link"); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(hlnk) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TC_CLEANUP(ftok_link, tc) +{ + (void)unlink(path); + (void)unlink(hlnk); + (void)unlink(slnk); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ftok_err); + ATF_TP_ADD_TC(tp, ftok_link); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c new file mode 100644 index 0000000..76c287a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c @@ -0,0 +1,151 @@ +/* $NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fts.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(getcwd_err); +ATF_TC_HEAD(getcwd_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in getcwd(3)"); +} + +ATF_TC_BODY(getcwd_err, tc) +{ + char buf[MAXPATHLEN]; + + errno = 0; + + ATF_REQUIRE(getcwd(buf, 0) == NULL); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TC(getcwd_fts); +ATF_TC_HEAD(getcwd_fts, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of getcwd(3)"); +} + +ATF_TC_BODY(getcwd_fts, tc) +{ + const char *str = NULL; + char buf[MAXPATHLEN]; + char *argv[2]; + FTSENT *ftse; + FTS *fts; + int ops; + short depth; + + /* + * Do not traverse too deep; cf. PR bin/45180. + */ + depth = 2; + + argv[1] = NULL; + argv[0] = __UNCONST("/"); + + /* + * Test that getcwd(3) works with basic + * system directories. Note that having + * no FTS_NOCHDIR specified should ensure + * that the current directory is visited. + */ + ops = FTS_PHYSICAL | FTS_NOSTAT; + fts = fts_open(argv, ops, NULL); + + if (fts == NULL) { + str = "failed to initialize fts(3)"; + goto out; + } + + while ((ftse = fts_read(fts)) != NULL) { + + if (ftse->fts_level < 1) + continue; + + if (ftse->fts_level > depth) { + (void)fts_set(fts, ftse, FTS_SKIP); + continue; + } + + switch(ftse->fts_info) { + + case FTS_DP: + + (void)memset(buf, 0, sizeof(buf)); + + if (getcwd(buf, sizeof(buf)) == NULL) { + str = "getcwd(3) failed"; + goto out; + } + + if (strstr(ftse->fts_path, buf) == NULL) { + str = "getcwd(3) returned incorrect path"; + goto out; + } + + break; + + default: + break; + } + } + +out: + if (fts != NULL) + (void)fts_close(fts); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getcwd_err); + ATF_TP_ADD_TC(tp, getcwd_fts); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c new file mode 100644 index 0000000..df9cdd1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c @@ -0,0 +1,181 @@ +/* $NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <grp.h> +#include <stdlib.h> +#include <unistd.h> + +ATF_TC(getgrent_loop); +ATF_TC_HEAD(getgrent_loop, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sequential getgrent(2)"); +} + +ATF_TC_BODY(getgrent_loop, tc) +{ + struct group *gr; + size_t i, j; + + /* + * Loop over the group database. The first + * call returns the first entry and subsequent + * calls return the rest of the entries. + */ + i = j = 0; + + while((gr = getgrent()) != NULL) + i++; + + /* + * Rewind the database to the beginning + * and loop over again until the end. + */ + setgrent(); + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("sequential getgrent(3) failed"); + + /* + * Close the database and reopen it. + * The getgrent(3) call should always + * automatically rewind the database. + */ + endgrent(); + + j = 0; + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("getgrent(3) did not rewind"); +} + +ATF_TC(getgrent_setgid); +ATF_TC_HEAD(getgrent_setgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test consistency of the group db"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(getgrent_setgid, tc) +{ + struct group *gr, *gr1, *gr2; + int rv, sta; + pid_t pid; + + /* + * Verify that the database is consistent. + * + * Note that because of the static buffers + * used by getgrent(3), fork(2) is required, + * even without the setgid(2) check. + */ + while((gr = getgrent()) != NULL) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + gr1 = getgrgid(gr->gr_gid); + + if (gr1 == NULL) + _exit(EXIT_FAILURE); + + gr2 = getgrnam(gr->gr_name); + + if (gr2 == NULL) + _exit(EXIT_FAILURE); + + rv = setgid(gr->gr_gid); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + goto fail; + } + + return; + +fail: + atf_tc_fail("group database is inconsistent"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgrent_loop); + ATF_TP_ADD_TC(tp, getgrent_setgid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_glob.c b/contrib/netbsd-tests/lib/libc/gen/t_glob.c new file mode 100644 index 0000000..ff62b63 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c @@ -0,0 +1,273 @@ +/* $NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $"); + +#include <atf-c.h> + +#include <sys/param.h> +#include <sys/stat.h> + +#include <dirent.h> +#include <glob.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "../../../h_macros.h" + + +#ifdef DEBUG +#define DPRINTF(a) printf a +#else +#define DPRINTF(a) +#endif + +struct gl_file { + const char *name; + int dir; +}; + +static struct gl_file a[] = { + { "1", 0 }, + { "b", 1 }, + { "3", 0 }, + { "4", 0 }, +}; + +static struct gl_file b[] = { + { "x", 0 }, + { "y", 0 }, + { "z", 0 }, + { "w", 0 }, +}; + +struct gl_dir { + const char *name; /* directory name */ + const struct gl_file *dir; + size_t len, pos; +}; + +static struct gl_dir d[] = { + { "a", a, __arraycount(a), 0 }, + { "a/b", b, __arraycount(b), 0 }, +}; + +static const char *glob_star[] = { + "a/1", "a/3", "a/4", "a/b", "a/b/w", "a/b/x", "a/b/y", "a/b/z", +}; + +static const char *glob_star_not[] = { + "a/1", "a/3", "a/4", "a/b", +}; + +static void +trim(char *buf, size_t len, const char *name) +{ + char *path = buf, *epath = buf + len; + while (path < epath && (*path++ = *name++) != '\0') + continue; + path--; + while (path > buf && *--path == '/') + *path = '\0'; +} + +static void * +gl_opendir(const char *dir) +{ + size_t i; + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), dir); + + for (i = 0; i < __arraycount(d); i++) + if (strcmp(buf, d[i].name) == 0) { + DPRINTF(("opendir %s %zu\n", buf, i)); + return &d[i]; + } + errno = ENOENT; + return NULL; +} + +static struct dirent * +gl_readdir(void *v) +{ + static struct dirent dir; + struct gl_dir *dd = v; + if (dd->pos < dd->len) { + const struct gl_file *f = &dd->dir[dd->pos++]; + strcpy(dir.d_name, f->name); + dir.d_namlen = strlen(f->name); + dir.d_ino = dd->pos; + dir.d_type = f->dir ? DT_DIR : DT_REG; + DPRINTF(("readdir %s %d\n", dir.d_name, dir.d_type)); + dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen); + return &dir; + } + return NULL; +} + +static int +gl_stat(const char *name , __gl_stat_t *st) +{ + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), name); + memset(st, 0, sizeof(*st)); + + if (strcmp(buf, "a") == 0 || strcmp(buf, "a/b") == 0) { + st->st_mode |= _S_IFDIR; + return 0; + } + + if (buf[0] == 'a' && buf[1] == '/') { + struct gl_file *f; + size_t offs, count; + + if (buf[2] == 'b' && buf[3] == '/') { + offs = 4; + count = __arraycount(b); + f = b; + } else { + offs = 2; + count = __arraycount(a); + f = a; + } + + for (size_t i = 0; i < count; i++) + if (strcmp(f[i].name, buf + offs) == 0) + return 0; + } + DPRINTF(("stat %s %d\n", buf, st->st_mode)); + errno = ENOENT; + return -1; +} + +static int +gl_lstat(const char *name , __gl_stat_t *st) +{ + return gl_stat(name, st); +} + +static void +gl_closedir(void *v) +{ + struct gl_dir *dd = v; + dd->pos = 0; + DPRINTF(("closedir %p\n", dd)); +} + +static void +run(const char *p, int flags, const char **res, size_t len) +{ + glob_t gl; + size_t i; + + memset(&gl, 0, sizeof(gl)); + gl.gl_opendir = gl_opendir; + gl.gl_readdir = gl_readdir; + gl.gl_closedir = gl_closedir; + gl.gl_stat = gl_stat; + gl.gl_lstat = gl_lstat; + + RZ(glob(p, GLOB_ALTDIRFUNC | flags, NULL, &gl)); + + for (i = 0; i < gl.gl_pathc; i++) + DPRINTF(("%s\n", gl.gl_pathv[i])); + + ATF_CHECK(len == gl.gl_pathc); + for (i = 0; i < gl.gl_pathc; i++) + ATF_CHECK_STREQ(gl.gl_pathv[i], res[i]); + + globfree(&gl); +} + + +ATF_TC(glob_star); +ATF_TC_HEAD(glob_star, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** with GLOB_STAR"); +} + +ATF_TC_BODY(glob_star, tc) +{ + run("a/**", GLOB_STAR, glob_star, __arraycount(glob_star)); +} + +ATF_TC(glob_star_not); +ATF_TC_HEAD(glob_star_not, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** without GLOB_STAR"); +} + + +ATF_TC_BODY(glob_star_not, tc) +{ + run("a/**", 0, glob_star_not, __arraycount(glob_star_not)); +} + +#if 0 +ATF_TC(glob_nocheck); +ATF_TC_HEAD(glob_nocheck, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) pattern with backslash and GLOB_NOCHECK"); +} + + +ATF_TC_BODY(glob_nocheck, tc) +{ + static const char pattern[] = { 'f', 'o', 'o', '\\', ';', 'b', 'a', + 'r', '\0' }; + static const char *glob_nocheck[] = { + pattern + }; + run(pattern, GLOB_NOCHECK, glob_nocheck, __arraycount(glob_nocheck)); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, glob_star); + ATF_TP_ADD_TC(tp, glob_star_not); +/* + * Remove this test for now - the GLOB_NOCHECK return value has been + * re-defined to return a modified pattern in revision 1.33 of glob.c + * + * ATF_TP_ADD_TC(tp, glob_nocheck); + */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c new file mode 100644 index 0000000..1af579e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c @@ -0,0 +1,312 @@ +/* $NetBSD: t_humanize_number.c,v 1.8 2012/03/18 07:14:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <err.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <util.h> + +const struct hnopts { + size_t ho_len; + int64_t ho_num; + const char *ho_suffix; + int ho_scale; + int ho_flags; + int ho_retval; /* expected return value */ + const char *ho_retstr; /* expected string in buffer */ +} hnopts[] = { + /* + * Rev. 1.6 produces "10.0". + */ + { 5, 10737418236ULL * 1024, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10T" }, + + { 5, 10450000, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + { 5, 10500000, "", /* just for reference */ + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + + /* + * Trailing space. Rev. 1.7 produces "1 ". + */ + { 5, 1, "", 0, HN_NOSPACE, 1, "1" }, + + { 5, 1, "", 0, 0, 2, "1 " }, /* just for reference */ + { 5, 1, "", 0, HN_B, 3, "1 B" }, /* and more ... */ + { 5, 1, "", 0, HN_DECIMAL, 2, "1 " }, + { 5, 1, "", 0, HN_NOSPACE | HN_B, 2, "1B" }, + { 5, 1, "", 0, HN_B | HN_DECIMAL, 3, "1 B" }, + { 5, 1, "", 0, HN_NOSPACE | HN_B | HN_DECIMAL, 2, "1B" }, + + /* + * Space and HN_B. Rev. 1.7 produces "1B". + */ + { 5, 1, "", HN_AUTOSCALE, HN_B, 3, "1 B" }, + { 5, 1000, "", /* just for reference */ + HN_AUTOSCALE, HN_B, 3, "1 K" }, + + /* + * Truncated output. Rev. 1.7 produces "1.0 K". + */ + { 6, 1000, "A", HN_AUTOSCALE, HN_DECIMAL, -1, "" }, + + /* + * Failure case reported by Greg Troxel <gdt@NetBSD.org>. + * Rev. 1.11 incorrectly returns 5 with filling the buffer + * with "1000". + */ + { 5, 1048258238, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0G" }, + /* Similar case it prints 1000 where it shouldn't */ + { 5, 1023488, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, + { 5, 1023999, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, +}; + +struct hnflags { + int hf_flags; + const char *hf_name; +}; + +const struct hnflags scale_flags[] = { + { HN_GETSCALE, "HN_GETSCALE" }, + { HN_AUTOSCALE, "HN_AUTOSCALE" }, +}; +const struct hnflags normal_flags[] = { + { HN_DECIMAL, "HN_DECIMAL" }, + { HN_NOSPACE, "HN_NOSPACE" }, + { HN_B, "HN_B" }, + { HN_DIVISOR_1000, "HN_DIVISOR_1000" }, +}; + +const char *formatflags(char *, size_t, const struct hnflags *, size_t, int); +void newline(void); +void w_printf(const char *, ...) __printflike(1, 2); +int main(int, char *[]); + +const char * +formatflags(char *buf, size_t buflen, const struct hnflags *hfs, + size_t hfslen, int flags) +{ + const struct hnflags *hf; + char *p = buf; + ssize_t len = buflen; + unsigned int i, found; + int n; + + if (flags == 0) { + snprintf(buf, buflen, "0"); + return (buf); + } + for (i = found = 0; i < hfslen && flags & ~found; i++) { + hf = &hfs[i]; + if (flags & hf->hf_flags) { + found |= hf->hf_flags; + n = snprintf(p, len, "|%s", hf->hf_name); + if (n >= len) { + p = buf; + len = buflen; + /* Print `flags' as number */ + goto bad; + } + p += n; + len -= n; + } + } + flags &= ~found; + if (flags) +bad: + snprintf(p, len, "|0x%x", flags); + return (*buf == '|' ? buf + 1 : buf); +} + +static int col, bol = 1; +void +newline(void) +{ + + fprintf(stderr, "\n"); + col = 0; + bol = 1; +} + +void +w_printf(const char *fmt, ...) +{ + char buf[80]; + va_list ap; + int n; + + va_start(ap, fmt); + if (col >= 0) { + n = vsnprintf(buf, sizeof(buf), fmt, ap); + if (n >= (int)sizeof(buf)) { + col = -1; + goto overflow; + } else if (n == 0) + goto out; + + if (!bol) { + if (col + n > 75) + fprintf(stderr, "\n "), col = 4; + else + fprintf(stderr, " "), col++; + } + fprintf(stderr, "%s", buf); + col += n; + bol = 0; + } else { +overflow: + vfprintf(stderr, fmt, ap); + } +out: + va_end(ap); +} + +ATF_TC(humanize_number_basic); +ATF_TC_HEAD(humanize_number_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize_number(3)"); +} + +ATF_TC_BODY(humanize_number_basic, tc) +{ + char fbuf[128]; + const struct hnopts *ho; + char *buf = NULL; + size_t buflen = 0; + unsigned int i; + int rv = 0; + + for (i = 0; i < __arraycount(hnopts); i++) { + ho = &hnopts[i]; + if (buflen < ho->ho_len) { + buflen = ho->ho_len; + buf = realloc(buf, buflen); + if (buf == NULL) + atf_tc_fail("realloc(..., %zu) failed", buflen); + } + + rv = humanize_number(buf, ho->ho_len, ho->ho_num, + ho->ho_suffix, ho->ho_scale, ho->ho_flags); + + if (rv == ho->ho_retval && + (rv == -1 || strcmp(buf, ho->ho_retstr) == 0)) + continue; + + w_printf("humanize_number(\"%s\", %zu, %" PRId64 ",", + ho->ho_retstr, ho->ho_len, ho->ho_num); + w_printf("\"%s\",", ho->ho_suffix); + w_printf("%s,", formatflags(fbuf, sizeof(fbuf), scale_flags, + sizeof(scale_flags) / sizeof(scale_flags[0]), + ho->ho_scale)); + w_printf("%s)", formatflags(fbuf, sizeof(fbuf), normal_flags, + sizeof(normal_flags) / sizeof(normal_flags[0]), + ho->ho_flags)); + w_printf("= %d,", ho->ho_retval); + w_printf("but got"); + w_printf("%d/[%s]", rv, rv == -1 ? "" : buf); + newline(); + atf_tc_fail_nonfatal("Failed for table entry %d", i); + } +} + +ATF_TC(humanize_number_big); +ATF_TC_HEAD(humanize_number_big, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize " + "big numbers (PR lib/44097)"); +} + +ATF_TC_BODY(humanize_number_big, tc) +{ + char buf[1024]; + int rv; + + /* + * Seems to work. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, 10000, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_CHECK_STREQ(buf, "10000"); + + /* + * A bogus value with large number. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, INT64_MAX, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0") != 0); + + /* + * Large buffer with HN_AUTOSCALE. Entirely bogus. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, sizeof(buf), 10000, "", + HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0%d%s%d%s%s%s") != 0); + + /* + * Tight buffer. + * + * The man page says that len must be at least 4. + * 3 works, but anything less that will not. This + * is because baselen starts with 2 for positive + * numbers. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 3, 1, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, humanize_number_basic); + ATF_TP_ADD_TC(tp, humanize_number_big); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_isnan.c b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c new file mode 100644 index 0000000..2a97b9a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c @@ -0,0 +1,67 @@ +/* $NetBSD: t_isnan.c,v 1.4 2014/02/09 21:26:07 jmmv Exp $ */ + +/* + * This file is in the Public Domain. + * + * The nan test is blatently copied by Simon Burge from the infinity + * test by Ben Harris. + */ + +#include <sys/param.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <math.h> +#include <string.h> + +ATF_TC(isnan_basic); +ATF_TC_HEAD(isnan_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isnan(3) works"); +} + +ATF_TC_BODY(isnan_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + +#ifdef NAN + /* NAN is meant to be a (float)NaN. */ + ATF_CHECK(isnan(NAN) != 0); + ATF_CHECK(isnan((double)NAN) != 0); +#else + atf_tc_skip("Test not applicable"); +#endif +} + +ATF_TC(isinf_basic); +ATF_TC_HEAD(isinf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isinf(3) works"); +} + +ATF_TC_BODY(isinf_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + + /* HUGE_VAL is meant to be an infinity. */ + ATF_CHECK(isinf(HUGE_VAL) != 0); + + /* HUGE_VALF is the float analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALF) != 0); + + /* HUGE_VALL is the long double analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALL) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, isnan_basic); + ATF_TP_ADD_TC(tp, isinf_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_nice.c b/contrib/netbsd-tests/lib/libc/gen/t_nice.c new file mode 100644 index 0000000..f4a62e9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c @@ -0,0 +1,193 @@ +/* $NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); + +#include <sys/resource.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <stdlib.h> +#include <unistd.h> + +static void *threadfunc(void *); + +static void * +threadfunc(void *arg) +{ + int pri, val; + + val = *(int *)arg; + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (pri != val) + atf_tc_fail("nice(3) value was not propagated to threads"); + + return NULL; +} + +ATF_TC(nice_err); +ATF_TC_HEAD(nice_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test nice(3) for invalid parameters (PR lib/42587)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(nice_err, tc) +{ + int i; + + /* + * The call should fail with EPERM if the + * supplied parameter is negative and the + * caller does not have privileges. + */ + for (i = -20; i < 0; i++) { + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1); + } +} + +ATF_TC(nice_priority); +ATF_TC_HEAD(nice_priority, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)"); +} + +ATF_TC_BODY(nice_priority, tc) +{ + int i, pri, nic; + pid_t pid; + int sta; + + for (i = 0; i <= 20; i++) { + + nic = nice(i); + ATF_REQUIRE(nic != -1); + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (nic != pri) + atf_tc_fail("nice(3) and getpriority(2) conflict"); + + /* + * Also verify that the nice(3) values + * are inherited by child processes. + */ + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (nic != pri) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("nice(3) value was not inherited"); + } +} + +ATF_TC(nice_root); +ATF_TC_HEAD(nice_root, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that nice(3) works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(nice_root, tc) +{ + int i; + + for (i = -20; i <= 20; i++) { + + ATF_REQUIRE(nice(i) != -1); + } +} + +ATF_TC(nice_thread); +ATF_TC_HEAD(nice_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads"); +} + +ATF_TC_BODY(nice_thread, tc) +{ + pthread_t tid[5]; + int rv, val; + size_t i; + + /* + * Test that the scheduling priority is + * propagated to all system scope threads. + */ + for (i = 0; i < __arraycount(tid); i++) { + + val = nice(i); + ATF_REQUIRE(val != -1); + + rv = pthread_create(&tid[i], NULL, threadfunc, &val); + ATF_REQUIRE(rv == 0); + + rv = pthread_join(tid[i], NULL); + ATF_REQUIRE(rv == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nice_err); + ATF_TP_ADD_TC(tp, nice_priority); + ATF_TP_ADD_TC(tp, nice_root); + ATF_TP_ADD_TC(tp, nice_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_pause.c b/contrib/netbsd-tests/lib/libc/gen/t_pause.c new file mode 100644 index 0000000..62a74c9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_pause.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +static bool fail; +static void handler(int); + +static void +handler(int signo) +{ + + if (signo == SIGALRM) + fail = false; +} + +ATF_TC(pause_basic); +ATF_TC_HEAD(pause_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #1"); +} + +ATF_TC_BODY(pause_basic, tc) +{ + + fail = true; + + ATF_REQUIRE(signal(SIGALRM, handler) == 0); + + (void)alarm(1); + + if (pause() != -1 || fail != false) + atf_tc_fail("pause(3) did not cancel out from a signal"); +} + +ATF_TC(pause_kill); +ATF_TC_HEAD(pause_kill, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #2"); +} + +ATF_TC_BODY(pause_kill, tc) +{ + pid_t pid; + int sta; + + fail = true; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)pause(); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + + if (fail != true) + atf_tc_fail("child terminated before signal"); + + (void)kill(pid, SIGKILL); + (void)sleep(1); + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("pause(3) did not cancel from SIGKILL"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pause_basic); + ATF_TP_ADD_TC(tp, pause_kill); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_raise.c b/contrib/netbsd-tests/lib/libc/gen/t_raise.c new file mode 100644 index 0000000..adc032f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c @@ -0,0 +1,190 @@ +/* $NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $"); + +#include <atf-c.h> + +#include <signal.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +static bool fail; +static int count; +static void handler_err(int); +static void handler_ret(int); +static void handler_stress(int); +static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR }; + +static void +handler_stress(int signo) +{ + count++; +} + +static void +handler_err(int signo) +{ + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + if (sig[i] == signo) { + fail = false; + break; + } + } +} + +static void +handler_ret(int signo) +{ + + (void)sleep(1); + + fail = false; +} + +ATF_TC(raise_err); +ATF_TC_HEAD(raise_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test raise(3) for invalid parameters"); +} + +ATF_TC_BODY(raise_err, tc) +{ + int i = 0; + + while (i < 10) { + + ATF_REQUIRE(raise(10240 + i) == -1); + + i++; + } +} + +ATF_TC(raise_ret); +ATF_TC_HEAD(raise_ret, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test return order of raise(3)"); +} + +ATF_TC_BODY(raise_ret, tc) +{ + struct sigaction sa; + + fail = true; + + sa.sa_flags = 0; + sa.sa_handler = handler_ret; + + /* + * Verify that raise(3) does not return + * before the signal handler returns. + */ + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + ATF_REQUIRE(raise(SIGUSR1) == 0); + + if (fail != false) + atf_tc_fail("raise(3) returned before signal handler"); +} + +ATF_TC(raise_sig); +ATF_TC_HEAD(raise_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of raise(3)"); +} + +ATF_TC_BODY(raise_sig, tc) +{ + struct timespec tv, tr; + struct sigaction sa; + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + (void)memset(&sa, 0, sizeof(struct sigaction)); + + fail = true; + + tv.tv_sec = 0; + tv.tv_nsec = 2; + + sa.sa_flags = 0; + sa.sa_handler = handler_err; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(sig[i], &sa, 0) == 0); + + ATF_REQUIRE(raise(sig[i]) == 0); + ATF_REQUIRE(nanosleep(&tv, &tr) == 0); + + if (fail != false) + atf_tc_fail("raise(3) did not raise a signal"); + } +} + +ATF_TC(raise_stress); +ATF_TC_HEAD(raise_stress, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic stress test with raise(3)"); +} + +ATF_TC_BODY(raise_stress, tc) +{ + static const int maxiter = 1000 * 10; + struct sigaction sa; + int i; + + sa.sa_flags = 0; + sa.sa_handler = handler_stress; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + + for (count = i = 0; i < maxiter; i++) + (void)raise(SIGUSR1); + + if (count != maxiter) + atf_tc_fail("not all signals were catched"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, raise_err); + ATF_TP_ADD_TC(tp, raise_ret); + ATF_TP_ADD_TC(tp, raise_sig); + ATF_TP_ADD_TC(tp, raise_stress); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_randomid.c b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c new file mode 100644 index 0000000..8377806 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_randomid.c,v 1.3 2011/07/07 09:49:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <sys/types.h> + +#include <assert.h> +#include <inttypes.h> +#include <randomid.h> +#include <stdio.h> +#include <string.h> + +#define PERIOD 30000 + +uint64_t last[65536]; + +ATF_TC(randomid_basic); +ATF_TC_HEAD(randomid_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check randomid(3)"); +} + +ATF_TC_BODY(randomid_basic, tc) +{ + static randomid_t ctx = NULL; + uint64_t lowest, n, diff; + uint16_t id; + + memset(last, 0, sizeof(last)); + ctx = randomid_new(16, (long)3600); + + lowest = UINT64_MAX; + + for (n = 0; n < 1000000; n++) { + id = randomid(ctx); + + if (last[id] > 0) { + diff = n - last[id]; + + if (diff <= lowest) { + if (lowest != UINT64_MAX) + printf("id %5d: last call at %9"PRIu64 + ", current call %9"PRIu64 + " (diff %5"PRIu64"), " + "lowest %"PRIu64"\n", + id, last[id], n, diff, lowest); + + ATF_REQUIRE_MSG(diff >= PERIOD, + "diff (%"PRIu64") less than minimum " + "period (%d)", diff, PERIOD); + + lowest = diff; + } + } + + last[id] = n; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, randomid_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_realpath.c b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c new file mode 100644 index 0000000..d4998c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const struct { + const char *path; + const char *result; +} paths[] = { + + { "/", "/" }, + { "///////", "/" }, + { "", NULL }, + { " ", NULL }, + { "/ ", NULL }, + { " /", NULL }, + { "/etc///", "/etc" }, + { "///////etc", "/etc" }, + { "/a/b/c/d/e", NULL }, + { " /usr/bin ", NULL }, + { "\\//////usr//bin", NULL }, + { "//usr//bin//", "/usr/bin" }, + { "//////usr//bin//", "/usr/bin" }, + { "/usr/bin//////////", "/usr/bin" }, +}; + +ATF_TC(realpath_basic); +ATF_TC_HEAD(realpath_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)"); +} + +ATF_TC_BODY(realpath_basic, tc) +{ + char buf[MAXPATHLEN]; + char *ptr; + size_t i; + + for (i = 0; i < __arraycount(paths); i++) { + + (void)memset(buf, '\0', sizeof(buf)); + + ptr = realpath(paths[i].path, buf); + + if (ptr == NULL && paths[i].result == NULL) + continue; + + if (ptr == NULL && paths[i].result != NULL) + atf_tc_fail("realpath failed for '%s'", paths[i].path); + + if (strcmp(paths[i].result, buf) != 0) + atf_tc_fail("expected '%s', got '%s'", + paths[i].result, buf); + } +} + +ATF_TC(realpath_huge); +ATF_TC_HEAD(realpath_huge, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)"); +} + +ATF_TC_BODY(realpath_huge, tc) +{ + char result[MAXPATHLEN] = { 0 }; + char buffer[MAXPATHLEN] = { 0 }; + + (void)memset(buffer, '/', sizeof(buffer) - 1); + + ATF_CHECK(realpath(buffer, result) != NULL); + ATF_CHECK(strlen(result) == 1); + ATF_CHECK(result[0] == '/'); +} + +ATF_TC(realpath_symlink); +ATF_TC_HEAD(realpath_symlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)"); +} + +ATF_TC_BODY(realpath_symlink, tc) +{ + char path[MAXPATHLEN] = { 0 }; + char slnk[MAXPATHLEN] = { 0 }; + char resb[MAXPATHLEN] = { 0 }; + int fd; + + (void)getcwd(path, sizeof(path)); + (void)getcwd(slnk, sizeof(slnk)); + + (void)strlcat(path, "/realpath", sizeof(path)); + (void)strlcat(slnk, "/symbolic", sizeof(slnk)); + + fd = open(path, O_RDONLY | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(realpath(slnk, resb) != NULL); + ATF_REQUIRE(strcmp(resb, path) == 0); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, realpath_basic); + ATF_TP_ADD_TC(tp, realpath_huge); + ATF_TP_ADD_TC(tp, realpath_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c new file mode 100644 index 0000000..89818f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c @@ -0,0 +1,132 @@ +/* $NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +static char domain[MAXHOSTNAMELEN]; + +static const char domains[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(setdomainname_basic); +ATF_TC_HEAD(setdomainname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setdomainname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + for (i = 0; i < __arraycount(domains); i++) { + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0); + ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0); + ATF_REQUIRE(strcmp(domains[i], name) == 0); + } + + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_CLEANUP(setdomainname_basic, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_limit); +ATF_TC_HEAD(setdomainname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long domain name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(setdomainname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_limit, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_perm); +ATF_TC_HEAD(setdomainname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setdomainname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_perm, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(domain, 0, sizeof(domain)); + + ATF_REQUIRE(getdomainname(domain, sizeof(domain)) == 0); + + ATF_TP_ADD_TC(tp, setdomainname_basic); + ATF_TP_ADD_TC(tp, setdomainname_limit); + ATF_TP_ADD_TC(tp, setdomainname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c new file mode 100644 index 0000000..a753ac7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c @@ -0,0 +1,132 @@ +/* $NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +static char host[MAXHOSTNAMELEN]; + +static const char hosts[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(sethostname_basic); +ATF_TC_HEAD(sethostname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of sethostname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + for (i = 0; i < __arraycount(hosts); i++) { + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i])) == 0); + ATF_REQUIRE(gethostname(name, sizeof(name)) == 0); + ATF_REQUIRE(strcmp(hosts[i], name) == 0); + } + + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_CLEANUP(sethostname_basic, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_limit); +ATF_TC_HEAD(sethostname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long host name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(sethostname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(sethostname_limit, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_perm); +ATF_TC_HEAD(sethostname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the host name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(sethostname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, sethostname(host, sizeof(host)) == -1); +} + +ATF_TC_CLEANUP(sethostname_perm, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(host, 0, sizeof(host)); + + ATF_REQUIRE(gethostname(host, sizeof(host)) == 0); + + ATF_TP_ADD_TC(tp, sethostname_basic); + ATF_TP_ADD_TC(tp, sethostname_limit); + ATF_TP_ADD_TC(tp, sethostname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c new file mode 100644 index 0000000..2fb53e4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c @@ -0,0 +1,500 @@ +/* $NetBSD: t_siginfo.c,v 1.23 2014/02/09 21:26:07 jmmv Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <sys/inttypes.h> +#include <sys/resource.h> +#include <sys/sysctl.h> +#include <sys/time.h> +#include <sys/ucontext.h> +#include <sys/wait.h> + +#include <assert.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <setjmp.h> +#include <float.h> + +#ifdef HAVE_FENV +#include <fenv.h> +#elif defined(_FLOAT_IEEE754) +#include <ieeefp.h> +#endif + +#include "isqemu.h" + +/* for sigbus */ +volatile char *addr; + +/* for sigchild */ +pid_t child; +int code; +int status; + +/* for sigfpe */ +sig_atomic_t fltdiv_signalled = 0; +sig_atomic_t intdiv_signalled = 0; + +static void +sig_debug(int signo, siginfo_t *info, ucontext_t *ctx) +{ + unsigned int i; + + printf("%d %p %p\n", signo, info, ctx); + if (info != NULL) { + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_value.sival_int=%d\n", info->si_value.sival_int); + } + if (ctx != NULL) { + printf("uc_flags 0x%x\n", ctx->uc_flags); + printf("uc_link %p\n", ctx->uc_link); + for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++) + printf("uc_sigmask[%d] 0x%x\n", i, + ctx->uc_sigmask.__bits[i]); + printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp, + (unsigned long)ctx->uc_stack.ss_size, + ctx->uc_stack.ss_flags); + for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++) + printf("uc_mcontext.greg[%d] 0x%lx\n", i, + (long)ctx->uc_mcontext.__gregs[i]); + } +} + +static void +sigalrm_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGALRM); + ATF_REQUIRE_EQ(info->si_code, SI_TIMER); + ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigalarm); + +ATF_TC_HEAD(sigalarm, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGALRM handler"); +} + +ATF_TC_BODY(sigalarm, tc) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigalrm_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + for (;;) { + alarm(1); + sleep(1); + } + atf_tc_fail("SIGALRM handler wasn't called"); +} + +static void +sigchild_action(int signo, siginfo_t *info, void *ptr) +{ + if (info != NULL) { + printf("info=%p\n", info); + printf("ptr=%p\n", ptr); + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_uid=%d\n", info->si_uid); + printf("si_pid=%d\n", info->si_pid); + printf("si_status=%d\n", info->si_status); + printf("si_utime=%lu\n", (unsigned long int)info->si_utime); + printf("si_stime=%lu\n", (unsigned long int)info->si_stime); + } + ATF_REQUIRE_EQ(info->si_code, code); + ATF_REQUIRE_EQ(info->si_signo, SIGCHLD); + ATF_REQUIRE_EQ(info->si_uid, getuid()); + ATF_REQUIRE_EQ(info->si_pid, child); + if (WIFEXITED(info->si_status)) + ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status); + else if (WIFSTOPPED(info->si_status)) + ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status); + else if (WIFSIGNALED(info->si_status)) + ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status); +} + +static void +setchildhandler(void (*action)(int, siginfo_t *, void *)) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = action; + sigemptyset(&sa.sa_mask); + sigaction(SIGCHLD, &sa, NULL); +} + +static void +sigchild_setup(void) +{ + sigset_t set; + struct rlimit rlim; + + (void)getrlimit(RLIMIT_CORE, &rlim); + rlim.rlim_cur = rlim.rlim_max; + (void)setrlimit(RLIMIT_CORE, &rlim); + + setchildhandler(sigchild_action); + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, NULL); +} + +ATF_TC(sigchild_normal); +ATF_TC_HEAD(sigchild_normal, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child exits normally"); +} + +ATF_TC_BODY(sigchild_normal, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = 25; + code = CLD_EXITED; + + switch ((child = fork())) { + case 0: + sleep(1); + exit(status); + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_dump); +ATF_TC_HEAD(sigchild_dump, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child segfaults"); +} + +ATF_TC_BODY(sigchild_dump, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGSEGV; + code = CLD_DUMPED; + + switch ((child = fork())) { + case 0: + sleep(1); + *(volatile long *)0 = 0; + atf_tc_fail("Child did not segfault"); + /* NOTREACHED */ + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_kill); +ATF_TC_HEAD(sigchild_kill, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child is killed"); +} + +ATF_TC_BODY(sigchild_kill, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGPIPE; + code = CLD_KILLED; + + switch ((child = fork())) { + case 0: + sigemptyset(&set); + sigsuspend(&set); + break; + case -1: + atf_tc_fail("fork failed"); + default: + kill(child, SIGPIPE); + sigemptyset(&set); + sigsuspend(&set); + } +} + +static sigjmp_buf sigfpe_flt_env; +static void +sigfpe_flt_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (fltdiv_signalled++ != 0) + atf_tc_fail("FPE handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_flt_env, 1); +} + +ATF_TC(sigfpe_flt); +ATF_TC_HEAD(sigfpe_flt, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for floating div-by-zero"); +} + +ATF_TC_BODY(sigfpe_flt, tc) +{ + struct sigaction sa; + double d = strtod("0", NULL); + + if (isQEMU()) + atf_tc_skip("Test does not run correctly under QEMU"); +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#endif + if (sigsetjmp(sigfpe_flt_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_flt_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%g\n", 1 / d); + } + if (fltdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static sigjmp_buf sigfpe_int_env; +static void +sigfpe_int_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (intdiv_signalled++ != 0) + atf_tc_fail("INTDIV handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV); + atf_tc_expect_pass(); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_int_env, 1); +} + +ATF_TC(sigfpe_int); +ATF_TC_HEAD(sigfpe_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for integer div-by-zero (PR port-i386/43655)"); +} + +ATF_TC_BODY(sigfpe_int, tc) +{ + struct sigaction sa; + long l = strtol("0", NULL, 10); + +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#endif + if (sigsetjmp(sigfpe_int_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_int_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%ld\n", 1 / l); + } + if (intdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static void +sigsegv_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGSEGV); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR); + ATF_REQUIRE_EQ(info->si_addr, (void *)0); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigsegv); +ATF_TC_HEAD(sigsegv, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGSEGV handler"); +} + +ATF_TC_BODY(sigsegv, tc) +{ + struct sigaction sa; + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigsegv_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + + *(volatile long *)0 = 0; + atf_tc_fail("Test did not fault as expected"); +} + +static void +sigbus_action(int signo, siginfo_t *info, void *ptr) +{ + + printf("si_addr = %p\n", info->si_addr); + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGBUS); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN); + +#if defined(__i386__) || defined(__x86_64__) + atf_tc_expect_fail("x86 architecture does not correctly " + "report the address where the unaligned access occured"); +#endif + ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigbus_adraln); +ATF_TC_HEAD(sigbus_adraln, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGBUS handler " + "for invalid address alignment"); +} + +ATF_TC_BODY(sigbus_adraln, tc) +{ + struct sigaction sa; + +#if defined(__alpha__) + int rv, val; + size_t len = sizeof(val); + rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0); + ATF_REQUIRE(rv == 0); + if (val == 0) + atf_tc_skip("SIGBUS signal not enabled for unaligned accesses"); +#endif + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigbus_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGBUS, &sa, NULL); + + /* Enable alignment checks for x86. 0x40000 is PSL_AC. */ +#if defined(__i386__) + __asm__("pushf; orl $0x40000, (%esp); popf"); +#elif defined(__amd64__) + __asm__("pushf; orl $0x40000, (%rsp); popf"); +#endif + + addr = calloc(2, sizeof(int)); + ATF_REQUIRE(addr != NULL); + + if (isQEMU()) + atf_tc_expect_fail("QEMU fails to trap unaligned accesses"); + + /* Force an unaligned access */ + addr++; + printf("now trying to access unaligned address %p\n", addr); + ATF_REQUIRE_EQ(*(volatile int *)addr, 0); + + atf_tc_fail("Test did not fault as expected"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigalarm); + ATF_TP_ADD_TC(tp, sigchild_normal); + ATF_TP_ADD_TC(tp, sigchild_dump); + ATF_TP_ADD_TC(tp, sigchild_kill); + ATF_TP_ADD_TC(tp, sigfpe_flt); + ATF_TP_ADD_TC(tp, sigfpe_int); + ATF_TP_ADD_TC(tp, sigsegv); + ATF_TP_ADD_TC(tp, sigbus_adraln); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sleep.c b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c new file mode 100644 index 0000000..e4dc94e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c @@ -0,0 +1,337 @@ +/* $NetBSD: t_sleep.c,v 1.8 2014/07/15 14:56:34 gson Exp $ */ + +/*- + * Copyright (c) 2006 Frank Kardel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <errno.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <sys/cdefs.h> +#include <sys/event.h> +#include <sys/signal.h> + +#include "isqemu.h" + +#define BILLION 1000000000LL /* nano-seconds per second */ +#define MILLION 1000000LL /* nano-seconds per milli-second */ + +#define ALARM 6 /* SIGALRM after this many seconds */ +#define MAXSLEEP 22 /* Maximum delay in seconds */ +#define KEVNT_TIMEOUT 10300 /* measured in milli-seconds */ +#define FUZZ (40 * MILLION) /* scheduling fuzz accepted - 40 ms */ + +/* + * Timer notes + * + * Most tests use FUZZ as their initial delay value, but 'sleep' + * starts at 1sec (since it cannot handle sub-second intervals). + * Subsequent passes double the previous interval, up to MAXSLEEP. + * + * The current values result in 5 passes for the 'sleep' test (at 1, + * 2, 4, 8, and 16 seconds) and 10 passes for the other tests (at + * 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, and 20.48 + * seconds). + * + * The ALARM is only set if the current pass's delay is longer, and + * only if the ALARM has not already been triggered. + * + * The 'kevent' test needs the ALARM to be set on a different pass + * from when the KEVNT_TIMEOUT fires. So set ALARM to fire on the + * penultimate pass, and the KEVNT_TIMEOUT on the final pass. We + * set KEVNT_TIMEOUT just barely long enough to put it into the + * last test pass, and set MAXSLEEP a couple seconds longer than + * necessary, in order to avoid a QEMU bug which nearly doubles + * some timers. + */ + +static volatile int sig; + +int sleeptest(int (*)(struct timespec *, struct timespec *), bool, bool); +int do_nanosleep(struct timespec *, struct timespec *); +int do_select(struct timespec *, struct timespec *); +int do_poll(struct timespec *, struct timespec *); +int do_sleep(struct timespec *, struct timespec *); +int do_kevent(struct timespec *, struct timespec *); +void sigalrm(int); + +void +sigalrm(int s) +{ + + sig++; +} + +int +do_nanosleep(struct timespec *delay, struct timespec *remain) +{ + int ret; + + if (nanosleep(delay, remain) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_select(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (select(0, NULL, NULL, NULL, &tv) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_poll(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (pollts(NULL, 0, delay, NULL) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_sleep(struct timespec *delay, struct timespec *remain) +{ + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + remain->tv_sec = sleep(delay->tv_sec); + remain->tv_nsec = 0; + + return 0; +} + +int +do_kevent(struct timespec *delay, struct timespec *remain) +{ + struct kevent ktimer; + struct kevent kresult; + int rtc, kq, kerrno; + int tmo; + + ATF_REQUIRE_MSG((kq = kqueue()) != -1, "kqueue: %s", strerror(errno)); + + tmo = KEVNT_TIMEOUT; + + /* + * If we expect the KEVNT_TIMEOUT to fire, and we're running + * under QEMU, make sure the delay is long enough to account + * for the effects of PR kern/43997 ! + */ + if (isQEMU() && + tmo/1000 < delay->tv_sec && tmo/500 > delay->tv_sec) + delay->tv_sec = MAXSLEEP; + + EV_SET(&ktimer, 1, EVFILT_TIMER, EV_ADD, 0, tmo, 0); + + rtc = kevent(kq, &ktimer, 1, &kresult, 1, delay); + kerrno = errno; + + (void)close(kq); + + if (rtc == -1) { + ATF_REQUIRE_MSG(kerrno == EINTR, "kevent: %s", strerror(errno)); + return 0; + } + + if (delay->tv_sec * BILLION + delay->tv_nsec > tmo * MILLION) + ATF_REQUIRE_MSG(rtc > 0, + "kevent: KEVNT_TIMEOUT did not cause EVFILT_TIMER event"); + + return 0; +} + +ATF_TC(nanosleep); +ATF_TC_HEAD(nanosleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test nanosleep(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(nanosleep, tc) +{ + + sleeptest(do_nanosleep, true, false); +} + +ATF_TC(select); +ATF_TC_HEAD(select, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test select(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(select, tc) +{ + + sleeptest(do_select, true, true); +} + +ATF_TC(poll); +ATF_TC_HEAD(poll, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test poll(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(poll, tc) +{ + + sleeptest(do_poll, true, true); +} + +ATF_TC(sleep); +ATF_TC_HEAD(sleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sleep(3) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(sleep, tc) +{ + + sleeptest(do_sleep, false, false); +} + +ATF_TC(kevent); +ATF_TC_HEAD(kevent, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test kevent(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(kevent, tc) +{ + + sleeptest(do_kevent, true, true); +} + +int +sleeptest(int (*test)(struct timespec *, struct timespec *), + bool subsec, bool sim_remain) +{ + struct timespec tsa, tsb, tslp, tremain; + int64_t delta1, delta2, delta3, round; + + sig = 0; + signal(SIGALRM, sigalrm); + + if (subsec) { + round = 1; + delta3 = FUZZ; + } else { + round = 1000000000; + delta3 = round; + } + + tslp.tv_sec = delta3 / 1000000000; + tslp.tv_nsec = delta3 % 1000000000; + + while (tslp.tv_sec <= MAXSLEEP) { + /* + * disturb sleep by signal on purpose + */ + if (tslp.tv_sec > ALARM && sig == 0) + alarm(ALARM); + + clock_gettime(CLOCK_REALTIME, &tsa); + (*test)(&tslp, &tremain); + clock_gettime(CLOCK_REALTIME, &tsb); + + if (sim_remain) { + timespecsub(&tsb, &tsa, &tremain); + timespecsub(&tslp, &tremain, &tremain); + } + + delta1 = (int64_t)tsb.tv_sec - (int64_t)tsa.tv_sec; + delta1 *= BILLION; + delta1 += (int64_t)tsb.tv_nsec - (int64_t)tsa.tv_nsec; + + delta2 = (int64_t)tremain.tv_sec * BILLION; + delta2 += (int64_t)tremain.tv_nsec; + + delta3 = (int64_t)tslp.tv_sec * BILLION; + delta3 += (int64_t)tslp.tv_nsec - delta1 - delta2; + + delta3 /= round; + delta3 *= round; + + if (delta3 > FUZZ || delta3 < -FUZZ) { + if (!sim_remain) + atf_tc_expect_fail("Long reschedule latency " + "due to PR kern/43997"); + + atf_tc_fail("Reschedule latency %"PRId64" exceeds " + "allowable fuzz %lld", delta3, FUZZ); + } + delta3 = (int64_t)tslp.tv_sec * 2 * BILLION; + delta3 += (int64_t)tslp.tv_nsec * 2; + + delta3 /= round; + delta3 *= round; + if (delta3 < FUZZ) + break; + tslp.tv_sec = delta3 / BILLION; + tslp.tv_nsec = delta3 % BILLION; + } + ATF_REQUIRE_MSG(sig == 1, "Alarm did not fire!"); + + atf_tc_pass(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, nanosleep); + ATF_TP_ADD_TC(tp, select); + ATF_TP_ADD_TC(tp, poll); + ATF_TP_ADD_TC(tp, sleep); + ATF_TP_ADD_TC(tp, kevent); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_syslog.c b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c new file mode 100644 index 0000000..c9417c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c @@ -0,0 +1,56 @@ +/* $NetBSD: t_syslog.c,v 1.2 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> + +#include <atf-c.h> +#include <syslog.h> + +ATF_TC(syslog_pthread); +ATF_TC_HEAD(syslog_pthread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test that syslog(3) " + "works when linked to pthread(3) (PR lib/44248)"); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(syslog_pthread, tc) +{ + syslog(LOG_DEBUG, "from tests/lib/libc/gen/t_syslog"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, syslog_pthread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_time.c b/contrib/netbsd-tests/lib/libc/gen/t_time.c new file mode 100644 index 0000000..bfbdc73 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +ATF_TC(time_copy); +ATF_TC_HEAD(time_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test the return values of time(3)"); +} + +ATF_TC_BODY(time_copy, tc) +{ + time_t t1, t2 = 0; + + t1 = time(&t2); + + if (t1 != t2) + atf_tc_fail("incorrect return values from time(3)"); +} + +ATF_TC(time_mono); +ATF_TC_HEAD(time_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test monotonicity of time(3)"); +} + +ATF_TC_BODY(time_mono, tc) +{ + const size_t maxiter = 10; + time_t t1, t2; + size_t i; + + for (i = 0; i < maxiter; i++) { + + t1 = time(NULL); + (void)sleep(1); + t2 = time(NULL); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t1, (int64_t)t2); + + if (t1 >= t2) + atf_tc_fail("time(3) is not monotonic"); + } +} + +ATF_TC(time_timeofday); +ATF_TC_HEAD(time_timeofday, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test time(3) vs. gettimeofday(2)"); +} + +ATF_TC_BODY(time_timeofday, tc) +{ + struct timeval tv = { 0, 0 }; + time_t t; + + t = time(NULL); + ATF_REQUIRE(gettimeofday(&tv, NULL) == 0); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t, (int64_t)tv.tv_sec); + + if (t != tv.tv_sec) + atf_tc_fail("time(3) and gettimeofday(2) differ"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, time_copy); + ATF_TP_ADD_TC(tp, time_mono); + ATF_TP_ADD_TC(tp, time_timeofday); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c new file mode 100644 index 0000000..0c10c24 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c @@ -0,0 +1,188 @@ +/* $NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static long ttymax = 0; + +ATF_TC(ttyname_err); +ATF_TC_HEAD(ttyname_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname(3)"); +} + +ATF_TC_BODY(ttyname_err, tc) +{ + int fd; + + fd = open("XXX", O_RDONLY); + + if (fd < 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == EBADF); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == EBADF); + } + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == ENOTTY); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == ENOTTY); + } +} + +ATF_TC(ttyname_r_err); +ATF_TC_HEAD(ttyname_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname_r(3)"); +} + +ATF_TC_BODY(ttyname_r_err, tc) +{ + char sbuf[0]; + char *buf; + int fd; + int rv; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + if (isatty(STDIN_FILENO) != 0) { + + rv = ttyname_r(STDIN_FILENO, sbuf, sizeof(sbuf)); + ATF_REQUIRE(rv == ERANGE); + } + + rv = ttyname_r(-1, buf, ttymax); + ATF_REQUIRE(rv == EBADF); + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + rv = ttyname_r(fd, buf, ttymax); + ATF_REQUIRE(rv == ENOTTY); + ATF_REQUIRE(close(fd) == 0); + } + + free(buf); +} + +ATF_TC(ttyname_r_stdin); +ATF_TC_HEAD(ttyname_r_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname_r(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_r_stdin, tc) +{ + const char *str; + char *buf; + int rv; + + if (isatty(STDIN_FILENO) == 0) + return; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + str = ttyname(STDIN_FILENO); + rv = ttyname_r(STDIN_FILENO, buf, ttymax); + + ATF_REQUIRE(rv == 0); + ATF_REQUIRE(str != NULL); + + if (strcmp(str, buf) != 0) + atf_tc_fail("ttyname(3) and ttyname_r(3) conflict"); + + free(buf); +} + +ATF_TC(ttyname_stdin); +ATF_TC_HEAD(ttyname_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_stdin, tc) +{ + + if (isatty(STDIN_FILENO) != 0) + ATF_REQUIRE(ttyname(STDIN_FILENO) != NULL); + + (void)close(STDIN_FILENO); + + ATF_REQUIRE(isatty(STDIN_FILENO) != 1); + ATF_REQUIRE(ttyname(STDIN_FILENO) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ttymax = sysconf(_SC_TTY_NAME_MAX); + ATF_REQUIRE(ttymax >= 0); + + ATF_TP_ADD_TC(tp, ttyname_err); + ATF_TP_ADD_TC(tp, ttyname_r_err); + ATF_TP_ADD_TC(tp, ttyname_r_stdin); + ATF_TP_ADD_TC(tp, ttyname_stdin); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_vis.c b/contrib/netbsd-tests/lib/libc/gen/t_vis.c new file mode 100644 index 0000000..525bafa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_vis.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_vis.c,v 1.7 2014/09/08 19:01:03 christos Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <string.h> +#include <stdlib.h> +#include <err.h> +#include <vis.h> + +static int styles[] = { + VIS_OCTAL, + VIS_CSTYLE, + VIS_SP, + VIS_TAB, + VIS_NL, + VIS_WHITE, + VIS_SAFE, +#if 0 /* Not reversible */ + VIS_NOSLASH, +#endif + VIS_HTTP1808, + VIS_MIMESTYLE, +#if 0 /* Not supported by vis(3) */ + VIS_HTTP1866, +#endif +}; + +#define SIZE 256 + +ATF_TC(strvis_basic); +ATF_TC_HEAD(strvis_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test strvis(3)"); +} + +ATF_TC_BODY(strvis_basic, tc) +{ + char *srcbuf, *dstbuf, *visbuf; + unsigned int i, j; + + ATF_REQUIRE((dstbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((srcbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((visbuf = malloc(SIZE * 4 + 1)) != NULL); + + for (i = 0; i < SIZE; i++) + srcbuf[i] = (char)i; + + for (i = 0; i < __arraycount(styles); i++) { + ATF_REQUIRE(strsvisx(visbuf, srcbuf, SIZE, styles[i], "") > 0); + memset(dstbuf, 0, SIZE); + ATF_REQUIRE(strunvisx(dstbuf, visbuf, + styles[i] & (VIS_HTTP1808|VIS_MIMESTYLE)) > 0); + for (j = 0; j < SIZE; j++) + if (dstbuf[j] != (char)j) + atf_tc_fail_nonfatal("Failed for style %x, " + "char %d [%d]", styles[i], j, dstbuf[j]); + } + free(dstbuf); + free(srcbuf); + free(visbuf); +} + +ATF_TC(strvis_null); +ATF_TC_HEAD(strvis_null, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) NULL"); +} + +ATF_TC_BODY(strvis_null, tc) +{ + char dst[] = "fail"; + strvis(dst, NULL, VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strvis_empty); +ATF_TC_HEAD(strvis_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) empty"); +} + +ATF_TC_BODY(strvis_empty, tc) +{ + char dst[] = "fail"; + strvis(dst, "", VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strunvis_hex); +ATF_TC_HEAD(strunvis_hex, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strunvis(3) \\xXX"); +} + +ATF_TC_BODY(strunvis_hex, tc) +{ + static const struct { + const char *e; + const char *d; + int error; + } ed[] = { + { "\\xff", "\xff", 1 }, + { "\\x1", "\x1", 1 }, + { "\\x1\\x02", "\x1\x2", 2 }, + { "\\x1x", "\x1x", 2 }, + { "\\xx", "", -1 }, + }; + char uv[10]; + + for (size_t i = 0; i < __arraycount(ed); i++) { + ATF_REQUIRE(strunvis(uv, ed[i].e) == ed[i].error); + if (ed[i].error > 0) + ATF_REQUIRE(memcmp(ed[i].d, uv, ed[i].error) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strvis_basic); + ATF_TP_ADD_TC(tp, strvis_null); + ATF_TP_ADD_TC(tp, strvis_empty); + ATF_TP_ADD_TC(tp, strunvis_hex); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-in b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in new file mode 100644 index 0000000..763e4f9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in @@ -0,0 +1,7 @@ + +a +abc +message digest +abcdefghijklmnopqrstuvwxyz +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-out b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out new file mode 100644 index 0000000..bb86bb6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out @@ -0,0 +1,7 @@ +d41d8cd98f00b204e9800998ecf8427e +0cc175b9c0f1b6a831c399e269772661 +900150983cd24fb0d6963f7d28e17f72 +f96b697d7cb7938d525a2f31aaf161d0 +c3fcd3d76192e4007dfb496cca67e13b +d174ab98d277d9f5a5611c2c9f419d9f +57edf4a22be3c955ac49da2e2107b67a diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in new file mode 100644 index 0000000..632d133 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in @@ -0,0 +1,2 @@ +abc +abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out new file mode 100644 index 0000000..c23a058 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out @@ -0,0 +1,2 @@ +a9993e364706816aba3e25717850c26c9cd0d89d +84983e441c3bd26ebaae4aa1f95129e5e54670f1 diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out new file mode 100644 index 0000000..a483a0e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out @@ -0,0 +1 @@ +34aa973cd4c4daa4f61eeb2bdbad27316534016f diff --git a/contrib/netbsd-tests/lib/libc/hash/h_hash.c b/contrib/netbsd-tests/lib/libc/hash/h_hash.c new file mode 100644 index 0000000..33b9f9a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/h_hash.c @@ -0,0 +1,167 @@ +/* $NetBSD: h_hash.c,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Combined MD5/SHA1 time and regression test. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <md5.h> +#include <sha1.h> + + +int mflag, rflag, sflag, tflag; + +static void +usage(void) +{ + (void)fprintf(stderr, + "Usage:\t%s -r[ms] < test-file\n" + "\t%s -t[ms]\n", + getprogname(), getprogname()); + exit(1); + /* NOTREACHED */ +} + +static void +hexdump (unsigned char *buf, int len) +{ + int i; + for (i=0; i<len; i++) { + printf("%02x", buf[i]); + } + printf("\n"); +} + + +static void +timetest(void) +{ + printf("sorry, not yet\n"); +} + +#define CHOMP(buf, len, last) \ + if ((len > 0) && \ + (buf[len-1] == '\n')) { \ + buf[len-1] = '\0'; \ + len--; \ + last = 1; \ + } + +static void +regress(void) +{ + unsigned char buf[1024]; + unsigned char out[20]; + int len, outlen, last; + + while (fgets((char *)buf, sizeof(buf), stdin) != NULL) { + last = 0; + + len = strlen((char *)buf); + CHOMP(buf, len, last); + if (mflag) { + MD5_CTX ctx; + + MD5Init(&ctx); + MD5Update(&ctx, buf, len); + while (!last && + fgets((char *)buf, sizeof(buf), stdin) != NULL) { + len = strlen((char *)buf); + CHOMP(buf, len, last); + MD5Update(&ctx, buf, len); + } + MD5Final(out, &ctx); + outlen = 16; + } else { + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, buf, len); + while (!last && + fgets((char *)buf, sizeof(buf), stdin) != NULL) { + len = strlen((char *)buf); + CHOMP(buf, len, last); + SHA1Update(&ctx, buf, len); + } + SHA1Final(out, &ctx); + outlen = 20; + } + hexdump(out, outlen); + } +} + +int +main(int argc, char **argv) +{ + int ch; + + while ((ch = getopt(argc, argv, "mrst")) != -1) + switch (ch) { + case 'm': + mflag = 1; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = 1; + break; + case 't': + tflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); + + if (!(mflag || sflag)) + mflag = 1; + + if ((mflag ^ sflag) != 1) + usage(); + + if ((tflag ^ rflag) != 1) + usage(); + + if (tflag) + timetest(); + + if (rflag) + regress(); + + exit(0); + +} diff --git a/contrib/netbsd-tests/lib/libc/hash/t_hash.sh b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh new file mode 100755 index 0000000..719f19d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_hash.sh,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +prog() +{ + echo "$(atf_get_srcdir)/h_hash" +} + +datadir() +{ + echo "$(atf_get_srcdir)/data" +} + +atf_test_case md5 +md5_head() +{ + atf_set "descr" "Checks MD5 functions" +} +md5_body() +{ + atf_check -o file:"$(datadir)/md5test-out" -x \ + "$(prog) -r < $(datadir)/md5test-in" +} + +atf_test_case sha1 +sha1_head() +{ + atf_set "descr" "Checks SHA1 functions" +} +sha1_body() +{ + atf_check -o file:"$(datadir)/sha1test-out" -x \ + "$(prog) -rs < $(datadir)/sha1test-in" + + atf_check -o file:"$(datadir)/sha1test2-out" -x \ + "jot -s '' -b 'a' -n 1000000 | $(prog) -rs" +} + +atf_init_test_cases() +{ + atf_add_test_case md5 + atf_add_test_case sha1 +} diff --git a/contrib/netbsd-tests/lib/libc/hash/t_sha2.c b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c new file mode 100644 index 0000000..a45e82a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c @@ -0,0 +1,243 @@ +/* $NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $"); + +#include <atf-c.h> +#include <sys/types.h> +#include <sha2.h> +#include <string.h> + +ATF_TC(t_sha256); +ATF_TC(t_sha384); +ATF_TC(t_sha512); + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_sha256); + ATF_TP_ADD_TC(tp, t_sha384); + ATF_TP_ADD_TC(tp, t_sha512); + + return atf_no_error(); +} + +struct testvector { + const char *vector; + const char *hash; +}; + +static const struct testvector test256[] = { + { "hello, world", "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b" }, + { "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, + { "a", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" }, + { "ab", "fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603" }, + { "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" }, + { "abcd", "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589" }, + { "abcde", "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c" }, + { "abcdef", "bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721" }, + { "abcdefg", "7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a" }, + { "abcdefgh", "9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab" }, + { "abcdefghi", "19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f" }, + { "abcdefghij", "72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0" }, + { "abcdefghijk", "ca2f2069ea0c6e4658222e06f8dd639659cbb5e67cbbba6734bc334a3799bc68" }, + { "abcdefghijkl", "d682ed4ca4d989c134ec94f1551e1ec580dd6d5a6ecde9f3d35e6e4a717fbde4" }, + { "abcdefghijklm", "ff10304f1af23606ede1e2d8abcdc94c229047a61458d809d8bbd53ede1f6598" }, + { "abcdefghijklmn", "0653c7e992d7aad40cb2635738b870e4c154afb346340d02c797d490dd52d5f9" }, + { "abcdefghijklmno", "41c7760c50efde99bf574ed8fffc7a6dd3405d546d3da929b214c8945acf8a97" }, + { "abcdefghijklmnop", "f39dac6cbaba535e2c207cd0cd8f154974223c848f727f98b3564cea569b41cf" }, + { "abcdefghijklmnopq", "918a954ac4dfb54ac39f068d9868227f69ab39bc362e2c9b0083bf6a109d6ad7" }, + { "abcdefghijklmnopqr", "2d1222692afaf56e95a8ab00879ed023a00db3e26fa14236e542748579285efa" }, + { "abcdefghijklmnopqrs", "e250f886728b77ba63722c7e65fc73e203101a84281b32332fd67cc6a1ae3e22" }, + { "abcdefghijklmnopqrst", "dd65eea0329dcb94b17187af9dff28c31a1d78026737a16af75979a1fa4618e5" }, + { "abcdefghijklmnopqrstu", "25f62a5a3d414ec6e20907df7f367f2b72625aade552db64c07933f6044fc49a" }, + { "abcdefghijklmnopqrstuv", "f69f9b70d1c9a5442258ca76f8b0a7a45fcb4e31c36141b6357ec591328b0624" }, + { "abcdefghijklmnopqrstuvw", "7f07818e14d08944ce145629ca54332f5cfad148c590efbcb5c377f4d336e5f4" }, + { "abcdefghijklmnopqrstuvwq", "063132d7fbec0acb79b2f228777eec8885e7f09bc1896b3ce5aa1843e83de048" }, +}; + +static const struct testvector test384[] = { + { "hello, world", "1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e" }, + { "", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" }, + { "a", "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31" }, + { "ab", "c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd" }, + { "abc", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" }, + { "abcd", "1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b" }, + { "abcde", "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0" }, + { "abcdef", "c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5" }, + { "abcdefg", "9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22" }, + { "abcdefgh", "9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806" }, + { "abcdefghi", "ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df" }, + { "abcdefghij", "a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c" }, + { "abcdefghijk", "2440d0e751fe5b8b1aba067e20be00b9deecc5e218b0b4b37202de824bcd04294d67c8d0b73e393afa844fa9ca25fa51" }, + { "abcdefghijkl", "103ca96c06a1ce798f08f8eff0dfb0ccdb567d48b285b23d0cd773454667a3c2fa5f1b58d9cdf2329bd9979730bfaaff" }, + { "abcdefghijklm", "89a7179df195462f047393c36e4843183eb38404bdfbacfd0b0f9c2556632a2799f19c3ecf48bdb7c9bdf95d3f6c3704" }, + { "abcdefghijklmn", "3bc463b0a5614d39fd207cbfd108534bce68d5438235c6c577b34b70fe219954adceaf8808d1fad4a44fc9c420ea8ff1" }, + { "abcdefghijklmno", "5149860ee76dd6666308189e60090d615e36ce0c0ef753a610cca0524a022900489d70167a47cc74c4dd9f9f340066af" }, + { "abcdefghijklmnop", "96d3c1b54b1938600abe5b57232e185df1c5856f74656b8f9837c5317cf5b22ac38226fafc8c946b9d20aca1b0c53a98" }, + { "abcdefghijklmnopq", "dae0d8c29d8f1137df3afb8f502dc474d3bbb56de0c10fc219547826f23f38f37ec29e4ed203908e6e7955c83a138129" }, + { "abcdefghijklmnopqr", "5cfa62716d985d3b1efab0ed3460e7b7f6af9439ae8ee5c58b20e68607eeec3e8c6df8481f5f36e726eaa56512acea6e" }, + { "abcdefghijklmnopqrs", "c5d404fc93b0e59ecb5f40446da201876faf18a0af46e577ae2f7a4fe56dc4c419afff7edec90ff3de160d0c5e7a5ec1" }, + { "abcdefghijklmnopqrst", "bc1511cd8b813544cb60b13d1ceb63e81f46aa3ca114a23fc5c3aba54f9965cdf9afa68e2dc2a680934e429dff5aa7f2" }, + { "abcdefghijklmnopqrstu", "8f18622d37e0aceabba191e3836b30e8970aca202ce6e811f586ec5f950edb7bf799cc88a18468a3effb063397242d95" }, + { "abcdefghijklmnopqrstuv", "c8a4f46e609626543ce6c1362721fcbe95c8e7405aaee61da4f2da1740f0351172c98a66530f8607bf8609e387ff8456" }, + { "abcdefghijklmnopqrstuvw", "2daff33b3bd67de61550070696b431d54b1397b40d053912b07a94260812185907726e3efbe9ae9fc078659cd2ce36db" }, + { "abcdefghijklmnopqrstuvwq", "87dc70a2eaa0dd0b687f91f26383866161026e41bb310a9e32b7a17c99284db85b9743476a30caeedf3fbb3c8072bc5e" }, +}; + +static const struct testvector test512[] = { + { "hello, world", "8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9" }, + { "", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" }, + { "a", "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75" }, + { "ab", "2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d" }, + { "abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" }, + { "abcd", "d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f" }, + { "abcde", "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1" }, + { "abcdef", "e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7" }, + { "abcdefg", "d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c" }, + { "abcdefgh", "a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce" }, + { "abcdefghi", "f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe" }, + { "abcdefghij", "ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745" }, + { "abcdefghijk", "2798fd001ee8800e3da09ee99ae9600de2d0ccf464ab782c92fcc06ce3847cef0743365f1d49c2c8b4426db1635433f937d508672a9d0cb673b84f368eca1b23" }, + { "abcdefghijkl", "17807c728ee3ba35e7cf7af823116d26e41e5d4d6c2ff1f3720d3d96aacb6f69de642e63d5b73fc396c12be38b2bd5d884257c32c8f6d0854ae6b540f86dda2e" }, + { "abcdefghijklm", "e11a66f7b9a2acda5663e9434377137d73ea560a32782230412642a463c8558123bfb7c0dbf17851e9aa58cc9587c3b4f5e3f7f38dcb6f890702e5bed4d5b54a" }, + { "abcdefghijklmn", "8334134081070bf7fcc8bf1c242d24bb3182a5119e5fb19d8bbf6b9d0cdb7fed5336e83415fce93094c0e55123cf69e14d7ae41b22289232699824e31125b6d9" }, + { "abcdefghijklmno", "db723f341a042d8de1aa813efd5e02fc1745ccbe259486257514804e2ec4bcebb2a46f1e4ad442154943f9e97e1bc47c3ae0eddab7de0c01a9c51f15342a5b19" }, + { "abcdefghijklmnop", "d0cadd6834fa0c157b36cca30ee8b0b1435d841aa5b5ac850c11ae80a1440f51743e98fb1f1e7376c70f2f65404f088c28bcb4a511df2e64111f8f7424364b60" }, + { "abcdefghijklmnopq", "6196942a8495b721f82bbc385c74c1f10eeadf35db8adc9cf1a05ddeed19351228279644cd5d686ee48a31631ebb64747a2b68b733dd6015e3d27750878fa875" }, + { "abcdefghijklmnopqr", "fb3bd1fc157ea6f7a6728986a59b271b766fb723f6b7cf2b4194437435f2c497f33b6a56ae7eb3830fa9e04d5ebb4cb5e3f4d4bd812c498bdf0167e125de3fba" }, + { "abcdefghijklmnopqrs", "836f9ecf2aa02f522a94f1370af45a9fd538ac3c70e3b709d614b2f8981881d6b0070fc6387b74ee371fc2549309f82926e78084b401deb61a106c399089bee8" }, + { "abcdefghijklmnopqrst", "8cd9c137651425fb32d193d99b281735ec68eb5fd296f16459d1b33eac7badcfce0dca22eadaa5f209fa4ac3bbecd41342bac8b8a5dc3626e7f22cdc96e17cb4" }, + { "abcdefghijklmnopqrstu", "7079853a3e36241a8d83639f168ef38e883d7f72851a84ef3ed4d91c6a3896cf542b8b4518c2816fb19d4692a4b9aae65cb857e3642ce0a3936e20363bcbd4ca" }, + { "abcdefghijklmnopqrstuv", "a4e8a90b7058fb078e6cdcfd0c6a33c366437eb9084eac657830356804c9f9b53f121496d8e972d8707a4cf02615e6f58ed1a770c28ac79ffd845401fe18a928" }, + { "abcdefghijklmnopqrstuvw", "d91b1fd7c7785975493826719f333d090b214ff42351c84d8f8b2538509a28d2d59a36d0ac798d99d3908083b072a4be606ae391def5daa74156350fec71dd24" }, + { "abcdefghijklmnopqrstuvwq", "404eb5652173323320cac6bf8d9714aef0747693a8ab4570700c6262268d367f30e31c44fa66860568ff058fe39c9aa8dac76bc78566c691a884cb9052c4aa0a" }, +}; + +static void +digest2string(const uint8_t *digest, char *string, size_t len) +{ + while (len--) { + if (*digest / 16 < 10) + *string++ = '0' + *digest / 16; + else + *string++ = 'a' + *digest / 16 - 10; + if (*digest % 16 < 10) + *string++ = '0' + *digest % 16; + else + *string++ = 'a' + *digest % 16 - 10; + ++digest; + } + *string = '\0'; +} + +ATF_TC_HEAD(t_sha256, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA256 functions for consistent results"); +} + +ATF_TC_BODY(t_sha256, tc) +{ + size_t i, j, len; + SHA256_CTX ctx; + unsigned char buf[256]; + unsigned char digest[8 + SHA256_DIGEST_LENGTH]; + char output[SHA256_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test256) / sizeof(test256[0]); ++i) { + len = strlen(test256[i].vector); + for (j = 0; j < 8; ++j) { + SHA256_Init(&ctx); + memcpy(buf + j, test256[i].vector, len); + SHA256_Update(&ctx, buf + j, len); + SHA256_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA256_DIGEST_LENGTH); + ATF_CHECK_STREQ(test256[i].hash, output); + } + } +} + +ATF_TC_HEAD(t_sha384, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA384 functions for consistent results"); +} + +ATF_TC_BODY(t_sha384, tc) +{ + size_t i, j, len; + SHA384_CTX ctx; + unsigned char buf[384]; + unsigned char digest[8 + SHA384_DIGEST_LENGTH]; + char output[SHA384_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test384) / sizeof(test384[0]); ++i) { + len = strlen(test384[i].vector); + for (j = 0; j < 8; ++j) { + SHA384_Init(&ctx); + memcpy(buf + j, test384[i].vector, len); + SHA384_Update(&ctx, buf + j, len); + SHA384_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA384_DIGEST_LENGTH); + ATF_CHECK_STREQ(test384[i].hash, output); + } + } +} + +ATF_TC_HEAD(t_sha512, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA512 functions for consistent results"); +} + +ATF_TC_BODY(t_sha512, tc) +{ + size_t i, j, len; + SHA512_CTX ctx; + unsigned char buf[512]; + unsigned char digest[8 + SHA512_DIGEST_LENGTH]; + char output[SHA512_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test512) / sizeof(test512[0]); ++i) { + len = strlen(test512[i].vector); + for (j = 0; j < 8; ++j) { + SHA512_Init(&ctx); + memcpy(buf + j, test512[i].vector, len); + SHA512_Update(&ctx, buf + j, len); + SHA512_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA512_DIGEST_LENGTH); + ATF_CHECK_STREQ(test512[i].hash, output); + } + } +} diff --git a/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c new file mode 100644 index 0000000..99f75b3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c @@ -0,0 +1,170 @@ +/* $NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Brian Ginsbach. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $"); + +#include <arpa/inet.h> + +#include <atf-c.h> +#include <stdio.h> +#include <string.h> + +#define H_REQUIRE(input, expected) \ + ATF_REQUIRE_EQ_MSG(inet_network(input), (in_addr_t) expected, \ + "inet_network(%s) returned: 0x%08X, expected: %s", #input, \ + inet_network(input), #expected) + +ATF_TC(inet_addr_basic); +ATF_TC_HEAD(inet_addr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks inet_addr(3)"); +} + +ATF_TC_BODY(inet_addr_basic, tc) +{ + static const char *addrs[] = { + "127.0.0.1", "99.99.99.99", "0.0.0.0", "255.255.255.255" }; + + struct in_addr ia; + const char *ian; + in_addr_t addr; + size_t i; + + for (i = 0; i < __arraycount(addrs); i++) { + + (void)fprintf(stderr, "checking %s\n", addrs[i]);; + + addr = inet_addr(addrs[i]); + ia.s_addr = addr; + ian = inet_ntoa(ia); + + ATF_REQUIRE(ian != NULL); + ATF_CHECK(strcmp(ian, addrs[i]) == 0); + } +} + +ATF_TC(inet_addr_err); +ATF_TC_HEAD(inet_addr_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Invalid addresses with inet_addr(3)"); +} + +ATF_TC_BODY(inet_addr_err, tc) +{ + static const char *addrs[] = { + ". . . .", "1.2.3.", "0.0.0.256", "255.255.255.256", + "................................................", + "a.b.c.d", "0x0.0x1.0x2.0x3", "-1.-1.-1.-1", "", " "}; + + struct in_addr ia; + const char *ian; + in_addr_t addr; + size_t i; + + for (i = 0; i < __arraycount(addrs); i++) { + + (void)fprintf(stderr, "checking %s\n", addrs[i]);; + + addr = inet_addr(addrs[i]); + ia.s_addr = addr; + ian = inet_ntoa(ia); + + ATF_REQUIRE(ian != NULL); + ATF_CHECK(strcmp(ian, addrs[i]) != 0); + } +} + +ATF_TC(inet_network_basic); +ATF_TC_HEAD(inet_network_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks inet_network(3)"); +} + +ATF_TC_BODY(inet_network_basic, tc) +{ + + H_REQUIRE("0x12", 0x00000012); + H_REQUIRE("127.1", 0x00007f01); + H_REQUIRE("127.1.2.3", 0x7f010203); + H_REQUIRE("0X12", 0x00000012); + H_REQUIRE("0", 0x0); + H_REQUIRE("01.02.07.077", 0x0102073f); + H_REQUIRE("0x1.23.045.0", 0x01172500); + H_REQUIRE("0x12.0x34", 0x00001234); + + /* This is valid (because of the trailing space after the digit). */ + H_REQUIRE("1 bar", 0x00000001); +} + +ATF_TC(inet_network_err); +ATF_TC_HEAD(inet_network_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Invalid addresses w/ inet_network(3)"); +} + +ATF_TC_BODY(inet_network_err, tc) +{ + /* Malformed requests. */ + H_REQUIRE("4.2.3.1.", 0xffffffff); + H_REQUIRE("0x123456", 0xffffffff); + H_REQUIRE("0x12.0x345", 0xffffffff); + H_REQUIRE("1.2.3.4.5", 0xffffffff); + H_REQUIRE("1..3.4", 0xffffffff); + H_REQUIRE(".", 0xffffffff); + H_REQUIRE("1.", 0xffffffff); + H_REQUIRE(".1", 0xffffffff); + H_REQUIRE("0x", 0xffffffff); + H_REQUIRE("", 0xffffffff); + H_REQUIRE(" ", 0xffffffff); + H_REQUIRE("bar", 0xffffffff); + H_REQUIRE("1.2bar", 0xffffffff); + H_REQUIRE("1.", 0xffffffff); + H_REQUIRE("\xc3\x8a\xc3\x83\xc3\x95\xc3\x8b\xc3\x85\xc3\x8e", + 0xffffffff); + H_REQUIRE("255.255.255.255", 0xffffffff); + H_REQUIRE("x", 0xffffffff); + H_REQUIRE("078", 0xffffffff); + H_REQUIRE("127.0xfff", 0xffffffff); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, inet_addr_basic); + ATF_TP_ADD_TC(tp, inet_addr_err); + ATF_TP_ADD_TC(tp, inet_network_basic); + ATF_TP_ADD_TC(tp, inet_network_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_io.c b/contrib/netbsd-tests/lib/libc/locale/t_io.c new file mode 100644 index 0000000..782bed8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_io.c @@ -0,0 +1,178 @@ +/* $NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $"); + +#include <sys/param.h> +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#include <atf-c.h> + + +ATF_TC(bad_big5_wprintf); +ATF_TC_HEAD(bad_big5_wprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar wprintf"); +} + +ATF_TC_BODY(bad_big5_wprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf10, 0 }; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_ERRNO(EILSEQ, wprintf(L"%ls\n", ibuf) < 0); + ATF_REQUIRE(ferror(stdout)); +} + +ATF_TC(bad_big5_swprintf); +ATF_TC_HEAD(bad_big5_swprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar swprintf"); +} + +ATF_TC_BODY(bad_big5_swprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf10, 0 }; + wchar_t obuf[20]; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_ERRNO(EILSEQ, + swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf) < 0); +} + +ATF_TC(good_big5_wprintf); +ATF_TC_HEAD(good_big5_wprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar wprintf"); +} + +ATF_TC_BODY(good_big5_wprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf40, 0 }; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_EQ(wprintf(L"%ls\n", ibuf), 2); +} + +ATF_TC(good_big5_swprintf); +ATF_TC_HEAD(good_big5_swprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar swprintf"); +} + +ATF_TC_BODY(good_big5_swprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf40, 0 }; + wchar_t obuf[20]; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_EQ(swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf), 2); +} + +struct ibuf { + off_t off; + size_t buflen; + const char *buf; +}; + +static int +readfn(void *vp, char *buf, int len) +{ + struct ibuf *ib = vp; + size_t todo = MIN((size_t)len, ib->buflen - ib->off); + + memcpy(buf, ib->buf + ib->off, todo); + ib->off += todo; + return todo; +} + +ATF_TC(good_big5_getwc); +ATF_TC_HEAD(good_big5_getwc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar getwc"); +} + +ATF_TC_BODY(good_big5_getwc, tc) +{ + const char buf[] = { 0xcf, 0x40 }; + struct ibuf ib = { + .buf = buf, + .buflen = sizeof(buf), + }; + FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL); + + ATF_REQUIRE(fp != NULL); + setlocale(LC_CTYPE, "zh_TW.Big5"); + /* XXX implementation detail knowledge (wchar_t encoding) */ + ATF_REQUIRE_EQ(getwc(fp), 0xcf40); + fclose(fp); +} + +ATF_TC(bad_big5_getwc); +ATF_TC_HEAD(bad_big5_getwc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar getwc"); +} + +ATF_TC_BODY(bad_big5_getwc, tc) +{ + const char buf[] = { 0xcf, 0x20 }; + struct ibuf ib = { + .buf = buf, + .buflen = sizeof(buf), + }; + FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL); + + ATF_REQUIRE(fp != NULL); + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_EQ(getwc(fp), WEOF); + fclose(fp); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, bad_big5_wprintf); + ATF_TP_ADD_TC(tp, bad_big5_swprintf); + ATF_TP_ADD_TC(tp, good_big5_wprintf); + ATF_TP_ADD_TC(tp, good_big5_swprintf); + ATF_TP_ADD_TC(tp, good_big5_getwc); + ATF_TP_ADD_TC(tp, bad_big5_getwc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c new file mode 100644 index 0000000..b4ad841 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c @@ -0,0 +1,267 @@ +/* $NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by YAMAMOTO Takashi + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $"); + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vis.h> +#include <wchar.h> + +#include <atf-c.h> + +#define SIZE 256 + +static struct test { + const char *locale; + const char *data; + const wchar_t wchars[64]; + const wchar_t widths[64]; + size_t length; +} tests[] = { +{ + "C", + "ABCD01234_\\", + { 0x41, 0x42, 0x43, 0x44, 0x30, 0x31, 0x32, 0x33, 0x34, 0x5F, 0x5C }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + 11 +}, { + "en_US.UTF-8", + "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200" + "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374" + "\204\200\200\200\200\375\277\277\277\277\277]", + { 0x5b, 0x01, 0x7f, 0x5d, 0x5b, 0x80, 0x7ff, 0x5d, 0x5b, 0x800, 0xffff, + 0x5d, 0x5b, 0x10000, 0x1fffff, 0x5d, 0x5b, 0x200000, 0x3ffffff, 0x5d, + 0x5b, 0x4000000, 0x7fffffff, 0x5d }, + { 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1, 5, 5, 1, 1, 6, 6, 1 }, + 24 +}, { + "ja_JP.ISO2022-JP2", + "\033$BF|K\1348l\033(BA\033$B$\"\033(BB\033$B$$\033(B", + { 0x4200467c, 0x42004b5c, 0x4200386c, 0x41, 0x42002422, 0x42, 0x42002424 }, + { 5, 2, 2, 4, 5, 4, 5 }, + 7 +}, { + "ja_JP.SJIS", + "\223\372\226{\214\352A\202\240B\202\242", + { 0x93fa, 0x967b, 0x8cea, 0x41, 0x82a0, 0x42, 0x82a2 }, + { 2, 2, 2, 1, 2, 1, 2 }, + 7 +}, { + "ja_JP.eucJP", + "\306\374\313\334\270\354A\244\242B\244\244", + { 0xc6fc, 0xcbdc, 0xb8ec, 0x41, 0xa4a2, 0x42, 0xa4a4 }, + { 2, 2, 2, 1, 2, 1, 2 }, + 7 +}, { + NULL, + NULL, + { }, + { }, + 0 +} +}; + +static void +h_ctype2(const struct test *t, bool use_mbstate) +{ + mbstate_t *stp; + mbstate_t st; + char buf[SIZE]; + char *str; + size_t n; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); + + (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking string: \"%s\"\n", buf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + (void)printf("Using mbstate: %s\n", use_mbstate ? "yes" : "no"); + + (void)memset(&st, 0, sizeof(st)); +// mbrtowc(0, 0, 0, &st); /* XXX for ISO2022-JP */ + stp = use_mbstate ? &st : 0; + + for (n = 9; n > 0; n--) { + const char *src = t->data; + wchar_t dst; + size_t nchar = 0; + int width = 0; + + ATF_REQUIRE(mbsinit(stp) != 0); + + for (;;) { + size_t rv = mbrtowc(&dst, src, n, stp); + + if (rv == 0) + break; + + if (rv == (size_t)-2) { + src += n; + width += n; + + continue; + } + if (rv == (size_t)-1) { + ATF_REQUIRE_EQ(errno, EILSEQ); + atf_tc_fail("Invalid sequence"); + /* NOTREACHED */ + } + + width += rv; + src += rv; + + if (dst != t->wchars[nchar] || + width != t->widths[nchar]) { + (void)printf("At position %zd:\n", nchar); + (void)printf(" expected: 0x%04X (%u)\n", + t->wchars[nchar], t->widths[nchar]); + (void)printf(" got : 0x%04X (%u)\n", + dst, width); + atf_tc_fail("Test failed"); + } + + nchar++; + width = 0; + } + + ATF_REQUIRE_EQ_MSG(dst, 0, "Incorrect terminating character: " + "0x%04X (expected: 0x00)", dst); + + ATF_REQUIRE_EQ_MSG(nchar, t->length, "Incorrect length: " + "%zd (expected: %zd)", nchar, t->length); + } + + { + wchar_t wbuf[SIZE]; + size_t rv; + char const *src = t->data; + int i; + + (void)memset(wbuf, 0xFF, sizeof(wbuf)); + + rv = mbsrtowcs(wbuf, &src, SIZE, stp); + + ATF_REQUIRE_EQ_MSG(rv, t->length, "Incorrect length: %zd " + "(expected: %zd)", rv, t->length); + ATF_REQUIRE_EQ(src, NULL); + + for (i = 0; wbuf[i] != 0; ++i) { + if (wbuf[i] == t->wchars[i]) + continue; + + (void)printf("At position %d:\n", i); + (void)printf(" expected: 0x%04X\n", t->wchars[i]); + (void)printf(" got : 0x%04X\n", wbuf[i]); + atf_tc_fail("Test failed"); + } + + ATF_REQUIRE_EQ_MSG((size_t)i, t->length, "Incorrect length: " + "%d (expected: %zd)", i, t->length); + } + + (void)printf("Ok.\n"); +} + +ATF_TC(mbrtowc_internal); +ATF_TC_HEAD(mbrtowc_internal, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbrtowc(3) and mbsrtowcs(3) (using internal " + "state) with different locales"); +} +ATF_TC_BODY(mbrtowc_internal, tc) +{ + struct test *t; + + for (t = &tests[0]; t->data != NULL; ++t) + h_ctype2(t, false); +} + +ATF_TC(mbrtowc_object); +ATF_TC_HEAD(mbrtowc_object, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbrtowc(3) and mbsrtowcs(3) (using state " + "object) with different locales"); +} +ATF_TC_BODY(mbrtowc_object, tc) +{ + struct test *t; + + for (t = &tests[0]; t->data != NULL; ++t) + h_ctype2(t, true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mbrtowc_internal); + ATF_TP_ADD_TC(tp, mbrtowc_object); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c new file mode 100644 index 0000000..446d7ef --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $"); + +#include <locale.h> +#include <string.h> +#include <wchar.h> + +#include <atf-c.h> + +static const struct test { + const char *locale; + const char *data; + size_t limit; + const wchar_t output1[64]; + size_t output1_len; + const wchar_t output2[64]; + size_t output2_len; +} tests[] = { + { "C", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4, + { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 }, + { "en_US.UTF-8", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4, + { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 }, + { "en_US.UTF-8", "ABC\303\2440123", 4, { 0x41, 0x42, 0x43, }, 3, + { 0xe4, 0x30, 0x31, 0x32, 0x33, 0x0 }, 6 }, +}; + +ATF_TC(mbsnrtowcs); +ATF_TC_HEAD(mbsnrtowcs, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbsnrtowc(3) with different locales"); +} +ATF_TC_BODY(mbsnrtowcs, tc) +{ + size_t i; + const struct test *t; + mbstate_t state; + wchar_t buf[64]; + const char *src; + size_t len; + + for (i = 0; i < __arraycount(tests); ++i) { + t = &tests[i]; + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); + memset(&state, 0, sizeof(state)); + src = t->data; + len = mbsnrtowcs(buf, &src, t->limit, + __arraycount(buf), &state); + ATF_REQUIRE_EQ(src, t->data + t->limit); + ATF_REQUIRE_EQ(len, t->output1_len); + ATF_REQUIRE(wmemcmp(t->output1, buf, len) == 0); + len = mbsnrtowcs(buf, &src, strlen(src) + 1, + __arraycount(buf), &state); + ATF_REQUIRE_EQ(len, strlen(t->data) - t->limit); + ATF_REQUIRE(wmemcmp(t->output2, buf, len + 1) == 0); + ATF_REQUIRE_EQ(src, NULL); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mbsnrtowcs); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c new file mode 100644 index 0000000..ec06729 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c @@ -0,0 +1,202 @@ +/* $NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $"); + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vis.h> +#include <wchar.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x, v) \ + ATF_REQUIRE_MSG((x) != (v), "%s: %s", #x, strerror(errno)) + +#define SIZE 256 + +static struct test { + const char *locale; + const char *data; + wchar_t wchars[64]; + int widths[64]; + int width; +} tests[] = { +{ + "en_US.UTF-8", + "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200" + "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374" + "\204\200\200\200\200\375\277\277\277\277\277]", + { + 0x5B, 0x01, 0x7F, 0x5D, 0x5B, 0x80, 0x07FF, 0x5D, 0x5B, 0x0800, + 0xFFFF, 0x5D, 0x5B, 0x10000, 0x1FFFFF, 0x5D, 0x5B, 0x200000, + 0x3FFFFFF, 0x5D, 0x5B, 0x4000000, 0x7FFFFFFF, 0x5D, 0x0A + }, + { 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, + 1, 1, -1, -1, 1, 1, -1, -1, 1, -1 + }, + -1 +}, { + "ja_JP.ISO2022-JP", + "\033$B#J#I#S$G$9!#\033(Baaaa\033$B$\"$$$&$($*\033(B", + { + 0x4200234A, 0x42002349, 0x42002353, 0x42002447, 0x42002439, + 0x42002123, 0x61, 0x61, 0x61, 0x61, 0x42002422, 0x42002424, + 0x42002426, 0x42002428, 0x4200242A, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 26 +}, { + "ja_JP.SJIS", + "\202r\202i\202h\202r\202\305\202\267\201Baaaa\202\240\202\242" + "\202\244\202\246\202\250", + { + 0x8272, 0x8269, 0x8268, 0x8272, 0x82C5, 0x82B7, 0x8142, 0x61, + 0x61, 0x61, 0x61, 0x82A0, 0x82A2, 0x82A4, 0x82A6, 0x82A8, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 28 +}, { + "ja_JP.eucJP", + "\243\305\243\325\243\303\244\307\244\271\241\243aaaa\244\242\244" + "\244\244\246\244\250\244\252", + { + 0xA3C5, 0xA3D5, 0xA3C3, 0xA4C7, 0xA4B9, 0xA1A3, 0x61, 0x61, 0x61, + 0x61, 0xA4A2, 0xA4A4, 0xA4A6, 0xA4A8, 0xA4AA, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 26 +}, { + NULL, + NULL, + {}, + {}, + 0 +} +}; + +ATF_TC(mbstowcs_basic); +ATF_TC_HEAD(mbstowcs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wide character functions with different locales"); +} +ATF_TC_BODY(mbstowcs_basic, tc) +{ + struct test *t; + + for (t = &tests[0]; t->data != NULL; ++t) { + wchar_t wbuf[SIZE]; + char buf[SIZE]; + char visbuf[SIZE]; + char *str; + int i; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); + + (void)strvis(visbuf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking string: \"%s\"\n", visbuf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + REQUIRE_ERRNO((ssize_t)mbstowcs(wbuf, t->data, SIZE-1), -1); + REQUIRE_ERRNO((ssize_t)wcstombs(buf, wbuf, SIZE-1), -1); + + if (strcmp(buf, t->data) != 0) { + (void)strvis(visbuf, buf, VIS_WHITE | VIS_OCTAL); + (void)printf("Conversion to wcs and back failed: " + "\"%s\"\n", visbuf); + atf_tc_fail("Test failed"); + } + + /* The output here is implementation-dependent. */ + + for (i = 0; wbuf[i] != 0; ++i) { + if (wbuf[i] == t->wchars[i] && + wcwidth(wbuf[i]) == t->widths[i]) + continue; + + (void)printf("At position %d:\n", i); + (void)printf(" expected: 0x%04X (%d)\n", + t->wchars[i], t->widths[i]); + (void)printf(" got : 0x%04X (%d)\n", wbuf[i], + wcwidth(wbuf[i])); + atf_tc_fail("Test failed"); + } + + if (wcswidth(wbuf, SIZE-1) != t->width) { + (void)printf("Incorrect wcswidth:\n"); + (void)printf(" expected: %d\n", t->width); + (void)printf(" got : %d\n", wcswidth(wbuf, SIZE-1)); + atf_tc_fail("Test failed"); + } + + (void)printf("Ok.\n"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mbstowcs_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c new file mode 100644 index 0000000..62f62b1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c @@ -0,0 +1,143 @@ +/* $NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2007 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $"); + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vis.h> +#include <wchar.h> + +#include <atf-c.h> + +static void +h_mbtowc(const char *locale, const char *illegal, const char *legal) +{ + char buf[64]; + size_t stateful, ret; + char *str; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); + ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + stateful = wctomb(NULL, L'\0'); + (void)printf("Locale is state-%sdependent\n", + stateful ? "in" : ""); + + /* initialize internal state */ + ret = mbtowc(NULL, NULL, 0); + ATF_REQUIRE(stateful ? ret : !ret); + + (void)strvis(buf, illegal, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking illegal sequence: \"%s\"\n", buf); + + ret = mbtowc(NULL, illegal, strlen(illegal)); + (void)printf("mbtowc() returned: %zd\n", ret); + ATF_REQUIRE_EQ(ret, (size_t)-1); + (void)printf("errno: %s\n", strerror(errno)); + ATF_REQUIRE_EQ(errno, EILSEQ); + + /* if this is stateless encoding, this re-initialization is not required. */ + if (stateful) { + /* re-initialize internal state */ + ret = mbtowc(NULL, NULL, 0); + ATF_REQUIRE(stateful ? ret : !ret); + } + + /* valid multibyte sequence case */ + (void)strvis(buf, legal, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking legal sequence: \"%s\"\n", buf); + + errno = 0; + ret = mbtowc(NULL, legal, strlen(legal)); + (void)printf("mbtowc() returned: %zd\n", ret); + ATF_REQUIRE(ret != (size_t)-1); + (void)printf("errno: %s\n", strerror(errno)); + ATF_REQUIRE_EQ(errno, 0); + + (void)printf("Ok.\n"); +} + +ATF_TC(mbtowc); +ATF_TC_HEAD(mbtowc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mbtowc(3)"); +} +ATF_TC_BODY(mbtowc, tc) +{ + h_mbtowc("en_US.UTF-8", "\240", "\302\240"); + h_mbtowc("ja_JP.ISO2022-JP", "\033$B", "\033$B$\"\033(B"); + h_mbtowc("ja_JP.SJIS", "\202", "\202\240"); + h_mbtowc("ja_JP.eucJP", "\244", "\244\242"); + h_mbtowc("zh_CN.GB18030", "\241", "\241\241"); + h_mbtowc("zh_TW.Big5", "\241", "\241@"); + h_mbtowc("zh_TW.eucTW", "\241", "\241\241"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mbtowc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c new file mode 100644 index 0000000..10756b5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <wchar.h> + +ATF_TC(wcscspn); +ATF_TC_HEAD(wcscspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcscspn(3)"); +} + +ATF_TC_BODY(wcscspn, tc) +{ + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L""), 16); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"a"), 0); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"b"), 1); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"cd"), 2); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"qrstuvwxyz"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcscspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c new file mode 100644 index 0000000..57c1ac5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c @@ -0,0 +1,62 @@ +/* $NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <wchar.h> + +ATF_TC(wcspbrk); +ATF_TC_HEAD(wcspbrk, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcspbrk(3)"); +} + +ATF_TC_BODY(wcspbrk, tc) +{ + static const wchar_t s[] = L"abcdefghijklmnop"; + + ATF_CHECK_EQ(wcspbrk(s, L""), NULL); + ATF_CHECK_EQ(wcspbrk(s, L"qrst"), NULL); + ATF_CHECK_EQ(wcspbrk(s, L"a"), s); + ATF_CHECK_EQ(wcspbrk(s, L"b"), s + 1); + ATF_CHECK_EQ(wcspbrk(s, L"ab"), s); + ATF_CHECK_EQ(wcspbrk(s, L"cdef"), s + 2); + ATF_CHECK_EQ(wcspbrk(s, L"fedc"), s + 2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcspbrk); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c new file mode 100644 index 0000000..2083650 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c @@ -0,0 +1,60 @@ +/* $NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <wchar.h> + +ATF_TC(wcsspn); +ATF_TC_HEAD(wcsspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcsspn(3)"); +} + +ATF_TC_BODY(wcsspn, tc) +{ + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L""), 0); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"a"), 1); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"b"), 0); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"ab"), 2); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abc"), 3); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abce"), 3); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abcdefghijklmnop"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcsspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c new file mode 100644 index 0000000..85b1ee1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c @@ -0,0 +1,456 @@ +/* $NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2005 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $"); + +#include <errno.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#include <atf-c.h> + +#define ALT_HUGE_VAL -1 +#define ALT_MINUS_HUGE_VAL -2 +#define ALT_NAN -3 + +#if !defined(__vax__) +static struct test { + const wchar_t *wcs; + size_t len; + double val; + int err; +} tests[] = { +{ L"IN", 0, 0, 0 }, +{ L"+IN", 0, 0, 0 }, +{ L"-IN", 0, 0, 0 }, +{ L"INX", 0, 0, 0 }, +{ L"+INX", 0, 0, 0 }, +{ L"-INX", 0, 0, 0 }, +{ L"INF", 3, ALT_HUGE_VAL, 0 }, +{ L"+INF", 4, ALT_HUGE_VAL, 0 }, +{ L"-INF", 4, ALT_MINUS_HUGE_VAL, 0 }, +{ L"INFX", 3, ALT_HUGE_VAL, 0 }, +{ L"+INFX", 4, ALT_HUGE_VAL, 0 }, +{ L"-INFX", 4, ALT_MINUS_HUGE_VAL, 0 }, +{ L" IN", 0, 0, 0 }, +{ L" +IN", 0, 0, 0 }, +{ L" -IN", 0, 0, 0 }, +{ L" INX", 0, 0, 0 }, +{ L" +INX", 0, 0, 0 }, +{ L" -INX", 0, 0, 0 }, +{ L"+ INF", 0, 0, 0 }, +{ L"- INF", 0, 0, 0 }, +{ L" INF", 8, ALT_HUGE_VAL, 0 }, +{ L" +INF", 9, ALT_HUGE_VAL, 0 }, +{ L" -INF", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFX", 8, ALT_HUGE_VAL, 0 }, +{ L" +INFX", 9, ALT_HUGE_VAL, 0 }, +{ L" -INFX", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINIT", 8, ALT_HUGE_VAL, 0 }, +{ L" +INFINIT", 9, ALT_HUGE_VAL, 0 }, +{ L" -INFINIT", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINITY", 13, ALT_HUGE_VAL, 0 }, +{ L" +INFINITY", 14, ALT_HUGE_VAL, 0 }, +{ L" -INFINITY", 14, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINITYX", 13, ALT_HUGE_VAL, 0 }, +{ L" +INFINITYX", 14, ALT_HUGE_VAL, 0 }, +{ L" -INFINITYX", 14, ALT_MINUS_HUGE_VAL, 0 }, + +/* NAN */ +{ L"NA", 0, 0, 0 }, +{ L"+NA", 0, 0, 0 }, +{ L"-NA", 0, 0, 0 }, +{ L"NAX", 0, 0, 0 }, +{ L"+NAX", 0, 0, 0 }, +{ L"-NAX", 0, 0, 0 }, +{ L"NAN", 3, ALT_NAN, 0 }, +{ L"+NAN", 4, ALT_NAN, 0 }, +{ L"-NAN", 4, ALT_NAN, 0 }, +{ L"NANX", 3, ALT_NAN, 0 }, +{ L"+NANX", 4, ALT_NAN, 0 }, +{ L"-NANX", 4, ALT_NAN, 0 }, +{ L" NA", 0, 0, 0 }, +{ L" +NA", 0, 0, 0 }, +{ L" -NA", 0, 0, 0 }, +{ L" NAX", 0, 0, 0 }, +{ L" +NAX", 0, 0, 0 }, +{ L" -NAX", 0, 0, 0 }, +{ L"+ NAN", 0, 0, 0 }, +{ L"- NAN", 0, 0, 0 }, +{ L" NAN", 8, ALT_NAN, 0 }, +{ L" +NAN", 9, ALT_NAN, 0 }, +{ L" -NAN", 9, ALT_NAN, 0 }, +{ L" NANX", 8, ALT_NAN, 0 }, +{ L" +NANX", 9, ALT_NAN, 0 }, +{ L" -NANX", 9, ALT_NAN, 0 }, + +{ L"0", 1, 0, 0 }, +{ L"+0", 2, 0, 0 }, +{ L"-0", 2, 0, 0 }, +{ L" 0", 11, 0, 0 }, +{ L" +0", 12, 0, 0 }, +{ L" -0", 12, 0, 0 }, +{ L"+ 0", 0, 0, 0 }, +{ L"- 0", 0, 0, 0 }, + +{ L".", 0, 0, 0 }, +{ L".0", 2, 0, 0 }, +{ L".00", 3, 0, 0 }, +{ L".000", 4, 0, 0 }, + +{ L"0.", 2, 0, 0 }, +{ L"+0.", 3, 0, 0 }, +{ L"-0.", 3, 0, 0 }, +{ L" 0.", 12, 0, 0 }, +{ L" +0.", 13, 0, 0 }, +{ L" -0.", 13, 0, 0 }, + +{ L"0.0", 3, 0, 0 }, +{ L"+0.0", 4, 0, 0 }, +{ L"-0.0", 4, 0, 0 }, +{ L" 0.0", 13, 0, 0 }, +{ L" +0.0", 14, 0, 0 }, +{ L" -0.0", 14, 0, 0 }, + +{ L"000", 3, 0, 0 }, +{ L"+000", 4, 0, 0 }, +{ L"-000", 4, 0, 0 }, +{ L" 000", 13, 0, 0 }, +{ L" +000", 14, 0, 0 }, +{ L" -000", 14, 0, 0 }, + +{ L"000.", 4, 0, 0 }, +{ L"+000.", 5, 0, 0 }, +{ L"-000.", 5, 0, 0 }, +{ L" 000.", 14, 0, 0 }, +{ L" +000.", 15, 0, 0 }, +{ L" -000.", 15, 0, 0 }, + +{ L"000.0", 5, 0, 0 }, +{ L"+000.0", 6, 0, 0 }, +{ L"-000.0", 6, 0, 0 }, +{ L" 000.0", 15, 0, 0 }, +{ L" +000.0", 16, 0, 0 }, +{ L" -000.0", 16, 0, 0 }, + + +{ L"0.0.", 3, 0, 0 }, +{ L"+0.0.", 4, 0, 0 }, +{ L"-0.0.", 4, 0, 0 }, +{ L" 0.0.", 13, 0, 0 }, +{ L" +0.0.", 14, 0, 0 }, +{ L" -0.0.", 14, 0, 0 }, + +{ L"0.0.0", 3, 0, 0 }, +{ L"+0.0.0", 4, 0, 0 }, +{ L"-0.0.0", 4, 0, 0 }, +{ L" 0.0.0", 13, 0, 0 }, +{ L" +0.0.0", 14, 0, 0 }, +{ L" -0.0.0", 14, 0, 0 }, + +/* XXX: FIXME */ +#if defined(__linux__) +{ L"0X", 2, 0, 0 }, +{ L"+0X", 3, 0, 0 }, +{ L"-0X", 3, 0, 0 }, +#else +{ L"0X", 1, 0, 0 }, +{ L"+0X", 2, 0, 0 }, +{ L"-0X", 2, 0, 0 }, +#endif + +/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */ +#if !defined(__SunOS__) +#if defined(__linux__) +{ L"0X.", 3, 0, 0 }, +{ L"+0X.", 4, 0, 0 }, +{ L"-0X.", 4, 0, 0 }, +{ L" 0X.", 13, 0, 0 }, +{ L" +0X.", 14, 0, 0 }, +{ L" -0X.", 14, 0, 0 }, +#else +{ L"0X.", 1, 0, 0 }, +{ L"+0X.", 2, 0, 0 }, +{ L"-0X.", 2, 0, 0 }, +{ L" 0X.", 11, 0, 0 }, +{ L" +0X.", 12, 0, 0 }, +{ L" -0X.", 12, 0, 0 }, +#endif +/* XXX: FIXME */ +#if defined(__NetBSD__) || defined(__linux__) +{ L"0X.0", 4, 0, 0 }, +{ L"+0X.0", 5, 0, 0 }, +{ L"-0X.0", 5, 0, 0 }, +{ L" 0X.0", 14, 0, 0 }, +{ L" +0X.0", 15, 0, 0 }, +{ L" -0X.0", 15, 0, 0 }, + +{ L"0X.0P", 4, 0, 0 }, +{ L"+0X.0P", 5, 0, 0 }, +{ L"-0X.0P", 5, 0, 0 }, +{ L" 0X.0P", 14, 0, 0 }, +{ L" +0X.0P", 15, 0, 0 }, +{ L" -0X.0P", 15, 0, 0 }, +#else +{ L"0X.0", 1, 0, 0 }, +{ L"+0X.0", 2, 0, 0 }, +{ L"-0X.0", 2, 0, 0 }, +{ L" 0X.0", 11, 0, 0 }, +{ L" +0X.0", 12, 0, 0 }, +{ L" -0X.0", 12, 0, 0 }, + +{ L"0X.0P", 1, 0, 0 }, +{ L"+0X.0P", 2, 0, 0 }, +{ L"-0X.0P", 2, 0, 0 }, +{ L" 0X.0P", 11, 0, 0 }, +{ L" +0X.0P", 12, 0, 0 }, +{ L" -0X.0P", 12, 0, 0 }, +#endif + +{ L"0X0", 3, 0, 0 }, +{ L"+0X0", 4, 0, 0 }, +{ L"-0X0", 4, 0, 0 }, +{ L" 0X0", 13, 0, 0 }, +{ L" +0X0", 14, 0, 0 }, +{ L" -0X0", 14, 0, 0 }, + +{ L"00X0.0", 2, 0, 0 }, +{ L"+00X0.0", 3, 0, 0 }, +{ L"-00X0.0", 3, 0, 0 }, +{ L" 00X0.0", 12, 0, 0 }, +{ L" +00X0.0", 13, 0, 0 }, +{ L" -00X0.0", 13, 0, 0 }, + +{ L"0X0P", 3, 0, 0 }, +{ L"+0X0P", 4, 0, 0 }, +{ L"-0X0P", 4, 0, 0 }, +{ L" 0X0P", 13, 0, 0 }, +{ L" +0X0P", 14, 0, 0 }, +{ L" -0X0P", 14, 0, 0 }, + +{ L"0X0.", 4, 0, 0 }, +{ L"+0X0.", 5, 0, 0 }, +{ L"-0X0.", 5, 0, 0 }, +{ L" 0X0.", 14, 0, 0 }, +{ L" +0X0.", 15, 0, 0 }, +{ L" -0X0.", 15, 0, 0 }, + +{ L"0X0.0", 5, 0, 0 }, +{ L"+0X0.0", 6, 0, 0 }, +{ L"-0X0.0", 6, 0, 0 }, +{ L" 0X0.0", 15, 0, 0 }, +{ L" +0X0.0", 16, 0, 0 }, +{ L" -0X0.0", 16, 0, 0 }, + +{ L"0X0.P", 4, 0, 0 }, +{ L"+0X0.P", 5, 0, 0 }, +{ L"-0X0.P", 5, 0, 0 }, +{ L" 0X0.P", 14, 0, 0 }, +{ L" +0X0.P", 15, 0, 0 }, +{ L" -0X0.P", 15, 0, 0 }, + +{ L"0X0.P", 4, 0, 0 }, +{ L"+0X0.P", 5, 0, 0 }, +{ L"-0X0.P", 5, 0, 0 }, +{ L" 0X0.P", 14, 0, 0 }, +{ L" +0X0.P", 15, 0, 0 }, +{ L" -0X0.P", 15, 0, 0 }, + +#endif +{ L"0.12345678", 10, 0.12345678, 0 }, +{ L"+0.12345678", 11, +0.12345678, 0 }, +{ L"-0.12345678", 11, -0.12345678, 0 }, +{ L" 0.12345678", 15, 0.12345678, 0 }, +{ L" +0.12345678", 16, +0.12345678, 0 }, +{ L" -0.12345678", 16, -0.12345678, 0 }, + +{ L"0.12345E67", 10, 0.12345E67, 0 }, +{ L"+0.12345E67", 11, +0.12345E67, 0 }, +{ L"-0.12345E67", 11, -0.12345E67, 0 }, +{ L" 0.12345E67", 15, 0.12345E67, 0 }, +{ L" +0.12345E67", 16, +0.12345E67, 0 }, +{ L" -0.12345E67", 16, -0.12345E67, 0 }, + +{ L"0.12345E+6", 10, 0.12345E+6, 0 }, +{ L"+0.12345E+6", 11, +0.12345E+6, 0 }, +{ L"-0.12345E+6", 11, -0.12345E+6, 0 }, +{ L" 0.12345E+6", 15, 0.12345E+6, 0 }, +{ L" +0.12345E+6", 16, +0.12345E+6, 0 }, +{ L" -0.12345E+6", 16, -0.12345E+6, 0 }, + +{ L"0.98765E-4", 10, 0.98765E-4, 0 }, +{ L"+0.98765E-4", 11, +0.98765E-4, 0 }, +{ L"-0.98765E-4", 11, -0.98765E-4, 0 }, +{ L" 0.98765E-4", 15, 0.98765E-4, 0 }, +{ L" +0.98765E-4", 16, +0.98765E-4, 0 }, +{ L" -0.98765E-4", 16, -0.98765E-4, 0 }, + +{ L"12345678E9", 10, 12345678E9, 0 }, +{ L"+12345678E9", 11, +12345678E9, 0 }, +{ L"-12345678E9", 11, -12345678E9, 0 }, +{ L" 12345678E9", 15, 12345678E9, 0 }, +{ L" +12345678E9", 16, +12345678E9, 0 }, +{ L" -12345678E9", 16, -12345678E9, 0 }, + +/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */ +#if !defined(__SunOS__) +{ L"0x1P+2", 6, 4, 0 }, +{ L"+0x1P+2", 7, +4, 0 }, +{ L"-0x1P+2", 7, -4, 0 }, +{ L" 0x1P+2", 11, 4, 0 }, +{ L" +0x1P+2", 12, +4, 0 }, +{ L" -0x1P+2", 12, -4, 0 }, + +{ L"0x1.0P+2", 8, 4, 0 }, +{ L"+0x1.0P+2", 9, +4, 0 }, +{ L"-0x1.0P+2", 9, -4, 0 }, +{ L" 0x1.0P+2", 13, 4, 0 }, +{ L" +0x1.0P+2", 14, +4, 0 }, +{ L" -0x1.0P+2", 14, -4, 0 }, + +{ L"0x1P-2", 6, 0.25, 0 }, +{ L"+0x1P-2", 7, +0.25, 0 }, +{ L"-0x1P-2", 7, -0.25, 0 }, +{ L" 0x1P-2", 11, 0.25, 0 }, +{ L" +0x1P-2", 12, +0.25, 0 }, +{ L" -0x1P-2", 12, -0.25, 0 }, + +{ L"0x1.0P-2", 8, 0.25, 0 }, +{ L"+0x1.0P-2", 9, +0.25, 0 }, +{ L"-0x1.0P-2", 9, -0.25, 0 }, +{ L" 0x1.0P-2", 13, 0.25, 0 }, +{ L" +0x1.0P-2", 14, +0.25, 0 }, +{ L" -0x1.0P-2", 14, -0.25, 0 }, +#endif + +{ NULL, 0, 0, 0 } +}; +#endif /* !defined(__vax__) */ + +ATF_TC(wcstod); +ATF_TC_HEAD(wcstod, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks wcstod(3)"); +} +ATF_TC_BODY(wcstod, tc) +{ +#if defined(__vax__) +#else + struct test *t; +#endif + +#if !defined(__vax__) + for (t = &tests[0]; t->wcs != NULL; ++t) { + double d; + size_t n; + wchar_t *tail; + char *buf; + + /* we do not supported %ls nor %S yet. */ + n = wcstombs(NULL, t->wcs, 0); + ATF_REQUIRE((buf = (void *)malloc(n + 1)) != NULL); + (void)wcstombs(buf, t->wcs, n + 1); + (void)printf("Checking wcstod(\"%s\", &tail):\n", buf); + free(buf); + + errno = 0; + d = wcstod(t->wcs, &tail); + (void)printf("[errno]\n"); + (void)printf(" got : %s\n", strerror(errno)); + (void)printf(" expected: %s\n", strerror(t->err)); + ATF_REQUIRE_EQ(errno, t->err); + + n = (size_t)(tail - t->wcs); + (void)printf("[endptr - nptr]\n"); + (void)printf(" got : %zd\n", n); + (void)printf(" expected: %zd\n", t->len); + ATF_REQUIRE_EQ(n, t->len); + + (void)printf("[result]\n"); + (void)printf(" real: %F\n", d); + if (t->val == ALT_HUGE_VAL) { + (void)printf(" expected: %F\n", HUGE_VAL); + ATF_REQUIRE(isinf(d)); + ATF_REQUIRE_EQ(d, HUGE_VAL); + } else if (t->val == ALT_MINUS_HUGE_VAL) { + (void)printf(" expected: %F\n", -HUGE_VAL); + ATF_REQUIRE(isinf(d)); + ATF_REQUIRE_EQ(d, -HUGE_VAL); + } else if (t->val == ALT_NAN) { + (void)printf(" expected: %F\n", NAN); + ATF_REQUIRE(isnan(d)); + } else { + (void)printf(" expected: %F\n", t->val); + ATF_REQUIRE_EQ(d, t->val); + } + + (void)printf("\n"); + } +#else /* !defined(__vax__) */ + atf_tc_skip("Test is unavailable on vax."); +#endif /* !defined(__vax__) */ +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, wcstod); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c new file mode 100644 index 0000000..f553c8c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c @@ -0,0 +1,205 @@ +/* $NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2004 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <vis.h> +#include <wchar.h> +#include <string.h> +#include <limits.h> + +#include <atf-c.h> + +#define TC_WCTOMB 0 +#define TC_WCRTOMB 1 +#define TC_WCRTOMB_ST 2 + +static struct test { + const char *locale; + const char *data; + size_t wclen; + size_t mblen[16]; +} tests[] = { +{ + "ja_JP.ISO2022-JP", + "\x1b$B" /* JIS X 0208-1983 */ + "\x46\x7c\x4b\x5c\x38\x6c" /* "nihongo" */ + "\x1b(B" /* ISO 646 */ + "ABC" + "\x1b(I" /* JIS X 0201 katakana */ + "\xb1\xb2\xb3" /* "aiu" */ + "\x1b(B", /* ISO 646 */ + 3 + 3 + 3, + { 3+2, 2, 2, 3+1, 1, 1, 3+1, 1, 1, 3+1 } +}, { + "C", + "ABC", + 3, + { 1, 1, 1, 1 } +}, { NULL, NULL, 0, { } } +}; + +static void +h_wctomb(const struct test *t, char tc) +{ + wchar_t wcs[16 + 2]; + char buf[128]; + char cs[MB_LEN_MAX]; + const char *pcs; + char *str; + mbstate_t st; + mbstate_t *stp = NULL; + size_t sz, ret, i; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); + + (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking sequence: \"%s\"\n", buf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + if (tc == TC_WCRTOMB_ST) { + (void)memset(&st, 0, sizeof(st)); + stp = &st; + } + + wcs[t->wclen] = L'X'; /* poison */ + pcs = t->data; + sz = mbsrtowcs(wcs, &pcs, t->wclen + 2, NULL); + ATF_REQUIRE_EQ_MSG(sz, t->wclen, "mbsrtowcs() returned: " + "%zu, expected: %zu", sz, t->wclen); + ATF_REQUIRE_EQ(wcs[t->wclen], 0); + + for (i = 0; i < t->wclen + 1; i++) { + if (tc == TC_WCTOMB) + ret = wctomb(cs, wcs[i]); + else + ret = wcrtomb(cs, wcs[i], stp); + + if (ret == t->mblen[i]) + continue; + + (void)printf("At position %zd:\n", i); + (void)printf(" expected: %zd\n", t->mblen[i]); + (void)printf(" got : %zd\n", ret); + atf_tc_fail("Test failed"); + /* NOTREACHED */ + } + + (void)printf("Ok.\n"); +} + +ATF_TC(wctomb); +ATF_TC_HEAD(wctomb, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks wctomb(3)"); +} +ATF_TC_BODY(wctomb, tc) +{ + struct test *t; + + (void)printf("Checking wctomb()\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCTOMB); +} + +ATF_TC(wcrtomb_state); +ATF_TC_HEAD(wcrtomb_state, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wcrtomb(3) (using state object)"); +} +ATF_TC_BODY(wcrtomb_state, tc) +{ + struct test *t; + + (void)printf("Checking wcrtomb() (with state object)\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCRTOMB_ST); +} + +ATF_TC(wcrtomb); +ATF_TC_HEAD(wcrtomb, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wcrtomb(3) (using internal state)"); +} +ATF_TC_BODY(wcrtomb, tc) +{ + struct test *t; + + (void)printf("Checking wcrtomb() (using internal state)\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCRTOMB); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, wctomb); + ATF_TP_ADD_TC(tp, wcrtomb); + ATF_TP_ADD_TC(tp, wcrtomb_state); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/gen_ether_subr b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr new file mode 100755 index 0000000..9f9b63c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr @@ -0,0 +1,25 @@ +#!/bin/sh + +awk ' +BEGIN { + print + print "#include <ctype.h>" + print "#include <sys/types.h>" + print "#include <errno.h>" + print + print "#define ETHER_ADDR_LEN 6" + print + print "int ether_aton_r(u_char *dest, size_t len, const char *str);" + print +} +/^ether_aton_r/ { + print prevline + out = 1 +} +{ + if (out) print + else prevline = $0 +} +/^}$/ { + if (out) exit(0) +}' $1 >$2 diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README new file mode 100644 index 0000000..e856fe7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README @@ -0,0 +1,7 @@ +This test may fail if + + - your /etc/services file is not in sync with what this test expects + - your /etc/hosts file or DNS have unusual entries for "localhost" + (a duplicate "localhost 127.0.0.1" line in /etc/hosts for example) + +On kernels without IPv6 support some of the tests are skipped. diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp new file mode 100644 index 0000000..d2945f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp @@ -0,0 +1,36 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp new file mode 100644 index 0000000..0238f83 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp @@ -0,0 +1,42 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c new file mode 100644 index 0000000..939fcdb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c @@ -0,0 +1,186 @@ +/* $NetBSD: h_gai.c,v 1.1 2011/01/12 02:58:40 pgoyette Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <arpa/inet.h> + +struct addrinfo ai; + +char host[NI_MAXHOST]; +char serv[NI_MAXSERV]; +int vflag = 0; + +static void usage(void); +static void print1(const char *, const struct addrinfo *, char *, char *); +int main(int, char *[]); + +static void +usage() +{ + fprintf(stderr, "usage: test [-f family] [-s socktype] [-p proto] [-DPRSv46] host serv\n"); +} + +static void +print1(const char *title, const struct addrinfo *res, char *h, char *s) +{ + const char *start, *end; + int error; + const int niflag = NI_NUMERICHOST; + + if (res->ai_addr) { + error = getnameinfo(res->ai_addr, res->ai_addr->sa_len, + host, sizeof(host), serv, sizeof(serv), + niflag); + h = host; + s = serv; + } else + error = 0; + + if (vflag) { + start = "\t"; + end = "\n"; + } else { + start = " "; + end = ""; + } + printf("%s%s", title, end); + printf("%sflags 0x%x%s", start, res->ai_flags, end); + printf("%sfamily %d%s", start, res->ai_family, end); + printf("%ssocktype %d%s", start, res->ai_socktype, end); + printf("%sprotocol %d%s", start, res->ai_protocol, end); + printf("%saddrlen %d%s", start, res->ai_addrlen, end); + if (error) + printf("%serror %d%s", start, error, end); + else { + printf("%shost %s%s", start, h, end); + printf("%sserv %s%s", start, s, end); + } +#if 0 + if (res->ai_canonname) + printf("%scname \"%s\"%s", start, res->ai_canonname, end); +#endif + if (!vflag) + printf("\n"); + +} + +int +main(int argc, char *argv[]) +{ + struct addrinfo *res; + int error, i; + char *p, *q; + extern int optind; + extern char *optarg; + int c; + char nbuf[10]; + + memset(&ai, 0, sizeof(ai)); + ai.ai_family = PF_UNSPEC; + ai.ai_flags |= AI_CANONNAME; + while ((c = getopt(argc, argv, "Df:p:PRs:Sv46")) != -1) { + switch (c) { + case 'D': + ai.ai_socktype = SOCK_DGRAM; + break; + case 'f': + ai.ai_family = atoi(optarg); + break; + case 'p': + ai.ai_protocol = atoi(optarg); + break; + case 'P': + ai.ai_flags |= AI_PASSIVE; + break; + case 'R': + ai.ai_socktype = SOCK_RAW; + break; + case 's': + ai.ai_socktype = atoi(optarg); + break; + case 'S': + ai.ai_socktype = SOCK_STREAM; + break; + case 'v': + vflag++; + break; + case '4': + ai.ai_family = PF_INET; + break; + case '6': + ai.ai_family = PF_INET6; + break; + default: + usage(); + exit(1); + } + } + argc -= optind; + argv += optind; + + if (argc != 2){ + usage(); + exit(1); + } + + p = *argv[0] ? argv[0] : NULL; + q = *argv[1] ? argv[1] : NULL; + + strncpy(nbuf, "(empty)", sizeof(nbuf)); + print1("arg:", &ai, p ? p : nbuf , q ? q : nbuf); + + error = getaddrinfo(p, q, &ai, &res); + if (error) { + printf("%s\n", gai_strerror(error)); + exit(1); + } + + i = 1; + do { + snprintf(nbuf, sizeof(nbuf), "ai%d:", i); + print1(nbuf, res, NULL, NULL); + + i++; + } while ((res = res->ai_next) != NULL); + printf("\n"); + + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp new file mode 100644 index 0000000..21059c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp @@ -0,0 +1,38 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp new file mode 100644 index 0000000..7d30fea --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp @@ -0,0 +1,56 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv echo +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv echo +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv tftp +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv tftp +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp new file mode 100644 index 0000000..9de5c56 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp @@ -0,0 +1,14 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty) +hostname nor servname provided, or not known diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp new file mode 100644 index 0000000..1df5663 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp @@ -0,0 +1,16 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty) +hostname nor servname provided, or not known diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp new file mode 100644 index 0000000..d06d163 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp @@ -0,0 +1,4 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host fe80::1%lo0 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host fe80::1%lo0 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host fe80::1%lo0 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp new file mode 100644 index 0000000..bc850e0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp @@ -0,0 +1,13 @@ +arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80 +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp new file mode 100644 index 0000000..a4f2fb8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp @@ -0,0 +1,15 @@ +arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 0 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80 +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp new file mode 100644 index 0000000..1c0ce43 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp @@ -0,0 +1,6 @@ +arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http +No address associated with hostname diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp new file mode 100644 index 0000000..e24036e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp @@ -0,0 +1,8 @@ +arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh new file mode 100755 index 0000000..94a3c0b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh @@ -0,0 +1,198 @@ +# $NetBSD: t_getaddrinfo.sh,v 1.2 2011/06/15 07:54:32 jmmv Exp $ + +# +# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +check_output() +{ + if [ "$2" = "none" ] ; then + exp="${1}.exp" + elif [ "$2" = "hosts" ] ; then + # Determine if localhost has an IPv6 address or not + lcl=$( cat /etc/hosts | \ + sed -e 's/#.*$//' -e 's/[ ][ ]*/ /g' | \ + awk '/ localhost($| )/ {printf "%s ", $1}' ) + if [ "${lcl%*::*}" = "${lcl}" ] ; then + exp="${1}_v4.exp" + else + exp="${1}_v4v6.exp" + fi + elif [ "$2" = "ifconfig" ] ; then + lcl=$( ifconfig lo0 | grep inet6 ) + if [ -n "${lcl}" ] ; then + exp="${1}_v4v6.exp" + else + exp="${1}_v4.exp" + fi + else + atf_fail "Invalid family_match_type $2 requested." + fi + + cmp -s $(atf_get_srcdir)/data/${exp} out && return + diff -u $(atf_get_srcdir)/data/${exp} out && \ + atf_fail "Actual output does not match expected output" +} + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Testing basic ones" +} +basic_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST ::1 http + $TEST 127.0.0.1 http + $TEST localhost http + $TEST ::1 tftp + $TEST 127.0.0.1 tftp + $TEST localhost tftp + $TEST ::1 echo + $TEST 127.0.0.1 echo + $TEST localhost echo ) > out 2>&1 + + check_output basics hosts +} + +atf_test_case specific +specific_head() +{ + atf_set "descr" "Testing specific address family" +} +specific_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -4 localhost http + $TEST -6 localhost http ) > out 2>&1 + + check_output spec_fam hosts +} + +atf_test_case empty_hostname +empty_hostname_head() +{ + atf_set "descr" "Testing empty hostname" +} +empty_hostname_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST '' http + $TEST '' echo + $TEST '' tftp + $TEST '' 80 + $TEST -P '' http + $TEST -P '' echo + $TEST -P '' tftp + $TEST -P '' 80 + $TEST -S '' 80 + $TEST -D '' 80 ) > out 2>&1 + + check_output no_host ifconfig +} + +atf_test_case empty_servname +empty_servname_head() +{ + atf_set "descr" "Testing empty service name" +} +empty_servname_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST ::1 '' + $TEST 127.0.0.1 '' + $TEST localhost '' + $TEST '' '' ) > out 2>&1 + + check_output no_serv hosts +} + +atf_test_case sock_raw +sock_raw_head() +{ + atf_set "descr" "Testing raw socket" +} +sock_raw_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -R -p 0 localhost '' + $TEST -R -p 59 localhost '' + $TEST -R -p 59 localhost 80 + $TEST -R -p 59 localhost www + $TEST -R -p 59 ::1 '' ) > out 2>&1 + + check_output sock_raw hosts +} + +atf_test_case unsupported_family +unsupported_family_head() +{ + atf_set "descr" "Testing unsupported family" +} +unsupported_family_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -f 99 localhost '' ) > out 2>&1 + + check_output unsup_fam none +} + +atf_test_case scopeaddr +scopeaddr_head() +{ + atf_set "descr" "Testing scoped address format" +} +scopeaddr_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST fe80::1%lo0 http +# IF=`ifconfig -a | grep -v '^ ' | \ +# sed -e 's/:.*//' | head -1 | awk '{print $1}'` +# $TEST fe80::1%$IF http + ) > out 2>&1 + + check_output scoped none +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case specific + atf_add_test_case empty_hostname + atf_add_test_case empty_servname + atf_add_test_case sock_raw + atf_add_test_case unsupported_family + atf_add_test_case scopeaddr +} diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp new file mode 100644 index 0000000..b6133c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp @@ -0,0 +1,2 @@ +arg: flags 0x2 family 99 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai_family not supported diff --git a/contrib/netbsd-tests/lib/libc/net/h_dns_server.c b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c new file mode 100644 index 0000000..47472de --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c @@ -0,0 +1,298 @@ +/* $NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andreas Gustafsson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * A minimal DNS server capable of providing canned answers to the + * specific queries issued by t_hostent.sh and nothing more. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $"); + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <memory.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <sys/socket.h> + +#include <netinet/in.h> +#include <netinet6/in6.h> + +union sockaddr_either { + struct sockaddr s; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; +}; + +#ifdef DEBUG +#define DPRINTF(...) fprintf(stderr, __VA_ARGS__) +#else +#define DPRINTF(...) +#endif + +/* A DNS question and its corresponding answer */ + +struct dns_data { + size_t qname_size; + const char *qname; /* Wire-encode question name */ + int qtype; + size_t answer_size; + const char *answer; /* One wire-encoded answer RDATA */ +}; + +/* Convert C string constant to length + data pair */ +#define STR_DATA(s) sizeof(s) - 1, s + +/* Canned DNS queestion-answer pairs */ +struct dns_data data[] = { + /* Forward mappings */ + /* localhost IN A -> 127.0.0.1 */ + { STR_DATA("\011localhost\000"), 1, + STR_DATA("\177\000\000\001") }, + /* localhost IN AAAA -> ::1 */ + { STR_DATA("\011localhost\000"), 28, + STR_DATA("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001") }, + /* sixthavenue.astron.com IN A -> 38.117.134.16 */ + { STR_DATA("\013sixthavenue\006astron\003com\000"), 1, + STR_DATA("\046\165\206\020") }, + /* sixthavenue.astron.com IN AAAA -> 2620:106:3003:1f00:3e4a:92ff:fef4:e180 */ + { STR_DATA("\013sixthavenue\006astron\003com\000"), 28, + STR_DATA("\x26\x20\x01\x06\x30\x03\x1f\x00\x3e\x4a\x92\xff\xfe\xf4\xe1\x80") }, + /* Reverse mappings */ + { STR_DATA("\0011\0010\0010\003127\007in-addr\004arpa\000"), 12, + STR_DATA("\011localhost\000") }, + { STR_DATA("\0011\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\003ip6\004arpa\000"), 12, + STR_DATA("\011localhost\000") }, + { STR_DATA("\00216\003134\003117\00238" + "\007in-addr\004arpa\000"), 12, + STR_DATA("\013sixthavenue\006astron\003com\000") }, + { STR_DATA("\0010\0018\0011\001e\0014\001f\001e\001f" + "\001f\001f\0012\0019\001a\0014\001e\0013" + "\0010\0010\001f\0011\0013\0010\0010\0013" + "\0016\0010\0011\0010\0010\0012\0016\0012" + "\003ip6\004arpa\000"), 12, + STR_DATA("\013sixthavenue\006astron\003com\000") }, + /* End marker */ + { STR_DATA(""), 0, STR_DATA("") } +}; + +/* + * Compare two DNS names for equality. If equal, return their + * length, and if not, return zero. Does not handle compression. + */ +static int +name_eq(const unsigned char *a, const unsigned char *b) { + const unsigned char *a_save = a; + for (;;) { + int i; + int lena = *a++; + int lenb = *b++; + if (lena != lenb) + return 0; + if (lena == 0) + return a - a_save; + for (i = 0; i < lena; i++) + if (tolower(a[i]) != tolower(b[i])) + return 0; + a += lena; + b += lena; + } +} + +#ifdef DEBUG +static char * +name2str(const void *v, char *buf, size_t buflen) { + const unsigned char *a = v; + char *b = buf; + char *eb = buf + buflen; + +#define ADDC(c) do { \ + if (b < eb) \ + *b++ = c; \ + else \ + return NULL; \ + } while (/*CONSTCOND*/0) + for (int did = 0;; did++) { + int lena = *a++; + if (lena == 0) { + ADDC('\0'); + return buf; + } + if (did) + ADDC('.'); + for (int i = 0; i < lena; i++) + ADDC(a[i]); + a += lena; + } +} +#endif + +int main(int argc, char **argv) { + int s, r, protocol; + union sockaddr_either saddr; + struct dns_data *dp; + unsigned char *p; + char pidfile_name[40]; + FILE *f; + int one = 1; +#ifdef DEBUG + char buf1[1024], buf2[1024]; +#endif + + if (argc < 2 || ((protocol = argv[1][0]) != '4' && protocol != '6')) + errx(1, "usage: dns_server 4 | 6"); + s = socket(protocol == '4' ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (s < 0) + err(1, "socket"); + if (protocol == '4') { + memset(&saddr.sin, 0, sizeof(saddr.sin)); + saddr.sin.sin_family = AF_INET; + saddr.sin.sin_len = sizeof(saddr.sin); + saddr.sin.sin_port = htons(53); + saddr.sin.sin_addr.s_addr = INADDR_ANY; + } else { + static struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT; + memset(&saddr.sin6, 0, sizeof(saddr.sin6)); + saddr.sin6.sin6_family = AF_INET6; + saddr.sin6.sin6_len = sizeof(saddr.sin6); + saddr.sin6.sin6_port = htons(53); + saddr.sin6.sin6_addr = loopback; + } + + r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); + if (r < 0) + err(1, "setsockopt"); + + r = bind(s, + (struct sockaddr *) &saddr, + protocol == '4' ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); + if (r < 0) + err(1, "bind"); + + snprintf(pidfile_name, sizeof pidfile_name, + "dns_server_%c.pid", protocol); + f = fopen(pidfile_name, "w"); + fprintf(f, "%d", getpid()); + fclose(f); +#ifdef DEBUG + daemon(0, 1); +#else + daemon(0, 0); +#endif + + for (;;) { + unsigned char buf[512]; + union sockaddr_either from; + ssize_t nrecv, nsent; + socklen_t fromlen = + protocol == '4' ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6); + memset(buf, 0, sizeof buf); + nrecv = recvfrom(s, buf, sizeof buf, 0, &from.s, &fromlen); + if (nrecv < 0) + err(1, "recvfrom"); + if (nrecv < 12) { + DPRINTF("Too short %zd\n", nrecv); + continue; + } + if ((buf[2] & 0x80) != 0) { + DPRINTF("Not a query 0x%x\n", buf[2]); + continue; + } + if (!(buf[4] == 0 && buf[5] == 1)) { + DPRINTF("QCOUNT is not 1 0x%x 0x%x\n", buf[4], buf[5]); + continue; /* QDCOUNT is not 1 */ + } + + for (dp = data; dp->qname_size != 0; dp++) { + int qtype, qclass; + p = buf + 12; /* Point to QNAME */ + int n = name_eq(p, (const unsigned char *) dp->qname); + if (n == 0) { + DPRINTF("no match name %s != %s\n", + name2str(p, buf1, sizeof(buf1)), + name2str(dp->qname, buf2, sizeof(buf2))); + continue; /* Name does not match */ + } + DPRINTF("match name %s\n", + name2str(p, buf1, sizeof(buf1))); + p += n; /* Skip QNAME */ + qtype = *p++ << 8; + qtype |= *p++; + if (qtype != dp->qtype) { + DPRINTF("no match name 0x%x != 0x%x\n", + qtype, dp->qtype); + continue; + } + DPRINTF("match type 0x%x\n", qtype); + qclass = *p++ << 8; + qclass |= *p++; + if (qclass != 1) { /* IN */ + DPRINTF("no match class %d != 1\n", qclass); + continue; + } + DPRINTF("match class %d\n", qclass); + goto found; + } + continue; + found: + buf[2] |= 0x80; /* QR */ + buf[3] |= 0x80; /* RA */ + memset(buf + 6, 0, 6); /* Clear ANCOUNT, NSCOUNT, ARCOUNT */ + buf[7] = 1; /* ANCOUNT */ + memcpy(p, dp->qname, dp->qname_size); + p += dp->qname_size; + *p++ = dp->qtype >> 8; + *p++ = dp->qtype & 0xFF; + *p++ = 0; + *p++ = 1; /* IN */ + memset(p, 0, 4); /* TTL = 0 */ + p += 4; + *p++ = 0; /* RDLENGTH MSB */ + *p++ = dp->answer_size; /* RDLENGTH LSB */ + memcpy(p, dp->answer, dp->answer_size); + p += dp->answer_size; + nsent = sendto(s, buf, p - buf, 0, &from.s, fromlen); + DPRINTF("sent %zd\n", nsent); + if (nsent != p - buf) + warn("sendto"); + } +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_hostent.c b/contrib/netbsd-tests/lib/libc/net/h_hostent.c new file mode 100644 index 0000000..4a72923 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_hostent.c @@ -0,0 +1,195 @@ +/* $NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $"); + +#include <stdio.h> +#include <string.h> +#include <nsswitch.h> +#include <netdb.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> + +#include <netinet/in.h> +#include <sys/types.h> +#include <arpa/nameser.h> +#include <arpa/inet.h> + +#include "hostent.h" + +extern const char *__res_conf_name; + +static void +phostent(const struct hostent *h) +{ + size_t i; + char buf[1024]; + const int af = h->h_length == NS_INADDRSZ ? AF_INET : AF_INET6; + + printf("name=%s, length=%d, addrtype=%d, aliases=[", + h->h_name, h->h_length, h->h_addrtype); + + for (i = 0; h->h_aliases[i]; i++) + printf("%s%s", i == 0 ? "" : " ", h->h_aliases[i]); + + printf("] addr_list=["); + + for (i = 0; h->h_addr_list[i]; i++) + printf("%s%s", i == 0 ? "" : " ", inet_ntop(af, + h->h_addr_list[i], buf, (socklen_t)sizeof(buf))); + + printf("]\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s [-f <hostsfile>] " + "[-t <any|dns|nis|files>] " + "[-46a] <name|address>\n", getprogname()); + exit(EXIT_FAILURE); +} + +static void +getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...) +{ + va_list ap; + int e; + + va_start(ap, info); + e = (*f)(info, NULL, ap); + va_end(ap); + switch (e) { + case NS_SUCCESS: + phostent(info->hp); + break; + default: + printf("error %d\n", e); + break; + } +} + +static void +geta(struct hostent *hp) { + if (hp == NULL) + printf("error %d\n", h_errno); + else + phostent(hp); +} + +int +main(int argc, char *argv[]) +{ + int (*f)(void *, void *, va_list) = NULL; + const char *type = "any"; + int c, af, e, byaddr, len; + struct hostent hent; + struct getnamaddr info; + char buf[4096]; + + af = AF_INET; + byaddr = 0; + len = 0; + info.hp = &hent; + info.buf = buf; + info.buflen = sizeof(buf); + info.he = &e; + + while ((c = getopt(argc, argv, "46af:r:t:")) != -1) { + switch (c) { + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; + case 'a': + byaddr++; + break; + case 'f': + _hf_sethostsfile(optarg); + break; + case 'r': + __res_conf_name = optarg; + break; + case 't': + type = optarg; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + switch (*type) { + case 'a': + break; + case 'd': + f = byaddr ? _dns_gethtbyaddr : _dns_gethtbyname; + break; +#ifdef YP + case 'n': + f = byaddr ? _yp_gethtbyaddr : _yp_gethtbyname; + break; +#endif + case 'f': + f = byaddr ? _hf_gethtbyaddr : _hf_gethtbyname; + break; + default: + errx(EXIT_FAILURE, "Unknown db type `%s'", type); + } + + if (byaddr) { + struct in6_addr addr; + af = strchr(*argv, ':') ? AF_INET6 : AF_INET; + len = af == AF_INET ? NS_INADDRSZ : NS_IN6ADDRSZ; + if (inet_pton(af, *argv, &addr) == -1) + err(EXIT_FAILURE, "Can't parse `%s'", *argv); + if (*type == 'a') + geta(gethostbyaddr((const char *)&addr, len, af)); + else + getby(f, &info, &addr, len, af); + } else { + if (*type == 'a') + geta(gethostbyname2(*argv, af)); + else + getby(f, &info, *argv, len, af); + } + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c new file mode 100644 index 0000000..2f315d2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c @@ -0,0 +1,107 @@ +/* $NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $"); + +#define _REENTRANT + +#include <assert.h> +#include <nsswitch.h> +#include <pthread.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +static const ns_src testsrc[] = { + { "test", NS_SUCCESS }, + { NULL, 0 } +}; + +static int +func3(void *rv, void *cb_data, va_list ap) +{ + (void)printf("func3: enter\n"); + (void)printf("func3: exit\n"); + + return NS_SUCCESS; +} + +static int +func2(void *rv, void *cb_data, va_list ap) +{ + static const ns_dtab dtab[] = { + { "test", func3, NULL }, + { NULL, NULL, NULL } + }; + int r; + + (void)printf("func2: enter\n"); + r = nsdispatch(NULL, dtab, "test", "test", testsrc); + (void)printf("func2: exit\n"); + + return r; +} + +static int +func1(void) +{ + static const ns_dtab dtab[] = { + { "test", func2, NULL }, + { NULL, NULL, NULL } + }; + int r; + + (void)printf("func1: enter\n"); + r = nsdispatch(NULL, dtab, "test", "test", testsrc); + (void)printf("func1: exit\n"); + + return r; +} + +static void * +thrfunc(void *arg) +{ + pthread_exit(NULL); +} + +int +main(int argc, char *argv[]) +{ + pthread_t thr; + void *threval; + + assert(pthread_create(&thr, NULL, thrfunc, NULL) == 0); + assert(func1() == NS_SUCCESS); + assert(pthread_join(thr, &threval) == 0); +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_protoent.c b/contrib/netbsd-tests/lib/libc/net/h_protoent.c new file mode 100644 index 0000000..f37a85c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_protoent.c @@ -0,0 +1,97 @@ +/* $NetBSD: h_protoent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <netdb.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <stdio.h> + +static void +pserv(const struct protoent *prp) +{ + char **pp; + + printf("name=%s, proto=%d, aliases=", + prp->p_name, prp->p_proto); + for (pp = prp->p_aliases; *pp; pp++) + printf("%s ", *pp); + printf("\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s\n" + "\t%s -p <proto>\n" + "\t%s -n <name>\n", getprogname(), getprogname(), + getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct protoent *prp; + const char *proto = NULL, *name = NULL; + int c; + + while ((c = getopt(argc, argv, "p:n:")) != -1) { + switch (c) { + case 'n': + name = optarg; + break; + case 'p': + proto = optarg; + break; + default: + usage(); + } + } + + if (proto && name) + usage(); + if (proto) { + if ((prp = getprotobynumber(atoi(proto))) != NULL) + pserv(prp); + return 0; + } + if (name) { + if ((prp = getprotobyname(name)) != NULL) + pserv(prp); + return 0; + } + + setprotoent(0); + while ((prp = getprotoent()) != NULL) + pserv(prp); + endprotoent(); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_servent.c b/contrib/netbsd-tests/lib/libc/net/h_servent.c new file mode 100644 index 0000000..6d7efd8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_servent.c @@ -0,0 +1,100 @@ +/* $NetBSD: h_servent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <netdb.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <stdio.h> + +static void +pserv(const struct servent *svp) +{ + char **pp; + + printf("name=%s, port=%d, proto=%s, aliases=", + svp->s_name, ntohs((uint16_t)svp->s_port), svp->s_proto); + for (pp = svp->s_aliases; *pp; pp++) + printf("%s ", *pp); + printf("\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s\n" + "\t%s -p <port> [-P <proto>]\n" + "\t%s -n <name> [-P <proto>]\n", getprogname(), getprogname(), + getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct servent *svp; + const char *port = NULL, *proto = NULL, *name = NULL; + int c; + + while ((c = getopt(argc, argv, "p:n:P:")) != -1) { + switch (c) { + case 'n': + name = optarg; + break; + case 'p': + port = optarg; + break; + case 'P': + proto = optarg; + break; + default: + usage(); + } + } + + if (port && name) + usage(); + if (port) { + if ((svp = getservbyport(htons(atoi(port)), proto)) != NULL) + pserv(svp); + return 0; + } + if (name) { + if ((svp = getservbyname(name, proto)) != NULL) + pserv(svp); + return 0; + } + + setservent(0); + while ((svp = getservent()) != NULL) + pserv(svp); + endservent(); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/hosts b/contrib/netbsd-tests/lib/libc/net/hosts new file mode 100644 index 0000000..87ccbe8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/hosts @@ -0,0 +1,11 @@ +# $NetBSD: hosts,v 1.1 2013/08/16 15:29:45 christos Exp $ +# +# Host Database +# This file should contain the addresses and aliases +# for local hosts that share this file. +# It is used only for "ifconfig" and other operations +# before the nameserver is started. +# +# +::1 localhost localhost. localhost.localdomain. +127.0.0.1 localhost localhost. localhost.localdomain. diff --git a/contrib/netbsd-tests/lib/libc/net/resolv.conf b/contrib/netbsd-tests/lib/libc/net/resolv.conf new file mode 100644 index 0000000..bbc8559 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/resolv.conf @@ -0,0 +1 @@ +nameserver 127.0.0.1 diff --git a/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c new file mode 100644 index 0000000..6ca3c5b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c @@ -0,0 +1,104 @@ +/* $NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <err.h> +#include <string.h> +#include <errno.h> + +#define ETHER_ADDR_LEN 6 + +int ether_aton_r(u_char *dest, size_t len, const char *str); + +static const struct { + u_char res[ETHER_ADDR_LEN]; + const char *str; + int error; +} tests[] = { + { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }, "01:23:45:67:89:ab", 0 }, + { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "0:1:22-3:14:05", 0 }, + { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "000122031405", 0 }, + { { 0x0a, 0x0B, 0xcc, 0xdD, 0xEE, 0x0f }, "0a0BccdDEE0f", 0 }, +#define ZERO { 0, 0, 0, 0, 0, 0 } + { ZERO, "0:1:2-3:04:05:06", ENAMETOOLONG }, + { ZERO, "0:1:2-3:04:", ENOBUFS }, + { ZERO, "0:1:2-3:04:x7", EINVAL }, + { ZERO, "1:x-3:04:05:7", EINVAL }, + { ZERO, NULL, 0 }, +}; + +ATF_TC(tc_ether_aton); +ATF_TC_HEAD(tc_ether_aton, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that ether_aton(3) works"); +} + +ATF_TC_BODY(tc_ether_aton, tc) +{ + u_char dest[ETHER_ADDR_LEN]; + size_t t; + int e, r; + const char *s; + + for (t = 0; tests[t].str; t++) { + s = tests[t].str; + if ((e = tests[t].error) == 0) { + if (ether_aton_r(dest, sizeof(dest), s) != e) + atf_tc_fail("failed on `%s'", s); + if (memcmp(dest, tests[t].res, sizeof(dest)) != 0) + atf_tc_fail("unexpected result on `%s'", s); + } else { + if ((r = ether_aton_r(dest, sizeof(dest), s)) != e) + atf_tc_fail("unexpectedly succeeded on `%s' " + "(%d != %d)", s, r, e); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tc_ether_aton); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c new file mode 100644 index 0000000..1c1a0e0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c @@ -0,0 +1,233 @@ +/* $NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $"); + +#include <atf-c.h> +#include <netdb.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> + +static const struct { + const char *name; + int number; +} protos[] = { + + { "icmp", 1 }, { "tcp", 6 }, { "udp", 17 }, { "gre", 47 }, + { "esp", 50 }, { "ah", 51 }, { "sctp", 132}, { "ipv6-icmp", 58 } +}; + +ATF_TC(endprotoent_rewind); +ATF_TC_HEAD(endprotoent_rewind, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that endprotoent(3) rewinds"); +} + +ATF_TC_BODY(endprotoent_rewind, tc) +{ + struct protoent *p; + int i = 0; + + setprotoent(0); + + while ((p = getprotoent()) != NULL && i <= 10) { + ATF_REQUIRE(p->p_proto == i); + i++; + } + + i = 0; + endprotoent(); + + while ((p = getprotoent()) != NULL && i <= 10) { + ATF_REQUIRE(p->p_proto == i); + i++; + } + + endprotoent(); +} + +ATF_TC(getprotobyname_basic); +ATF_TC_HEAD(getprotobyname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of getprotobyname(3)"); +} + +ATF_TC_BODY(getprotobyname_basic, tc) +{ + struct protoent *p; + size_t i; + + for (i = 0; i < __arraycount(protos); i++) { + + p = getprotobyname(protos[i].name); + + ATF_REQUIRE(p != NULL); + ATF_REQUIRE(p->p_proto == protos[i].number); + ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0); + } + + endprotoent(); +} + +ATF_TC(getprotobyname_err); +ATF_TC_HEAD(getprotobyname_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobyname(3)"); +} + +ATF_TC_BODY(getprotobyname_err, tc) +{ + static const char * name[] = + { "xxx", "yyy", "xyz", ".as.d}9x.._?!!#\xa4,\xa8^//&%%,", + "0", "", "tCp", "uDp", "t c p", "tcp ", " tcp" }; + + size_t i; + + for (i = 0; i < __arraycount(name); i++) + ATF_REQUIRE(getprotobyname(name[i]) == NULL); + + endprotoent(); +} + +ATF_TC(getprotobynumber_basic); +ATF_TC_HEAD(getprotobynumber_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of getprotobynumber(3)"); +} + +ATF_TC_BODY(getprotobynumber_basic, tc) +{ + struct protoent *p; + size_t i; + + /* + * No ATF_CHECK() due static storage. + */ + for (i = 0; i < __arraycount(protos); i++) { + + p = getprotobynumber(protos[i].number); + + ATF_REQUIRE(p != NULL); + ATF_REQUIRE(p->p_proto == protos[i].number); + ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0); + } + + endprotoent(); +} + +ATF_TC(getprotobynumber_err); +ATF_TC_HEAD(getprotobynumber_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobynumber(3)"); +} + +ATF_TC_BODY(getprotobynumber_err, tc) +{ + static const int number[] = { -1, -99999, INT_MAX, 1000000000 }; + size_t i; + + for (i = 0; i < __arraycount(number); i++) + ATF_REQUIRE(getprotobynumber(number[i]) == NULL); + + endprotoent(); +} + +ATF_TC(getprotoent_next); +ATF_TC_HEAD(getprotoent_next, tc) +{ + atf_tc_set_md_var(tc, "descr", "getprotoent(3) returns next line?"); +} + +ATF_TC_BODY(getprotoent_next, tc) +{ + struct protoent *p; + int i = 0; + + /* + * The range [0, 60] is already reserved by IANA. + */ + while ((p = getprotoent()) != NULL && i <= 60) { + ATF_CHECK(p->p_proto == i); + i++; + } + + endprotoent(); +} + +ATF_TC(setprotoent_rewind); +ATF_TC_HEAD(setprotoent_rewind, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that setprotoent(3) rewinds"); +} + +ATF_TC_BODY(setprotoent_rewind, tc) +{ + struct protoent *p; + + setprotoent(0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 1); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 2); + + setprotoent(0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 1); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 2); + + endprotoent(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getprotobyname_basic); + ATF_TP_ADD_TC(tp, getprotobyname_err); + ATF_TP_ADD_TC(tp, getprotobynumber_basic); + ATF_TP_ADD_TC(tp, getprotobynumber_err); + ATF_TP_ADD_TC(tp, endprotoent_rewind); + ATF_TP_ADD_TC(tp, getprotoent_next); + ATF_TP_ADD_TC(tp, setprotoent_rewind); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_hostent.sh b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh new file mode 100755 index 0000000..b597b6d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh @@ -0,0 +1,240 @@ +# $NetBSD: t_hostent.sh,v 1.10 2014/01/13 11:08:14 gson Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +n6="sixthavenue.astron.com" +a6="2620:106:3003:1f00:3e4a:92ff:fef4:e180" +ans6="name=$n6, length=16, addrtype=24, aliases=[] addr_list=[$a6]\n" + +n4="sixthavenue.astron.com" +a4="38.117.134.16" +ans4="name=$n4, length=4, addrtype=2, aliases=[] addr_list=[$a4]\n" + +l6="localhost" +al6="::1" +loc6="name=$l6, length=16, addrtype=24, aliases=[localhost. localhost.localdomain.] addr_list=[$al6]\n" + +l4="localhost" +al4="127.0.0.1" +loc4="name=$l4, length=4, addrtype=2, aliases=[localhost. localhost.localdomain.] addr_list=[$al4]\n" + +dir="$(atf_get_srcdir)" +res="-r ${dir}/resolv.conf" + +# Hijack DNS traffic using a single rump server instance and a DNS +# server listening on its loopback address. + +start_dns_server() { + export RUMP_SERVER=unix:///tmp/rumpserver + rump_server -lrumpdev -lrumpnet -lrumpnet_net -lrumpnet_netinet \ + -lrumpnet_netinet6 -lrumpnet_local $RUMP_SERVER + HIJACK_DNS="LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK='socket=inet:inet6'" + eval $HIJACK_DNS ${dir}/h_dns_server $1 +} + +stop_dns_server() { + export RUMP_SERVER=unix:///tmp/rumpserver + kill $(cat dns_server_$1.pid) + rump.halt +} + +atf_test_case gethostbyname4 cleanup +gethostbyname4_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyname4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -4 $n4" +} +gethostbyname4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyname6 cleanup cleanup +gethostbyname6_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyname6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -6 $n6" +} +gethostbyname6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyaddr4 cleanup +gethostbyaddr4_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a4" +} +gethostbyaddr4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyaddr6 cleanup +gethostbyaddr6_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a6" +} +gethostbyaddr6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case hostsbynamelookup4 +hostsbynamelookup4_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET" +} +hostsbynamelookup4_body() +{ + atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 $l4" +} + +atf_test_case hostsbynamelookup6 +hostsbynamelookup6_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET6" +} +hostsbynamelookup6_body() +{ + atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 $l6" +} + +atf_test_case hostsbyaddrlookup4 +hostsbyaddrlookup4_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET" +} +hostsbyaddrlookup4_body() +{ + atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 -a $al4" +} + +atf_test_case hostsbyaddrlookup6 +hostsbyaddrlookup6_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET6" +} +hostsbyaddrlookup6_body() +{ + atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 -a $al6" +} + +atf_test_case dnsbynamelookup4 cleanup +dnsbynamelookup4_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET" +} +dnsbynamelookup4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 $n4" +} +dnsbynamelookup4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbynamelookup6 cleanup +dnsbynamelookup6_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET6" +} +dnsbynamelookup6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 $n6" +} +dnsbynamelookup6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbyaddrlookup4 cleanup +dnsbyaddrlookup4_head() +{ + atf_set "descr" "Checks DNS address lookup for AF_INET" +} +dnsbyaddrlookup4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 -a $a4" +} +dnsbyaddrlookup4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbyaddrlookup6 cleanup +dnsbyaddrlookup6_head() +{ + atf_set "descr" "Checks dns address lookup for AF_INET6" +} +dnsbyaddrlookup6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 -a $a6" +} +dnsbyaddrlookup6_cleanup() +{ + stop_dns_server 4 +} + +atf_init_test_cases() +{ + atf_add_test_case gethostbyname4 + atf_add_test_case gethostbyname6 + atf_add_test_case gethostbyaddr4 + atf_add_test_case gethostbyaddr6 + + atf_add_test_case hostsbynamelookup4 + atf_add_test_case hostsbynamelookup6 + atf_add_test_case hostsbyaddrlookup4 + atf_add_test_case hostsbyaddrlookup6 + + atf_add_test_case dnsbynamelookup4 + atf_add_test_case dnsbynamelookup6 + atf_add_test_case dnsbyaddrlookup4 + atf_add_test_case dnsbyaddrlookup6 +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh new file mode 100755 index 0000000..b584369 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh @@ -0,0 +1,51 @@ +# $NetBSD: t_nsdispatch.sh,v 1.1 2011/01/13 01:56:44 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case recurse +recurse_head() +{ + atf_set "descr" "Checks recursive calls to nsdispatch()" \ + "within threaded program" +} +recurse_body() +{ + cat >exp <<EOF +func1: enter +func2: enter +func3: enter +func3: exit +func2: exit +func1: exit +EOF + + atf_check -o file:exp "$(atf_get_srcdir)/h_nsd_recurse" +} + +atf_init_test_cases() +{ + atf_add_test_case recurse +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_protoent.sh b/contrib/netbsd-tests/lib/libc/net/t_protoent.sh new file mode 100755 index 0000000..322d426 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_protoent.sh @@ -0,0 +1,91 @@ +# $NetBSD: t_protoent.sh,v 1.2 2012/09/03 15:32:18 christos Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case protoent +protoent_head() +{ + atf_set "descr" "Checks {get,set,end}protoent(3)" +} +protoent_body() +{ + # + # Munge original to: + # (1) match output format of the test program + # (2) fold all names for the same port/proto together + # (3) prune duplicates + # + tr '\t' ' ' </etc/protocols | awk ' + function add(key, name, i, n, ar) { + n = split(names[key], ar); + for (i = 1; i <= n; i++) { + if (name == ar[i]) { + return; + } + } + delete ar; + names[key] = names[key] " " name; + } + { + sub("#.*", "", $0); + gsub(" *", " ", $0); + if (NF == 0) { + next; + } + add($2, $1, 0); + for (i = 3; i <= NF; i++) { + add($2, $i, 1); + } + } + END { + for (key in names) { + proto = key; + + n = split(names[key], ar); + printf "name=%s, proto=%s, aliases=", ar[1], proto; + for (i=2; i<=n; i++) { + if (i>2) { + printf " "; + } + printf "%s", ar[i]; + } + printf "\n"; + delete ar; + } + } + ' | sort >exp + + # run test program + "$(atf_get_srcdir)/h_protoent" | sed 's/ *$//' | sort >out + + diff -u exp out || \ + atf_fail "Observed output does not match reference output" +} + +atf_init_test_cases() +{ + atf_add_test_case protoent +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_servent.sh b/contrib/netbsd-tests/lib/libc/net/t_servent.sh new file mode 100755 index 0000000..b9aa2b7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_servent.sh @@ -0,0 +1,93 @@ +# $NetBSD: t_servent.sh,v 1.1 2011/01/12 17:32:27 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case servent +servent_head() +{ + atf_set "descr" "Checks {get,set,end}servent(3)" +} +servent_body() +{ + # + # Munge original to: + # (1) match output format of the test program + # (2) fold all names for the same port/proto together + # (3) prune duplicates + # + tr '\t' ' ' </etc/services | awk ' + function add(key, name, i, n, ar) { + n = split(names[key], ar); + for (i=1; i<=n; i++) { + if (name == ar[i]) { + return; + } + } + delete ar; + names[key] = names[key] " " name; + } + + { + sub("#.*", "", $0); + gsub(" *", " ", $0); + if (NF==0) { + next; + } + add($2, $1, 0); + for (i=3; i<=NF; i++) { + add($2, $i, 1); + } + } + END { + for (key in names) { + portproto = key; + sub("/", ", proto=", portproto); + portproto = "port=" portproto; + + n = split(names[key], ar); + printf "name=%s, %s, aliases=", ar[1], portproto; + for (i=2; i<=n; i++) { + if (i>2) { + printf " "; + } + printf "%s", ar[i]; + } + printf "\n"; + delete ar; + } + } + ' | sort >exp + + # run test program + "$(atf_get_srcdir)/h_servent" | sed 's/ *$//' | sort >out + + diff -u exp out || atf_fail "Observed output does not match reference output" +} + +atf_init_test_cases() +{ + atf_add_test_case servent +} diff --git a/contrib/netbsd-tests/lib/libc/regex/README b/contrib/netbsd-tests/lib/libc/regex/README new file mode 100644 index 0000000..6d9a28c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/README @@ -0,0 +1,33 @@ +regular expression test set +Lines are at least three fields, separated by one or more tabs. "" stands +for an empty field. First field is an RE. Second field is flags. If +C flag given, regcomp() is expected to fail, and the third field is the +error name (minus the leading REG_). + +Otherwise it is expected to succeed, and the third field is the string to +try matching it against. If there is no fourth field, the match is +expected to fail. If there is a fourth field, it is the substring that +the RE is expected to match. If there is a fifth field, it is a comma- +separated list of what the subexpressions should match, with - indicating +no match for that one. In both the fourth and fifth fields, a (sub)field +starting with @ indicates that the (sub)expression is expected to match +a null string followed by the stuff after the @; this provides a way to +test where null strings match. The character `N' in REs and strings +is newline, `S' is space, `T' is tab, `Z' is NUL. + +The full list of flags: + - placeholder, does nothing + b RE is a BRE, not an ERE + & try it as both an ERE and a BRE + C regcomp() error expected, third field is error name + i REG_ICASE + m ("mundane") REG_NOSPEC + s REG_NOSUB (not really testable) + n REG_NEWLINE + ^ REG_NOTBOL + $ REG_NOTEOL + # REG_STARTEND (see below) + p REG_PEND + +For REG_STARTEND, the start/end offsets are those of the substring +enclosed in (). diff --git a/contrib/netbsd-tests/lib/libc/regex/data/anchor.in b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in new file mode 100644 index 0000000..d145408 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in @@ -0,0 +1,33 @@ +# anchoring and REG_NEWLINE +^abc$ & abc abc +a^b - a^b +a^b b a^b a^b +a$b - a$b +a$b b a$b a$b +^ & abc @abc +$ & abc @ +^$ & "" @ +$^ - "" @ +\($\)\(^\) b "" @ +# stop retching, those are legitimate (although disgusting) +^^ - "" @ +$$ - "" @ +b$ & abNc +b$ &n abNc b +^b$ & aNbNc +^b$ &n aNbNc b +^$ &n aNNb @Nb +^$ n abc +^$ n abcN @ +$^ n aNNb @Nb +\($\)\(^\) bn aNNb @Nb +^^ n^ aNNb @Nb +$$ n aNNb @NN +^a ^ a +a$ $ a +^a ^n aNb +^b ^n aNb b +a$ $n bNa +b$ $n bNa b +a*(^b$)c* - b b +a*\(^b$\)c* b b b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/README b/contrib/netbsd-tests/lib/libc/regex/data/att/README new file mode 100644 index 0000000..e2ee6f6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/README @@ -0,0 +1,8 @@ +AT&T test data from: http://www2.research.att.com/~gsf/testregex/ + +Quoting from the page: + testregex.c 2004-05-31 is the latest source for the AT&T Research + regression test harness for the X/Open regex pattern match interface. + See testregex(1) for option and test input details. The source and + test data posted here are license free. + diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat new file mode 100644 index 0000000..4399ca1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat @@ -0,0 +1,216 @@ +NOTE all standard compliant implementations should pass these : 2002-05-31 + +BE abracadabra$ abracadabracadabra (7,18) +BE a...b abababbb (2,7) +BE XXXXXX ..XXXXXX (2,8) +E \) () (1,2) +BE a] a]a (0,2) +B } } (0,1) +E \} } (0,1) +BE \] ] (0,1) +B ] ] (0,1) +E ] ] (0,1) +B { { (0,1) +B } } (0,1) +BE ^a ax (0,1) +BE \^a a^a (1,3) +BE a\^ a^ (0,2) +BE a$ aa (1,2) +BE a\$ a$ (0,2) +BE ^$ NULL (0,0) +E $^ NULL (0,0) +E a($) aa (1,2)(2,2) +E a*(^a) aa (0,1)(0,1) +E (..)*(...)* a (0,0) +E (..)*(...)* abcd (0,4)(2,4) +E (ab|a)(bc|c) abc (0,3)(0,2)(2,3) +E (ab)c|abc abc (0,3)(0,2) +E a{0}b ab (1,2) +E (a*)(b?)(b+)b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7) +E (a*)(b{0,1})(b{1,})b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7) +E a{9876543210} NULL BADBR +E ((a|a)|a) a (0,1)(0,1)(0,1) +E (a*)(a|aa) aaaa (0,4)(0,3)(3,4) +E a*(a.|aa) aaaa (0,4)(2,4) +E a(b)|c(d)|a(e)f aef (0,3)(?,?)(?,?)(1,2) +E (a|b)?.* b (0,1)(0,1) +E (a|b)c|a(b|c) ac (0,2)(0,1) +E (a|b)c|a(b|c) ab (0,2)(?,?)(1,2) +E (a|b)*c|(a|ab)*c abc (0,3)(1,2) +E (a|b)*c|(a|ab)*c xc (1,2) +E (.a|.b).*|.*(.a|.b) xa (0,2)(0,2) +E a?(ab|ba)ab abab (0,4)(0,2) +E a?(ac{0}b|ba)ab abab (0,4)(0,2) +E ab|abab abbabab (0,2) +E aba|bab|bba baaabbbaba (5,8) +E aba|bab baaabbbaba (6,9) +E (aa|aaa)*|(a|aaaaa) aa (0,2)(0,2) +E (a.|.a.)*|(a|.a...) aa (0,2)(0,2) +E ab|a xabc (1,3) +E ab|a xxabc (2,4) +Ei (Ab|cD)* aBcD (0,4)(2,4) +BE [^-] --a (2,3) +BE [a-]* --a (0,3) +BE [a-m-]* --amoma-- (0,4) +E :::1:::0:|:::1:1:0: :::0:::1:::1:::0: (8,17) +E :::1:::0:|:::1:1:1: :::0:::1:::1:::0: (8,17) +{E [[:upper:]] A (0,1) [[<element>]] not supported +E [[:lower:]]+ `az{ (1,3) +E [[:upper:]]+ @AZ[ (1,3) +BE [[-]] [[-]] (2,4) +BE [[.NIL.]] NULL ECOLLATE +BE [[=aleph=]] NULL ECOLLATE +} +BE$ \n \n (0,1) +BEn$ \n \n (0,1) +BE$ [^a] \n (0,1) +BE$ \na \na (0,2) +E (a)(b)(c) abc (0,3)(0,1)(1,2)(2,3) +BE xxx xxx (0,3) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 6, (0,6) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) 2/7 (0,3) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 1,Feb 6 (5,11) +E3 ((((((((((((((((((((((((((((((x)))))))))))))))))))))))))))))) x (0,1)(0,1)(0,1) +E3 ((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))* xx (0,2)(1,2)(1,2) +E a?(ab|ba)* ababababababababababababababababababababababababababababababababababababababababa (0,81)(79,81) +E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabbbbaa (18,25) +E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabaa (18,22) +E aaac|aabc|abac|abbc|baac|babc|bbac|bbbc baaabbbabac (7,11) +BE$ .* \x01\xff (0,2) +E aaaa|bbbb|cccc|ddddd|eeeeee|fffffff|gggg|hhhh|iiiii|jjjjj|kkkkk|llll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa (53,57) +L aaaa\nbbbb\ncccc\nddddd\neeeeee\nfffffff\ngggg\nhhhh\niiiii\njjjjj\nkkkkk\nllll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa NOMATCH +E a*a*a*a*a*b aaaaaaaaab (0,10) +BE ^ NULL (0,0) +BE $ NULL (0,0) +BE ^$ NULL (0,0) +BE ^a$ a (0,1) +BE abc abc (0,3) +BE abc xabcy (1,4) +BE abc ababc (2,5) +BE ab*c abc (0,3) +BE ab*bc abc (0,3) +BE ab*bc abbc (0,4) +BE ab*bc abbbbc (0,6) +E ab+bc abbc (0,4) +E ab+bc abbbbc (0,6) +E ab?bc abbc (0,4) +E ab?bc abc (0,3) +E ab?c abc (0,3) +BE ^abc$ abc (0,3) +BE ^abc abcc (0,3) +BE abc$ aabc (1,4) +BE ^ abc (0,0) +BE $ abc (3,3) +BE a.c abc (0,3) +BE a.c axc (0,3) +BE a.*c axyzc (0,5) +BE a[bc]d abd (0,3) +BE a[b-d]e ace (0,3) +BE a[b-d] aac (1,3) +BE a[-b] a- (0,2) +BE a[b-] a- (0,2) +BE a] a] (0,2) +BE a[]]b a]b (0,3) +BE a[^bc]d aed (0,3) +BE a[^-b]c adc (0,3) +BE a[^]b]c adc (0,3) +E ab|cd abc (0,2) +E ab|cd abcd (0,2) +E a\(b a(b (0,3) +E a\(*b ab (0,2) +E a\(*b a((b (0,4) +E ((a)) abc (0,1)(0,1)(0,1) +E (a)b(c) abc (0,3)(0,1)(2,3) +E a+b+c aabbabc (4,7) +E a* aaa (0,3) +E (a*)* - (0,0)(0,0) +E (a*)+ - (0,0)(0,0) +E (a*|b)* - (0,0)(0,0) +E (a+|b)* ab (0,2)(1,2) +E (a+|b)+ ab (0,2)(1,2) +E (a+|b)? ab (0,1)(0,1) +BE [^ab]* cde (0,3) +E (^)* - (0,0)(0,0) +BE a* NULL (0,0) +E ([abc])*d abbbcd (0,6)(4,5) +E ([abc])*bcd abcd (0,4)(0,1) +E a|b|c|d|e e (0,1) +E (a|b|c|d|e)f ef (0,2)(0,1) +E ((a*|b))* - (0,0)(0,0)(0,0) +BE abcd*efg abcdefg (0,7) +BE ab* xabyabbbz (1,3) +BE ab* xayabbbz (1,2) +E (ab|cd)e abcde (2,5)(2,4) +BE [abhgefdc]ij hij (0,3) +E (a|b)c*d abcd (1,4)(1,2) +E (ab|ab*)bc abc (0,3)(0,1) +E a([bc]*)c* abc (0,3)(1,3) +E a([bc]*)(c*d) abcd (0,4)(1,3)(3,4) +E a([bc]+)(c*d) abcd (0,4)(1,3)(3,4) +E a([bc]*)(c+d) abcd (0,4)(1,2)(2,4) +E a[bcd]*dcdcde adcdcde (0,7) +E (ab|a)b*c abc (0,3)(0,2) +E ((a)(b)c)(d) abcd (0,4)(0,3)(0,1)(1,2)(3,4) +BE [A-Za-z_][A-Za-z0-9_]* alpha (0,5) +E ^a(bc+|b[eh])g|.h$ abh (1,3) +E (bc+d$|ef*g.|h?i(j|k)) effgz (0,5)(0,5) +E (bc+d$|ef*g.|h?i(j|k)) ij (0,2)(0,2)(1,2) +E (bc+d$|ef*g.|h?i(j|k)) reffgz (1,6)(1,6) +E (((((((((a))))))))) a (0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1) +BE multiple words multiple words yeah (0,14) +E (.*)c(.*) abcde (0,5)(0,2)(3,5) +BE abcd abcd (0,4) +E a(bc)d abcd (0,4)(1,3) +E a[-]?c ac (0,3) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qaddafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mo'ammar Gadhafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Kaddafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qadhafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gadafi (0,14)(?,?)(10,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadafi (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moamar Gaddafi (0,14)(?,?)(9,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadhdhafi (0,18)(?,?)(13,15) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Khaddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafy (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghadafi (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muamar Kaddafi (0,14)(?,?)(9,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Quathafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gheddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Khadafy (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Qudhafi (0,15)(?,?)(10,12) +E a+(b|c)*d+ aabcdd (0,6)(3,4) +E ^.+$ vivi (0,4) +E ^(.+)$ vivi (0,4)(0,4) +E ^([^!.]+).att.com!(.+)$ gryphon.att.com!eby (0,19)(0,7)(16,19) +E ^([^!]+!)?([^!]+)$ bas (0,3)(?,?)(0,3) +E ^([^!]+!)?([^!]+)$ bar!bas (0,7)(0,4)(4,7) +E ^([^!]+!)?([^!]+)$ foo!bas (0,7)(0,4)(4,7) +E ^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(4,8)(8,11) +E ((foo)|(bar))!bas bar!bas (0,7)(0,3)(?,?)(0,3) +E ((foo)|(bar))!bas foo!bar!bas (4,11)(4,7)(?,?)(4,7) +E ((foo)|(bar))!bas foo!bas (0,7)(0,3)(0,3) +E ((foo)|bar)!bas bar!bas (0,7)(0,3) +E ((foo)|bar)!bas foo!bar!bas (4,11)(4,7) +E ((foo)|bar)!bas foo!bas (0,7)(0,3)(0,3) +E (foo|(bar))!bas bar!bas (0,7)(0,3)(0,3) +E (foo|(bar))!bas foo!bar!bas (4,11)(4,7)(4,7) +E (foo|(bar))!bas foo!bas (0,7)(0,3) +E (foo|bar)!bas bar!bas (0,7)(0,3) +E (foo|bar)!bas foo!bar!bas (4,11)(4,7) +E (foo|bar)!bas foo!bas (0,7)(0,3) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bas (0,3)(?,?)(0,3) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bar!bas (0,7)(0,4)(4,7) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(?,?)(?,?)(4,8)(8,11) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bas (0,7)(0,4)(4,7) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bas (0,3)(0,3)(?,?)(0,3) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bar!bas (0,7)(0,7)(0,4)(4,7) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bas (0,7)(0,7)(0,4)(4,7) +E .*(/XXX).* /XXX (0,4)(0,4) +E .*(\\XXX).* \XXX (0,4)(0,4) +E \\XXX \XXX (0,4) +E .*(/000).* /000 (0,4)(0,4) +E .*(\\000).* \000 (0,4)(0,4) +E \\000 \000 (0,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat new file mode 100644 index 0000000..d348512 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat @@ -0,0 +1,62 @@ +NOTE regex implementation categorization 2004-05-31 + +?E aa* xaxaax (1,2) POSITION=leftmost +; POSITION=bug + +?E (a*)(ab)*(b*) abc (0,2)(0,1)(?,?)(1,2) ASSOCIATIVITY=right +|E (a*)(ab)*(b*) abc (0,2)(0,0)(0,2)(2,2) ASSOCIATIVITY=left +; ASSOCIATIVITY=bug + +?E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,2)(0,0)(0,2)(2,3)(2,2)(2,3) SUBEXPRESSION=precedence +|E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,1)(0,1)(?,?)(1,3)(1,2)(2,3) SUBEXPRESSION=grouping +; SUBEXPRESSION=bug + +?E (...?.?)* xxxxxx (0,6)(4,6) REPEAT_LONGEST=first +|E (...?.?)* xxxxxx (0,6)(2,6) REPEAT_LONGEST=last +|E (...?.?)* xxxxxx OK REPEAT_LONGEST=unknown +; REPEAT_LONGEST=bug + +?E (a|ab)(bc|c) abcabc (0,3)(0,2)(2,3) EXPECTED +|E (a|ab)(bc|c) abcabc (0,3)(0,1)(1,3) BUG=alternation-order +; BUG=alternation-order-UNKNOWN + +?E (aba|a*b)(aba|a*b) ababa (0,5)(0,2)(2,5) EXPECTED +|E (aba|a*b)(aba|a*b) ababa (0,4)(0,3)(3,4) BUG=first-match +; BUG=unknown-match + +?B a\(b\)*\1 a NOMATCH EXPECTED +|B a\(b\)*\1 a (0,1) BUG=nomatch-match +|B a\(b\)*\1 abab (0,2)(1,2) # BUG=repeat-any +; BUG=nomatch-match-UNKNOWN + +?E (a*){2} xxxxx (0,0)(0,0) EXPECTED +|E (a*){2} xxxxx (5,5)(5,5) BUG=range-null +; BUG=range-null-UNKNOWN + +?B a\(b\)*\1 abab NOMATCH EXPECTED +|B a\(b\)*\1 abab (0,1) # BUG=nomatch-match +|B a\(b\)*\1 abab (0,2)(1,2) BUG=repeat-any +; BUG=repeat-any-UNKNOWN + +?E (a*)* a (0,1)(0,1) EXPECTED +|E (a*)* ax (0,1)(0,1) BUG=repeat-null-unknown +|E (a*)* a (0,1)(1,1) BUG=repeat-null +; BUG=repeat-null-UNKNOWN + +?E (aba|a*b)* ababa (0,5)(2,5) EXPECTED +|E (aba|a*b)* ababa (0,5)(3,4) BUG=repeat-short +|E (aba|a*b)* ababa (0,4)(3,4) # LENGTH=first +; BUG=repeat-short-UNKNOWN + +?E (a(b)?)+ aba (0,3)(2,3) EXPECTED +|E (a(b)?)+ aba (0,3)(2,3)(1,2) BUG=repeat-artifact +; BUG=repeat-artifact-UNKNOWN + +?B \(a\(b\)*\)*\2 abab NOMATCH EXPECTED +|B \(a\(b\)*\)*\2 abab (0,4)(2,3)(1,2) BUG=repeat-artifact-nomatch +; BUG=repeat-artifact-nomatch-UNKNOWN + +?E (a?)((ab)?)(b?)a?(ab)?b? abab (0,4)(0,1)(1,1)(?,?)(1,2)(2,4) BUG=subexpression-first +|E .*(.*) ab (0,2)(2,2) EXPECTED +|E .*(.*) ab (0,2)(0,2) BUG=subexpression-first +; BUG=subexpression-first-UNKNOWN diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat new file mode 100644 index 0000000..39f3111 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat @@ -0,0 +1,30 @@ +NOTE left-assoc:pass-all right-assoc:pass-all : 2002-04-29 + +E (a|ab)(c|bcd) abcd (0,4)(0,1)(1,4) +E (a|ab)(bcd|c) abcd (0,4)(0,1)(1,4) +E (ab|a)(c|bcd) abcd (0,4)(0,1)(1,4) +E (ab|a)(bcd|c) abcd (0,4)(0,1)(1,4) +E ((a|ab)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((a|ab)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((ab|a)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((ab|a)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E (a|ab)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (a|ab)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (ab|a)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (ab|a)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (a*)(b|abc) abc (0,3)(0,0)(0,3) +E (a*)(abc|b) abc (0,3)(0,0)(0,3) +E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)(b|abc) abc (0,3)(0,0)(0,3) +E (a*)(abc|b) abc (0,3)(0,0)(0,3) +E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a|ab) ab (0,2)(0,2) +E (ab|a) ab (0,2)(0,2) +E (a|ab)(b*) ab (0,2)(0,2)(2,2) +E (ab|a)(b*) ab (0,2)(0,2)(2,2) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat new file mode 100644 index 0000000..9c068c6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat @@ -0,0 +1,16 @@ +NOTE left-assoc:pass-all right-assoc:pass-none : 2002-04-29 + +E (a|ab)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (a|ab)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4) + +E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3) + +E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat new file mode 100644 index 0000000..c73d8f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat @@ -0,0 +1,73 @@ +NOTE null subexpression matches : 2002-06-06 + +E (a*)* a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a*)+ a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a+)* a (0,1)(0,1) +E SAME x (0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a+)+ a (0,1)(0,1) +E SAME x NOMATCH +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) + +E ([a]*)* a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E ([a]*)+ a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E ([^b]*)* a (0,1)(0,1) +E SAME b (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaab (0,6)(0,6) +E ([ab]*)* a (0,1)(0,1) +E SAME aaaaaa (0,6)(0,6) +E SAME ababab (0,6)(0,6) +E SAME bababa (0,6)(0,6) +E SAME b (0,1)(0,1) +E SAME bbbbbb (0,6)(0,6) +E SAME aaaabcde (0,5)(0,5) +E ([^a]*)* b (0,1)(0,1) +E SAME bbbbbb (0,6)(0,6) +E SAME aaaaaa (0,0)(0,0) +E ([^ab]*)* ccccxx (0,6)(0,6) +E SAME ababab (0,0)(0,0) + +E ((z)+|a)* zabcde (0,2)(1,2) + +{E a+? aaaaaa (0,1) no *? +? mimimal match ops +E (a) aaa (0,1)(0,1) +E (a*?) aaa (0,0)(0,0) +E (a)*? aaa (0,0) +E (a*?)*? aaa (0,0) +} + +B \(a*\)*\(x\) x (0,1)(0,0)(0,1) +B \(a*\)*\(x\) ax (0,2)(0,1)(1,2) +B \(a*\)*\(x\) axa (0,2)(0,1)(1,2) +B \(a*\)*\(x\)\(\1\) x (0,1)(0,0)(0,1)(1,1) +B \(a*\)*\(x\)\(\1\) ax (0,2)(1,1)(1,2)(2,2) +B \(a*\)*\(x\)\(\1\) axa (0,3)(0,1)(1,2)(2,3) +B \(a*\)*\(x\)\(\1\)\(x\) axax (0,4)(0,1)(1,2)(2,3)(3,4) +B \(a*\)*\(x\)\(\1\)\(x\) axxa (0,3)(1,1)(1,2)(2,2)(2,3) + +E (a*)*(x) x (0,1)(0,0)(0,1) +E (a*)*(x) ax (0,2)(0,1)(1,2) +E (a*)*(x) axa (0,2)(0,1)(1,2) + +E (a*)+(x) x (0,1)(0,0)(0,1) +E (a*)+(x) ax (0,2)(0,1)(1,2) +E (a*)+(x) axa (0,2)(0,1)(1,2) + +E (a*){2}(x) x (0,1)(0,0)(0,1) +E (a*){2}(x) ax (0,2)(1,1)(1,2) +E (a*){2}(x) axa (0,2)(1,1)(1,2) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat new file mode 100644 index 0000000..c24749c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat @@ -0,0 +1,140 @@ +NOTE implicit vs. explicit repetitions : 2009-02-02 + +# Glenn Fowler <gsf@research.att.com> +# conforming matches (column 4) must match one of the following BREs +# NOMATCH +# (0,.)\((\(.\),\(.\))(?,?)(\2,\3)\)* +# (0,.)\((\(.\),\(.\))(\2,\3)(?,?)\)* +# i.e., each 3-tuple has two identical elements and one (?,?) + +E ((..)|(.)) NULL NOMATCH +E ((..)|(.))((..)|(.)) NULL NOMATCH +E ((..)|(.))((..)|(.))((..)|(.)) NULL NOMATCH + +E ((..)|(.)){1} NULL NOMATCH +E ((..)|(.)){2} NULL NOMATCH +E ((..)|(.)){3} NULL NOMATCH + +E ((..)|(.))* NULL (0,0) + +E ((..)|(.)) a (0,1)(0,1)(?,?)(0,1) +E ((..)|(.))((..)|(.)) a NOMATCH +E ((..)|(.))((..)|(.))((..)|(.)) a NOMATCH + +E ((..)|(.)){1} a (0,1)(0,1)(?,?)(0,1) +E ((..)|(.)){2} a NOMATCH +E ((..)|(.)){3} a NOMATCH + +E ((..)|(.))* a (0,1)(0,1)(?,?)(0,1) + +E ((..)|(.)) aa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aa (0,2)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2) +E ((..)|(.))((..)|(.))((..)|(.)) aa NOMATCH + +E ((..)|(.)){1} aa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aa (0,2)(1,2)(?,?)(1,2) +E ((..)|(.)){3} aa NOMATCH + +E ((..)|(.))* aa (0,2)(0,2)(0,2)(?,?) + +E ((..)|(.)) aaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaa (0,3)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3) +E ((..)|(.))((..)|(.))((..)|(.)) aaa (0,3)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2)(2,3)(?,?)(2,3) + +E ((..)|(.)){1} aaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaa (0,3)(2,3)(?,?)(2,3) +E ((..)|(.)){3} aaa (0,3)(2,3)(?,?)(2,3) + +E ((..)|(.))* aaa (0,3)(2,3)(?,?)(2,3) + +E ((..)|(.)) aaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3)(3,4)(?,?)(3,4) + +E ((..)|(.)){1} aaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaa (0,4)(3,4)(?,?)(3,4) + +E ((..)|(.))* aaaa (0,4)(2,4)(2,4)(?,?) + +E ((..)|(.)) aaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaaa (0,5)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,5)(?,?)(4,5) + +E ((..)|(.)){1} aaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaaa (0,5)(4,5)(?,?)(4,5) + +E ((..)|(.))* aaaaa (0,5)(4,5)(?,?)(4,5) + +E ((..)|(.)) aaaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaaaa (0,6)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,6)(4,6)(?,?) + +E ((..)|(.)){1} aaaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaaaa (0,6)(4,6)(4,6)(?,?) + +E ((..)|(.))* aaaaaa (0,6)(4,6)(4,6)(?,?) + +NOTE additional repetition tests graciously provided by Chris Kuklewicz www.haskell.org 2009-02-02 + +# These test a bug in OS X / FreeBSD / NetBSD, and libtree. +# Linux/GLIBC gets the {8,} and {8,8} wrong. + +:HA#100:E X(.?){0,}Y X1234567Y (0,9)(7,8) +:HA#101:E X(.?){1,}Y X1234567Y (0,9)(7,8) +:HA#102:E X(.?){2,}Y X1234567Y (0,9)(7,8) +:HA#103:E X(.?){3,}Y X1234567Y (0,9)(7,8) +:HA#104:E X(.?){4,}Y X1234567Y (0,9)(7,8) +:HA#105:E X(.?){5,}Y X1234567Y (0,9)(7,8) +:HA#106:E X(.?){6,}Y X1234567Y (0,9)(7,8) +:HA#107:E X(.?){7,}Y X1234567Y (0,9)(7,8) +:HA#108:E X(.?){8,}Y X1234567Y (0,9)(8,8) +:HA#110:E X(.?){0,8}Y X1234567Y (0,9)(7,8) +:HA#111:E X(.?){1,8}Y X1234567Y (0,9)(7,8) +:HA#112:E X(.?){2,8}Y X1234567Y (0,9)(7,8) +:HA#113:E X(.?){3,8}Y X1234567Y (0,9)(7,8) +:HA#114:E X(.?){4,8}Y X1234567Y (0,9)(7,8) +:HA#115:E X(.?){5,8}Y X1234567Y (0,9)(7,8) +:HA#116:E X(.?){6,8}Y X1234567Y (0,9)(7,8) +:HA#117:E X(.?){7,8}Y X1234567Y (0,9)(7,8) +:HA#118:E X(.?){8,8}Y X1234567Y (0,9)(8,8) + +# These test a fixed bug in my regex-tdfa that did not keep the expanded +# form properly grouped, so right association did the wrong thing with +# these ambiguous patterns (crafted just to test my code when I became +# suspicious of my implementation). The first subexpression should use +# "ab" then "a" then "bcd". + +# OS X / FreeBSD / NetBSD badly fail many of these, with impossible +# results like (0,6)(4,5)(6,6). + +:HA#260:E (a|ab|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#261:E (a|ab|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#262:E (a|ab|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#263:E (a|ab|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#264:E (a|ab|c|bcd){4,}(d*) ababcd NOMATCH +:HA#265:E (a|ab|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#266:E (a|ab|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#267:E (a|ab|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#268:E (a|ab|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#269:E (a|ab|c|bcd){4,10}(d*) ababcd NOMATCH +:HA#270:E (a|ab|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6) +:HA#271:E (a|ab|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6) + +# The above worked on Linux/GLIBC but the following often fail. +# They also trip up OS X / FreeBSD / NetBSD: + +:HA#280:E (ab|a|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#281:E (ab|a|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#282:E (ab|a|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#283:E (ab|a|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#284:E (ab|a|c|bcd){4,}(d*) ababcd NOMATCH +:HA#285:E (ab|a|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#286:E (ab|a|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#287:E (ab|a|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#288:E (ab|a|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#289:E (ab|a|c|bcd){4,10}(d*) ababcd NOMATCH +:HA#290:E (ab|a|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6) +:HA#291:E (ab|a|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat new file mode 100644 index 0000000..ed7f28e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat @@ -0,0 +1,16 @@ +NOTE left-assoc:pass-none right-assoc:pass-all : 2002-04-29 + +E (a|ab)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (a|ab)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4) + +E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3) + +E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/backref.in b/contrib/netbsd-tests/lib/libc/regex/data/backref.in new file mode 100644 index 0000000..cc59b06 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/backref.in @@ -0,0 +1,21 @@ +# back references, ugh +a\(b\)\2c bC ESUBREG +a\(b\1\)c bC ESUBREG +a\(b*\)c\1d b abbcbbd abbcbbd bb +a\(b*\)c\1d b abbcbd +a\(b*\)c\1d b abbcbbbd +^\(.\)\1 b abc +a\([bc]\)\1d b abcdabbd abbd b +a\(\([bc]\)\2\)*d b abbccd abbccd +a\(\([bc]\)\2\)*d b abbcbd +# actually, this next one probably ought to fail, but the spec is unclear +a\(\(b\)*\2\)*d b abbbd abbbd +# here is a case that no NFA implementation does right +\(ab*\)[ab]*\1 b ababaaa ababaaa a +# check out normal matching in the presence of back refs +\(a\)\1bcd b aabcd aabcd +\(a\)\1bc*d b aabcd aabcd +\(a\)\1bc*d b aabd aabd +\(a\)\1bc*d b aabcccd aabcccd +\(a\)\1bc*[ce]d b aabcccd aabcccd +^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd diff --git a/contrib/netbsd-tests/lib/libc/regex/data/basic.in b/contrib/netbsd-tests/lib/libc/regex/data/basic.in new file mode 100644 index 0000000..d1e3aa9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/basic.in @@ -0,0 +1,5 @@ +# basics +a & a a +abc & abc abc +abc|de - abc abc +a|b|c - abc a diff --git a/contrib/netbsd-tests/lib/libc/regex/data/bracket.in b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in new file mode 100644 index 0000000..53a0b20 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in @@ -0,0 +1,55 @@ +# brackets, and numerous perversions thereof +a[b]c & abc abc +a[ab]c & abc abc +a[^ab]c & adc adc +a[]b]c & a]c a]c +a[[b]c & a[c a[c +a[-b]c & a-c a-c +a[^]b]c & adc adc +a[^-b]c & adc adc +a[b-]c & a-c a-c +a[b &C EBRACK +a[] &C EBRACK +a[1-3]c & a2c a2c +a[3-1]c &C ERANGE +a[1-3-5]c &C ERANGE +a[[.-.]--]c & a-c a-c +a[1- &C ERANGE +a[[. &C EBRACK +a[[.x &C EBRACK +a[[.x. &C EBRACK +a[[.x.] &C EBRACK +a[[.x.]] & ax ax +a[[.x,.]] &C ECOLLATE +a[[.one.]]b & a1b a1b +a[[.notdef.]]b &C ECOLLATE +a[[.].]]b & a]b a]b +a[[:alpha:]]c & abc abc +a[[:notdef:]]c &C ECTYPE +a[[: &C EBRACK +a[[:alpha &C EBRACK +a[[:alpha:] &C EBRACK +a[[:alpha,:] &C ECTYPE +a[[:]:]]b &C ECTYPE +a[[:-:]]b &C ECTYPE +a[[:alph:]] &C ECTYPE +a[[:alphabet:]] &C ECTYPE +[[:alnum:]]+ - -%@a0X- a0X +[[:alpha:]]+ - -%@aX0- aX +[[:blank:]]+ - aSSTb SST +[[:cntrl:]]+ - aNTb NT +[[:digit:]]+ - a019b 019 +[[:graph:]]+ - Sa%bS a%b +[[:lower:]]+ - AabC ab +[[:print:]]+ - NaSbN aSb +[[:punct:]]+ - S%-&T %-& +[[:space:]]+ - aSNTb SNT +[[:upper:]]+ - aBCd BC +[[:xdigit:]]+ - p0f3Cq 0f3C +a[[=b=]]c & abc abc +a[[= &C EBRACK +a[[=b &C EBRACK +a[[=b= &C EBRACK +a[[=b=] &C EBRACK +a[[=b,=]] &C ECOLLATE +a[[=one=]]b & a1b a1b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in new file mode 100644 index 0000000..ea3faf9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in @@ -0,0 +1,17 @@ +# Let's have some fun -- try to match a C comment. +# first the obvious, which looks okay at first glance... +/\*.*\*/ - /*x*/ /*x*/ +# but... +/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/ +# okay, we must not match */ inside; try to do that... +/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/ +/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/ +# but... +/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/ +# and a still fancier version, which does it right (I think)... +/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/ +/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/ diff --git a/contrib/netbsd-tests/lib/libc/regex/data/complex.in b/contrib/netbsd-tests/lib/libc/regex/data/complex.in new file mode 100644 index 0000000..e114058 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/complex.in @@ -0,0 +1,23 @@ +# complexities +a(((b)))c - abc abc +a(b|(c))d - abd abd +a(b*|c)d - abbd abbd +# just gotta have one DFA-buster, of course +a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and an inline expansion in case somebody gets tricky +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and in case somebody just slips in an NFA... +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights +# fish for anomalies as the number of states passes 32 +12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789 +123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890 +1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901 +12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012 +123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123 +# and one really big one, beyond any plausible word width +1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890 +# fish for problems as brackets go past 8 +[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm +[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo +[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq +[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq diff --git a/contrib/netbsd-tests/lib/libc/regex/data/error.in b/contrib/netbsd-tests/lib/libc/regex/data/error.in new file mode 100644 index 0000000..61e0ea4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/error.in @@ -0,0 +1,30 @@ +# certain syntax errors and non-errors +| C EMPTY +| b | | +* C BADRPT +* b * * ++ C BADRPT +? C BADRPT +"" &C EMPTY +() - abc @abc +\(\) b abc @abc +a||b C EMPTY +|ab C EMPTY +ab| C EMPTY +(|a)b C EMPTY +(a|)b C EMPTY +(*a) C BADRPT +(+a) C BADRPT +(?a) C BADRPT +({1}a) C BADRPT +\(\{1\}a\) bC BADRPT +(a|*b) C BADRPT +(a|+b) C BADRPT +(a|?b) C BADRPT +(a|{1}b) C BADRPT +^* C BADRPT +^* b * * +^+ C BADRPT +^? C BADRPT +^{1} C BADRPT +^\{1\} bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/meta.in b/contrib/netbsd-tests/lib/libc/regex/data/meta.in new file mode 100644 index 0000000..4533d35 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/meta.in @@ -0,0 +1,21 @@ +# metacharacters, backslashes +a.c & abc abc +a[bc]d & abd abd +a\*c & a*c a*c +a\\b & a\b a\b +a\\\*b & a\*b a\*b +a\bc & abc abc +a\ &C EESCAPE +a\\bc & a\bc a\bc +\{ bC BADRPT +a\[b & a[b a[b +a[b &C EBRACK +# trailing $ is a peculiar special case for the BRE code +a$ & a a +a$ & a$ +a\$ & a +a\$ & a$ a$ +a\\$ & a +a\\$ & a$ +a\\$ & a\$ +a\\$ & a\ a\ diff --git a/contrib/netbsd-tests/lib/libc/regex/data/nospec.in b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in new file mode 100644 index 0000000..baf8d04 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in @@ -0,0 +1,7 @@ +# plain strings, with the NOSPEC flag +abc m abc abc +abc m xabcy abc +abc m xyz +a*b m aba*b a*b +a*b m ab +"" mC EMPTY diff --git a/contrib/netbsd-tests/lib/libc/regex/data/paren.in b/contrib/netbsd-tests/lib/libc/regex/data/paren.in new file mode 100644 index 0000000..9d206ce --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/paren.in @@ -0,0 +1,19 @@ +# parentheses and perversions thereof +a(b)c - abc abc +a\(b\)c b abc abc +a( C EPAREN +a( b a( a( +a\( - a( a( +a\( bC EPAREN +a\(b bC EPAREN +a(b C EPAREN +a(b b a(b a(b +# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly) +a) - a) a) +) - ) ) +# end gagging (in a just world, those *should* give EPAREN) +a) b a) a) +a\) bC EPAREN +\) bC EPAREN +a()b - ab ab +a\(\)b b ab ab diff --git a/contrib/netbsd-tests/lib/libc/regex/data/regress.in b/contrib/netbsd-tests/lib/libc/regex/data/regress.in new file mode 100644 index 0000000..afd832a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/regress.in @@ -0,0 +1,9 @@ +# past problems, and suspected problems +(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1 +abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop +abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv +(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11 +CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11 +Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz +a?b - ab ab +-\{0,1\}[0-9]*$ b -5 -5 diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in new file mode 100644 index 0000000..ee6ff4c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in @@ -0,0 +1,45 @@ +# the dreaded bounded repetitions +{ & { { +{abc & {abc {abc +{1 C BADRPT +{1} C BADRPT +a{b & a{b a{b +a{1}b - ab ab +a\{1\}b b ab ab +a{1,}b - ab ab +a\{1,\}b b ab ab +a{1,2}b - aab aab +a\{1,2\}b b aab aab +a{1 C EBRACE +a\{1 bC EBRACE +a{1a C EBRACE +a\{1a bC EBRACE +a{1a} C BADBR +a\{1a\} bC BADBR +a{,2} - a{,2} a{,2} +a\{,2\} bC BADBR +a{,} - a{,} a{,} +a\{,\} bC BADBR +a{1,x} C BADBR +a\{1,x\} bC BADBR +a{1,x C EBRACE +a\{1,x bC EBRACE +a{300} C BADBR +a\{300\} bC BADBR +a{1,0} C BADBR +a\{1,0\} bC BADBR +ab{0,0}c - abcac ac +ab\{0,0\}c b abcac ac +ab{0,1}c - abcac abc +ab\{0,1\}c b abcac abc +ab{0,3}c - abbcac abbc +ab\{0,3\}c b abbcac abbc +ab{1,1}c - acabc abc +ab\{1,1\}c b acabc abc +ab{1,3}c - acabc abc +ab\{1,3\}c b acabc abc +ab{2,2}c - abcabbc abbc +ab\{2,2\}c b abcabbc abbc +ab{2,4}c - abcabbc abbc +ab\{2,4\}c b abcabbc abbc +((a{1,10}){1,10}){1,10} - a a a,a diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in new file mode 100644 index 0000000..da97bad --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in @@ -0,0 +1,21 @@ +# multiple repetitions +a** &C BADRPT +a++ C BADRPT +a?? C BADRPT +a*+ C BADRPT +a*? C BADRPT +a+* C BADRPT +a+? C BADRPT +a?* C BADRPT +a?+ C BADRPT +a{1}{1} C BADRPT +a*{1} C BADRPT +a+{1} C BADRPT +a?{1} C BADRPT +a{1}* C BADRPT +a{1}+ C BADRPT +a{1}? C BADRPT +a*{b} - a{b} a{b} +a\{1\}\{1\} bC BADRPT +a*\{1\} bC BADRPT +a\{1\}* bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in new file mode 100644 index 0000000..08bc286 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in @@ -0,0 +1,10 @@ +# ordinary repetitions +ab*c & abc abc +ab+c - abc abc +ab?c - abc abc +a\(*\)b b a*b a*b +a\(**\)b b ab ab +a\(***\)b bC BADRPT +*a b *a *a +**a b a a +***a bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/startend.in b/contrib/netbsd-tests/lib/libc/regex/data/startend.in new file mode 100644 index 0000000..c396e58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/startend.in @@ -0,0 +1,9 @@ +# check out the STARTEND option +[abc] &# a(b)c b +[abc] &# a(d)c +[abc] &# a(bc)d b +[abc] &# a(dc)d c +. &# a()c +b.*c &# b(bc)c bc +b.* &# b(bc)c bc +.*c &# b(bc)c bc diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subexp.in b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in new file mode 100644 index 0000000..c7bcc06 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in @@ -0,0 +1,57 @@ +# subexpressions +a(b)(c)d - abcd abcd b,c +a(((b)))c - abc abc b,b,b +a(b|(c))d - abd abd b,- +a(b*|c|e)d - abbd abbd bb +a(b*|c|e)d - acd acd c +a(b*|c|e)d - ad ad @d +a(b?)c - abc abc b +a(b?)c - ac ac @c +a(b+)c - abc abc b +a(b+)c - abbbc abbbc bbb +a(b*)c - ac ac @c +(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de +# the regression tester only asks for 9 subexpressions +a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j +a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k +a([bc]?)c - abc abc b +a([bc]?)c - ac ac @c +a([bc]+)c - abc abc b +a([bc]+)c - abcc abcc bc +a([bc]+)bc - abcbc abcbc bc +a(bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abbb abbb bb +a(bbb+|bb+|b)bb - abbb abbb b +(.*).* - abcdef abcdef abcdef +(a*)* - bc @b @b + +# do we get the right subexpression when it is used more than once? +a(b|c)*d - ad ad - +a(b|c)*d - abcd abcd c +a(b|c)+d - abd abd b +a(b|c)+d - abcd abcd c +a(b|c?)+d - ad ad @d +a(b|c?)+d - abcd abcd @d +a(b|c){0,0}d - ad ad - +a(b|c){0,1}d - ad ad - +a(b|c){0,1}d - abd abd b +a(b|c){0,2}d - ad ad - +a(b|c){0,2}d - abcd abcd c +a(b|c){0,}d - ad ad - +a(b|c){0,}d - abcd abcd c +a(b|c){1,1}d - abd abd b +a(b|c){1,1}d - acd acd c +a(b|c){1,2}d - abd abd b +a(b|c){1,2}d - abcd abcd c +a(b|c){1,}d - abd abd b +a(b|c){1,}d - abcd abcd c +a(b|c){2,2}d - acbd acbd b +a(b|c){2,2}d - abcd abcd c +a(b|c){2,4}d - abcd abcd c +a(b|c){2,4}d - abcbd abcbd b +a(b|c){2,4}d - abcbcd abcbcd c +a(b|c){2,}d - abcd abcd c +a(b|c){2,}d - abcbd abcbd b +a(b+|((c)*))+d - abd abd @d,@d,- +a(b+|((c)*))+d - abcd abcd @d,@d,- diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subtle.in b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in new file mode 100644 index 0000000..92d68bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in @@ -0,0 +1,21 @@ +# subtleties of matching +abc & xabcy abc +a\(b\)?c\1d b acd +aBc i Abc Abc +a[Bc]*d i abBCcd abBCcd +0[[:upper:]]1 &i 0a1 0a1 +0[[:lower:]]1 &i 0A1 0A1 +a[^b]c &i abc +a[^b]c &i aBc +a[^b]c &i adc adc +[a]b[c] - abc abc +[a]b[a] - aba aba +[abc]b[abc] - abc abc +[abc]b[abd] - abd abd +a(b?c)+d - accd accd +(wee|week)(knights|night) - weeknights weeknights +(we|wee|week|frob)(knights|night|day) - weeknights weeknights +a[bc]d - xyzaaabcaababdacd abd +a[ab]c - aaabc abc +abc s abc abc +a* & b @b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in new file mode 100644 index 0000000..e09a329 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in @@ -0,0 +1,13 @@ +# word boundaries (ick) +[[:<:]]a & a a +[[:<:]]a & ba +[[:<:]]a & -a a +a[[:>:]] & a a +a[[:>:]] & ab +a[[:>:]] & a- a +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc +[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc +[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc +[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_ +[[:<:]]a_b[[:>:]] & x_a_b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/zero.in b/contrib/netbsd-tests/lib/libc/regex/data/zero.in new file mode 100644 index 0000000..2786944 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/zero.in @@ -0,0 +1,7 @@ +# cases involving NULs +aZb & a a +aZb &p a +aZb &p# (aZb) aZb +aZ*b &p# (ab) ab +a.b &# (aZb) aZb +a.* &# (aZb)c aZb diff --git a/contrib/netbsd-tests/lib/libc/regex/debug.c b/contrib/netbsd-tests/lib/libc/regex/debug.c new file mode 100644 index 0000000..c1528b9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/debug.c @@ -0,0 +1,266 @@ +/* $NetBSD: debug.c,v 1.2 2011/10/10 04:32:41 christos Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <ctype.h> +#include <limits.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> + +/* Don't sort these! */ +#include "utils.h" +#include "regex2.h" + +#include "test_regex.h" + +static void s_print(struct re_guts *, FILE *); +static char *regchar(int); + +/* + * regprint - print a regexp for debugging + */ +void +regprint(regex_t *r, FILE *d) +{ + struct re_guts *g = r->re_g; + int c; + int last; + int nincat[NC]; + + fprintf(d, "%ld states, %zu categories", (long)g->nstates, + g->ncategories); + fprintf(d, ", first %ld last %ld", (long)g->firststate, + (long)g->laststate); + if (g->iflags&USEBOL) + fprintf(d, ", USEBOL"); + if (g->iflags&USEEOL) + fprintf(d, ", USEEOL"); + if (g->iflags&BAD) + fprintf(d, ", BAD"); + if (g->nsub > 0) + fprintf(d, ", nsub=%ld", (long)g->nsub); + if (g->must != NULL) + fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen, + g->must); + if (g->backrefs) + fprintf(d, ", backrefs"); + if (g->nplus > 0) + fprintf(d, ", nplus %ld", (long)g->nplus); + fprintf(d, "\n"); + s_print(g, d); + for (size_t i = 0; i < g->ncategories; i++) { + nincat[i] = 0; + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (g->categories[c] == i) + nincat[i]++; + } + fprintf(d, "cc0#%d", nincat[0]); + for (size_t i = 1; i < g->ncategories; i++) + if (nincat[i] == 1) { + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (g->categories[c] == i) + break; + fprintf(d, ", %zu=%s", i, regchar(c)); + } + fprintf(d, "\n"); + for (size_t i = 1; i < g->ncategories; i++) + if (nincat[i] != 1) { + fprintf(d, "cc%zu\t", i); + last = -1; + for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */ + if (c <= CHAR_MAX && g->categories[c] == i) { + if (last < 0) { + fprintf(d, "%s", regchar(c)); + last = c; + } + } else { + if (last >= 0) { + if (last != c-1) + fprintf(d, "-%s", + regchar(c-1)); + last = -1; + } + } + fprintf(d, "\n"); + } +} + +/* + * s_print - print the strip for debugging + */ +static void +s_print(struct re_guts *g, FILE *d) +{ + sop *s; + cset *cs; + int done = 0; + sop opnd; + int col = 0; + ssize_t last; + sopno offset = 2; +# define GAP() { if (offset % 5 == 0) { \ + if (col > 40) { \ + fprintf(d, "\n\t"); \ + col = 0; \ + } else { \ + fprintf(d, " "); \ + col++; \ + } \ + } else \ + col++; \ + offset++; \ + } + + if (OP(g->strip[0]) != OEND) + fprintf(d, "missing initial OEND!\n"); + for (s = &g->strip[1]; !done; s++) { + opnd = OPND(*s); + switch (OP(*s)) { + case OEND: + fprintf(d, "\n"); + done = 1; + break; + case OCHAR: + if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) + fprintf(d, "\\%c", (char)opnd); + else + fprintf(d, "%s", regchar((char)opnd)); + break; + case OBOL: + fprintf(d, "^"); + break; + case OEOL: + fprintf(d, "$"); + break; + case OBOW: + fprintf(d, "\\{"); + break; + case OEOW: + fprintf(d, "\\}"); + break; + case OANY: + fprintf(d, "."); + break; + case OANYOF: + fprintf(d, "[(%ld)", (long)opnd); + cs = &g->sets[opnd]; + last = -1; + for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */ + if (CHIN(cs, i) && i < g->csetsize) { + if (last < 0) { + fprintf(d, "%s", regchar(i)); + last = i; + } + } else { + if (last >= 0) { + if (last != (ssize_t)i - 1) + fprintf(d, "-%s", + regchar(i - 1)); + last = -1; + } + } + fprintf(d, "]"); + break; + case OBACK_: + fprintf(d, "(\\<%ld>", (long)opnd); + break; + case O_BACK: + fprintf(d, "<%ld>\\)", (long)opnd); + break; + case OPLUS_: + fprintf(d, "(+"); + if (OP(*(s+opnd)) != O_PLUS) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_PLUS: + if (OP(*(s-opnd)) != OPLUS_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "+)"); + break; + case OQUEST_: + fprintf(d, "(?"); + if (OP(*(s+opnd)) != O_QUEST) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_QUEST: + if (OP(*(s-opnd)) != OQUEST_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "?)"); + break; + case OLPAREN: + fprintf(d, "((<%ld>", (long)opnd); + break; + case ORPAREN: + fprintf(d, "<%ld>))", (long)opnd); + break; + case OCH_: + fprintf(d, "<"); + if (OP(*(s+opnd)) != OOR2) + fprintf(d, "<%ld>", (long)opnd); + break; + case OOR1: + if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "|"); + break; + case OOR2: + fprintf(d, "|"); + if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_CH: + if (OP(*(s-opnd)) != OOR1) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, ">"); + break; + default: + fprintf(d, "!%d(%d)!", OP(*s), opnd); + break; + } + if (!done) + GAP(); + } +} + +/* + * regchar - make a character printable + */ +static char * /* -> representation */ +regchar(int ch) +{ + static char buf[10]; + + if (isprint(ch) || ch == ' ') + sprintf(buf, "%c", ch); + else + sprintf(buf, "\\%o", ch); + return(buf); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/main.c b/contrib/netbsd-tests/lib/libc/regex/main.c new file mode 100644 index 0000000..eac4e2d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/main.c @@ -0,0 +1,523 @@ +/* $NetBSD: main.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> + +#include "test_regex.h" + +char *progname; +int debug = 0; +int line = 0; +int status = 0; + +int copts = REG_EXTENDED; +int eopts = 0; +regoff_t startoff = 0; +regoff_t endoff = 0; + +static char empty = '\0'; + +static char *eprint(int); +static int efind(char *); + +/* + * main - do the simple case, hand off to regress() for regression + */ +int +main(int argc, char *argv[]) +{ + regex_t re; +# define NS 10 + regmatch_t subs[NS]; + char erbuf[100]; + int err; + size_t len; + int c; + int errflg = 0; + int i; + extern int optind; + extern char *optarg; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "c:e:S:E:x")) != -1) + switch (c) { + case 'c': /* compile options */ + copts = options('c', optarg); + break; + case 'e': /* execute options */ + eopts = options('e', optarg); + break; + case 'S': /* start offset */ + startoff = (regoff_t)atoi(optarg); + break; + case 'E': /* end offset */ + endoff = (regoff_t)atoi(optarg); + break; + case 'x': /* Debugging. */ + debug++; + break; + case '?': + default: + errflg++; + break; + } + if (errflg) { + fprintf(stderr, "usage: %s ", progname); + fprintf(stderr, "[-c copt][-C][-d] [re]\n"); + exit(2); + } + + if (optind >= argc) { + regress(stdin); + exit(status); + } + + err = regcomp(&re, argv[optind++], copts); + if (err) { + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "error %s, %zd/%zd `%s'\n", + eprint(err), len, (size_t)sizeof(erbuf), erbuf); + exit(status); + } + regprint(&re, stdout); + + if (optind >= argc) { + regfree(&re); + exit(status); + } + + if (eopts®_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®_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] = ∅ + 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®_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)®_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®_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] = ∅ + } + 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 = ∅ + } + + /* check rm_so and rm_eo for consistency */ + if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) || + (sub.rm_so != -1 && sub.rm_eo == -1) || + (sub.rm_so != -1 && sub.rm_so < 0) || + (sub.rm_eo != -1 && sub.rm_eo < 0) ) { + sprintf(grump, "start %ld end %ld", (long)sub.rm_so, + (long)sub.rm_eo); + return(grump); + } + + /* check for no match */ + if (sub.rm_so == -1) { + if (should == NULL) + return(NULL); + else { + sprintf(grump, "did not match"); + return(grump); + } + } + + /* check for in range */ + if (sub.rm_eo > (ssize_t)strlen(str)) { + sprintf(grump, "start %ld end %ld, past end of string", + (long)sub.rm_so, (long)sub.rm_eo); + return(grump); + } + + len = (int)(sub.rm_eo - sub.rm_so); + p = str + sub.rm_so; + + /* check for not supposed to match */ + if (should == NULL) { + sprintf(grump, "matched `%.*s'", len, p); + return(grump); + } + + /* check for wrong match */ + shlen = (int)strlen(should); + if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { + sprintf(grump, "matched `%.*s' instead", len, p); + return(grump); + } + if (shlen > 0) + return(NULL); + + /* check null match in right place */ + if (at == NULL) + return(NULL); + shlen = strlen(at); + if (shlen == 0) + shlen = 1; /* force check for end-of-string */ + if (strncmp(p, at, shlen) != 0) { + sprintf(grump, "matched null at `%.20s'", p); + return(grump); + } + return(NULL); +} + +/* + * eprint - convert error number to name + */ +static char * +eprint(int err) +{ + static char epbuf[100]; + size_t len; + + len = regerror(REG_ITOA|err, NULL, epbuf, sizeof(epbuf)); + assert(len <= sizeof(epbuf)); + return(epbuf); +} + +/* + * efind - convert error name to number + */ +static int +efind(char *name) +{ + static char efbuf[100]; + regex_t re; + + sprintf(efbuf, "REG_%s", name); + assert(strlen(efbuf) < sizeof(efbuf)); + re.re_endp = efbuf; + (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); + return(atoi(efbuf)); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/split.c b/contrib/netbsd-tests/lib/libc/regex/split.c new file mode 100644 index 0000000..2a26b50 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/split.c @@ -0,0 +1,344 @@ +/* $NetBSD: split.c,v 1.1 2011/01/08 18:10:31 pgoyette Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <regex.h> +#include <stdio.h> +#include <string.h> + +#include "test_regex.h" + +/* + * split - divide a string into fields, like awk split() + * + * returns number of fields, including overflow + * + * fields[] list is not NULL-terminated + * nfields number of entries available in fields[] + * sep "" white, "c" single char, "ab" [ab]+ + */ +int +split(char *string, char *fields[], int nfields, const char *sep) +{ + char *p = string; + char c; /* latest character */ + char sepc = *sep; + char sepc2; + int fn; + char **fp = fields; + const char *sepp; + int trimtrail; + + /* white space */ + if (sepc == '\0') { + while ((c = *p++) == ' ' || c == '\t') + continue; + p--; + trimtrail = 1; + sep = " \t"; /* note, code below knows this is 2 long */ + sepc = ' '; + } else + trimtrail = 0; + sepc2 = sep[1]; /* now we can safely pick this up */ + + /* catch empties */ + if (*p == '\0') + return(0); + + /* single separator */ + if (sepc2 == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + if (fn == 0) + break; + while ((c = *p++) != sepc) + if (c == '\0') + return(nfields - fn); + *(p-1) = '\0'; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + for (;;) { + while ((c = *p++) != sepc) + if (c == '\0') + return(fn); + fn++; + } + /* not reached */ + } + + /* two separators */ + if (sep[2] == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + while ((c = *p++) != sepc && c != sepc2) + if (c == '\0') { + if (trimtrail && **(fp-1) == '\0') + fn++; + return(nfields - fn); + } + if (fn == 0) + break; + *(p-1) = '\0'; + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + while (c != '\0') { + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + fn++; + while ((c = *p++) != '\0' && c != sepc && c != sepc2) + continue; + } + /* might have to trim trailing white space */ + if (trimtrail) { + p--; + while ((c = *--p) == sepc || c == sepc2) + continue; + p++; + if (*p != '\0') { + if (fn == nfields+1) + *p = '\0'; + fn--; + } + } + return(fn); + } + + /* n separators */ + fn = 0; + for (;;) { + if (fn < nfields) + *fp++ = p; + fn++; + for (;;) { + c = *p++; + if (c == '\0') + return(fn); + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc != '\0') /* it was a separator */ + break; + } + if (fn < nfields) + *(p-1) = '\0'; + for (;;) { + c = *p++; + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc == '\0') /* it wasn't a separator */ + break; + } + p--; + } + + /* not reached */ +} + +#ifdef TEST_SPLIT + + +/* + * test program + * pgm runs regression + * pgm sep splits stdin lines by sep + * pgm str sep splits str by sep + * pgm str sep n splits str by sep n times + */ +int +main(int argc, char *argv[]) +{ + char buf[512]; + int n; +# define MNF 10 + char *fields[MNF]; + + if (argc > 4) + for (n = atoi(argv[3]); n > 0; n--) { + (void) strcpy(buf, argv[1]); + } + else if (argc > 3) + for (n = atoi(argv[3]); n > 0; n--) { + (void) strcpy(buf, argv[1]); + (void) split(buf, fields, MNF, argv[2]); + } + else if (argc > 2) + dosplit(argv[1], argv[2]); + else if (argc > 1) + while (fgets(buf, sizeof(buf), stdin) != NULL) { + buf[strlen(buf)-1] = '\0'; /* stomp newline */ + dosplit(buf, argv[1]); + } + else + regress(); + + exit(0); +} + +void +dosplit(char *string, char *seps) +{ +# define NF 5 + char *fields[NF]; + int nf; + + nf = split(string, fields, NF, seps); + print(nf, NF, fields); +} + +void +print(int nf, int nfp, char *fields) +{ + int fn; + int bound; + + bound = (nf > nfp) ? nfp : nf; + printf("%d:\t", nf); + for (fn = 0; fn < bound; fn++) + printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n"); +} + +#define RNF 5 /* some table entries know this */ +struct { + char *str; + char *seps; + int nf; + char *fi[RNF]; +} tests[] = { + "", " ", 0, { "" }, + " ", " ", 2, { "", "" }, + "x", " ", 1, { "x" }, + "xy", " ", 1, { "xy" }, + "x y", " ", 2, { "x", "y" }, + "abc def g ", " ", 5, { "abc", "def", "", "g", "" }, + " a bcd", " ", 4, { "", "", "a", "bcd" }, + "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " ", 6, { "", "a", "b", "c", "d " }, + + "", " _", 0, { "" }, + " ", " _", 2, { "", "" }, + "x", " _", 1, { "x" }, + "x y", " _", 2, { "x", "y" }, + "ab _ cd", " _", 2, { "ab", "cd" }, + " a_b c ", " _", 5, { "", "a", "b", "c", "" }, + "a b c_d e f", " _", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " _", 6, { "", "a", "b", "c", "d " }, + + "", " _~", 0, { "" }, + " ", " _~", 2, { "", "" }, + "x", " _~", 1, { "x" }, + "x y", " _~", 2, { "x", "y" }, + "ab _~ cd", " _~", 2, { "ab", "cd" }, + " a_b c~", " _~", 5, { "", "a", "b", "c", "" }, + "a b_c d~e f", " _~", 6, { "a", "b", "c", "d", "e f" }, + "~a b c d ", " _~", 6, { "", "a", "b", "c", "d " }, + + "", " _~-", 0, { "" }, + " ", " _~-", 2, { "", "" }, + "x", " _~-", 1, { "x" }, + "x y", " _~-", 2, { "x", "y" }, + "ab _~- cd", " _~-", 2, { "ab", "cd" }, + " a_b c~", " _~-", 5, { "", "a", "b", "c", "" }, + "a b_c-d~e f", " _~-", 6, { "a", "b", "c", "d", "e f" }, + "~a-b c d ", " _~-", 6, { "", "a", "b", "c", "d " }, + + "", " ", 0, { "" }, + " ", " ", 2, { "", "" }, + "x", " ", 1, { "x" }, + "xy", " ", 1, { "xy" }, + "x y", " ", 2, { "x", "y" }, + "abc def g ", " ", 4, { "abc", "def", "g", "" }, + " a bcd", " ", 3, { "", "a", "bcd" }, + "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " ", 6, { "", "a", "b", "c", "d " }, + + "", "", 0, { "" }, + " ", "", 0, { "" }, + "x", "", 1, { "x" }, + "xy", "", 1, { "xy" }, + "x y", "", 2, { "x", "y" }, + "abc def g ", "", 3, { "abc", "def", "g" }, + "\t a bcd", "", 2, { "a", "bcd" }, + " a \tb\t c ", "", 3, { "a", "b", "c" }, + "a b c d e ", "", 5, { "a", "b", "c", "d", "e" }, + "a b\tc d e f", "", 6, { "a", "b", "c", "d", "e f" }, + " a b c d e f ", "", 6, { "a", "b", "c", "d", "e f " }, + + NULL, NULL, 0, { NULL }, +}; + +void +regress(void) +{ + char buf[512]; + int n; + char *fields[RNF+1]; + int nf; + int i; + int printit; + char *f; + + for (n = 0; tests[n].str != NULL; n++) { + (void) strcpy(buf, tests[n].str); + fields[RNF] = NULL; + nf = split(buf, fields, RNF, tests[n].seps); + printit = 0; + if (nf != tests[n].nf) { + printf("split `%s' by `%s' gave %d fields, not %d\n", + tests[n].str, tests[n].seps, nf, tests[n].nf); + printit = 1; + } else if (fields[RNF] != NULL) { + printf("split() went beyond array end\n"); + printit = 1; + } else { + for (i = 0; i < nf && i < RNF; i++) { + f = fields[i]; + if (f == NULL) + f = "(NULL)"; + if (strcmp(f, tests[n].fi[i]) != 0) { + printf("split `%s' by `%s', field %d is `%s', not `%s'\n", + tests[n].str, tests[n].seps, + i, fields[i], tests[n].fi[i]); + printit = 1; + } + } + } + if (printit) + print(nf, RNF, fields); + } +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c new file mode 100644 index 0000000..468492c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c @@ -0,0 +1,210 @@ +/* $NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $"); + +#include <stdio.h> +#include <regex.h> +#include <string.h> +#include <stdlib.h> +#include <err.h> +#include <atf-c.h> + +#ifndef REGEX_MAXSIZE +#define REGEX_MAXSIZE 9999 +#endif + +static char * +mkstr(const char *str, size_t len) +{ + size_t slen = strlen(str); + char *p = malloc(slen * len + 1); + ATF_REQUIRE(p != NULL); + for (size_t i = 0; i < len; i++) + strcpy(&p[i * slen], str); + return p; +} + +static char * +concat(const char *d, const char *s) +{ + size_t dlen = strlen(d); + size_t slen = strlen(s); + char *p = malloc(dlen + slen + 1); + + ATF_REQUIRE(p != NULL); + strcpy(p, d); + strcpy(p + dlen, s); + return p; +} + +static char * +p0(size_t len) +{ + char *d, *s1, *s2; + s1 = mkstr("\\(", len); + s2 = concat(s1, ")"); + free(s1); + d = concat("(", s2); + free(s2); + return d; +} + +static char * +p1(size_t len) +{ + char *d, *s1, *s2, *s3; + s1 = mkstr("\\(", 60); + s2 = mkstr("(.*)", len); + s3 = concat(s1, s2); + free(s2); + free(s1); + s1 = concat(s3, ")"); + free(s3); + d = concat("(", s1); + free(s1); + return d; +} + +static char * +ps(const char *m, const char *s, size_t len) +{ + char *d, *s1, *s2, *s3; + s1 = mkstr(m, len); + s2 = mkstr(s, len); + s3 = concat(s1, s2); + free(s2); + free(s1); + d = concat("(.?)", s3); + free(s3); + return d; +} + +static char * +p2(size_t len) +{ + return ps("((.*){0,255}", ")", len); +} + +static char * +p3(size_t len) +{ + return ps("(.\\{0,}", ")", len); +} + +static char * +p4(size_t len) +{ + return ps("((.*){1,255}", ")", len); +} + +static char * +p5(size_t len) +{ + return ps("(", "){1,100}", len); +} + +static char * +p6(size_t len) +{ + char *d, *s1, *s2; + s1 = mkstr("(?:(.*)|", len); + s2 = concat(s1, "(.*)"); + free(s1); + s1 = mkstr(")", len); + d = concat(s2, s1); + free(s1); + free(s2); + return d; +} + +static const struct { + char *(*pattern)(size_t); + int type; +} tests[] = { + { p0, REG_EXTENDED }, + { p1, REG_EXTENDED }, + { p2, REG_EXTENDED }, + { p3, REG_EXTENDED }, + { p4, REG_EXTENDED }, + { p5, REG_EXTENDED }, + { p6, REG_BASIC }, +}; + +ATF_TC(regcomp_too_big); + +ATF_TC_HEAD(regcomp_too_big, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that large patterns don't" + " crash, but return a proper error code"); + // libtre needs it. + atf_tc_set_md_var(tc, "timeout", "600"); + atf_tc_set_md_var(tc, "require.memory", "120M"); +} + +ATF_TC_BODY(regcomp_too_big, tc) +{ + regex_t re; + int e; + + for (size_t i = 0; i < __arraycount(tests); i++) { + char *d = (*tests[i].pattern)(REGEX_MAXSIZE); + e = regcomp(&re, d, tests[i].type); + if (e) { + char ebuf[1024]; + (void)regerror(e, &re, ebuf, sizeof(ebuf)); + ATF_REQUIRE_MSG(e == REG_ESPACE, + "regcomp returned %d (%s) for pattern %zu [%s]", e, ebuf, + i, d); + free(d); + continue; + } + free(d); + (void)regexec(&re, "aaaaaaaaaaa", 0, NULL, 0); + regfree(&re); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, regcomp_too_big); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex.sh b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh new file mode 100755 index 0000000..bef3ac9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh @@ -0,0 +1,73 @@ +# $NetBSD: t_regex.sh,v 1.1 2012/08/24 20:24:40 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +check() +{ + local dataname="${1}"; shift + + prog="$(atf_get_srcdir)/h_regex" + data="$(atf_get_srcdir)/data/${dataname}.in" + + atf_check -x "${prog} <${data}" + atf_check -x "${prog} -el <${data}" + atf_check -x "${prog} -er <${data}" +} + +create_tc() +{ + local name="${1}"; shift + local descr="${1}"; shift + + atf_test_case "${name}" + eval "${name}_head() { atf_set 'descr' '${descr}'; }" + eval "${name}_body() { check '${name}'; }" + + atf_add_test_case "${name}" +} + +atf_init_test_cases() +{ + create_tc basic "Checks basic functionality" + create_tc paren "Checks parentheses" + create_tc anchor "Checks anchors and REG_NEWLINE" + create_tc error "Checks syntax errors and non-errors" + create_tc meta "Checks metacharacters and backslashes" + create_tc backref "Checks back references" + create_tc repet_ordinary "Checks ordinary repetitions" + create_tc repet_bounded "Checks bounded repetitions" + create_tc repet_multi "Checks multiple repetitions" + create_tc bracket "Checks brackets" + create_tc complex "Checks various complex examples" + create_tc subtle "Checks various subtle examples" + create_tc c_comments "Checks matching C comments" + create_tc subexp "Checks subexpressions" + create_tc startend "Checks STARTEND option" + create_tc nospec "Checks NOSPEC option" + create_tc zero "Checks NULs" + create_tc word_bound "Checks word boundaries" + create_tc regress "Checks various past problems and suspected problems" +} diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c new file mode 100644 index 0000000..beaeb04 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c @@ -0,0 +1,629 @@ +/* $NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $"); + +#include <sys/param.h> + +#include <stdio.h> +#include <regex.h> +#include <string.h> +#include <stdlib.h> +#include <vis.h> +#include <ctype.h> +#include <atf-c.h> + +static const char sep[] = "\r\n\t"; +static const char delim[3] = "\\\\\0"; + + +static void +fail(const char *pattern, const char *input, size_t lineno) { + fprintf(stderr, + "skipping failed test at line %zu (pattern=%s, input=%s)\n", + lineno, pattern, input); +} + +static int +bug(const char *pattern, const char *input, size_t lineno) { + static const struct { + const char *p; + const char *i; + } b[] = { +#if defined(REGEX_SPENCER) + /* + * The default libc implementation by Henry Spencer + */ + { "a[-]?c", "ac" }, // basic.dat + { "(a*)*", "a" }, // categorization.dat + { "(aba|a*b)*", "ababa" }, // categorization.dat + { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat + { "(a*)*", "aaaaaa" }, // nullsubexpression.dat + { "(a*)*", "aaaaaax" }, // nullsubexpression.dat + { "(a*)+", "a" }, // nullsubexpression.dat + { "(a*)+", "aaaaaa" }, // nullsubexpression.dat + { "(a*)+", "aaaaaax" }, // nullsubexpression.dat + { "([a]*)*", "a" }, // nullsubexpression.dat + { "([a]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([a]*)*", "aaaaaax" }, // nullsubexpression.dat + { "([a]*)+", "a" }, // nullsubexpression.dat + { "([a]*)+", "aaaaaa" }, // nullsubexpression.dat + { "([a]*)+", "aaaaaax" }, // nullsubexpression.dat + { "([^b]*)*", "a" }, // nullsubexpression.dat + { "([^b]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([^b]*)*", "aaaaaab" }, // nullsubexpression.dat + { "([ab]*)*", "a" }, // nullsubexpression.dat + { "([ab]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([ab]*)*", "ababab" }, // nullsubexpression.dat + { "([ab]*)*", "bababa" }, // nullsubexpression.dat + { "([ab]*)*", "b" }, // nullsubexpression.dat + { "([ab]*)*", "bbbbbb" }, // nullsubexpression.dat + { "([ab]*)*", "aaaabcde" }, // nullsubexpression.dat + { "([^a]*)*", "b" }, // nullsubexpression.dat + { "([^a]*)*", "bbbbbb" }, // nullsubexpression.dat + { "([^ab]*)*", "ccccxx" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)", "ax" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)", "axa" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)", "x" }, // nullsubexpression.dat +/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // nullsubexpression.dat +/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // "" + { "(a*)*(x)", "ax" }, // nullsubexpression.dat + { "(a*)*(x)", "axa" }, // nullsubexpression.dat + { "(a*)+(x)", "ax" }, // nullsubexpression.dat + { "(a*)+(x)", "axa" }, // nullsubexpression.dat + { "((a|ab)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat + { "((a|ab)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat + { "((ab|a)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat + { "((ab|a)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat + { "((a*)(b|abc))(c*)", "abc" }, // forcedassoc.dat + { "((a*)(abc|b))(c*)", "abc" }, // forcedassoc.dat + { "((..)|(.)){2}", "aaa" }, // repetition.dat + { "((..)|(.)){3}", "aaa" }, // repetition.dat + { "((..)|(.)){3}", "aaaa" }, // repetition.dat + { "((..)|(.)){3}", "aaaaa" }, // repetition.dat + { "X(.?){0,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){1,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){2,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){3,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){4,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){5,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){6,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){0,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){1,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){2,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){3,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){4,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){5,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){6,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){7,8}Y", "X1234567Y" }, // repetition.dat + { "(a|ab|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd)*(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd)+(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd)*(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd)+(d*)", "ababcd" }, // repetition.dat +#elif defined(REGEX_TRE) + { "a[-]?c", "ac" }, // basic.dat + { "a\\(b\\)*\\1", "a" }, // categorization.dat + { "a\\(b\\)*\\1", "abab" }, // categorization.dat + { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // categorization.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // "" + { "((..)|(.))*", "aa" }, // repetition.dat + { "((..)|(.))*", "aaa" }, // repetition.dat + { "((..)|(.))*", "aaaaa" }, // repetition.dat + { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat +#else + { "", "" } +#endif + }; + + for (size_t i = 0; i < __arraycount(b); i++) { + if (strcmp(pattern, b[i].p) == 0 && + strcmp(input, b[i].i) == 0) { + fail(pattern, input, lineno); + return 1; + } + } + return 0; +} + +#ifdef REGEX_SPENCER +#define HAVE_BRACES 1 +#define HAVE_MINIMAL 0 +#endif +#ifndef HAVE_BRACES +#define HAVE_BRACES 1 +#endif +#ifndef HAVE_MINIMAL +#define HAVE_MINIMAL 1 +#endif + +static int +optional(const char *s) +{ + static const struct{ + const char *n; + int v; + } nv[]= { + { "[[<element>]] not supported", HAVE_BRACES }, + { "no *? +? mimimal match ops", HAVE_MINIMAL }, + }; + + for (size_t i = 0; i < __arraycount(nv); i++) + if (strcmp(nv[i].n, s) == 0) { + if (nv[i].v) + return 0; + fprintf(stderr, "skipping unsupported [%s] tests\n", s); + return 1; + } + + ATF_REQUIRE_MSG(0, "Unknown feature: %s", s); + return 0; +} + +static int +unsupported(const char *s) +{ + static const char *we[] = { +#if defined(REGEX_SPENCER) + "ASSOCIATIVITY=left", // have right associativity + "SUBEXPRESSION=precedence", // have grouping subexpression + "REPEAT_LONGEST=last", // have first repeat longest + "BUG=alternation-order", // don't have it + "BUG=first-match", // don't have it + "BUG=nomatch-match", // don't have it + "BUG=repeat-any", // don't have it + "BUG=range-null", // don't have it + "BUG=repeat-null-unknown", // don't have it + "BUG=repeat-null", // don't have it + "BUG=repeat-artifact", // don't have it + "BUG=subexpression-first", // don't have it +#elif defined(REGEX_TRE) + "ASSOCIATIVITY=right", // have left associativity + "SUBEXPRESSION=grouping", // have precedence subexpression + "REPEAT_LONGEST=first", // have last repeat longest + "LENGTH=first", // have last length + "BUG=alternation-order", // don't have it + "BUG=first-match", // don't have it + "BUG=range-null", // don't have it + "BUG=repeat-null", // don't have it + "BUG=repeat-artifact", // don't have it + "BUG=subexpression-first", // don't have it + "BUG=repeat-short", // don't have it +#endif + }; + + if (s == NULL) + return 0; + + while (*s == '#' || isspace((unsigned char)*s)) + s++; + + for (size_t i = 0; i < __arraycount(we); i++) + if (strcmp(we[i], s) == 0) + return 1; + return 0; +} + +static void +geterror(const char *s, int *comp, int *exec) +{ + static const struct { + const char *n; + int v; + int ce; + } nv[] = { +#define COMP 1 +#define EXEC 2 + { "OK", 0, COMP|EXEC }, +#define _DO(a, b) { # a, REG_ ## a, b }, + _DO(NOMATCH, EXEC) + _DO(BADPAT, COMP) + _DO(ECOLLATE, COMP) + _DO(ECTYPE, COMP) + _DO(EESCAPE, COMP) + _DO(ESUBREG, COMP) + _DO(EBRACK, COMP) + _DO(EPAREN, COMP) + _DO(EBRACE, COMP) + _DO(BADBR, COMP) + _DO(ERANGE, COMP) + _DO(ESPACE, EXEC) + _DO(BADRPT, COMP) + _DO(EMPTY, COMP) + _DO(ASSERT, COMP) + _DO(INVARG, COMP) + _DO(ENOSYS, COMP) +#undef _DO + }; + *comp = 0; + *exec = 0; + for (size_t i = 0; i < __arraycount(nv); i++) + if (strcmp(s, nv[i].n) == 0) { + if (nv[i].ce & COMP) + *comp = nv[i].v; + if (nv[i].ce & EXEC) + *exec = nv[i].v; + return; + } + ATF_REQUIRE_MSG(0, "Unknown error %s", s); + return; +} + +static int +getflags(char *s) +{ + int flags = 0; + + for (;; s++) + switch (*s) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *s = '\0'; + break; + case '\0': + return flags; + case 'B': + case 'E': + case 'F': + case 'L': + break; + case 'i': + flags |= REG_ICASE; + *s = '\0'; + break; + case '$': + *s = '\0'; + break; + case 'n': + *s = '\0'; + break; + default: + ATF_REQUIRE_MSG(0, "Unknown char %c", *s); + break; + } +} + +static size_t +getmatches(const char *s) +{ + size_t i; + char *q; + for (i = 0; (q = strchr(s, '(')) != NULL; i++, s = q + 1) + continue; + ATF_REQUIRE_MSG(i != 0, "No parentheses found"); + return i; +} + +static void +checkcomment(const char *s, size_t lineno) +{ + if (s && strstr(s, "BUG") != NULL) + fprintf(stderr, "Expected %s at line %zu\n", s, lineno); +} + +static void +checkmatches(const char *matches, size_t nm, const regmatch_t *pm, + size_t lineno) +{ + if (nm == 0) + return; + + char *res; + size_t len = strlen(matches) + 1, off = 0; + + ATF_REQUIRE((res = strdup(matches)) != NULL); + for (size_t i = 0; i < nm; i++) { + int l; + if (pm[i].rm_so == -1 && pm[i].rm_eo == -1) + l = snprintf(res + off, len - off, "(?,?)"); + else + l = snprintf(res + off, len - off, "(%lld,%lld)", + (long long)pm[i].rm_so, (long long)pm[i].rm_eo); + ATF_REQUIRE_MSG((size_t) l < len - off, "String too long %s" + " cur=%d, max=%zu", res, l, len - off); + off += l; + } + ATF_REQUIRE_STREQ_MSG(res, matches, " at line %zu", lineno); + free(res); +} + +static void +att_test(const struct atf_tc *tc, const char *data_name) +{ + regex_t re; + char *line, *lastpattern = NULL, data_path[MAXPATHLEN]; + size_t len, lineno = 0; + int skipping = 0; + FILE *input_file; + + snprintf(data_path, sizeof(data_path), "%s/data/%s.dat", + atf_tc_get_config_var(tc, "srcdir"), data_name); + + input_file = fopen(data_path, "r"); + if (input_file == NULL) + atf_tc_fail("Failed to open input file %s", data_path); + + for (; (line = fparseln(input_file, &len, &lineno, delim, 0)) + != NULL; free(line)) { + char *name, *pattern, *input, *matches, *comment; + regmatch_t *pm; + size_t nm; +#ifdef DEBUG + fprintf(stderr, "[%s]\n", line); +#endif + if ((name = strtok(line, sep)) == NULL) + continue; + + /* + * We check these early so that we skip the lines quickly + * in order to do more strict testing on the other arguments + * The same characters are also tested in the switch below + */ + if (*name == '}') { + skipping = 0; + continue; + } + if (skipping) + continue; + if (*name == ';' || *name == '#' || strcmp(name, "NOTE") == 0) + continue; + if (*name == ':') { + /* Skip ":HA#???:" prefix */ + while (*++name && *name != ':') + continue; + if (*name) + name++; + } + + ATF_REQUIRE_MSG((pattern = strtok(NULL, sep)) != NULL, + "Missing pattern at line %zu", lineno); + ATF_REQUIRE_MSG((input = strtok(NULL, sep)) != NULL, + "Missing input at line %zu", lineno); + + if (strchr(name, '$')) { + ATF_REQUIRE(strunvis(pattern, pattern) != -1); + ATF_REQUIRE(strunvis(input, input) != -1); + } + + + if (strcmp(input, "NULL") == 0) + *input = '\0'; + + if (strcmp(pattern, "SAME") == 0) { + ATF_REQUIRE(lastpattern != NULL); + pattern = lastpattern; + } else { + free(lastpattern); + ATF_REQUIRE((lastpattern = strdup(pattern)) != NULL); + } + + ATF_REQUIRE_MSG((matches = strtok(NULL, sep)) != NULL, + "Missing matches at line %zu", lineno); + + comment = strtok(NULL, sep); + switch (*name) { + case '{': /* Begin optional implementation */ + if (optional(comment)) { + skipping++; + continue; + } + name++; /* We have it, so ignore */ + break; + case '}': /* End optional implementation */ + skipping = 0; + continue; + case '?': /* Optional */ + case '|': /* Alternative */ + if (unsupported(comment)) + continue; + name++; /* We have it, so ignore */ + break; + case '#': /* Comment */ + case ';': /* Skip */ + continue; + default: + break; + } + + /* XXX: Our bug */ + if (bug(pattern, input, lineno)) + continue; + + int comp, exec; + if (*matches != '(') { + geterror(matches, &comp, &exec); + pm = NULL; + nm = 0; + } else { + comp = exec = 0; + nm = getmatches(matches); + ATF_REQUIRE((pm = calloc(nm, sizeof(*pm))) != NULL); + } + + + + int iflags = getflags(name); + for (; *name; name++) { + int flags; + switch (*name) { + case 'B': + flags = REG_BASIC; + break; + case 'E': + flags = REG_EXTENDED; + break; + case 'L': + flags = REG_NOSPEC; + break; + default: + ATF_REQUIRE_MSG(0, "Bad name %c", *name); + continue; + } + int c = regcomp(&re, pattern, flags | iflags); + ATF_REQUIRE_MSG(c == comp, + "regcomp returned %d for pattern %s at line %zu", + c, pattern, lineno); + if (c) + continue; + int e = regexec(&re, input, nm, pm, 0); + ATF_REQUIRE_MSG(e == exec, "Expected error %d," + " got %d at line %zu", exec, e, lineno); + checkmatches(matches, nm, pm, lineno); + checkcomment(comment, lineno); + regfree(&re); + } + free(pm); + } + + fclose(input_file); +} + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests basic functionality"); +} +ATF_TC_BODY(basic, tc) +{ + att_test(tc, "basic"); +} + +ATF_TC(categorization); +ATF_TC_HEAD(categorization, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests implementation categorization"); +} +ATF_TC_BODY(categorization, tc) +{ + att_test(tc, "categorization"); +} + +ATF_TC(nullsubexpr); +ATF_TC_HEAD(nullsubexpr, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests (...)*"); +} +ATF_TC_BODY(nullsubexpr, tc) +{ + att_test(tc, "nullsubexpr"); +} + +ATF_TC(leftassoc); +ATF_TC_HEAD(leftassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests left-associative " + "implementations"); +} +ATF_TC_BODY(leftassoc, tc) +{ +#if SKIP_LEFTASSOC + /* jmmv: I converted the original shell-based tests to C and they + * disabled this test in a very unconventional way without giving + * any explation. Mark as broken here, but I don't know why. */ + atf_tc_expect_fail("Reason for breakage unknown"); +#endif + att_test(tc, "leftassoc"); +} + +ATF_TC(rightassoc); +ATF_TC_HEAD(rightassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests right-associative " + "implementations"); +} +ATF_TC_BODY(rightassoc, tc) +{ +#if SKIP_RIGHTASSOC + /* jmmv: I converted the original shell-based tests to C and they + * disabled this test in a very unconventional way without giving + * any explation. Mark as broken here, but I don't know why. */ + atf_tc_expect_fail("Reason for breakage unknown"); +#endif + att_test(tc, "rightassoc"); +} + +ATF_TC(forcedassoc); +ATF_TC_HEAD(forcedassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests subexpression grouping to " + "force association"); +} +ATF_TC_BODY(forcedassoc, tc) +{ + att_test(tc, "forcedassoc"); +} + +ATF_TC(repetition); +ATF_TC_HEAD(repetition, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests implicit vs. explicit " + "repetition"); +} +ATF_TC_BODY(repetition, tc) +{ + att_test(tc, "repetition"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, categorization); + ATF_TP_ADD_TC(tp, nullsubexpr); + ATF_TP_ADD_TC(tp, leftassoc); + ATF_TP_ADD_TC(tp, rightassoc); + ATF_TP_ADD_TC(tp, forcedassoc); + ATF_TP_ADD_TC(tp, repetition); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/test_regex.h b/contrib/netbsd-tests/lib/libc/regex/test_regex.h new file mode 100644 index 0000000..1d9f59d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/test_regex.h @@ -0,0 +1,44 @@ +/* $NetBSD: test_regex.h,v 1.1 2011/01/08 18:10:31 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* from main.c */ +void regress(FILE *); +void try(char *, char *, char *, char *, char *, int); +int options(int, char *); +int opt(int, char *); +void fixstr(char *); +char *check(char *, regmatch_t, char *); + +/* from split.c */ +int split(char *string, char *fields[], int nfields, const char *sep); + +/* from debug.c */ +void regprint(regex_t *r, FILE *d); diff --git a/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x new file mode 100644 index 0000000..cbddfcc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x @@ -0,0 +1,21 @@ +/* $NetBSD: h_testbits.x,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */ + +enum smallenum { + SE_ONE = 1, + SE_TWO = 2 +}; + +enum medenum { + ME_NEG = -1234, + ME_ONE = 1, + ME_TWO = 2, + ME_MANY = 1234 +}; + +enum bigenum { + BE_ONE = 1, + BE_TWO = 2, + BE_MANY = 1234, + BE_LOTS = 1234567 +}; + diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c new file mode 100644 index 0000000..cc1ec09 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c @@ -0,0 +1,157 @@ +/* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $"); + +#include <sys/types.h> +#include <sys/socket.h> +#include <rpc/rpc.h> +#include <stdlib.h> +#include <err.h> +#include <netdb.h> +#include <stdio.h> +#include <unistd.h> + + +#ifndef TEST +#include <atf-c.h> + +#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) + +#define SKIPX(ev, msg, ...) do { \ + atf_tc_skip(msg, __VA_ARGS__); \ + return; \ +} while(/*CONSTCOND*/0) + +#else +#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) +#define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) +#endif + + +#define RPCBPROC_NULL 0 + +static int +reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) +{ + char host[NI_MAXHOST]; + struct sockaddr *sock = raddrp->buf; + int error; + + + error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0); + if (error) + warnx("Cannot resolve address (%s)", gai_strerror(error)); + else + printf("response from: %s\n", host); + return 0; +} + +extern bool __rpc_control(int, void *); + +static void +onehost(const char *host, const char *transp) +{ + CLIENT *clnt; + struct netbuf addr; + struct timeval tv; + + /* + * Magic! + */ + tv.tv_sec = 0; + tv.tv_usec = 500000; +#define CLCR_SET_RPCB_TIMEOUT 2 + __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv); + + if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL) + SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror("")); + + tv.tv_sec = 1; + tv.tv_usec = 0; + if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) + != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); + clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); + reply(NULL, &addr, NULL); +} + +#ifdef TEST +static void +allhosts(void) +{ + enum clnt_stat clnt_stat; + + clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, + (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, + NULL, (resultproc_t)reply, transp); + if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) + ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); +} + +int +main(int argc, char *argv[]) +{ + int ch; + const char *transp = "udp"; + + + while ((ch = getopt(argc, argv, "ut")) != -1) + switch (ch) { + case 't': + transp = "tcp"; + break; + case 'u': + transp = "udp"; + break; + default: + fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n", + getprogname()); + return EXIT_FAILURE; + } + + if (argc == optind) + allhosts(); + else + for (; optind < argc; optind++) + onehost(argv[optind], transp); + + return EXIT_SUCCESS; +} + +#else + +ATF_TC(get_svc_addr_tcp); +ATF_TC_HEAD(get_svc_addr_tcp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp"); + +} + +ATF_TC_BODY(get_svc_addr_tcp, tc) +{ + onehost("localhost", "tcp"); + +} + +ATF_TC(get_svc_addr_udp); +ATF_TC_HEAD(get_svc_addr_udp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp"); +} + +ATF_TC_BODY(get_svc_addr_udp, tc) +{ + onehost("localhost", "udp"); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, get_svc_addr_udp); + ATF_TP_ADD_TC(tp, get_svc_addr_tcp); + + return atf_no_error(); +} + +#endif diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c new file mode 100644 index 0000000..2a68eb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c @@ -0,0 +1,129 @@ +/* $NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Ben Harris. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 2001 Ben Harris + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $"); + +#include <rpc/types.h> +#include <rpc/xdr.h> + +#include <string.h> + +#include <atf-c.h> + +#include "h_testbits.h" + +char xdrdata[] = { + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* double 1.0 */ + 0x00, 0x00, 0x00, 0x01, /* enum smallenum SE_ONE */ + 0xff, 0xff, 0xfb, 0x2e, /* enum medenum ME_NEG */ + 0x00, 0x12, 0xd6, 0x87, /* enum bigenum BE_LOTS */ +}; + +ATF_TC(xdr); +ATF_TC_HEAD(xdr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks encoding/decoding of doubles and enumerations"); +} +ATF_TC_BODY(xdr, tc) +{ + XDR x; + double d; + smallenum s; + medenum m; + bigenum b; + char newdata[sizeof(xdrdata)]; + + xdrmem_create(&x, xdrdata, sizeof(xdrdata), XDR_DECODE); + + ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double DECODE failed"); + ATF_REQUIRE_EQ_MSG(d, 1.0, "double 1.0 decoded as %g", d); + + ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(s, SE_ONE, "SE_ONE decoded as %d", s); + + ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(m, ME_NEG, "ME_NEG decoded as %d", m); + + ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(b, BE_LOTS, "BE_LOTS decoded as %d", b); + + xdr_destroy(&x); + + + xdrmem_create(&x, newdata, sizeof(newdata), XDR_ENCODE); + + ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double ENCODE failed"); + ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum ENCODE failed"); + ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum ENCODE failed"); + ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum ENCODE failed"); + ATF_REQUIRE_MSG(memcmp(newdata, xdrdata, sizeof(xdrdata)) == 0, + "xdr ENCODE result differs"); + + xdr_destroy(&x); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, xdr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c new file mode 100644 index 0000000..4d2a93b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c @@ -0,0 +1,196 @@ +/* $NetBSD: t_setjmp.c,v 1.1 2010/12/27 19:35:31 pgoyette Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1994 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_setjmp.c,v 1.1 2010/12/27 19:35:31 pgoyette Exp $"); + +#include <sys/types.h> + +#include <errno.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +#define TEST_SETJMP 0 +#define TEST_U_SETJMP 1 +#define TEST_SIGSETJMP_SAVE 2 +#define TEST_SIGSETJMP_NOSAVE 3 + +static int expectsignal; + +static void +aborthandler(int signo) +{ + ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); + atf_tc_pass(); +} + +static void +h_check(int test) +{ + struct sigaction sa; + jmp_buf jb; + sigjmp_buf sjb; + sigset_t ss; + int i, x; + + i = getpid(); + + if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) + expectsignal = 0; + else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) + expectsignal = 1; + else + atf_tc_fail("unknown test"); + + sa.sa_handler = aborthandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); + REQUIRE_ERRNO(sigemptyset(&ss) != -1); + REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); + REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + x = setjmp(jb); + else if (test == TEST_U_SETJMP) + x = _setjmp(jb); + else + x = sigsetjmp(sjb, !expectsignal); + + if (x != 0) { + ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); + kill(i, SIGABRT); + ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); + atf_tc_pass(); + } + + REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + longjmp(jb, i); + else if (test == TEST_U_SETJMP) + _longjmp(jb, i); + else + siglongjmp(sjb, i); + + atf_tc_fail("jmp failed"); +} + +ATF_TC(setjmp); +ATF_TC_HEAD(setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks setjmp(3)"); +} +ATF_TC_BODY(setjmp, tc) +{ + h_check(TEST_SETJMP); +} + +ATF_TC(_setjmp); +ATF_TC_HEAD(_setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks _setjmp(3)"); +} +ATF_TC_BODY(_setjmp, tc) +{ + h_check(TEST_U_SETJMP); +} + +ATF_TC(sigsetjmp_save); +ATF_TC_HEAD(sigsetjmp_save, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask enabled"); +} +ATF_TC_BODY(sigsetjmp_save, tc) +{ + h_check(TEST_SIGSETJMP_SAVE); +} + +ATF_TC(sigsetjmp_nosave); +ATF_TC_HEAD(sigsetjmp_nosave, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask disabled"); +} +ATF_TC_BODY(sigsetjmp_nosave, tc) +{ + h_check(TEST_SIGSETJMP_NOSAVE); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, setjmp); + ATF_TP_ADD_TC(tp, _setjmp); + ATF_TP_ADD_TC(tp, sigsetjmp_save); + ATF_TP_ADD_TC(tp, sigsetjmp_nosave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c new file mode 100644 index 0000000..4437c92 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c @@ -0,0 +1,218 @@ +/* $NetBSD: t_threadjmp.c,v 1.1 2011/04/21 18:58:20 martin Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1994 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_threadjmp.c,v 1.1 2011/04/21 18:58:20 martin Exp $"); + +#include <sys/types.h> + +#include <errno.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <pthread.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +#define TEST_SETJMP 0 +#define TEST_U_SETJMP 1 +#define TEST_SIGSETJMP_SAVE 2 +#define TEST_SIGSETJMP_NOSAVE 3 + +static pthread_t myself = NULL; + +static int expectsignal; + +static void +aborthandler(int signo) +{ + ATF_REQUIRE(myself == pthread_self()); + ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); + atf_tc_pass(); +} + +static void +h_check(int test) +{ + struct sigaction sa; + jmp_buf jb; + sigjmp_buf sjb; + sigset_t ss; + int i, x; + + myself = pthread_self(); + i = getpid(); + + if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) + expectsignal = 0; + else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) + expectsignal = 1; + else + atf_tc_fail("unknown test"); + + sa.sa_handler = aborthandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); + REQUIRE_ERRNO(sigemptyset(&ss) != -1); + REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); + REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); + ATF_REQUIRE(myself == pthread_self()); + + if (test == TEST_SETJMP) + x = setjmp(jb); + else if (test == TEST_U_SETJMP) + x = _setjmp(jb); + else + x = sigsetjmp(sjb, !expectsignal); + + if (x != 0) { + ATF_REQUIRE(myself == pthread_self()); + ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); + kill(i, SIGABRT); + ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); + ATF_REQUIRE(myself == pthread_self()); + atf_tc_pass(); + } + + ATF_REQUIRE(myself == pthread_self()); + REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + longjmp(jb, i); + else if (test == TEST_U_SETJMP) + _longjmp(jb, i); + else + siglongjmp(sjb, i); + + atf_tc_fail("jmp failed"); +} + +ATF_TC(setjmp); +ATF_TC_HEAD(setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and setjmp(3)"); +} +ATF_TC_BODY(setjmp, tc) +{ + h_check(TEST_SETJMP); +} + +ATF_TC(_setjmp); +ATF_TC_HEAD(_setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and _setjmp(3)"); +} +ATF_TC_BODY(_setjmp, tc) +{ + h_check(TEST_U_SETJMP); +} + +ATF_TC(sigsetjmp_save); +ATF_TC_HEAD(sigsetjmp_save, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and sigsetjmp(3) with savemask enabled"); +} +ATF_TC_BODY(sigsetjmp_save, tc) +{ + h_check(TEST_SIGSETJMP_SAVE); +} + +ATF_TC(sigsetjmp_nosave); +ATF_TC_HEAD(sigsetjmp_nosave, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and sigsetjmp(3) with savemask disabled"); +} +ATF_TC_BODY(sigsetjmp_nosave, tc) +{ + h_check(TEST_SIGSETJMP_NOSAVE); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * These test cases try to verify setjmp and friends in a program + * linked with pthreads, and verify that pthread_self() stays + * consistent throughout the program. A setcontext() call invoked + * by *setjmp() might clobber the TLS special register used to + * implement pthread_self(). + */ + ATF_TP_ADD_TC(tp, setjmp); + ATF_TP_ADD_TC(tp, _setjmp); + ATF_TP_ADD_TC(tp, sigsetjmp_save); + ATF_TP_ADD_TC(tp, sigsetjmp_nosave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c new file mode 100644 index 0000000..ad9376a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c @@ -0,0 +1,46 @@ +/* $NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)fgets(b, len, stdin); + (void)printf("%s\n", b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c new file mode 100644 index 0000000..68e3a6f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <sys/param.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + (void)getcwd(b, len); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_gets.c b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c new file mode 100644 index 0000000..8c601b0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c @@ -0,0 +1,43 @@ +/* $NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)gets(b); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c new file mode 100644 index 0000000..1950f73 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + + (void)memcpy(b, "1020202020202", len); + (void)printf("%*.*s\n", len, len, b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c new file mode 100644 index 0000000..0ebfd29 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + + (void)memmove(b, "1020202020202", len); + (void)printf("%*.*s\n", len, len, b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memset.c b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c new file mode 100644 index 0000000..65ed5f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c @@ -0,0 +1,45 @@ +/* $NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + size_t len = atoi(argv[1]); + (void)memset(b, 0, len); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_raw.c b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c new file mode 100644 index 0000000..a232481 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c @@ -0,0 +1,57 @@ +/* $NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $"); + +#include <stdio.h> +#include <stdlib.h> + +void poke(int *, size_t); + +void +poke(int *b, size_t index) +{ + size_t i; + volatile int sum = 0; + + b[index] = 42; + for (i = 0; i < 10; i++) + sum += b[i]; +} + +int +main(int argc, char *argv[]) +{ + int b[10]; + + poke(b, atoi(argv[1])); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_read.c b/contrib/netbsd-tests/lib/libc/ssp/h_read.c new file mode 100644 index 0000000..5240af2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_read.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <sys/param.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + (void)read(0, b, len); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c new file mode 100644 index 0000000..c18faed --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <sys/param.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + (void)readlink("/", b, len); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c new file mode 100644 index 0000000..93575a8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c @@ -0,0 +1,45 @@ +/* $NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + size_t len = atoi(argv[1]); + (void)snprintf(b, len, "%s", "0123456789"); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c new file mode 100644 index 0000000..0f6d0cb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c @@ -0,0 +1,43 @@ +/* $NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)sprintf(b, "%s", argv[1]); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c new file mode 100644 index 0000000..c8dfbb7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c @@ -0,0 +1,49 @@ +/* $NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + char *q = stpcpy(b, argv[1]); + + if ((size_t)(q - b) != strlen(argv[1])) + abort(); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c new file mode 100644 index 0000000..c03d2a8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c @@ -0,0 +1,56 @@ +/* $NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $"); + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); +#if __GNUC_PREREQ__(4, 8) + char *q = stpncpy(b, "1020202020202", len); + + if (q - b != len) + abort(); +#else + // gcc-4.5 lacks __builtin___stpncpy_chk, lose. + (void)strncpy(b, "1020202020202", len); +#endif + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c new file mode 100644 index 0000000..687acf7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c @@ -0,0 +1,46 @@ +/* $NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)strcpy(b, "1"); + (void)strcat(b, argv[1]); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c new file mode 100644 index 0000000..2a7f1f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c @@ -0,0 +1,45 @@ +/* $NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)strcpy(b, argv[1]); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c new file mode 100644 index 0000000..0d66c7b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)strcpy(b, "1"); + (void)strncat(b, "1020202020202", len); + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c new file mode 100644 index 0000000..fddf67b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)strncpy(b, "1020202020202", len); + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c new file mode 100644 index 0000000..0f6af85 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c @@ -0,0 +1,57 @@ +/* $NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +static void wrap(size_t, const char *, ...) __printflike(2, 3); + +void +wrap(size_t len, const char *fmt, ...) +{ + char b[10]; + va_list ap; + va_start(ap, fmt); + (void)vsnprintf(b, len, fmt, ap); + (void)printf("%s\n", b); + va_end(ap); +} + +int +main(int argc, char *argv[]) +{ + size_t len = atoi(argv[1]); + wrap(len, "%s", "012345678901234567890"); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c new file mode 100644 index 0000000..c7fc780 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c @@ -0,0 +1,55 @@ +/* $NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $"); + +#include <stdio.h> +#include <stdarg.h> + +static void wrap(const char *, ...) __printflike(1, 2); + +static void +wrap(const char *fmt, ...) +{ + char b[10]; + va_list ap; + va_start(ap, fmt); + (void)vsprintf(b, fmt, ap); + (void)printf("%s\n", b); + va_end(ap); +} + +int +main(int argc, char *argv[]) +{ + wrap("%s", argv[1]); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh new file mode 100755 index 0000000..0514348 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh @@ -0,0 +1,308 @@ +# $NetBSD: t_ssp.sh,v 1.7 2014/04/06 19:28:59 christos Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +h_pass() +{ + echo "Executing command [ $2$1 ]" + eval $2 atf_check -s exit:0 -o ignore -e ignore $1 +} + +h_fail() +{ + echo "Executing command [ $2$1 ]" + eval $2 atf_check -s signal:6 -o ignore -e ignore $1 +} + +atf_test_case sprintf +sprintf_head() +{ + atf_set "descr" "Checks sprintf(3)" +} +sprintf_body() +{ + prog="$(atf_get_srcdir)/h_sprintf" + + h_pass "$prog ok" + h_fail "$prog 0123456789" +} + +atf_test_case vsprintf +vsprintf_head() +{ + atf_set "descr" "Checks vsprintf(3)" +} +vsprintf_body() +{ + prog="$(atf_get_srcdir)/h_vsprintf" + + h_pass "$prog ok" + h_fail "$prog 0123456789" +} + +atf_test_case snprintf +snprintf_head() +{ + atf_set "descr" "Checks snprintf(3)" +} +snprintf_body() +{ + prog="$(atf_get_srcdir)/h_snprintf" + + h_pass "$prog 10" + h_fail "$prog 11" +} + +atf_test_case vsnprintf +vsnprintf_head() +{ + atf_set "descr" "Checks vsnprintf(3)" +} +vsnprintf_body() +{ + prog="$(atf_get_srcdir)/h_vsnprintf" + + h_pass "$prog 10" + h_fail "$prog 11" +} + +atf_test_case gets +gets_head() +{ + atf_set "descr" "Checks gets(3)" +} +gets_body() +{ + prog="$(atf_get_srcdir)/h_gets" + + h_pass "$prog" "echo ok |" + h_fail "$prog" "echo 0123456789 |" +} + +atf_test_case fgets +fgets_head() +{ + atf_set "descr" "Checks fgets(3)" +} +fgets_body() +{ + prog="$(atf_get_srcdir)/h_fgets" + + h_pass "$prog 10" "echo ok |" + h_fail "$prog 11" "echo busted |" +} + +atf_test_case memcpy +memcpy_head() +{ + atf_set "descr" "Checks memcpy(3)" +} +memcpy_body() +{ + prog="$(atf_get_srcdir)/h_memcpy" + + h_pass "$prog 10" + h_fail "$prog 11" +} + +atf_test_case memmove +memmove_head() +{ + atf_set "descr" "Checks memmove(3)" +} +memmove_body() +{ + prog="$(atf_get_srcdir)/h_memmove" + + h_pass "$prog 10" + h_fail "$prog 11" +} + +atf_test_case memset +memset_head() +{ + atf_set "descr" "Checks memset(3)" +} +memset_body() +{ + prog="$(atf_get_srcdir)/h_memset" + + h_pass "$prog 10" + h_fail "$prog 11" +} + +atf_test_case strcpy +strcpy_head() +{ + atf_set "descr" "Checks strcpy(3)" +} +strcpy_body() +{ + prog="$(atf_get_srcdir)/h_strcpy" + + h_pass "$prog 0123456" + h_fail "$prog 0123456789" +} + +atf_test_case stpcpy +stpcpy_head() +{ + atf_set "descr" "Checks stpcpy(3)" +} +stpcpy_body() +{ + prog="$(atf_get_srcdir)/h_stpcpy" + + h_pass "$prog 0123456" + h_fail "$prog 0123456789" +} + +atf_test_case strcat +strcat_head() +{ + atf_set "descr" "Checks strcat(3)" +} +strcat_body() +{ + prog="$(atf_get_srcdir)/h_strcat" + + h_pass "$prog 0123456" + h_fail "$prog 0123456789ABCDEF" +} + +atf_test_case strncpy +strncpy_head() +{ + atf_set "descr" "Checks strncpy(3)" +} +strncpy_body() +{ + prog="$(atf_get_srcdir)/h_strncpy" + + h_pass "$prog 10" + h_fail "$prog 11" +} + +atf_test_case stpncpy +stpncpy_head() +{ + atf_set "descr" "Checks stpncpy(3)" +} +stpncpy_body() +{ + prog="$(atf_get_srcdir)/h_stpncpy" + + h_pass "$prog 10" + h_fail "$prog 11" +} + +atf_test_case strncat +strncat_head() +{ + atf_set "descr" "Checks strncat(3)" +} +strncat_body() +{ + prog="$(atf_get_srcdir)/h_strncat" + + h_pass "$prog 8" + h_fail "$prog 9" +} + +atf_test_case raw +raw_head() +{ + atf_set "descr" "Checks raw array overflow" +} +raw_body() +{ + prog="$(atf_get_srcdir)/h_raw" + + h_pass "$prog 9" + h_fail "$prog 10" +} + +atf_test_case read +read_head() +{ + atf_set "descr" "Checks read(2)" +} +read_body() +{ + prog="$(atf_get_srcdir)/h_read" + + h_pass "$prog 1024" "echo foo |" + h_fail "$prog 1025" "echo bar |" +} + +atf_test_case readlink +readlink_head() +{ + atf_set "descr" "Checks readlink(2)" +} +readlink_body() +{ + prog="$(atf_get_srcdir)/h_readlink" + + h_pass "$prog 1024" + h_fail "$prog 1025" +} + +atf_test_case getcwd +getcwd_head() +{ + atf_set "descr" "Checks getcwd(3)" +} +getcwd_body() +{ + prog="$(atf_get_srcdir)/h_getcwd" + + h_pass "$prog 1024" + h_fail "$prog 1025" +} + +atf_init_test_cases() +{ + atf_add_test_case sprintf + atf_add_test_case vsprintf + atf_add_test_case snprintf + atf_add_test_case vsnprintf + atf_add_test_case gets + atf_add_test_case fgets + atf_add_test_case memcpy + atf_add_test_case memmove + atf_add_test_case memset + atf_add_test_case stpcpy + atf_add_test_case stpncpy + atf_add_test_case strcat + atf_add_test_case strcpy + atf_add_test_case strncat + atf_add_test_case strncpy + atf_add_test_case raw + atf_add_test_case read + atf_add_test_case readlink + atf_add_test_case getcwd +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c new file mode 100644 index 0000000..251804e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $ */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> + +static const char path[] = "/etc/passwd"; + +ATF_TC(clearerr_basic); +ATF_TC_HEAD(clearerr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of clearerr(3)"); +} + +ATF_TC_BODY(clearerr_basic, tc) +{ + char buf[2048]; + FILE *fp; + + fp = fopen(path, "r"); + ATF_REQUIRE(fp != NULL); + + while (feof(fp) == 0) + (void)fread(buf, sizeof(buf), 1, fp); + + ATF_REQUIRE(feof(fp) != 0); + + errno = 0; + clearerr(fp); + + ATF_REQUIRE(errno == 0); + ATF_REQUIRE(feof(fp) == 0); + ATF_REQUIRE(fclose(fp) != EOF); +} + +ATF_TC(clearerr_err); +ATF_TC_HEAD(clearerr_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that clearerr(3) does not fail"); +} + +ATF_TC_BODY(clearerr_err, tc) +{ + FILE *fp; + + fp = fopen(path, "r"); + + ATF_REQUIRE(fp != NULL); + ATF_REQUIRE(fclose(fp) == 0); + + errno = 0; + clearerr(fp); + + ATF_REQUIRE(errno == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clearerr_basic); + ATF_TP_ADD_TC(tp, clearerr_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c new file mode 100644 index 0000000..766070c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c @@ -0,0 +1,171 @@ +/* $NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <unistd.h> + +static const char *path = "fflush"; + +ATF_TC_WITH_CLEANUP(fflush_err); +ATF_TC_HEAD(fflush_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fflush(3)"); +} + +ATF_TC_BODY(fflush_err, tc) +{ + FILE *f; + + f = fopen(path, "w"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fflush(NULL) == 0); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + ATF_REQUIRE(f != NULL); + + /* + * In NetBSD the call should fail if the supplied + * parameteris not an open stream or the stream is + * not open for writing. + */ + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF); + + ATF_REQUIRE(fclose(f) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fflush_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fflush_seek); +ATF_TC_HEAD(fflush_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test file offsets with fflush(3)"); +} + +ATF_TC_BODY(fflush_seek, tc) +{ + char buf[12]; + int fd = -1; + FILE *f; + + /* + * IEEE Std 1003.1-2008: + * + * "For a stream open for reading, if the file + * is not already at EOF, and the file is one + * capable of seeking, the file offset of the + * underlying open file description shall be + * adjusted so that the next operation on the + * open file description deals with the byte + * after the last one read from or written to + * the stream being flushed." + */ + f = fopen(path, "w"); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r+"); + ATF_REQUIRE(f != NULL); + + fd = fileno(f); + ATF_REQUIRE(fd != -1); + + ATF_REQUIRE(fread(buf, 1, 3, f) == 3); + ATF_REQUIRE(fflush(f) == 0); + ATF_REQUIRE(fseek(f, 0, SEEK_CUR) == 0); + + /* + * Verify that the offsets are right and that + * a read operation resumes at the correct location. + */ + ATF_REQUIRE(ftell(f) == 3); + ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == 3); + ATF_REQUIRE(fgetc(f) == 'b'); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fflush_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fpurge_err); +ATF_TC_HEAD(fpurge_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fpurge(3)"); +} + +ATF_TC_BODY(fpurge_err, tc) +{ + FILE *f; + + f = fopen(path, "w"); + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fpurge(f) == EOF); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fpurge_err, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fflush_err); + ATF_TP_ADD_TC(tp, fflush_seek); + ATF_TP_ADD_TC(tp, fpurge_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c new file mode 100644 index 0000000..212c7c86 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c @@ -0,0 +1,1166 @@ +/* $NetBSD: t_fmemopen.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */ + +/*- + * Copyright (c)2010 Takehiko NOZAKI, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#if defined(__NetBSD__) +#include <atf-c.h> +#else +#if defined(__linux__) +#define _GNU_SOURCE +#include <features.h> +#endif +#include <assert.h> +#include <stdio.h> +#define ATF_TC(arg0) static void arg0##_head(void) +#define ATF_TC_HEAD(arg0, arg1) static void arg0##_head() +#define atf_tc_set_md_var(arg0, arg1, ...) do { \ + printf(__VA_ARGS__); \ + puts(""); \ +} while (/*CONSTCOND*/0) +#define ATF_TC_BODY(arg0, arg1) static void arg0##_body() +#define ATF_CHECK(arg0) assert(arg0) +#define ATF_TP_ADD_TCS(arg0) int main(void) +#define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body() +#define atf_no_error() 0 +#endif + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +const char *mode_rwa[] = { + "r", "rb", "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + "a", "ab", "a+", "ab+", "a+b", + NULL +}; + +const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL }; +const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL }; +const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL }; + +struct testcase { + const char *s; + off_t n; +} testcases[] = { +#define TESTSTR(s) { s, sizeof(s)-1 } + TESTSTR("\0he quick brown fox jumps over the lazy dog"), + TESTSTR("T\0e quick brown fox jumps over the lazy dog"), + TESTSTR("Th\0 quick brown fox jumps over the lazy dog"), + TESTSTR("The\0quick brown fox jumps over the lazy dog"), + TESTSTR("The \0uick brown fox jumps over the lazy dog"), + TESTSTR("The q\0ick brown fox jumps over the lazy dog"), + TESTSTR("The qu\0ck brown fox jumps over the lazy dog"), + TESTSTR("The qui\0k brown fox jumps over the lazy dog"), + TESTSTR("The quic\0 brown fox jumps over the lazy dog"), + TESTSTR("The quick\0brown fox jumps over the lazy dog"), + TESTSTR("The quick \0rown fox jumps over the lazy dog"), + TESTSTR("The quick b\0own fox jumps over the lazy dog"), + TESTSTR("The quick br\0wn fox jumps over the lazy dog"), + TESTSTR("The quick bro\0n fox jumps over the lazy dog"), + TESTSTR("The quick brow\0 fox jumps over the lazy dog"), + TESTSTR("The quick brown\0fox jumps over the lazy dog"), + TESTSTR("The quick brown \0ox jumps over the lazy dog"), + TESTSTR("The quick brown f\0x jumps over the lazy dog"), + TESTSTR("The quick brown fo\0 jumps over the lazy dog"), + TESTSTR("The quick brown fox\0jumps over the lazy dog"), + TESTSTR("The quick brown fox \0umps over the lazy dog"), + TESTSTR("The quick brown fox j\0mps over the lazy dog"), + TESTSTR("The quick brown fox ju\0ps over the lazy dog"), + TESTSTR("The quick brown fox jum\0s over the lazy dog"), + TESTSTR("The quick brown fox jump\0 over the lazy dog"), + TESTSTR("The quick brown fox jumps\0over the lazy dog"), + TESTSTR("The quick brown fox jumps \0ver the lazy dog"), + TESTSTR("The quick brown fox jumps o\0er the lazy dog"), + TESTSTR("The quick brown fox jumps ov\0r the lazy dog"), + TESTSTR("The quick brown fox jumps ove\0 the lazy dog"), + TESTSTR("The quick brown fox jumps over\0the lazy dog"), + TESTSTR("The quick brown fox jumps over \0he lazy dog"), + TESTSTR("The quick brown fox jumps over t\0e lazy dog"), + TESTSTR("The quick brown fox jumps over th\0 lazy dog"), + TESTSTR("The quick brown fox jumps over the\0lazy dog"), + TESTSTR("The quick brown fox jumps over the \0azy dog"), + TESTSTR("The quick brown fox jumps over the l\0zy dog"), + TESTSTR("The quick brown fox jumps over the la\0y dog"), + TESTSTR("The quick brown fox jumps over the laz\0 dog"), + TESTSTR("The quick brown fox jumps over the lazy\0dog"), + TESTSTR("The quick brown fox jumps over the lazy \0og"), + TESTSTR("The quick brown fox jumps over the lazy d\0g"), + TESTSTR("The quick brown fox jumps over the lazy do\0"), + TESTSTR("The quick brown fox jumps over the lazy dog"), + { NULL, 0 }, +}; + +ATF_TC(test00); +ATF_TC_HEAD(test00, tc) +{ + atf_tc_set_md_var(tc, "descr", "test00"); +} +ATF_TC_BODY(test00, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_rwa[0]; *p != NULL; ++p) { + fp = fmemopen(&buf[0], sizeof(buf), *p); +/* + * Upon successful completion, fmemopen() shall return a pointer to the + * object controlling the stream. + */ + ATF_CHECK(fp != NULL); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test01); +ATF_TC_HEAD(test01, tc) +{ + atf_tc_set_md_var(tc, "descr", "test01"); +} +ATF_TC_BODY(test01, tc) +{ + const char **p; + const char *mode[] = { + "r+", "rb+", "r+b", + "w+", "wb+", "w+b", + "a+", "ab+", "a+b", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * If a null pointer is specified as the buf argument, fmemopen() shall + * allocate size bytes of memory as if by a call to malloc(). + */ + fp = fmemopen(NULL, BUFSIZ, *p); + ATF_CHECK(fp != NULL); + +/* + * If buf is a null pointer, the initial position shall always be set + * to the beginning of the buffer. + */ + ATF_CHECK(ftello(fp) == (off_t)0); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test02); +ATF_TC_HEAD(test02, tc) +{ + atf_tc_set_md_var(tc, "descr", "test02"); +} +ATF_TC_BODY(test02, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_r[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + +/* + * This position is initially set to either the beginning of the buffer + * (for r and w modes) + */ + ATF_CHECK((unsigned char)buf[0] == 0x1); + ATF_CHECK(ftello(fp) == (off_t)0); + +/* + * The stream also maintains the size of the current buffer contents. + * For modes r and r+ the size is set to the value given by the size argument. + */ +#if !defined(__GLIBC__) + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test03); +ATF_TC_HEAD(test03, tc) +{ + atf_tc_set_md_var(tc, "descr", "test03"); +} +ATF_TC_BODY(test03, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_w[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + +/* + * This position is initially set to either the beginning of the buffer + * (for r and w modes) + */ + ATF_CHECK(buf[0] == '\0'); + ATF_CHECK(ftello(fp) == (off_t)0); + +/* + * For modes w and w+ the initial size is zero + */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test04); +ATF_TC_HEAD(test04, tc) +{ + atf_tc_set_md_var(tc, "descr", "test04"); +} +ATF_TC_BODY(test04, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + +/* + * or to the first null byte in the buffer (for a modes) + */ + for (p = &mode_a[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + + ATF_CHECK((unsigned char)buf[0] == 0x1); + +/* If no null byte is found in append mode, + * the initial position is set to one byte after the end of the buffer. + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + +/* + * and for modes a and a+ the initial size is either the position of the + * first null byte in the buffer or the value of the size argument + * if no null byte is found. + */ +#if !defined(__GLIBC__) + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test05); +ATF_TC_HEAD(test05, tc) +{ + atf_tc_set_md_var(tc, "descr", "test05"); +} +ATF_TC_BODY(test05, tc) +{ + const char **p; + FILE *fp; + char buf[BUFSIZ]; + + for (p = &mode_rwa[0]; *p != NULL; ++p) { +/* + * Otherwise, a null pointer shall be returned, and errno shall be set + * to indicate the error. + */ + errno = 0; + fp = fmemopen(NULL, (size_t)0, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + + errno = 0; + fp = fmemopen((void *)&buf[0], 0, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +} + +ATF_TC(test06); +ATF_TC_HEAD(test06, tc) +{ + atf_tc_set_md_var(tc, "descr", "test06"); +} +ATF_TC_BODY(test06, tc) +{ + const char **p; + const char *mode[] = { "", " ", "???", NULL }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * The value of the mode argument is not valid. + */ + fp = fmemopen(NULL, 1, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +} + +ATF_TC(test07); +ATF_TC_HEAD(test07, tc) +{ + atf_tc_set_md_var(tc, "descr", "test07"); +} +ATF_TC_BODY(test07, tc) +{ +#if !defined(__GLIBC__) + const char **p; + const char *mode[] = { + "r", "rb", + "w", "wb", + "a", "ab", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * Because this feature is only useful when the stream is opened for updating + * (because there is no way to get a pointer to the buffer) the fmemopen() + * call may fail if the mode argument does not include a '+' . + */ + errno = 0; + fp = fmemopen(NULL, 1, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +#endif +} + +ATF_TC(test08); +ATF_TC_HEAD(test08, tc) +{ + atf_tc_set_md_var(tc, "descr", "test08"); +} +ATF_TC_BODY(test08, tc) +{ +#if !defined(__GLIBC__) + const char **p; + const char *mode[] = { + "r+", "rb+", "r+b", + "w+", "wb+", "w+b", + "a+", "ab+", "a+b", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * The buf argument is a null pointer and the allocation of a buffer of + * length size has failed. + */ + fp = fmemopen(NULL, SIZE_MAX, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == ENOMEM); + } +#endif +} + +/* + * test09 - test14: + * An attempt to seek a memory buffer stream to a negative position or to a + * position larger than the buffer size given in the size argument shall fail. + */ + +ATF_TC(test09); +ATF_TC_HEAD(test09, tc) +{ + atf_tc_set_md_var(tc, "descr", "test09"); +} +ATF_TC_BODY(test09, tc) +{ + struct testcase *t; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + off_t i; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rwa[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_SET) + */ + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_SET) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive */ + for (i = (off_t)1; i <= (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_SET) == 0); + ATF_CHECK(ftello(fp) == i); + } + /* positive + OOB */ + ATF_CHECK(fseeko(fp, t->n + 1, SEEK_SET) == -1); + ATF_CHECK(ftello(fp) == t->n); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_SET) == -1); + ATF_CHECK(ftello(fp) == t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_rw[] = { + "r", "rb", "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + NULL +}; + +ATF_TC(test10); +ATF_TC_HEAD(test10, tc) +{ + atf_tc_set_md_var(tc, "descr", "test10"); +} +ATF_TC_BODY(test10, tc) +{ + struct testcase *t; + off_t i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_CUR) + */ + ATF_CHECK(ftello(fp) == (off_t)0); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* negative & OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive */ + for (i = 0; i < (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == i + 1); + } + + /* positive & OOB */ + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test11); +ATF_TC_HEAD(test11, tc) +{ + atf_tc_set_md_var(tc, "descr", "test11"); +} +ATF_TC_BODY(test11, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_CUR) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = (off_t)t->n - len; + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_CUR) + */ +#if defined(__GLIBC__) + if (i < (off_t)t->n) { +#endif + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == len); + + /* posive */ + for (i = (off_t)1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == len + i); + } + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + /* negative */ + for (i = (off_t)1; i <= (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == (off_t)t->n - i); + } + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test12); +ATF_TC_HEAD(test12, tc) +{ + atf_tc_set_md_var(tc, "descr", "test12"); +} +ATF_TC_BODY(test12, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = t->n - len; + for (p = &mode_r[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)0); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* positive */ + for (i = 1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len + i); + } + + /* negative */ + for (i = 1; i < len; ++i) { + ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len - i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test13); +ATF_TC_HEAD(test13, tc) +{ + atf_tc_set_md_var(tc, "descr", "test13"); +} +ATF_TC_BODY(test13, tc) +{ + struct testcase *t; + off_t i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_w[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(buf[0] == '\0'); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive */ + for (i = 1; i <= t->n; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test14); +ATF_TC_HEAD(test14, tc) +{ + atf_tc_set_md_var(tc, "descr", "test14"); +} +ATF_TC_BODY(test14, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = (off_t)t->n - len; + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == len); + + /* zero */ + ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* positive */ + for (i = 1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len + i); + } + + /* negative */ + for (i = 1; i < len; ++i) { + ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len - i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_rw1[] = { + "r", "rb", "r+", "rb+", "r+b", + "w+", "wb+", + NULL +}; + +/* test15 - 18: + * When a stream open for writing is flushed or closed, a null byte is written + * at the current position or at the end of the buffer, depending on the size + * of the contents. + */ + +ATF_TC(test15); +ATF_TC_HEAD(test15, tc) +{ + atf_tc_set_md_var(tc, "descr", "test15"); +} +ATF_TC_BODY(test15, tc) +{ + struct testcase *t; + const char **p; + char buf0[BUFSIZ]; + FILE *fp; + int i; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fgetc(3) + */ + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf0[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test16); +ATF_TC_HEAD(test16, tc) +{ + atf_tc_set_md_var(tc, "descr", "test16"); +} +ATF_TC_BODY(test16, tc) +{ + struct testcase *t; + const char **p; + char buf0[BUFSIZ], buf1[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + buf1[t->n] = 0x1; + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fread(4) + */ + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0); + ATF_CHECK((unsigned char)buf1[t->n] == 0x1); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_a1[] = { "a+", "ab+", NULL }; + +ATF_TC(test17); +ATF_TC_HEAD(test17, tc) +{ + atf_tc_set_md_var(tc, "descr", "test17"); +} +ATF_TC_BODY(test17, tc) +{ + struct testcase *t; + size_t len; + int i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a1[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fgetc(3) + */ +#if defined(__GLIBC__) + if (i < t->n) { +#endif + for (i = len; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + rewind(fp); + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test18); +ATF_TC_HEAD(test18, tc) +{ + atf_tc_set_md_var(tc, "descr", "test18"); +} +ATF_TC_BODY(test18, tc) +{ + struct testcase *t; + size_t len; + const char **p; + char buf0[BUFSIZ], buf1[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + buf1[t->n - len] = 0x1; + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fread(3) + */ +#if defined(__GLIBC__) + if (i < t->n) { +#endif + ATF_CHECK(ftello(fp) == (off_t)len); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) + == t->n - len); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len)); + ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1); + rewind(fp); + buf1[t->n] = 0x1; + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) + == (size_t)t->n); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n)); + ATF_CHECK((unsigned char)buf1[t->n] == 0x1); +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +/* + * test19 - test22: + * If a stream open for update is flushed or closed and the last write has + * advanced the current buffer size, a null byte is written at the end of the + * buffer if it fits. + */ + +const char *mode_rw2[] = { + "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + NULL +}; + +ATF_TC(test19); +ATF_TC_HEAD(test19, tc) +{ + atf_tc_set_md_var(tc, "descr", "test19"); +} +ATF_TC_BODY(test19, tc) +{ + struct testcase *t; + int i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw2[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + buf[t->n] = 0x1; + fp = fmemopen(&buf[0], t->n + 1, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fputc(3) + */ + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fputc(t->s[i], fp) == t->s[i]); + ATF_CHECK(buf[i] == t->s[i]); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + ATF_CHECK(buf[i] == t->s[i]); +#if !defined(__GLIBC__) + ATF_CHECK(buf[i + 1] == '\0'); +#endif + } + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(fputc(0x1, fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(feof(fp) == 0); + +/* accept nul character at end of buffer */ + ATF_CHECK(fputc('\0', fp) == '\0'); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + ATF_CHECK(feof(fp) == 0); + +/* reach EOF */ + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + + /* compare */ + ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); + ATF_CHECK(buf[t->n] == '\0'); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test20); +ATF_TC_HEAD(test20, tc) +{ + atf_tc_set_md_var(tc, "descr", "test20"); +} +ATF_TC_BODY(test20, tc) +{ + struct testcase *t; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw2[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + buf[t->n] = 0x1; + fp = fmemopen(&buf[0], t->n + 1, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); + ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n); +/* + * test fmemopen_write + fwrite(3) + */ +#if !defined(__GLIBC__) + ATF_CHECK(buf[t->n] == '\0'); + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(feof(fp) == 0); +#endif + +/* accept nul character at end of buffer */ + ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + ATF_CHECK(feof(fp) == 0); + +/* reach EOF */ + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + +/* compare */ + ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); + ATF_CHECK(buf[t->n] == '\0'); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test21); +ATF_TC_HEAD(test21, tc) +{ + atf_tc_set_md_var(tc, "descr", "test21"); +} +ATF_TC_BODY(test21, tc) +{ + struct testcase *t; + int len, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a[0]; *p != NULL; ++p) { + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fputc(3) + */ + if (len < t->n) { + for (i = len; i < t->n - 1; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fputc(t->s[i - len], fp) + == t->s[i - len]); + ATF_CHECK(buf[i] == t->s[i - len]); + ATF_CHECK(ftello(fp) == (off_t)i + 1); +#if !defined(__GLIBC__) + ATF_CHECK(buf[i + 1] == '\0'); +#endif + } + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + ATF_CHECK(fputc(0x1, fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + +/* accept nul character at end of buffer */ + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + ATF_CHECK(fputc('\0', fp) == '\0'); + ATF_CHECK(ftello(fp) == (off_t)t->n); + } + +/* reach EOF */ + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test22); +ATF_TC_HEAD(test22, tc) +{ + atf_tc_set_md_var(tc, "descr", "test22"); +} +ATF_TC_BODY(test22, tc) +{ + struct testcase *t0, *t1; + size_t len0, len1, nleft; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t0 = &testcases[0]; t0->s != NULL; ++t0) { + len0 = strnlen(t0->s, t0->n); + for (t1 = &testcases[0]; t1->s != NULL; ++t1) { + len1 = strnlen(t1->s, t1->n); + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t0->s, t0->n); + fp = fmemopen(&buf[0], t0->n, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fwrite(3) + */ + nleft = t0->n - len0; +#if !defined(__GLIBC__) + if (nleft == 0 || len1 == nleft - 1) { + ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) + == nleft); + ATF_CHECK(ftell(fp) == t1->n); + } else { + ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) + == nleft - 1); + ATF_CHECK(ftell(fp) == t1->n - 1); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, test00); + ATF_TP_ADD_TC(tp, test01); + ATF_TP_ADD_TC(tp, test02); + ATF_TP_ADD_TC(tp, test03); + ATF_TP_ADD_TC(tp, test04); + ATF_TP_ADD_TC(tp, test05); + ATF_TP_ADD_TC(tp, test06); + ATF_TP_ADD_TC(tp, test07); + ATF_TP_ADD_TC(tp, test08); + ATF_TP_ADD_TC(tp, test09); + ATF_TP_ADD_TC(tp, test10); + ATF_TP_ADD_TC(tp, test11); + ATF_TP_ADD_TC(tp, test12); + ATF_TP_ADD_TC(tp, test13); + ATF_TP_ADD_TC(tp, test14); + ATF_TP_ADD_TC(tp, test15); + ATF_TP_ADD_TC(tp, test16); + ATF_TP_ADD_TC(tp, test17); + ATF_TP_ADD_TC(tp, test18); + ATF_TP_ADD_TC(tp, test19); + ATF_TP_ADD_TC(tp, test20); + ATF_TP_ADD_TC(tp, test21); + ATF_TP_ADD_TC(tp, test22); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c new file mode 100644 index 0000000..c5b8921 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c @@ -0,0 +1,442 @@ +/* $NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static const char *path = "fopen"; + +ATF_TC_WITH_CLEANUP(fdopen_close); +ATF_TC_HEAD(fdopen_close, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that descriptors are closed"); +} + +ATF_TC_BODY(fdopen_close, tc) +{ + FILE *f; + int fd; + + /* + * Check that the file descriptor + * used to fdopen(3) a stream is + * closed once the stream is closed. + */ + fd = open(path, O_RDWR | O_CREAT); + + ATF_REQUIRE(fd >= 0); + + f = fdopen(fd, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(close(fd) == -1); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fdopen_close, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fdopen_err); +ATF_TC_HEAD(fdopen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fdopen(3)"); +} + +ATF_TC_BODY(fdopen_err, tc) +{ + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "w") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "a") == NULL); + + ATF_REQUIRE(close(fd) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fdopen(fd, "r") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fdopen(-1, "w+") == NULL); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fdopen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fdopen_seek); +ATF_TC_HEAD(fdopen_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stream position with fdopen(3)"); +} + +ATF_TC_BODY(fdopen_seek, tc) +{ + FILE *f; + int fd; + + /* + * Verify that the file position associated + * with the stream corresponds with the offset + * set earlier for the file descriptor. + */ + fd = open(path, O_RDWR | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(write(fd, "garbage", 7) == 7); + ATF_REQUIRE(lseek(fd, 3, SEEK_SET) == 3); + + f = fdopen(fd, "r+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftell(f) == 3); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fdopen_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_err); +ATF_TC_HEAD(fopen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fopen(3)"); +} + +ATF_TC_BODY(fopen_err, tc) +{ + static const char *mode[] = { + "x", "xr", "xr", "+r+", "R", "W+", " aXX", "Xr", " r+", "" }; + + char buf[PATH_MAX + 1]; + size_t i; + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + /* + * Note that also "invalid" characters + * may follow the mode-string whenever + * the first character is valid. + */ + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + f = fopen(path, mode[i]); + + if (f == NULL && errno == EINVAL) + continue; + + if (f != NULL) + (void)fclose(f); + + atf_tc_fail_nonfatal("opened file as '%s'", mode[i]); + } + + (void)unlink(path); + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EISDIR, fopen("/usr/bin", "w") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, fopen("/a/b/c/d/e/f", "r") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, fopen(buf, "r+") == NULL); +} + +ATF_TC_CLEANUP(fopen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_append); +ATF_TC_HEAD(fopen_append, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that append-mode works"); +} + +ATF_TC_BODY(fopen_append, tc) +{ + char buf[15]; + FILE *f; + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "a"); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + + ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); + ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fopen_append, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_mode); +ATF_TC_HEAD(fopen_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fopen(3) modes"); +} + +ATF_TC_BODY(fopen_mode, tc) +{ + size_t i; + FILE *f; + + static const char *mode[] = { + "r", "r+", "w", "w+", "a", "a+", + "rb", "r+b", "wb", "w+b", "ab", "a+b" + "re", "r+e", "we", "w+e", "ae", "a+e" + "rf", "r+f", "wf", "w+f", "af", "a+f" + }; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + /* + * Verify that various modes work. + */ + for (i = 0; i < __arraycount(mode); i++) { + + f = fopen(path, mode[i]); + + if (f != NULL) { + ATF_REQUIRE(fclose(f) == 0); + continue; + } + + atf_tc_fail_nonfatal("failed to open file as %s", mode[i]); + } + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fopen_mode, tc) +{ + (void)unlink(path); +} + +ATF_TC(fopen_perm); +ATF_TC_HEAD(fopen_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with fopen(3)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(fopen_perm, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "a+") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "w+") == NULL); +} + +ATF_TC(fopen_regular); +ATF_TC_HEAD(fopen_regular, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fopen(3) with 'f' mode"); +} + +ATF_TC_BODY(fopen_regular, tc) +{ + static const char *mode[] = { "rf", "r+f", "wf", "w+f", "af", "a+f" }; + static const char *devs[] = { _PATH_DEVNULL }; + + size_t i, j; + FILE *f; + + for (i = 0; i < __arraycount(devs); i++) { + + for (j = 0; j < __arraycount(mode); j++) { + + errno = 0; + f = fopen(devs[i], mode[j]); + + if (f == NULL && errno == EFTYPE) + continue; + + if (f != NULL) + (void)fclose(f); + + atf_tc_fail_nonfatal("opened %s as %s", + devs[i], mode[j]); + } + } +} + +ATF_TC_WITH_CLEANUP(fopen_seek); +ATF_TC_HEAD(fopen_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test initial stream position"); +} + +ATF_TC_BODY(fopen_seek, tc) +{ + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + /* + * The position of the stream should be + * at the start, except for append-mode. + */ + f = fopen(path, "r"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftello(f) == 0); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "a"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftello(f) == 7); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fopen_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(freopen_std); +ATF_TC_HEAD(freopen_std, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of freopen(3)"); +} + +ATF_TC_BODY(freopen_std, tc) +{ + FILE *std[2] = { stdin, stdout }; + char buf[15]; + size_t i; + FILE *f; + + /* + * Associate a standard stream with a custom stream. + * Then write to the standard stream and verify that + * the result now appears in the custom stream. + */ + for (i = 0; i < __arraycount(std); i++) { + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + ATF_REQUIRE(f != NULL); + + f = freopen(path, "w+", std[i]); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fprintf(std[i], "garbage") == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); + ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); + + ATF_REQUIRE(fclose(f) == 0); + } + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(freopen_std, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fdopen_close); + ATF_TP_ADD_TC(tp, fdopen_err); + ATF_TP_ADD_TC(tp, fdopen_seek); + ATF_TP_ADD_TC(tp, fopen_append); + ATF_TP_ADD_TC(tp, fopen_err); + ATF_TP_ADD_TC(tp, fopen_mode); + ATF_TP_ADD_TC(tp, fopen_perm); + ATF_TP_ADD_TC(tp, fopen_regular); + ATF_TP_ADD_TC(tp, fopen_seek); + ATF_TP_ADD_TC(tp, freopen_std); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c new file mode 100644 index 0000000..ed7c0dc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static const char *path = "fputc"; +static void puterr(int (*)(int, FILE *)); +static void putstr(int (*)(int, FILE *)); + +static void +puterr(int (*func)(int, FILE *)) +{ + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(func('x', f) == EOF); +} + +static void +putstr(int (*func)(int, FILE *)) +{ + const char *str = "1234567890x"; + unsigned short i = 0; + char buf[10]; + FILE *f; + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + ATF_REQUIRE(f != NULL); + + while (str[i] != 'x') { + ATF_REQUIRE(func(str[i], f) == str[i]); + i++; + } + + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fread(buf, 1, 10, f) == 10); + ATF_REQUIRE(strncmp(buf, str, 10) == 0); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_WITH_CLEANUP(fputc_basic); +ATF_TC_HEAD(fputc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fputc(3)"); +} + +ATF_TC_BODY(fputc_basic, tc) +{ + putstr(fputc); +} + +ATF_TC_CLEANUP(fputc_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fputc_err); +ATF_TC_HEAD(fputc_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fputc(3)"); +} + +ATF_TC_BODY(fputc_err, tc) +{ + puterr(fputc); +} + +ATF_TC_CLEANUP(fputc_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_basic); +ATF_TC_HEAD(putc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of putc(3)"); +} + +ATF_TC_BODY(putc_basic, tc) +{ + putstr(putc); +} + +ATF_TC_CLEANUP(putc_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_err); +ATF_TC_HEAD(putc_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from putc(3)"); +} + +ATF_TC_BODY(putc_err, tc) +{ + puterr(putc); +} + +ATF_TC_CLEANUP(putc_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_unlocked_basic); +ATF_TC_HEAD(putc_unlocked_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of putc_unlocked(3)"); +} + +ATF_TC_BODY(putc_unlocked_basic, tc) +{ + putstr(putc_unlocked); +} + +ATF_TC_CLEANUP(putc_unlocked_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_unlocked_err); +ATF_TC_HEAD(putc_unlocked_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from putc_unlocked(3)"); +} + +ATF_TC_BODY(putc_unlocked_err, tc) +{ + puterr(putc_unlocked); +} + +ATF_TC_CLEANUP(putc_unlocked_err, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fputc_basic); + ATF_TP_ADD_TC(tp, fputc_err); + ATF_TP_ADD_TC(tp, putc_basic); + ATF_TP_ADD_TC(tp, putc_err); + ATF_TP_ADD_TC(tp, putc_unlocked_basic); + ATF_TP_ADD_TC(tp, putc_unlocked_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c new file mode 100644 index 0000000..e423060 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c @@ -0,0 +1,54 @@ +/* $NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $"); + +#include <atf-c.h> +#include <stdlib.h> + +ATF_TC(mktemp_not_exist); +ATF_TC_HEAD(mktemp_not_exist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that mktemp does not fail on" + " a path that does not exist"); +} + +ATF_TC_BODY(mktemp_not_exist, tc) +{ + char template[] = "I will barf/XXXXXX"; + ATF_REQUIRE(mktemp(template) != NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mktemp_not_exist); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_popen.c b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c new file mode 100644 index 0000000..699498c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1999\ + The NetBSD Foundation, Inc. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +__RCSID("$NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $"); +#endif /* not lint */ + +#include <atf-c.h> + +#include <sys/param.h> + +#include <errno.h> +#include <err.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +#define _PATH_CAT "/bin/cat" +#define BUFSIZE (640*1024) + /* 640KB ought to be enough for everyone. */ +#define DATAFILE "popen.data" + +#define TEST_ERROR(a) \ + do \ + { \ + warn(a); \ + atf_tc_fail("Check stderr for error details."); \ + } while ( /*CONSTCOND*/ 0 ) + +ATF_TC_WITH_CLEANUP(popen_zeropad); +ATF_TC_HEAD(popen_zeropad, tc) +{ + + atf_tc_set_md_var(tc, "descr", "output format zero padding"); +} + +ATF_TC_BODY(popen_zeropad, tc) +{ + char *buffer, command[MAXPATHLEN]; + int idx, in; + FILE *my_pipe; + + if ((buffer = malloc(BUFSIZE)) == NULL) + atf_tc_skip("Unable to allocate buffer."); + + srand ((unsigned int)time(NULL)); + + for (idx = 0; idx < BUFSIZE; idx++) + buffer[idx]=(char)rand(); + + (void)snprintf(command, sizeof(command), "%s >%s", + _PATH_CAT, DATAFILE); + + if ((my_pipe = popen(command, "w")) == NULL) + TEST_ERROR("popen write"); + + if (fwrite(buffer, sizeof(char), BUFSIZE, my_pipe) != BUFSIZE) + TEST_ERROR("fwrite"); + + if (pclose(my_pipe) == -1) + TEST_ERROR("pclose"); + + (void)snprintf(command, sizeof(command), "%s %s", _PATH_CAT, DATAFILE); + + if ((my_pipe = popen(command, "r")) == NULL) + TEST_ERROR("popen read"); + + idx = 0; + while ((in = fgetc(my_pipe)) != EOF) + if (idx == BUFSIZE) { + errno = EFBIG; + TEST_ERROR("read"); + } + else if ((char)in != buffer[idx++]) { + errno = EINVAL; + TEST_ERROR("read"); + } + + if (idx < BUFSIZE) { + errno = EIO; + TEST_ERROR("read"); + } + + if (pclose(my_pipe) == -1) + TEST_ERROR("pclose"); +} + +ATF_TC_CLEANUP(popen_zeropad, tc) +{ + (void)unlink(DATAFILE); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, popen_zeropad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c new file mode 100644 index 0000000..95b4b2c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_printf.c,v 1.8 2012/04/11 16:21:42 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/resource.h> +#include <atf-c.h> +#include <math.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <time.h> +#include <stdlib.h> + +ATF_TC(snprintf_c99); +ATF_TC_HEAD(snprintf_c99, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Test printf(3) C99 conformance (PR lib/22019)"); +} + +ATF_TC_BODY(snprintf_c99, tc) +{ + char s[4]; + + (void)memset(s, '\0', sizeof(s)); + (void)snprintf(s, sizeof(s), "%#.o", 0); + (void)printf("printf = %#.o\n", 0); + (void)fprintf(stderr, "snprintf = %s", s); + + ATF_REQUIRE(strlen(s) == 1); + ATF_REQUIRE(s[0] == '0'); +} + +ATF_TC(snprintf_dotzero); +ATF_TC_HEAD(snprintf_dotzero, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "PR lib/32951: %%.0f formats (0.0,0.5] to \"0.\""); +} + +ATF_TC_BODY(snprintf_dotzero, tc) +{ + char s[4]; + + ATF_CHECK(snprintf(s, sizeof(s), "%.0f", 0.1) == 1); + ATF_REQUIRE_STREQ(s, "0"); +} + +ATF_TC(snprintf_posarg); +ATF_TC_HEAD(snprintf_posarg, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments"); +} + +ATF_TC_BODY(snprintf_posarg, tc) +{ + char s[16]; + + ATF_CHECK(snprintf(s, sizeof(s), "%1$d", -23) == 3); + ATF_REQUIRE_STREQ(s, "-23"); +} + +ATF_TC(snprintf_posarg_width); +ATF_TC_HEAD(snprintf_posarg_width, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments with " + "field width"); +} + +ATF_TC_BODY(snprintf_posarg_width, tc) +{ + char s[16]; + + ATF_CHECK(snprintf(s, sizeof(s), "%1$*2$d", -23, 4) == 4); + ATF_REQUIRE_STREQ(s, " -23"); +} + +ATF_TC(snprintf_posarg_error); +ATF_TC_HEAD(snprintf_posarg_error, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments out " + "of bounds"); +} + +ATF_TC_BODY(snprintf_posarg_error, tc) +{ + char s[16], fmt[32]; + + snprintf(fmt, sizeof(fmt), "%%%zu$d", SIZE_MAX / sizeof(size_t)); + + ATF_CHECK(snprintf(s, sizeof(s), fmt, -23) == -1); +} + +ATF_TC(snprintf_float); +ATF_TC_HEAD(snprintf_float, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test that floating conversions don't" + " leak memory"); +} + +ATF_TC_BODY(snprintf_float, tc) +{ + union { + double d; + uint64_t bits; + } u; + uint32_t ul, uh; + time_t now; + char buf[1000]; + struct rlimit rl; + + rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_AS, &rl) != -1); + rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_DATA, &rl) != -1); + + time(&now); + srand(now); + for (size_t i = 0; i < 10000; i++) { + ul = rand(); + uh = rand(); + u.bits = (uint64_t)uh << 32 | ul; + ATF_CHECK(snprintf(buf, sizeof buf, " %.2f", u.d) != -1); + } +} + +ATF_TC(sprintf_zeropad); +ATF_TC_HEAD(sprintf_zeropad, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test output format zero padding (PR lib/44113)"); +} + +ATF_TC_BODY(sprintf_zeropad, tc) +{ + char str[1024]; + + ATF_CHECK(sprintf(str, "%010f", 0.0) == 10); + ATF_REQUIRE_STREQ(str, "000.000000"); + + /* ieeefp */ +#ifndef __vax__ + /* printf(3) should ignore zero padding for nan/inf */ + ATF_CHECK(sprintf(str, "%010f", NAN) == 10); + ATF_REQUIRE_STREQ(str, " nan"); + ATF_CHECK(sprintf(str, "%010f", INFINITY) == 10); + ATF_REQUIRE_STREQ(str, " inf"); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, snprintf_c99); + ATF_TP_ADD_TC(tp, snprintf_dotzero); + ATF_TP_ADD_TC(tp, snprintf_posarg); + ATF_TP_ADD_TC(tp, snprintf_posarg_width); + ATF_TP_ADD_TC(tp, snprintf_posarg_error); + ATF_TP_ADD_TC(tp, snprintf_float); + ATF_TP_ADD_TC(tp, sprintf_zeropad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c new file mode 100644 index 0000000..fea35a7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c @@ -0,0 +1,81 @@ +/* $NetBSD: t_scanf.c,v 1.3 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> +#include <stdio.h> +#include <string.h> + +#define NUM -0x1234 +#define STRNUM ___STRING(NUM) + +ATF_TC(sscanf_neghex); +ATF_TC_HEAD(sscanf_neghex, tc) +{ + atf_tc_set_md_var(tc, "descr", + "PR lib/21691: %%i and %%x fail with negative hex numbers"); +} + +ATF_TC_BODY(sscanf_neghex, tc) +{ + int i; + + sscanf(STRNUM, "%i", &i); + ATF_REQUIRE(i == NUM); + + sscanf(STRNUM, "%x", &i); + ATF_REQUIRE(i == NUM); +} + +ATF_TC(sscanf_whitespace); +ATF_TC_HEAD(sscanf_whitespace, tc) +{ + + atf_tc_set_md_var(tc, "descr", "verify sscanf skips all whitespace"); +} + +ATF_TC_BODY(sscanf_whitespace, tc) +{ + const char str[] = "\f\n\r\t\v%z"; + char c; + + /* set of "white space" symbols from isspace(3) */ + c = 0; + (void)sscanf(str, "%%%c", &c); + ATF_REQUIRE(c == 'z'); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sscanf_neghex); + ATF_TP_ADD_TC(tp, sscanf_whitespace); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c new file mode 100644 index 0000000..b2f91c4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c @@ -0,0 +1,178 @@ +/* $NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +extern int __cxa_atexit(void (*func)(void *), void *, void *); +extern void __cxa_finalize(void *); + +static int dso_handle_1; +static int dso_handle_2; +static int dso_handle_3; + +static int arg_1; +static int arg_2; +static int arg_3; + +static int exiting_state; + +#define ASSERT(expr) \ +do { \ + if ((expr) == 0) { \ + write(STDERR_FILENO, __func__, strlen(__func__)); \ + write(STDERR_FILENO, ": ", 2); \ + write(STDERR_FILENO, __STRING(expr), \ + strlen(__STRING(expr))); \ + write(STDERR_FILENO, "\n", 1); \ + my_abort(); \ + } \ +} while (/*CONSTCOND*/0) + +#define SUCCESS() \ +do { \ + write(STDOUT_FILENO, __func__, strlen(__func__)); \ + write(STDOUT_FILENO, "\n", 1); \ +} while (/*CONSTCOND*/0) + +static void +my_abort(void) +{ + + kill(getpid(), SIGABRT); + /* NOTREACHED */ +} + +static void +cxa_handler_5(void *arg) +{ + static int cxa_handler_5_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_5_called == 0); + ASSERT(exiting_state == 5); + + exiting_state--; + cxa_handler_5_called = 1; + SUCCESS(); +} + +static void +cxa_handler_4(void *arg) +{ + static int cxa_handler_4_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_4_called == 0); + ASSERT(exiting_state == 4); + + exiting_state--; + cxa_handler_4_called = 1; + SUCCESS(); +} + +static void +cxa_handler_3(void *arg) +{ + static int cxa_handler_3_called; + + ASSERT(arg == (void *)&arg_2); + ASSERT(cxa_handler_3_called == 0); + ASSERT(exiting_state == 3); + + exiting_state--; + cxa_handler_3_called = 1; + SUCCESS(); +} + +static void +cxa_handler_2(void *arg) +{ + static int cxa_handler_2_called; + + ASSERT(arg == (void *)&arg_3); + ASSERT(cxa_handler_2_called == 0); + ASSERT(exiting_state == 2); + + exiting_state--; + cxa_handler_2_called = 1; + SUCCESS(); +} + +static void +normal_handler_1(void) +{ + static int normal_handler_1_called; + + ASSERT(normal_handler_1_called == 0); + ASSERT(exiting_state == 1); + + exiting_state--; + normal_handler_1_called = 1; + SUCCESS(); +} + +static void +normal_handler_0(void) +{ + static int normal_handler_0_called; + + ASSERT(normal_handler_0_called == 0); + ASSERT(exiting_state == 0); + + normal_handler_0_called = 1; + SUCCESS(); +} + +int +main(int argc, char *argv[]) +{ + + exiting_state = 5; + + ASSERT(0 == atexit(normal_handler_0)); + ASSERT(0 == atexit(normal_handler_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3)); + + __cxa_finalize(&dso_handle_1); + __cxa_finalize(&dso_handle_2); + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c new file mode 100644 index 0000000..074e4dd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c @@ -0,0 +1,127 @@ +/* $NetBSD: h_getopt.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> + +#define WS "\t\n " +#define debug 0 + +int +main(int argc, char *argv[]) +{ + size_t len, lineno = 0; + char *line, *ptr, *optstring = NULL, *result = NULL; + char buf[1024]; + char *args[100]; + char arg[100]; + int nargs = -1; + int c; + + while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) { + if (strncmp(line, "load:", 5) == 0) { + if (optstring) + free(optstring); + optstring = strtok(&line[6], WS); + if (optstring == NULL) + errx(1, "missing optstring at line %ld", + (unsigned long)lineno); + optstring = strdup(optstring); + if (debug) + fprintf(stderr, "optstring = %s\n", optstring); + } else if (strncmp(line, "args:", 5) == 0) { + for (; nargs >= 0; nargs--) { + if (args[nargs] != NULL) + free(args[nargs]); + } + args[nargs = 0] = strtok(&line[6], WS); + if (args[nargs] == NULL) + errx(1, "missing args at line %ld", + (unsigned long)lineno); + + args[nargs] = strdup(args[nargs]); + while ((args[++nargs] = strtok(NULL, WS)) != NULL) + args[nargs] = strdup(args[nargs]); + if (debug) { + int i = 0; + for (i = 0; i < nargs; i++) + fprintf(stderr, "argv[%d] = %s\n", i, + args[i]); + } + } else if (strncmp(line, "result:", 7) == 0) { + buf[0] = '\0'; + optind = optreset = 1; + if (result) + free(result); + result = strtok(&line[8], WS); + if (result == NULL) + errx(1, "missing result at line %ld", + (unsigned long)lineno); + result = strdup(result); + if (nargs == -1) + errx(1, "result: without args:"); + if (debug) + fprintf(stderr, "result = %s\n", result); + while ((c = getopt(nargs, args, optstring)) != -1) { + if (c == ':') + err(1, "`:' found as argument char"); + if ((ptr = strchr(optstring, c)) == NULL) { + snprintf(arg, sizeof(arg), "!%c,", c); + strcat(buf, arg); + continue; + } + if (ptr[1] != ':') + snprintf(arg, sizeof(arg), "%c,", c); + else + snprintf(arg, sizeof(arg), "%c=%s,", + c, optarg); + strcat(buf, arg); + } + len = strlen(buf); + if (len > 0) { + buf[len - 1] = '|'; + buf[len] = '\0'; + } else { + buf[0] = '|'; + buf[1] = '\0'; + } + snprintf(arg, sizeof(arg), "%d", nargs - optind); + strcat(buf, arg); + if (strcmp(buf, result) != 0) + errx(1, "`%s' != `%s'", buf, result); + } + free(line); + } + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c new file mode 100644 index 0000000..17258f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c @@ -0,0 +1,239 @@ +/* $NetBSD: h_getopt_long.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <ctype.h> +#include <err.h> +#include <getopt.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#define SKIPWS(p) while (isspace((int)(*p))) p++ +#define WS "\t\n " + +int +main(int argc, char *argv[]) +{ + size_t len, lineno = 0; + char *line, *eptr, *longopt, *ptr, *optstring = NULL, *result = NULL; + char buf[1024]; + char *args[128]; + char arg[256]; + int nargs = -1; + int c; + int nlongopts = 0; + int maxnlongopts = 0; + int *longopt_flags = NULL; + struct option *longopts = NULL; + + while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) { + if (strncmp(line, "optstring:", 10) == 0) { + if (optstring) + free(optstring); + optstring = strtok(&line[11], WS); + if (optstring == NULL) + errx(1, "missing optstring at line %ld", + (unsigned long)lineno); + optstring = strdup(optstring); + } else if (strncmp(line, "longopts:", 9) == 0) { + if (longopts) { + int i; + for (i = 0; i < nlongopts; i++) + if (longopts[i].name != NULL) + free(__UNCONST(longopts[i].name)); + free(longopts); + } + if (longopt_flags) + free(longopt_flags); + nlongopts = 0; + ptr = strtok(&line[10], WS); + if (ptr == NULL) + errx(1, "missing longopts at line %ld", + (unsigned long)lineno); + maxnlongopts = strtoul(ptr, &eptr, 10); + if (*eptr != '\0') + warnx("garbage in longopts at line %ld", + (unsigned long)lineno); + maxnlongopts++; /* space for trailer */ + longopts = + (struct option *)calloc(sizeof(struct option), + maxnlongopts); + if (longopts == NULL) + err(1, "calloc"); + longopt_flags = (int *)calloc(sizeof(int), maxnlongopts); + if (longopt_flags == NULL) + err(1, "calloc"); + } else if (strncmp(line, "longopt:", 8) == 0) { + if (longopts == NULL) + errx(1, "longopt: without longopts at line %ld", + (unsigned long)lineno); + if (nlongopts >= maxnlongopts) + errx(1, "longopt: too many options at line %ld", + (unsigned long)lineno); + /* name */ + ptr = &line[9]; + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (longopt == NULL) + errx(1, "missing longopt at line %ld", + (unsigned long)lineno); + longopts[nlongopts].name = strdup(longopt); + /* has_arg */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt != '\0') { + if (strncmp(longopt, "0", 1) == 0 || + strncmp(longopt, "no_argument", 2) == 0) + longopts[nlongopts].has_arg = no_argument; + else if (strncmp(longopt, "1", 1) == 0 || + strncmp(longopt, "required_argument", 8) == 0) + longopts[nlongopts].has_arg = required_argument; + else if (strncmp(longopt, "2", 1) == 0 || + strncmp(longopt, "optional_argument", 8) == 0) + longopts[nlongopts].has_arg = optional_argument; + else + errx(1, "unknown has_arg %s at line %ld", + longopt, (unsigned long)lineno); + } + /* flag */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt != '\0' && + strncmp(longopt, "NULL", 4) != 0) + longopts[nlongopts].flag = &longopt_flags[nlongopts]; + /* val */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt == '\0') + errx(1, "missing val at line %ld", + (unsigned long)lineno); + if (*longopt != '\'') { + longopts[nlongopts].val = + (int)strtoul(longopt, &eptr, 10); + if (*eptr != '\0') + errx(1, "invalid val at line %ld", + (unsigned long)lineno); + } else + longopts[nlongopts].val = (int)longopt[1]; + nlongopts++; + } else if (strncmp(line, "args:", 5) == 0) { + for (; nargs >= 0; nargs--) { + if (args[nargs] != NULL) + free(args[nargs]); + } + args[nargs = 0] = strtok(&line[6], WS); + if (args[nargs] == NULL) + errx(1, "Missing args"); + + args[nargs] = strdup(args[nargs]); + while ((args[++nargs] = strtok(NULL, WS)) != NULL) + args[nargs] = strdup(args[nargs]); + } else if (strncmp(line, "result:", 7) == 0) { + int li; + buf[0] = '\0'; + optind = optreset = 1; + if (result) + free(result); + result = strtok(&line[8], WS); + if (result == NULL) + errx(1, "missing result at line %ld", + (unsigned long)lineno); + if (optstring == NULL) + errx(1, "result: without optstring"); + if (longopts == NULL || nlongopts == 0) + errx(1, "result: without longopts"); + result = strdup(result); + if (nargs == -1) + errx(1, "result: without args"); + li = -2; + while ((c = getopt_long(nargs, args, optstring, + longopts, &li)) != -1) { + if (c == ':') + errx(1, "`:' found as argument char"); + if (li == -2) { + ptr = strchr(optstring, c); + if (ptr == NULL) { + snprintf(arg, sizeof(arg), + "!%c,", c); + strcat(buf, arg); + continue; + } + if (ptr[1] != ':') + snprintf(arg, sizeof(arg), + "%c,", c); + else + snprintf(arg, sizeof(arg), + "%c=%s,", c, optarg); + } else { + switch (longopts[li].has_arg) { + case no_argument: + snprintf(arg, sizeof(arg), "-%s,", + longopts[li].name); + break; + case required_argument: + snprintf(arg, sizeof(arg), + "-%s=%s,", + longopts[li].name, optarg); + break; + case optional_argument: + snprintf(arg, sizeof(arg), + "-%s%s%s,", + longopts[li].name, + (optarg)? "=" : "", + (optarg)? optarg : ""); + break; + default: + errx(1, "internal error"); + } + } + strcat(buf, arg); + li = -2; + } + len = strlen(buf); + if (len > 0) { + buf[len - 1] = '|'; + buf[len] = '\0'; + } else { + buf[0] = '|'; + buf[1] = '\0'; + } + snprintf(arg, sizeof(arg), "%d", nargs - optind); + strcat(buf, arg); + if (strcmp(buf, result) != 0) + errx(1, "`%s' != `%s'", buf, result); + } else + errx(1, "unknown directive at line %ld", + (unsigned long)lineno); + free(line); + } + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c new file mode 100644 index 0000000..282a125 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c @@ -0,0 +1,154 @@ +/* $NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $"); + +#include <atf-c.h> +#include <inttypes.h> +#include <limits.h> +#include <stdlib.h> + +ATF_TC(abs_basic); +ATF_TC_HEAD(abs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that abs(3) works"); +} + +ATF_TC_BODY(abs_basic, tc) +{ + static const struct { + int val; + int res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -0x1010, 0x1010 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(abs(table[i].val) == table[i].res); +} + +ATF_TC(imaxabs_basic); +ATF_TC_HEAD(imaxabs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that imaxabs(3) works"); +} + +ATF_TC_BODY(imaxabs_basic, tc) +{ + static const struct { + intmax_t val; + intmax_t res; + } table[] = { + { 0, 0 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { LLONG_MAX, LLONG_MAX }, + { -LLONG_MAX, LLONG_MAX }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(imaxabs(table[i].val) == table[i].res); +} + +ATF_TC(labs_basic); +ATF_TC_HEAD(labs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that labs(3) works"); +} + +ATF_TC_BODY(labs_basic, tc) +{ + static const struct { + long val; + long res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -1, 1 }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(labs(table[i].val) == table[i].res); +} + +ATF_TC(llabs_basic); +ATF_TC_HEAD(llabs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that llabs(3) works"); +} + +ATF_TC_BODY(llabs_basic, tc) +{ + static const struct { + long long val; + long long res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -1, 1 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { LLONG_MAX, LLONG_MAX }, + { -LLONG_MAX, LLONG_MAX }, + { -0x100000000LL, 0x100000000LL }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(llabs(table[i].val) == table[i].res); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, abs_basic); + ATF_TP_ADD_TC(tp, imaxabs_basic); + ATF_TP_ADD_TC(tp, labs_basic); + ATF_TP_ADD_TC(tp, llabs_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh new file mode 100755 index 0000000..d11268b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh @@ -0,0 +1,54 @@ +# $NetBSD: t_atexit.sh,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case atexit +atexit_head() +{ + atf_set "descr" "Checks atexit(3) and __cxa_atexit()/__cxa_finalize()" +} +atexit_body() +{ + $(atf_get_srcdir)/h_atexit >out \ + || atf_fail "h_exit failed, see output of the test for details" + + cat >exp <<EOF +cxa_handler_5 +cxa_handler_4 +cxa_handler_3 +cxa_handler_2 +normal_handler_1 +normal_handler_0 +EOF + + diff -Nru exp out \ + || atf_fail "h_exit failed, see output of the test for details" +} + +atf_init_test_cases() +{ + atf_add_test_case atexit +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c b/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c new file mode 100644 index 0000000..3e0c35f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c @@ -0,0 +1,121 @@ +/* $NetBSD: t_atoi.c,v 1.2 2012/03/29 05:56:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_atoi.c,v 1.2 2012/03/29 05:56:36 jruoho Exp $"); + +#include <atf-c.h> +#include <float.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(atof_strtod); +ATF_TC_HEAD(atof_strtod, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atof(3) matches the corresponding strtod(3) call"); +} + +ATF_TC_BODY(atof_strtod, tc) +{ + char buf[128]; + + (void)snprintf(buf, sizeof(buf), "%f\n", DBL_MAX); + + ATF_REQUIRE(atof("0") == strtod("0", NULL)); + ATF_REQUIRE(atof("-1") == strtod("-1", NULL)); + ATF_REQUIRE(atof(buf) == strtod(buf, NULL)); +} + +ATF_TC(atoi_strtol); +ATF_TC_HEAD(atoi_strtol, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atoi(3) matches the corresponding strtol(3) call"); +} + +ATF_TC_BODY(atoi_strtol, tc) +{ + char buf[64]; + + (void)snprintf(buf, sizeof(buf), "%d\n", INT_MAX); + + ATF_REQUIRE(atoi("0") == strtol("0", NULL, 10)); + ATF_REQUIRE(atoi("-1") == strtol("-1", NULL, 10)); + ATF_REQUIRE(atoi(buf) == strtol(buf, NULL, 10)); +} + +ATF_TC(atol_strtol); +ATF_TC_HEAD(atol_strtol, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atol(3) matches the corresponding strtol(3) call"); +} + +ATF_TC_BODY(atol_strtol, tc) +{ + char buf[64]; + + (void)snprintf(buf, sizeof(buf), "%ld\n", LONG_MAX); + + ATF_REQUIRE(atol("0") == strtol("0", NULL, 10)); + ATF_REQUIRE(atol("-1") == strtol("-1", NULL, 10)); + ATF_REQUIRE(atol(buf) == strtol(buf, NULL, 10)); +} + +ATF_TC(atoll_strtoll); +ATF_TC_HEAD(atoll_strtoll, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atoll(3) matches the corresponding strtoll(3) call"); +} + +ATF_TC_BODY(atoll_strtoll, tc) +{ + char buf[128]; + + (void)snprintf(buf, sizeof(buf), "%lld\n", LLONG_MAX); + + ATF_REQUIRE(atoll("0") == strtoll("0", NULL, 10)); + ATF_REQUIRE(atoll("-1") == strtoll("-1", NULL, 10)); + ATF_REQUIRE(atoll(buf) == strtoll(buf, NULL, 10)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, atof_strtod); + ATF_TP_ADD_TC(tp, atoi_strtol); + ATF_TP_ADD_TC(tp, atol_strtol); + ATF_TP_ADD_TC(tp, atoll_strtoll); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_div.c b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c new file mode 100644 index 0000000..376f357 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_div.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> + +#define NUM 1999236 +#define DENOM 1000000 +#define QUOT 1 +#define REM 999236 + +ATF_TC(div_basic); +ATF_TC_HEAD(div_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test div(3) for correctness"); +} + +ATF_TC_BODY(div_basic, tc) +{ + div_t d; + + d = div(NUM, DENOM); + + ATF_CHECK(d.quot == QUOT); + ATF_CHECK(d.rem == REM); +} + +ATF_TC(ldiv_basic); +ATF_TC_HEAD(ldiv_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test ldiv(3) for correctness"); +} + +ATF_TC_BODY(ldiv_basic, tc) +{ + ldiv_t ld; + + ld = ldiv(NUM, DENOM); + + ATF_CHECK(ld.quot == QUOT); + ATF_CHECK(ld.rem == REM); +} + +ATF_TC(lldiv_basic); +ATF_TC_HEAD(lldiv_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test lllldiv(3) for correctness"); +} + +ATF_TC_BODY(lldiv_basic, tc) +{ + lldiv_t lld; + + lld = lldiv(NUM, DENOM); + + ATF_CHECK(lld.quot == QUOT); + ATF_CHECK(lld.rem == REM); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, div_basic); + ATF_TP_ADD_TC(tp, ldiv_basic); + ATF_TP_ADD_TC(tp, lldiv_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c new file mode 100644 index 0000000..067cb51 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c @@ -0,0 +1,186 @@ +/* $NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static bool fail; +static void func(void); + +static void +func(void) +{ + fail = false; +} + +ATF_TC(exit_atexit); +ATF_TC_HEAD(exit_atexit, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of atexit(3)"); +} + +ATF_TC_BODY(exit_atexit, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (atexit(func) != 0) + _exit(EXIT_FAILURE); + + fail = true; + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("atexit(3) failed"); + + if (fail != false) + atf_tc_fail("atexit(3) was not called"); +} + +ATF_TC(exit_basic); +ATF_TC_HEAD(exit_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of exit(3)"); +} + +ATF_TC_BODY(exit_basic, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("exit(3) did not exit successfully"); +} + +ATF_TC(exit_status); +ATF_TC_HEAD(exit_status, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exit(3) status"); +} + +ATF_TC_BODY(exit_status, tc) +{ + const int n = 10; + int i, sta; + pid_t pid; + + for (i = 0; i < n; i++) { + + pid = fork(); + + if (pid < 0) + exit(EXIT_FAILURE); + + if (pid == 0) + exit(i); + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != i) + atf_tc_fail("invalid exit(3) status"); + } +} + +ATF_TC(exit_tmpfile); +ATF_TC_HEAD(exit_tmpfile, tc) +{ + atf_tc_set_md_var(tc, "descr", "Temporary files are unlinked?"); +} + +ATF_TC_BODY(exit_tmpfile, tc) +{ + int sta, fd = -1; + char buf[12]; + pid_t pid; + FILE *f; + + (void)strlcpy(buf, "exit.XXXXXX", sizeof(buf)); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + fd = mkstemp(buf); + + if (fd < 0) + exit(EXIT_FAILURE); + + exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create temporary file"); + + f = fdopen(fd, "r"); + + if (f != NULL) + atf_tc_fail("exit(3) did not clear temporary file"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, exit_atexit); + ATF_TP_ADD_TC(tp, exit_basic); + ATF_TP_ADD_TC(tp, exit_status); + ATF_TP_ADD_TC(tp, exit_tmpfile); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c new file mode 100644 index 0000000..35d6874 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c @@ -0,0 +1,199 @@ +/* $NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +extern char **environ; + +ATF_TC(clearenv_basic); +ATF_TC_HEAD(clearenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test user clearing environment directly"); +} + +ATF_TC_BODY(clearenv_basic, tc) +{ + char name[1024], value[1024]; + + for (size_t i = 0; i < 1024; i++) { + snprintf(name, sizeof(name), "crap%zu", i); + snprintf(value, sizeof(value), "%zu", i); + ATF_CHECK(setenv(name, value, 1) != -1); + } + + *environ = NULL; + + for (size_t i = 0; i < 1; i++) { + snprintf(name, sizeof(name), "crap%zu", i); + snprintf(value, sizeof(value), "%zu", i); + ATF_CHECK(setenv(name, value, 1) != -1); + } + + ATF_CHECK_STREQ(getenv("crap0"), "0"); + ATF_CHECK(getenv("crap1") == NULL); + ATF_CHECK(getenv("crap2") == NULL); +} + +ATF_TC(getenv_basic); +ATF_TC_HEAD(getenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test setenv(3), getenv(3)"); +} + +ATF_TC_BODY(getenv_basic, tc) +{ + ATF_CHECK(setenv("EVIL", "very=bad", 1) != -1); + ATF_CHECK_STREQ(getenv("EVIL"), "very=bad"); + ATF_CHECK(getenv("EVIL=very") == NULL); + ATF_CHECK(unsetenv("EVIL") != -1); +} + +ATF_TC(putenv_basic); +ATF_TC_HEAD(putenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test putenv(3), getenv(3), unsetenv(3)"); +} + + +ATF_TC_BODY(putenv_basic, tc) +{ + char string[1024]; + + snprintf(string, sizeof(string), "crap=true"); + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("crap"), "true"); + string[1] = 'l'; + ATF_CHECK_STREQ(getenv("clap"), "true"); + ATF_CHECK(getenv("crap") == NULL); + string[1] = 'r'; + ATF_CHECK(unsetenv("crap") != -1); + ATF_CHECK(getenv("crap") == NULL); + + ATF_CHECK_ERRNO(EINVAL, putenv(NULL) == -1); + ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("val")) == -1); + ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("=val")) == -1); +} + +ATF_TC(setenv_basic); +ATF_TC_HEAD(setenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test setenv(3), getenv(3), unsetenv(3)"); + atf_tc_set_md_var(tc, "timeout", "300"); +} + +ATF_TC_BODY(setenv_basic, tc) +{ + const size_t numvars = 8192; + size_t i, offset; + char name[1024]; + char value[1024]; + + offset = lrand48(); + for (i = 0; i < numvars; i++) { + (void)snprintf(name, sizeof(name), "var%zu", + (i * 7 + offset) % numvars); + (void)snprintf(value, sizeof(value), "value%ld", lrand48()); + ATF_CHECK(setenv(name, value, 1) != -1); + ATF_CHECK(setenv(name, "foo", 0) != -1); + ATF_CHECK_STREQ(getenv(name), value); + } + + offset = lrand48(); + for (i = 0; i < numvars; i++) { + (void)snprintf(name, sizeof(name), "var%zu", + (i * 11 + offset) % numvars); + ATF_CHECK(unsetenv(name) != -1); + ATF_CHECK(getenv(name) == NULL); + ATF_CHECK(unsetenv(name) != -1); + } + + ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("var", NULL, 1) == -1); + + ATF_CHECK(setenv("var", "=val", 1) == 0); + ATF_CHECK_STREQ(getenv("var"), "=val"); +} + +ATF_TC(setenv_mixed); +ATF_TC_HEAD(setenv_mixed, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mixing setenv(3), unsetenv(3) and putenv(3)"); +} + +ATF_TC_BODY(setenv_mixed, tc) +{ + char string[32]; + + (void)strcpy(string, "mixedcrap=putenv"); + + ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); + ATF_CHECK(unsetenv("mixedcrap") != -1); + ATF_CHECK(getenv("mixedcrap") == NULL); + + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); + ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); + ATF_CHECK(unsetenv("mixedcrap") != -1); + ATF_CHECK(getenv("mixedcrap") == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clearenv_basic); + ATF_TP_ADD_TC(tp, getenv_basic); + ATF_TP_ADD_TC(tp, putenv_basic); + ATF_TP_ADD_TC(tp, setenv_basic); + ATF_TP_ADD_TC(tp, setenv_mixed); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c new file mode 100644 index 0000000..d935629 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c @@ -0,0 +1,250 @@ +/* $NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define THREADED_NUM_THREADS 8 +#define THREADED_NUM_VARS 16 +#define THREADED_VAR_NAME "THREADED%zu" +#define THREADED_RUN_TIME 10 + +static void *thread_getenv_r(void *); +static void *thread_putenv(void *); +static void *thread_setenv(void *); +static void *thread_unsetenv(void *); + +static void * +thread_getenv_r(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32], value[128]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + + if (getenv_r(name, value, sizeof(value)) == -1) { + ATF_CHECK(errno == ENOENT); + } + } while (time(NULL) < endtime); + + return NULL; +} + + +static void * +thread_putenv(void *arg) +{ + time_t endtime; + size_t i; + static char vars[THREADED_NUM_VARS][128]; + + for (i = 0; i < THREADED_NUM_VARS; i++) { + (void)snprintf(vars[i], sizeof(vars[i]), + THREADED_VAR_NAME "=putenv %ld", i, lrand48()); + } + + endtime = *(time_t *)arg; + do { + char name[128]; + + i = lrand48() % THREADED_NUM_VARS; + (void)strlcpy(name, vars[i], sizeof(name)); + *strchr(name, '=') = '\0'; + + ATF_CHECK(unsetenv(name) != -1); + ATF_CHECK(putenv(vars[i]) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +static void * +thread_setenv(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32], value[64]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + (void)snprintf(value, sizeof(value), "setenv %ld", lrand48()); + + ATF_CHECK(setenv(name, value, 1) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +static void * +thread_unsetenv(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + + ATF_CHECK(unsetenv(name) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +ATF_TC(getenv_r_thread); +ATF_TC_HEAD(getenv_r_thread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test getenv_r(3) with threads"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(getenv_r_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_getenv_r, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(putenv_thread); +ATF_TC_HEAD(putenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test concurrent access by putenv(3)"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(putenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_putenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(setenv_thread); +ATF_TC_HEAD(setenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test concurrent access by setenv(3)"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(setenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_setenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(unsetenv_thread); +ATF_TC_HEAD(unsetenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unsetenv(3) with threads"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(unsetenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_unsetenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getenv_r_thread); + ATF_TP_ADD_TC(tp, putenv_thread); + ATF_TP_ADD_TC(tp, setenv_thread); + ATF_TP_ADD_TC(tp, unsetenv_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh new file mode 100755 index 0000000..cc10f65 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh @@ -0,0 +1,123 @@ +# $NetBSD: t_getopt.sh,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +h_getopt() +{ + atf_check -e save:stderr -x "$(atf_get_srcdir)/h_getopt" <<EOF +load: $1 +args: $2 +result: $3 +EOF + cat stderr + rm -f stderr +} + +h_getopt_long() +{ + atf_check -e save:stderr -x "$(atf_get_srcdir)/h_getopt_long" <<EOF +$1 +args: $2 +result: $3 +EOF + cat stderr + rm -f stderr +} + +atf_test_case getopt +getopt_head() +{ + atf_set "descr" "Checks getopt(3)" +} +getopt_body() +{ + load="c:d" + + h_getopt "${load}" "foo -c 1 -d foo" "c=1,d|1" + h_getopt "${load}" "foo -d foo bar" "d|2" + h_getopt "${load}" "foo -c 2 foo bar" "c=2|2" + h_getopt "${load}" "foo -e 1 foo bar" "!?|3" + h_getopt "${load}" "foo -d -- -c 1" "d|2" + h_getopt "${load}" "foo -c- 1" "c=-|1" + h_getopt "${load}" "foo -d - 1" "d|2" +} + +atf_test_case getopt_long +getopt_long_head() +{ + atf_set "descr" "Checks getopt_long(3)" +} +getopt_long_body() +{ + # GNU libc tests with these + load="optstring: abc: +longopts: 5 +longopt: required, required_argument, , 'r' +longopt: optional, optional_argument, , 'o' +longopt: none, no_argument, , 'n' +longopt: color, no_argument, , 'C' +longopt: colour, no_argument, , 'C'" + + h_getopt_long "${load}" "foo --req foobar" "-required=foobar|0" + h_getopt_long "${load}" "foo --opt=bazbug" "-optional=bazbug|0" + + # This is problematic + # + # GNU libc 2.1.3 this fails with ambiguous result + # h_getopt_long "${load}" "foo --col" "!?|0" + # + # GNU libc 2.2 >= this works + h_getopt_long "${load}" "foo --col" "-color|0" + + h_getopt_long "${load}" "foo --colour" "-colour|0" + + # This is the real GNU libc test! + args="foo -a -b -cfoobar --required foobar --optional=bazbug --none random --col --color --colour" + # GNU libc 2.1.3 this fails with ambiguous + #result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,!?,-color,-colour|1" + # + # GNU libc 2.2 >= this works + result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,-color,-color,-colour|1" + h_getopt_long "${load}" "${args}" "${result}" + + # + # The order of long options in the long option array should not matter. + # An exact match should never be treated as ambiguous. + # + load="optstring: fgl +longopts: 3 +longopt: list-foobar, no_argument, lopt, 'f' +longopt: list-goobar, no_argument, lopt, 'g' +longopt: list, no_argument, lopt, 'l'" + h_getopt_long "${load}" "foo --list" "-list|0" +} + + +atf_init_test_cases() +{ + atf_add_test_case getopt + atf_add_test_case getopt_long +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c new file mode 100644 index 0000000..099b3e7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c @@ -0,0 +1,399 @@ +/* $NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2001 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $"); + +#include <errno.h> +#include <search.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +ATF_TC(hsearch_basic); +ATF_TC_HEAD(hsearch_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); +} + +ATF_TC_BODY(hsearch_basic, tc) +{ + ENTRY e, *ep; + char ch[2]; + int i; + + REQUIRE_ERRNO(hcreate(16) != 0); + + /* ch[1] should be constant from here on down. */ + ch[1] = '\0'; + + /* Basic insertions. Check enough that there'll be collisions. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + e.key = strdup(ch); /* ptr to provided key is kept! */ + ATF_REQUIRE(e.key != NULL); + e.data = (void *)(intptr_t)i; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + /* e.key should be constant from here on down. */ + e.key = ch; + + /* Basic lookups. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + + ep = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + hdestroy1(free, NULL); +} + +ATF_TC(hsearch_duplicate); +ATF_TC_HEAD(hsearch_duplicate, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " + "doesn't overwrite existing data"); +} + +ATF_TC_BODY(hsearch_duplicate, tc) +{ + ENTRY e, *ep; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("a"); + e.data = (void *)(intptr_t) 0; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.data = (void *)(intptr_t)12345; + + ep = hsearch(e, ENTER); + ep = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + hdestroy(); +} + +ATF_TC(hsearch_nonexistent); +ATF_TC_HEAD(hsearch_nonexistent, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks searching for non-existent entry"); +} + +ATF_TC_BODY(hsearch_nonexistent, tc) +{ + ENTRY e, *ep; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("A"); + ep = hsearch(e, FIND); + ATF_REQUIRE_EQ(ep, NULL); + + hdestroy(); +} + +ATF_TC(hsearch_two); +ATF_TC_HEAD(hsearch_two, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that searching doesn't overwrite previous search results"); +} + +ATF_TC_BODY(hsearch_two, tc) +{ + ENTRY e, *ep, *ep2; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("a"); + e.data = (void*)(intptr_t)0; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.key = __UNCONST("b"); + e.data = (void*)(intptr_t)1; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 1); + + e.key = __UNCONST("a"); + ep = hsearch(e, FIND); + + e.key = __UNCONST("b"); + ep2 = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + ATF_REQUIRE(ep2 != NULL); + ATF_REQUIRE_STREQ(ep2->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); + + hdestroy(); +} + +ATF_TC(hsearch_r_basic); +ATF_TC_HEAD(hsearch_r_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); +} + +ATF_TC_BODY(hsearch_r_basic, tc) +{ + ENTRY e, *ep; + char ch[2]; + int i; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t) != 0); + + /* ch[1] should be constant from here on down. */ + ch[1] = '\0'; + + /* Basic insertions. Check enough that there'll be collisions. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + e.key = strdup(ch); /* ptr to provided key is kept! */ + ATF_REQUIRE(e.key != NULL); + e.data = (void *)(intptr_t)i; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + /* e.key should be constant from here on down. */ + e.key = ch; + + /* Basic lookups. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + hdestroy1_r(&t, free, NULL); +} + +ATF_TC(hsearch_r_duplicate); +ATF_TC_HEAD(hsearch_r_duplicate, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " + "doesn't overwrite existing data"); +} + +ATF_TC_BODY(hsearch_r_duplicate, tc) +{ + ENTRY e, *ep; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("a"); + e.data = (void *)(intptr_t) 0; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.data = (void *)(intptr_t)12345; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + hdestroy_r(&t); +} + +ATF_TC(hsearch_r_nonexistent); +ATF_TC_HEAD(hsearch_r_nonexistent, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks searching for non-existent entry"); +} + +ATF_TC_BODY(hsearch_r_nonexistent, tc) +{ + ENTRY e, *ep; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("A"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + ATF_REQUIRE_EQ(ep, NULL); + + hdestroy_r(&t); +} + +ATF_TC(hsearch_r_two); +ATF_TC_HEAD(hsearch_r_two, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that searching doesn't overwrite previous search results"); +} + +ATF_TC_BODY(hsearch_r_two, tc) +{ + ENTRY e, *ep, *ep2; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("a"); + e.data = (void*)(intptr_t)0; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.key = __UNCONST("b"); + e.data = (void*)(intptr_t)1; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 1); + + e.key = __UNCONST("a"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + + e.key = __UNCONST("b"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep2, &t) == 1); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + ATF_REQUIRE(ep2 != NULL); + ATF_REQUIRE_STREQ(ep2->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); + + hdestroy_r(&t); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, hsearch_basic); + ATF_TP_ADD_TC(tp, hsearch_duplicate); + ATF_TP_ADD_TC(tp, hsearch_nonexistent); + ATF_TP_ADD_TC(tp, hsearch_two); + + ATF_TP_ADD_TC(tp, hsearch_r_basic); + ATF_TP_ADD_TC(tp, hsearch_r_duplicate); + ATF_TP_ADD_TC(tp, hsearch_r_nonexistent); + ATF_TP_ADD_TC(tp, hsearch_r_two); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c new file mode 100644 index 0000000..77d6443 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $ */ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $"); + +#include <atf-c.h> +#include <stdlib.h> +#include <string.h> + +ATF_TC(mi_vector_hash_basic); +ATF_TC_HEAD(mi_vector_hash_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mi_vector_hash_vector_hash for consistent results"); +} + +static const struct testvector { + const char *vector; + uint32_t hashes[3]; +} testv[] = { + { "hello, world", { 0xd38f7f21, 0xbf6be9ab, 0x37a0e989 } }, + { "", { 0x9b2ec03d, 0xdb2b69ae, 0xbd49d10d } }, + { "a", { 0x9454baa3, 0xb711c708, 0x29eec818 } }, + { "ab", { 0x9a5dca90, 0xdd212644, 0x9879ac41 } }, + { "abc", { 0x0b91c470, 0x4770cdf5, 0x251e4793 } }, + { "abcd", { 0x5f128df3, 0xf5a667a6, 0x5ae61fa5 } }, + { "abcde", { 0x4cbae281, 0x799c0ed5, 0x03a96866 } }, + { "abcdef", { 0x507a54c8, 0xb6bd06f4, 0xde922732 } }, + { "abcdefg", { 0xae2bca5d, 0x61e960ef, 0xb9e6762c } }, + { "abcdefgh", { 0xd1021264, 0x87f6988f, 0x053f775e } }, + { "abcdefghi", { 0xe380defc, 0xfc35a811, 0x3a7b0a5f } }, + { "abcdefghij", { 0x9a504408, 0x70d2e89d, 0xc9cac242 } }, + { "abcdefghijk", { 0x376117d0, 0x89f434d4, 0xe52b8e4c } }, + { "abcdefghijkl", { 0x92253599, 0x7b6ff99e, 0x0b1b3ea5 } }, + { "abcdefghijklm", { 0x92ee6a52, 0x55587d47, 0x3122b031 } }, + { "abcdefghijklmn", { 0x827baf08, 0x1d0ada73, 0xfec330e0 } }, + { "abcdefghijklmno", { 0x06ab787d, 0xc1ad17c2, 0x11dccf31 } }, + { "abcdefghijklmnop", { 0x2cf18103, 0x638c9268, 0xfa1ecf51 } }, +}; + +ATF_TC_BODY(mi_vector_hash_basic, tc) +{ + size_t i, j, len; + uint32_t hashes[3]; + char buf[256]; + + for (j = 0; j < 8; ++j) { + for (i = 0; i < sizeof(testv) / sizeof(testv[0]); ++i) { + len = strlen(testv[i].vector); + strcpy(buf + j, testv[i].vector); + mi_vector_hash(buf + j, len, 0, hashes); + ATF_CHECK_EQ(hashes[0], testv[i].hashes[0]); + ATF_CHECK_EQ(hashes[1], testv[i].hashes[1]); + ATF_CHECK_EQ(hashes[2], testv[i].hashes[2]); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mi_vector_hash_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c new file mode 100644 index 0000000..47afb84 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c @@ -0,0 +1,88 @@ +/* $NetBSD: t_posix_memalign.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_posix_memalign.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $"); + +#include <atf-c.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +ATF_TC(posix_memalign_basic); +ATF_TC_HEAD(posix_memalign_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_memalign(3)"); +} +ATF_TC_BODY(posix_memalign_basic, tc) +{ + size_t size[] = { + 1, 2, 3, 4, 10, 100, 16384, 32768, 65536 + }; + size_t align[] = { + 512, 1024, 16, 32, 64, 4, 2048, 16, 2 + }; + + size_t i; + void *p; + + for (i = 0; i < __arraycount(size); i++) { + int ret; + p = (void*)0x1; + + (void)printf("Checking posix_memalign(&p, %zd, %zd)...\n", + align[i], size[i]); + ret = posix_memalign(&p, align[i], size[i]); + + if ( align[i] < sizeof(void *)) + ATF_REQUIRE_EQ_MSG(ret, EINVAL, + "posix_memalign: %s", strerror(ret)); + else { + ATF_REQUIRE_EQ_MSG(ret, 0, + "posix_memalign: %s", strerror(ret)); + ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0, + "p = %p", p); + free(p); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, posix_memalign_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_random.c b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c new file mode 100644 index 0000000..9a6d21e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c @@ -0,0 +1,82 @@ +/* $NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> + +/* + * TODO: Add some general RNG tests (cf. the famous "diehard" tests?). + */ + +ATF_TC(random_same); +ATF_TC_HEAD(random_same, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that random(3) does not always return the same " + "value when the seed is initialized to zero"); +} + +#define MAX_ITER 10 + +ATF_TC_BODY(random_same, tc) +{ + long buf[MAX_ITER]; + size_t i, j; + + /* + * See CVE-2012-1577. + */ + srandom(0); + + for (i = 0; i < __arraycount(buf); i++) { + + buf[i] = random(); + + for (j = 0; j < i; j++) { + + (void)fprintf(stderr, "i = %zu, j = %zu: " + "%ld vs. %ld\n", i, j, buf[i], buf[j]); + + ATF_CHECK(buf[i] != buf[j]); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, random_same); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c new file mode 100644 index 0000000..d7ebe1b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c @@ -0,0 +1,335 @@ +/* $NetBSD: t_strtod.c,v 1.31 2012/09/26 07:24:38 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Public domain, Otto Moerbeek <otto@drijf.net>, 2006. */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strtod.c,v 1.31 2012/09/26 07:24:38 jruoho Exp $"); + +#include <errno.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#if defined(__i386__) || defined(__amd64__) || defined(__sparc__) +#include <fenv.h> +#endif + +#if !defined(__vax__) +static const char * const inf_strings[] = + { "Inf", "INF", "-Inf", "-INF", "Infinity", "+Infinity", + "INFINITY", "-INFINITY", "InFiNiTy", "+InFiNiTy" }; +const char *nan_string = "NaN(x)y"; +#endif + +ATF_TC(strtod_basic); +ATF_TC_HEAD(strtod_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strtod(3)"); +} + +ATF_TC_BODY(strtod_basic, tc) +{ + static const size_t n = 1024 * 1000; + + for (size_t i = 1; i < n; i = i + 1024) { + char buf[512]; + (void)snprintf(buf, sizeof(buf), "%zu.%zu", i, i + 1); + + errno = 0; + double d = strtod(buf, NULL); + + ATF_REQUIRE(d > 0.0); + ATF_REQUIRE(errno == 0); + } +} + +ATF_TC(strtod_hex); +ATF_TC_HEAD(strtod_hex, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with hexadecimals"); +} + +#ifdef __vax__ +#define SMALL_NUM 1.0e-38 +#else +#define SMALL_NUM 1.0e-40 +#endif + +ATF_TC_BODY(strtod_hex, tc) +{ + const char *str; + char *end; + volatile double d; + + str = "-0x0"; + d = strtod(str, &end); /* -0.0 */ + + ATF_REQUIRE(end == str + 4); + ATF_REQUIRE(signbit(d) != 0); + ATF_REQUIRE(fabs(d) < SMALL_NUM); + + str = "-0x"; + d = strtod(str, &end); /* -0.0 */ + + ATF_REQUIRE(end == str + 2); + ATF_REQUIRE(signbit(d) != 0); + ATF_REQUIRE(fabs(d) < SMALL_NUM); +} + +ATF_TC(strtod_inf); +ATF_TC_HEAD(strtod_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtod_inf, tc) +{ +#ifndef __vax__ + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile double d = strtod(inf_strings[i], NULL); + ATF_REQUIRE(isinf(d) != 0); + } +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtof_inf); +ATF_TC_HEAD(strtof_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtof(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtof_inf, tc) +{ +#ifndef __vax__ + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile float f = strtof(inf_strings[i], NULL); + ATF_REQUIRE(isinf(f) != 0); + } +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtold_inf); +ATF_TC_HEAD(strtold_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtold(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtold_inf, tc) +{ +#ifndef __vax__ +# ifdef __HAVE_LONG_DOUBLE + + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile long double ld = strtold(inf_strings[i], NULL); + ATF_REQUIRE(isinf(ld) != 0); + } +# else + atf_tc_skip("Requires long double support"); +# endif +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtod_nan); +ATF_TC_HEAD(strtod_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with NaN"); +} + +ATF_TC_BODY(strtod_nan, tc) +{ +#ifndef __vax__ + char *end; + + volatile double d = strtod(nan_string, &end); + ATF_REQUIRE(isnan(d) != 0); + ATF_REQUIRE(strcmp(end, "y") == 0); +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtof_nan); +ATF_TC_HEAD(strtof_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtof(3) with NaN"); +} + +ATF_TC_BODY(strtof_nan, tc) +{ +#ifndef __vax__ + char *end; + + volatile float f = strtof(nan_string, &end); + ATF_REQUIRE(isnanf(f) != 0); + ATF_REQUIRE(strcmp(end, "y") == 0); +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtold_nan); +ATF_TC_HEAD(strtold_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtold(3) with NaN (PR lib/45020)"); +} + +ATF_TC_BODY(strtold_nan, tc) +{ +#ifndef __vax__ +# ifdef __HAVE_LONG_DOUBLE + + char *end; + + volatile long double ld = strtold(nan_string, &end); + ATF_REQUIRE(isnan(ld) != 0); + ATF_REQUIRE(__isnanl(ld) != 0); + ATF_REQUIRE(strcmp(end, "y") == 0); +# else + atf_tc_skip("Requires long double support"); +# endif +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtod_round); +ATF_TC_HEAD(strtod_round, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test rouding in strtod(3)"); +} + +ATF_TC_BODY(strtod_round, tc) +{ +#if defined(__i386__) || defined(__amd64__) || defined(__sparc__) + + /* + * Test that strtod(3) honors the current rounding mode. + * The used value is somewhere near 1 + DBL_EPSILON + FLT_EPSILON. + */ + const char *val = + "1.00000011920928977282585492503130808472633361816406"; + + (void)fesetround(FE_UPWARD); + + volatile double d1 = strtod(val, NULL); + + (void)fesetround(FE_DOWNWARD); + + volatile double d2 = strtod(val, NULL); + + if (fabs(d1 - d2) > 0.0) + return; + else { + atf_tc_expect_fail("PR misc/44767"); + atf_tc_fail("strtod(3) did not honor fesetround(3)"); + } +#else + atf_tc_skip("Requires one of i386, amd64 or sparc"); +#endif +} + +ATF_TC(strtod_underflow); +ATF_TC_HEAD(strtod_underflow, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test underflow in strtod(3)"); +} + +ATF_TC_BODY(strtod_underflow, tc) +{ + + const char *tmp = + "0.0000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000002"; + + errno = 0; + volatile double d = strtod(tmp, NULL); + + if (d != 0 || errno != ERANGE) + atf_tc_fail("strtod(3) did not detect underflow"); +} + +/* + * Bug found by Geza Herman. + * See + * http://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/ + */ +ATF_TC(strtod_gherman_bug); +ATF_TC_HEAD(strtod_gherman_bug, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test a bug found by Geza Herman"); +} + +ATF_TC_BODY(strtod_gherman_bug, tc) +{ + + const char *str = + "1.8254370818746402660437411213933955878019332885742187"; + + errno = 0; + volatile double d = strtod(str, NULL); + + ATF_CHECK(d == 0x1.d34fd8378ea83p+0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strtod_basic); + ATF_TP_ADD_TC(tp, strtod_hex); + ATF_TP_ADD_TC(tp, strtod_inf); + ATF_TP_ADD_TC(tp, strtof_inf); + ATF_TP_ADD_TC(tp, strtold_inf); + ATF_TP_ADD_TC(tp, strtod_nan); + ATF_TP_ADD_TC(tp, strtof_nan); + ATF_TP_ADD_TC(tp, strtold_nan); + ATF_TP_ADD_TC(tp, strtod_round); + ATF_TP_ADD_TC(tp, strtod_underflow); + ATF_TP_ADD_TC(tp, strtod_gherman_bug); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c new file mode 100644 index 0000000..5a0c6d0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c @@ -0,0 +1,234 @@ +/* $NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +struct test { + const char *str; + int64_t res; + int base; + const char *end; +}; + +static void check(struct test *, long int, long long int, char *); + +static void +check(struct test *t, long int li, long long int lli, char *end) +{ + + if (li != -1 && li != t->res) + atf_tc_fail_nonfatal("strtol(%s, &end, %d) failed " + "(rv = %ld)", t->str, t->base, li); + + if (lli != -1 && lli != t->res) + atf_tc_fail_nonfatal("strtoll(%s, NULL, %d) failed " + "(rv = %lld)", t->str, t->base, lli); + + if (t->end != NULL && strcmp(t->end, end) != 0) + atf_tc_fail_nonfatal("invalid end pointer ('%s') from " + "strtol(%s, &end, %d)", end, t->str, t->base); +} + +ATF_TC(strtol_base); +ATF_TC_HEAD(strtol_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strtol(3) with different bases"); +} + +ATF_TC_BODY(strtol_base, tc) +{ + struct test t[] = { + { "123456789", 123456789, 0, NULL }, + { "111010110111100110100010101", 123456789, 2, NULL }, + { "22121022020212200", 123456789, 3, NULL }, + { "13112330310111", 123456789, 4, NULL }, + { "223101104124", 123456789, 5, NULL }, + { "20130035113", 123456789, 6, NULL }, + { "3026236221", 123456789, 7, NULL }, + { "726746425", 123456789, 8, NULL }, + { "277266780", 123456789, 9, NULL }, + { "123456789", 123456789, 10, NULL }, + { "63762A05", 123456789, 11, NULL }, + { "35418A99", 123456789, 12, NULL }, + { "1C767471", 123456789, 13, NULL }, + { "12579781", 123456789, 14, NULL }, + { "AC89BC9", 123456789, 15, NULL }, + { "75BCD15", 123456789, 16, NULL }, + { "123456789", 342391, 8, NULL }, + { "0123456789", 342391, 0, NULL }, + { "0123456789", 123456789, 10, NULL }, + { "0x75bcd15", 123456789, 0, NULL }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TC(strtol_case); +ATF_TC_HEAD(strtol_case, tc) +{ + atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtol(3)"); +} + +ATF_TC_BODY(strtol_case, tc) +{ + struct test t[] = { + { "abcd", 0xabcd, 16, NULL }, + { " dcba", 0xdcba, 16, NULL }, + { "abcd dcba", 0xabcd, 16, " dcba" }, + { "abc0x123", 0xabc0, 16, NULL }, + { "abcd\0x123", 0xabcd, 16, "\0x123" }, + { "ABCD", 0xabcd, 16, NULL }, + { "aBcD", 0xabcd, 16, NULL }, + { "0xABCD", 0xabcd, 16, NULL }, + { "0xABCDX", 0xabcd, 16, "X" }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TC(strtol_range); +ATF_TC_HEAD(strtol_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtol(3)"); +} + +ATF_TC_BODY(strtol_range, tc) +{ + +#if LONG_MAX == 0x7fffffff /* XXX: Is this portable? */ + + struct test t[] = { + { "20000000000", 2147483647, 8, NULL }, + { "2147483648", 2147483647, 10, NULL }, + { "80000000", 2147483647, 16, NULL }, + }; +#else + struct test t[] = { + { "1000000000000000000000", 9223372036854775807, 8, NULL }, + { "9223372036854775808", 9223372036854775807, 10, NULL }, + { "8000000000000000", 9223372036854775807, 16, NULL }, + }; +#endif + + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + errno = 0; + li = strtol(t[i].str, &end, t[i].base); + + if (errno != ERANGE) + atf_tc_fail("strtol(3) did not catch ERANGE"); + + check(&t[i], li, -1, end); + } +} + +ATF_TC(strtol_signed); +ATF_TC_HEAD(strtol_signed, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strtol(3)"); +} + +ATF_TC_BODY(strtol_signed, tc) +{ + struct test t[] = { + { "1", 1, 0, NULL }, + { " 2", 2, 0, NULL }, + { " 3", 3, 0, NULL }, + { " -3", -3, 0, NULL }, + { "--1", 0, 0, "--1" }, + { "+-2", 0, 0, "+-2" }, + { "++3", 0, 0, "++3" }, + { "+9", 9, 0, NULL }, + { "+123", 123, 0, NULL }, + { "-1 3", -1, 0, " 3" }, + { "-1.3", -1, 0, ".3" }, + { "- 3", 0, 0, "- 3" }, + { "+33.", 33, 0, "." }, + { "30x0", 30, 0, "x0" }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strtol_base); + ATF_TP_ADD_TC(tp, strtol_case); + ATF_TP_ADD_TC(tp, strtol_range); + ATF_TP_ADD_TC(tp, strtol_signed); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_system.c b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c new file mode 100644 index 0000000..235005b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c @@ -0,0 +1,83 @@ +/* $NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $"); + +#include <atf-c.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const char *path = "system"; + +ATF_TC_WITH_CLEANUP(system_basic); +ATF_TC_HEAD(system_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of system(3)"); +} + +ATF_TC_BODY(system_basic, tc) +{ + char buf[23]; + int fd, i = 2; + + ATF_REQUIRE(system("/bin/echo -n > system") == 0); + + while (i >= 0) { + ATF_REQUIRE(system("/bin/echo -n garbage >> system") == 0); + i--; + } + + fd = open(path, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, '\0', sizeof(buf)); + + ATF_REQUIRE(read(fd, buf, 21) == 21); + ATF_REQUIRE(strcmp(buf, "garbagegarbagegarbage") == 0); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(system_basic, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, system_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_bm.c b/contrib/netbsd-tests/lib/libc/string/t_bm.c new file mode 100644 index 0000000..5ec4022 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_bm.c @@ -0,0 +1,102 @@ +/* $Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $ */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Mateusz Kocielski. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <sys/types.h> +#include <bm.h> +#include <string.h> +#include <stdlib.h> + +ATF_TC(bm); +ATF_TC_HEAD(bm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bm(3)"); +} + +typedef struct { + const char *pattern; + const char *text; + const char *freq; + ssize_t match; +} t_testcase; + +const t_testcase testcases[] = { + {"test", "test", NULL, 0}, + {"test", "ttest", NULL, 1}, + {"test", "tes", NULL, -1}, + {"test", "testtesttest", NULL, 0}, + {"test", "testtesttesttesttesttest", NULL, 0}, + {"test", "------------------------", NULL, -1}, + {"a", "a", NULL, 0}, + {"a", "ba", NULL, 1}, + {"a", "bba", NULL, 2}, + {"bla", "bl", NULL, -1}, + {"a", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", NULL, -1}, + {"test", "qfwiofjqeiwofjioqewfjeiqwjfiqewjfioqewfjioewqjfioewqjfioewqjoi", + NULL, -1}, + {"needle", "haystack", NULL, -1}, + {"netbsd", "freebsd netbsd openbsd", NULL, 8}, +}; + +ATF_TC_BODY(bm, tc) +{ + size_t ts; + u_char *off; + char *text; + bm_pat *pattern; + + for (ts = 0; ts < sizeof(testcases)/sizeof(t_testcase); ts++) { + ATF_CHECK(pattern = bm_comp((const u_char *)testcases[ts].pattern, + strlen(testcases[ts].pattern), (const u_char *)testcases[ts].freq)); + + ATF_REQUIRE(text = strdup(testcases[ts].text)); + off = bm_exec(pattern, (u_char *)text, strlen(text)); + + if (testcases[ts].match == -1) + ATF_CHECK_EQ(off, NULL); + else + ATF_CHECK_EQ(testcases[ts].match, + (off-(u_char *)text)); + + bm_free(pattern); + free(text); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bm); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memchr.c b/contrib/netbsd-tests/lib/libc/string/t_memchr.c new file mode 100644 index 0000000..296f1f8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memchr.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_memchr.c,v 1.3 2012/04/06 07:53:10 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(memchr_basic); +ATF_TC_HEAD(memchr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #1"); +} + +ATF_TC_BODY(memchr_basic, tc) +{ + /* try to trick the compiler */ + void * (*f)(const void *, int, size_t) = memchr; + + unsigned int a, t; + void *off, *off2; + char buf[32]; + + struct tab { + const char *val; + size_t len; + char match; + ssize_t off; + }; + + const struct tab tab[] = { + { "", 0, 0, 0 }, + + { "/", 0, 0, 0 }, + { "/", 1, 1, 0 }, + { "/a", 2, 1, 0 }, + { "/ab", 3, 1, 0 }, + { "/abc", 4, 1, 0 }, + { "/abcd", 5, 1, 0 }, + { "/abcde", 6, 1, 0 }, + { "/abcdef", 7, 1, 0 }, + { "/abcdefg", 8, 1, 0 }, + + { "a/", 1, 0, 0 }, + { "a/", 2, 1, 1 }, + { "a/b", 3, 1, 1 }, + { "a/bc", 4, 1, 1 }, + { "a/bcd", 5, 1, 1 }, + { "a/bcde", 6, 1, 1 }, + { "a/bcdef", 7, 1, 1 }, + { "a/bcdefg", 8, 1, 1 }, + + { "ab/", 2, 0, 0 }, + { "ab/", 3, 1, 2 }, + { "ab/c", 4, 1, 2 }, + { "ab/cd", 5, 1, 2 }, + { "ab/cde", 6, 1, 2 }, + { "ab/cdef", 7, 1, 2 }, + { "ab/cdefg", 8, 1, 2 }, + + { "abc/", 3, 0, 0 }, + { "abc/", 4, 1, 3 }, + { "abc/d", 5, 1, 3 }, + { "abc/de", 6, 1, 3 }, + { "abc/def", 7, 1, 3 }, + { "abc/defg", 8, 1, 3 }, + + { "abcd/", 4, 0, 0 }, + { "abcd/", 5, 1, 4 }, + { "abcd/e", 6, 1, 4 }, + { "abcd/ef", 7, 1, 4 }, + { "abcd/efg", 8, 1, 4 }, + + { "abcde/", 5, 0, 0 }, + { "abcde/", 6, 1, 5 }, + { "abcde/f", 7, 1, 5 }, + { "abcde/fg", 8, 1, 5 }, + + { "abcdef/", 6, 0, 0 }, + { "abcdef/", 7, 1, 6 }, + { "abcdef/g", 8, 1, 6 }, + + { "abcdefg/", 7, 0, 0 }, + { "abcdefg/", 8, 1, 7 }, + + { "\xff\xff\xff\xff" "efg/", 8, 1, 7 }, + { "a" "\xff\xff\xff\xff" "fg/", 8, 1, 7 }, + { "ab" "\xff\xff\xff\xff" "g/", 8, 1, 7 }, + { "abc" "\xff\xff\xff\xff" "/", 8, 1, 7 }, + }; + + for (a = 1; a < 1 + sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + buf[a-1] = '/'; + strcpy(&buf[a], tab[t].val); + + off = f(&buf[a], '/', tab[t].len); + if (tab[t].match == 0) { + if (off != 0) { + fprintf(stderr, "a = %d, t = %d\n", + a, t); + atf_tc_fail("should not have found " + " char past len"); + } + } else if (tab[t].match == 1) { + if (tab[t].off != ((char*)off - &buf[a])) { + fprintf(stderr, "a = %d, t = %d\n", + a, t); + atf_tc_fail("char not found at " + "correct offset"); + } + } else { + fprintf(stderr, "a = %d, t = %d\n", a, t); + atf_tc_fail("Corrupt test case data"); + } + + /* check zero extension of char arg */ + off2 = f(&buf[a], 0xffffff00 | '/', tab[t].len); + if (off2 != off) + atf_tc_fail("zero extension of char arg " + "failed"); + } + } +} + +ATF_TC(memchr_simple); +ATF_TC_HEAD(memchr_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #2"); +} + +ATF_TC_BODY(memchr_simple, tc) +{ + char buf[] = "abcdefg"; + short i = 7; + + ATF_CHECK(memchr(buf, 'a', 0) == NULL); + ATF_CHECK(memchr(buf, 'g', 0) == NULL); + ATF_CHECK(memchr(buf, 'x', 7) == NULL); + + ATF_CHECK(memchr("\0", 'x', 0) == NULL); + ATF_CHECK(memchr("\0", 'x', 1) == NULL); + + while (i <= 14) { + + ATF_CHECK(memchr(buf, 'a', i) == buf + 0); + ATF_CHECK(memchr(buf, 'b', i) == buf + 1); + ATF_CHECK(memchr(buf, 'c', i) == buf + 2); + ATF_CHECK(memchr(buf, 'd', i) == buf + 3); + ATF_CHECK(memchr(buf, 'e', i) == buf + 4); + ATF_CHECK(memchr(buf, 'f', i) == buf + 5); + ATF_CHECK(memchr(buf, 'g', i) == buf + 6); + + i *= 2; + } +} + +ATF_TC(memrchr_simple); +ATF_TC_HEAD(memrchr_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memrchr(3) results"); +} + +ATF_TC_BODY(memrchr_simple, tc) +{ + char buf[] = "abcdabcd"; + + ATF_CHECK(memrchr(buf, 'a', 0) == NULL); + ATF_CHECK(memrchr(buf, 'g', 0) == NULL); + ATF_CHECK(memrchr(buf, 'x', 8) == NULL); + + ATF_CHECK(memrchr("\0", 'x', 0) == NULL); + ATF_CHECK(memrchr("\0", 'x', 1) == NULL); + + ATF_CHECK(memrchr(buf, 'a', 8) == buf + 4); + ATF_CHECK(memrchr(buf, 'b', 8) == buf + 5); + ATF_CHECK(memrchr(buf, 'c', 8) == buf + 6); + ATF_CHECK(memrchr(buf, 'd', 8) == buf + 7); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memchr_basic); + ATF_TP_ADD_TC(tp, memchr_simple); + ATF_TP_ADD_TC(tp, memrchr_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memcpy.c b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c new file mode 100644 index 0000000..6485a88 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_memcpy.c,v 1.5 2013/03/17 02:23:31 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <md5.h> + +#include <sys/types.h> + +#define ALIGNMENTS 16 +#define LENGTHS 4 +#define BLOCKTYPES 4 + +MD5_CTX mc[1]; + +typedef unsigned char testBlock_t[ALIGNMENTS * LENGTHS]; + +testBlock_t bss1, bss2; + +unsigned char *start[BLOCKTYPES] = { + bss1, bss2 +}; + +char result[100]; +const char goodResult[] = "7b405d24bc03195474c70ddae9e1f8fb"; + +static void +runTest(unsigned char *b1, unsigned char *b2) +{ + int i, j, k, m; + size_t n; + + for (i = 0; i < ALIGNMENTS; ++i) { + for (j = 0; j < ALIGNMENTS; ++j) { + k = sizeof(testBlock_t) - (i > j ? i : j); + for (m = 0; m < k; ++m) { + for (n = 0; n < sizeof(testBlock_t); ++n) { + b1[n] = (unsigned char)random(); + b2[n] = (unsigned char)random(); + } + memcpy(b1 + i, b2 + j, m); + MD5Update(mc, b1, sizeof(testBlock_t)); + MD5Update(mc, b2, sizeof(testBlock_t)); + } + } + } +} + +ATF_TC(memcpy_basic); +ATF_TC_HEAD(memcpy_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memcpy results"); +} + +ATF_TC_BODY(memcpy_basic, tc) +{ + int i, j; + testBlock_t auto1, auto2; + + start[2] = auto1; + start[3] = auto2; + + srandom(0L); + MD5Init(mc); + for (i = 0; i < BLOCKTYPES; ++i) + for (j = 0; j < BLOCKTYPES; ++j) + if (i != j) + runTest(start[i], start[j]); + MD5End(mc, result); + ATF_REQUIRE_EQ(strcmp(result, goodResult), 0); +} + +ATF_TC(memccpy_simple); +ATF_TC_HEAD(memccpy_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memccpy(3) results"); +} + +ATF_TC_BODY(memccpy_simple, tc) +{ + char buf[100]; + char c = ' '; + + (void)memset(buf, c, sizeof(buf)); + + ATF_CHECK(memccpy(buf, "foo bar", c, sizeof(buf)) != NULL); + ATF_CHECK(buf[4] == c); + + ATF_CHECK(memccpy(buf, "foo bar", '\0', sizeof(buf) - 1) != NULL); + ATF_CHECK(buf[8] == c); + + ATF_CHECK(memccpy(buf, "foo bar", 'x', 7) == NULL); + ATF_CHECK(strncmp(buf, "foo bar", 7) == 0); + + ATF_CHECK(memccpy(buf, "xxxxxxx", 'r', 7) == NULL); + ATF_CHECK(strncmp(buf, "xxxxxxx", 7) == 0); +} + +ATF_TC(memcpy_return); +ATF_TC_HEAD(memcpy_return, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memcpy(3) return value"); +} + +ATF_TC_BODY(memcpy_return, tc) +{ + char *b = (char *)0x1; + char c[2]; + ATF_REQUIRE_EQ(memcpy(b, b, 0), b); + ATF_REQUIRE_EQ(memcpy(c, "ab", sizeof(c)), c); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memcpy_basic); + ATF_TP_ADD_TC(tp, memcpy_return); + ATF_TP_ADD_TC(tp, memccpy_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memmem.c b/contrib/netbsd-tests/lib/libc/string/t_memmem.c new file mode 100644 index 0000000..1e87af8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memmem.c @@ -0,0 +1,100 @@ +/* $NetBSD: t_memmem.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char p0[] = ""; +int lp0 = 0; +char p1[] = "0123"; +int lp1 = 4; +char p2[] = "456"; +int lp2 = 3; +char p3[] = "789"; +int lp3 = 3; +char p4[] = "abc"; +int lp4 = 3; +char p5[] = "0"; +int lp5 = 1; +char p6[] = "9"; +int lp6 = 1; +char p7[] = "654"; +int lp7 = 3; + +char b0[] = ""; +int lb0 = 0; +char b1[] = "0"; +int lb1 = 1; +char b2[] = "0123456789"; +int lb2 = 10; + +#define expect(b) \ + if (!(b)) { \ + fprintf(stderr, "failed on line %d\n", __LINE__); \ + atf_tc_fail("Check stderr for test id/line"); \ + } + +ATF_TC(memmem_basic); +ATF_TC_HEAD(memmem_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test memmem results"); +} + +ATF_TC_BODY(memmem_basic, tc) +{ + + expect(memmem(b2, lb2, p0, lp0) == b2); + expect(memmem(b0, lb0, p0, lp0) == b0); + expect(memmem(b0, lb0, p1, lp1) == NULL); + expect(memmem(b1, lb1, p1, lp1) == NULL); + + expect(memmem(b2, lb2, p1, lp1) == b2); + expect(memmem(b2, lb2, p2, lp2) == (b2 + 4)); + expect(memmem(b2, lb2, p3, lp3) == (b2 + 7)); + + expect(memmem(b2, lb2, p5, lp5) == b2); + expect(memmem(b2, lb2, p6, lp6) == (b2 + 9)); + + expect(memmem(b2, lb2, p4, lp4) == NULL); + expect(memmem(b2, lb2, p7, lp7) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memmem_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memset.c b/contrib/netbsd-tests/lib/libc/string/t_memset.c new file mode 100644 index 0000000..c1fb385 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memset.c @@ -0,0 +1,207 @@ +/* $NetBSD: t_memset.c,v 1.3 2013/03/17 02:23:31 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_memset.c,v 1.3 2013/03/17 02:23:31 christos Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static long page = 0; +static void fill(char *, size_t, char); +static bool check(char *, size_t, char); + +ATF_TC(memset_array); +ATF_TC_HEAD(memset_array, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with arrays"); +} + +ATF_TC_BODY(memset_array, tc) +{ + char buf[1024]; + + (void)memset(buf, 0, sizeof(buf)); + + if (check(buf, sizeof(buf), 0) != true) + atf_tc_fail("memset(3) did not fill a static buffer"); + + (void)memset(buf, 'x', sizeof(buf)); + + if (check(buf, sizeof(buf), 'x') != true) + atf_tc_fail("memset(3) did not fill a static buffer"); +} + +ATF_TC(memset_return); +ATF_TC_HEAD(memset_return, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) return value"); +} + +ATF_TC_BODY(memset_return, tc) +{ + char *b = (char *)0x1; + char c[2]; + ATF_REQUIRE_EQ(memset(b, 0, 0), b); + ATF_REQUIRE_EQ(memset(c, 2, sizeof(c)), c); +} + +ATF_TC(memset_basic); +ATF_TC_HEAD(memset_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of memset(3)"); +} + +ATF_TC_BODY(memset_basic, tc) +{ + char *buf, *ret; + + buf = malloc(page); + ret = malloc(page); + + ATF_REQUIRE(buf != NULL); + ATF_REQUIRE(ret != NULL); + + fill(ret, page, 0); + memset(buf, 0, page); + + ATF_REQUIRE(memcmp(ret, buf, page) == 0); + + fill(ret, page, 'x'); + memset(buf, 'x', page); + + ATF_REQUIRE(memcmp(ret, buf, page) == 0); + + free(buf); + free(ret); +} + +ATF_TC(memset_nonzero); +ATF_TC_HEAD(memset_nonzero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with non-zero params"); +} + +ATF_TC_BODY(memset_nonzero, tc) +{ + const size_t n = 0x7f; + char *buf; + size_t i; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + for (i = 0x21; i < n; i++) { + + (void)memset(buf, i, page); + + if (check(buf, page, i) != true) + atf_tc_fail("memset(3) did not fill properly"); + } + + free(buf); +} + +ATF_TC(memset_struct); +ATF_TC_HEAD(memset_struct, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with a structure"); +} + +ATF_TC_BODY(memset_struct, tc) +{ + struct stat st; + + st.st_dev = 0; + st.st_ino = 1; + st.st_mode = 2; + st.st_nlink = 3; + st.st_uid = 4; + st.st_gid = 5; + st.st_rdev = 6; + st.st_size = 7; + st.st_atime = 8; + st.st_mtime = 9; + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_CHECK(st.st_dev == 0); + ATF_CHECK(st.st_ino == 0); + ATF_CHECK(st.st_mode == 0); + ATF_CHECK(st.st_nlink == 0); + ATF_CHECK(st.st_uid == 0); + ATF_CHECK(st.st_gid == 0); + ATF_CHECK(st.st_rdev == 0); + ATF_CHECK(st.st_size == 0); + ATF_CHECK(st.st_atime == 0); + ATF_CHECK(st.st_mtime == 0); +} + +static void +fill(char *buf, size_t len, char x) +{ + size_t i; + + for (i = 0; i < len; i++) + buf[i] = x; +} + +static bool +check(char *buf, size_t len, char x) +{ + size_t i; + + for (i = 0; i < len; i++) { + + if (buf[i] != x) + return false; + } + + return true; +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, memset_array); + ATF_TP_ADD_TC(tp, memset_basic); + ATF_TP_ADD_TC(tp, memset_nonzero); + ATF_TP_ADD_TC(tp, memset_struct); + ATF_TP_ADD_TC(tp, memset_return); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_popcount.c b/contrib/netbsd-tests/lib/libc/string/t_popcount.c new file mode 100644 index 0000000..2bae52f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_popcount.c @@ -0,0 +1,198 @@ +/* $NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $ */ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $"); + +#include <atf-c.h> +#include <strings.h> + +static unsigned int byte_count[256]; + +static void +popcount_init(const char *cfg_var) +{ + unsigned int i, j; + + if (strcasecmp(cfg_var, "YES") == 0 || + strcasecmp(cfg_var, "Y") == 0 || + strcasecmp(cfg_var, "1") == 0 || + strcasecmp(cfg_var, "T") == 0 || + strcasecmp(cfg_var, "TRUE") == 0) { + for (i = 0; i < 256; ++i) { + byte_count[i] = 0; + for (j = i; j != 0; j >>= 1) { + if (j & 1) + ++byte_count[i]; + } + } + return; + } + + atf_tc_skip("config variable \"run_popcount\" not set to YES/TRUE"); +} + +unsigned int test_parts[256] = { + 0x318e53e6U, 0x11710316U, 0x62608ffaU, 0x67e0f562U, + 0xe432e82cU, 0x9862e8b2U, 0x7d96a627U, 0x3f74ad31U, + 0x3cecf906U, 0xcdc0dcb4U, 0x241dab64U, 0x31e6133eU, + 0x23086ad4U, 0x721d5a91U, 0xc483da53U, 0x6a62af52U, + 0xf3f5c386U, 0xe0de3f77U, 0x65afe528U, 0xf4816485U, + 0x40ccbf08U, 0x25df49c1U, 0xae5a6ee0U, 0xab36ccadU, + 0x87e1ec29U, 0x60ca2407U, 0x49d62e47U, 0xa09f2df5U, + 0xaf4c1c68U, 0x8ef08d50U, 0x624cfd2fU, 0xa6a36f20U, + 0x68aaf879U, 0x0fe9deabU, 0x5c9a4060U, 0x215d8f08U, + 0x55e84712U, 0xea1f1681U, 0x3a10b8a1U, 0x08e06632U, + 0xcbc875e2U, 0x31e53258U, 0xcd3807a4U, 0xb9d17516U, + 0x8fbfd9abU, 0x6651b555U, 0x550fb381U, 0x05061b9dU, + 0x35aef3f2U, 0x9175078cU, 0xae0f14daU, 0x92a2d5f8U, + 0x70d968feU, 0xe86f41c5U, 0x5cfaf39fU, 0x8499b18dU, + 0xb33f879aU, 0x0a68ad3dU, 0x9323ecc1U, 0x060037ddU, + 0xb91a5051U, 0xa0dbebf6U, 0x3e6aa6f1U, 0x7b422b5bU, + 0x599e811eU, 0x199f7594U, 0xca453365U, 0x1cda6f48U, + 0xe9c75d2cU, 0x6a873217U, 0x79c45d72U, 0x143b8e37U, + 0xa11df26eU, 0xaf31f80aU, 0x311bf759U, 0x2378563cU, + 0x9ab95fa5U, 0xfcf4d47cU, 0x1f7db268U, 0xd64b09e1U, + 0xad7936daU, 0x7a59005cU, 0x45b173d3U, 0xc1a71b32U, + 0x7d9f0de2U, 0xa9ac3792U, 0x9e7f9966U, 0x7f0b8080U, + 0xece6c06fU, 0x78d92a3cU, 0x6d5f8f6cU, 0xc50ca544U, + 0x5d8ded27U, 0xd27a8462U, 0x4bcd13ccU, 0xd49075f2U, + 0xa8d52acfU, 0x41915d97U, 0x564f7062U, 0xefb046e2U, + 0xe296277aU, 0x605b0ea3U, 0x10b2c3a1U, 0x4e8e5c66U, + 0x4bd8ec04U, 0x29935be9U, 0x381839f3U, 0x555d8824U, + 0xd6befddbU, 0x5d8d6d6eU, 0xb2fdb7b4U, 0xb471c8fcU, + 0xc2fd325bU, 0x932d2487U, 0xbdbbadefU, 0x66c8895dU, + 0x5d77857aU, 0x259f1cc0U, 0x302037faU, 0xda9aa7a8U, + 0xb112c6aaU, 0x78f74192U, 0xfd4da741U, 0xfa5765c1U, + 0x6ea1bc5cU, 0xd283f39cU, 0x268ae67dU, 0xdedcd134U, + 0xbbf92410U, 0x6b45fb55U, 0x2f75ac71U, 0x64bf2ca5U, + 0x8b99675aU, 0x3f4923b6U, 0x7e610550U, 0x04b1c06dU, + 0x8f92e7c6U, 0x45cb608bU, 0x2d06d1f2U, 0x79cf387aU, + 0xfd3ed225U, 0x243eee20U, 0x2cbefc6fU, 0x8286cbaaU, + 0x70d4c182U, 0x054e3cc6U, 0xb66c5362U, 0x0c73fa5dU, + 0x539948feU, 0xec638563U, 0x0cf04ab6U, 0xec7b52f4U, + 0x58eeffceU, 0x6fe8049aU, 0xb3b33332U, 0x2e33bfdbU, + 0xcc817567U, 0x71ac57c8U, 0x4bab3ac7U, 0x327c558bU, + 0x82a6d279U, 0x5adf71daU, 0x1074a656U, 0x3c533c1fU, + 0x82fdbe69U, 0x21b4f6afU, 0xd59580e8U, 0x0de824ebU, + 0xa510941bU, 0x7cd91144U, 0xa8c10631U, 0x4c839267U, + 0x5d503c2fU, 0xe1567d55U, 0x23910cc7U, 0xdb1bdc34U, + 0x2a866704U, 0x33e21f0cU, 0x5c7681b4U, 0x818651caU, + 0xb1d18162U, 0x225ad014U, 0xadf7d6baU, 0xac548d9bU, + 0xe94736e5U, 0x2279c5f1U, 0x33215d2cU, 0xdc8ab90eU, + 0xf5e3d7f2U, 0xedcb15cfU, 0xc9a43c4cU, 0xfc678fc6U, + 0x43796b95U, 0x3f8b700cU, 0x867bbc72U, 0x81f71fecU, + 0xd00cad7dU, 0x302c458fU, 0x8ae21accU, 0x05850ce8U, + 0x7764d8e8U, 0x8a36cd68U, 0x40b44bd7U, 0x1cffaeb7U, + 0x2b248f34U, 0x1eefdbafU, 0x574d7437U, 0xe86cd935U, + 0xf53dd1c8U, 0x1b022513U, 0xef2d249bU, 0x94fb2b08U, + 0x15d3eff8U, 0x14245e1bU, 0x82aa8425U, 0x53959028U, + 0x9c5f9b80U, 0x325e0c82U, 0x3e236c24U, 0x74e1dd36U, + 0x9890df3fU, 0xaf9701a2U, 0x023b3413U, 0x7634c67eU, + 0x55cf5e45U, 0x56d2a95bU, 0xb6db869bU, 0xac19e260U, + 0xdd310740U, 0x26d68f84U, 0x45bebf17U, 0xe4a7728fU, + 0xf082e66eU, 0xb2fe3c10U, 0x2db1fa2cU, 0x4b3dfcfaU, + 0xc7b3a672U, 0xaeadc67bU, 0x6cce6f2bU, 0x8263dbbfU, + 0xd9724d5bU, 0xbcc767b5U, 0x8d563798U, 0x2db764b4U, + 0x76e0cee7U, 0xd34f9a67U, 0x035c810aU, 0x3f56bdc1U, + 0x5b3f2c84U, 0x0baca8c0U, 0xfe979a77U, 0x484ca775U, + 0xbdc7f104U, 0xc06c3efbU, 0xdbc5f32cU, 0x44b017e7U, +}; + +ATF_TC(popcount_basic); +ATF_TC_HEAD(popcount_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test popcount results"); + atf_tc_set_md_var(tc, "timeout", "0"); +} + +ATF_TC_BODY(popcount_basic, tc) +{ + unsigned int i, r; + + popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO")); + + for (i = 0; i < 0xffffffff; ++i) { + r = byte_count[i & 255] + byte_count[(i >> 8) & 255] + + byte_count[(i >> 16) & 255] + + byte_count[(i >> 24) & 255]; + + ATF_CHECK_EQ(r, popcount(i)); + } + ATF_CHECK_EQ(popcount(0xffffffff), 32); +} + +ATF_TC(popcountll_basic); +ATF_TC_HEAD(popcountll_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test popcountll results"); + atf_tc_set_md_var(tc, "timeout", "0"); +} + +ATF_TC_BODY(popcountll_basic, tc) +{ + unsigned int i, j, r, r2, p; + unsigned long long v; + + popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO")); + + for (j = 0; j < 256; ++j) { + p = test_parts[j]; + r2 = byte_count[p & 255] + byte_count[(p >> 8) & 255] + + byte_count[(p >> 16) & 255] + + byte_count[(p >> 24) & 255]; + + for (i = 0; i < 0xffffffff; ++i) { + r = byte_count[i & 255] + byte_count[(i >> 8) & 255] + + byte_count[(i >> 16) & 255] + + byte_count[(i >> 24) & 255] + r2; + + v = (((unsigned long long)i) << 32) + p; + ATF_CHECK_EQ(r, popcountll(v)); + v = (((unsigned long long)p) << 32) + i; + ATF_CHECK_EQ(r, popcountll(v)); + } + } + + ATF_CHECK_EQ(popcountll(0xffffffffffffffffULL), 64); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, popcount_basic); + ATF_TP_ADD_TC(tp, popcountll_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcat.c b/contrib/netbsd-tests/lib/libc/string/t_strcat.c new file mode 100644 index 0000000..bd98691 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcat.c @@ -0,0 +1,153 @@ +/* $NetBSD: t_strcat.c,v 1.2 2011/07/14 05:46:04 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strcat_basic); +ATF_TC_HEAD(strcat_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcat(3) results"); +} + +ATF_TC_BODY(strcat_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(char *, const char *s) = strcat; + + unsigned int a0, a1, t0, t1; + char buf0[64]; + char buf1[64]; + char *ret; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t0 = 0; t0 < __arraycount(tab); ++t0) { + for (t1 = 0; t1 < __arraycount(tab); ++t1) { + + memcpy(&buf0[a0], tab[t0].val, + tab[t0].len + 1); + memcpy(&buf1[a1], tab[t1].val, + tab[t1].len + 1); + + ret = f(&buf0[a0], &buf1[a1]); + + /* + * verify strcat returns address + * of first parameter + */ + if (&buf0[a0] != ret) { + fprintf(stderr, "a0 %d, a1 %d, " + "t0 %d, t1 %d\n", + a0, a1, t0, t1); + atf_tc_fail("strcat did not " + "return its first arg"); + } + + /* verify string copied correctly */ + if (memcmp(&buf0[a0] + tab[t0].len, + &buf1[a1], + tab[t1].len + 1) != 0) { + fprintf(stderr, "a0 %d, a1 %d, " + "t0 %d, t1 %d\n", + a0, a1, t0, t1); + atf_tc_fail("string not copied " + "correctly"); + } + } + } + } + } +} + +ATF_TC(strncat_simple); +ATF_TC_HEAD(strncat_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strncat(3) results"); +} + +ATF_TC_BODY(strncat_simple, tc) +{ + char buf[100] = "abcdefg"; + + ATF_CHECK(strncat(buf, "xxx", 0) == buf); + ATF_CHECK(strcmp(buf, "abcdefg") == 0); + ATF_CHECK(strncat(buf, "xxx", 1) == buf); + ATF_CHECK(strcmp(buf, "abcdefgx") == 0); + ATF_CHECK(strncat(buf, "xxx", 2) == buf); + ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0); + ATF_CHECK(strncat(buf, "\0", 1) == buf); + ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcat_basic); + ATF_TP_ADD_TC(tp, strncat_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strchr.c b/contrib/netbsd-tests/lib/libc/string/t_strchr.c new file mode 100644 index 0000000..958b186 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strchr.c @@ -0,0 +1,292 @@ +/* $NetBSD: t_strchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> + +static char *slow_strchr(char *, int); +static void verify_strchr(char *, int, unsigned int, unsigned int); + +char * (*volatile strchr_fn)(const char *, int); + +static char * +slow_strchr(char *buf, int ch) +{ + unsigned char c = 1; + + ch &= 0xff; + + for (; c != 0; buf++) { + c = *buf; + if (c == ch) + return buf; + } + return 0; +} + +static void +verify_strchr(char *buf, int ch, unsigned int t, unsigned int a) +{ + const char *off, *ok_off; + + off = strchr_fn(buf, ch); + ok_off = slow_strchr(buf, ch); + if (off == ok_off) + return; + + fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, " + "alignment %d)\n", + buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a); + + atf_tc_fail("Check stderr for details"); +} + +ATF_TC(strchr_basic); +ATF_TC_HEAD(strchr_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test strchr(3) results"); +} + +ATF_TC_BODY(strchr_basic, tc) +{ + unsigned int t, a; + char *off; + char buf[32]; + + const char *tab[] = { + "", + "a", + "aa", + "abc", + "abcd", + "abcde", + "abcdef", + "abcdefg", + "abcdefgh", + + "/", + "//", + "/a", + "/a/", + "/ab", + "/ab/", + "/abc", + "/abc/", + "/abcd", + "/abcd/", + "/abcde", + "/abcde/", + "/abcdef", + "/abcdef/", + "/abcdefg", + "/abcdefg/", + "/abcdefgh", + "/abcdefgh/", + + "a/", + "a//", + "a/a", + "a/a/", + "a/ab", + "a/ab/", + "a/abc", + "a/abc/", + "a/abcd", + "a/abcd/", + "a/abcde", + "a/abcde/", + "a/abcdef", + "a/abcdef/", + "a/abcdefg", + "a/abcdefg/", + "a/abcdefgh", + "a/abcdefgh/", + + "ab/", + "ab//", + "ab/a", + "ab/a/", + "ab/ab", + "ab/ab/", + "ab/abc", + "ab/abc/", + "ab/abcd", + "ab/abcd/", + "ab/abcde", + "ab/abcde/", + "ab/abcdef", + "ab/abcdef/", + "ab/abcdefg", + "ab/abcdefg/", + "ab/abcdefgh", + "ab/abcdefgh/", + + "abc/", + "abc//", + "abc/a", + "abc/a/", + "abc/ab", + "abc/ab/", + "abc/abc", + "abc/abc/", + "abc/abcd", + "abc/abcd/", + "abc/abcde", + "abc/abcde/", + "abc/abcdef", + "abc/abcdef/", + "abc/abcdefg", + "abc/abcdefg/", + "abc/abcdefgh", + "abc/abcdefgh/", + + "abcd/", + "abcd//", + "abcd/a", + "abcd/a/", + "abcd/ab", + "abcd/ab/", + "abcd/abc", + "abcd/abc/", + "abcd/abcd", + "abcd/abcd/", + "abcd/abcde", + "abcd/abcde/", + "abcd/abcdef", + "abcd/abcdef/", + "abcd/abcdefg", + "abcd/abcdefg/", + "abcd/abcdefgh", + "abcd/abcdefgh/", + + "abcde/", + "abcde//", + "abcde/a", + "abcde/a/", + "abcde/ab", + "abcde/ab/", + "abcde/abc", + "abcde/abc/", + "abcde/abcd", + "abcde/abcd/", + "abcde/abcde", + "abcde/abcde/", + "abcde/abcdef", + "abcde/abcdef/", + "abcde/abcdefg", + "abcde/abcdefg/", + "abcde/abcdefgh", + "abcde/abcdefgh/", + + "abcdef/", + "abcdef//", + "abcdef/a", + "abcdef/a/", + "abcdef/ab", + "abcdef/ab/", + "abcdef/abc", + "abcdef/abc/", + "abcdef/abcd", + "abcdef/abcd/", + "abcdef/abcde", + "abcdef/abcde/", + "abcdef/abcdef", + "abcdef/abcdef/", + "abcdef/abcdefg", + "abcdef/abcdefg/", + "abcdef/abcdefgh", + "abcdef/abcdefgh/", + + "abcdefg/", + "abcdefg//", + "abcdefg/a", + "abcdefg/a/", + "abcdefg/ab", + "abcdefg/ab/", + "abcdefg/abc", + "abcdefg/abc/", + "abcdefg/abcd", + "abcdefg/abcd/", + "abcdefg/abcde", + "abcdefg/abcde/", + "abcdefg/abcdef", + "abcdefg/abcdef/", + "abcdefg/abcdefg", + "abcdefg/abcdefg/", + "abcdefg/abcdefgh", + "abcdefg/abcdefgh/", + + "abcdefgh/", + "abcdefgh//", + "abcdefgh/a", + "abcdefgh/a/", + "abcdefgh/ab", + "abcdefgh/ab/", + "abcdefgh/abc", + "abcdefgh/abc/", + "abcdefgh/abcd", + "abcdefgh/abcd/", + "abcdefgh/abcde", + "abcdefgh/abcde/", + "abcdefgh/abcdef", + "abcdefgh/abcdef/", + "abcdefgh/abcdefg", + "abcdefgh/abcdefg/", + "abcdefgh/abcdefgh", + "abcdefgh/abcdefgh/", + }; + + + strchr_fn = dlsym(dlopen(0, RTLD_LAZY), "test_strchr"); + if (!strchr_fn) + strchr_fn = strchr; + + for (a = 3; a < 3 + sizeof(long); ++a) { + /* Put char and a \0 before the buffer */ + buf[a-1] = '/'; + buf[a-2] = '0'; + buf[a-3] = 0xff; + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + int len = strlen(tab[t]) + 1; + memcpy(&buf[a], tab[t], len); + + /* Put the char we are looking for after the \0 */ + buf[a + len] = '/'; + + /* Check search for NUL at end of string */ + verify_strchr(buf + a, 0, t, a); + + /* Then for the '/' in the strings */ + verify_strchr(buf + a, '/', t, a); + + /* check zero extension of char arg */ + verify_strchr(buf + a, 0xffffff00 | '/', t, a); + + /* Replace all the '/' with 0xff */ + while ((off = slow_strchr(buf + a, '/')) != NULL) + *off = 0xff; + + buf[a + len] = 0xff; + + /* Check we can search for 0xff as well as '/' */ + verify_strchr(buf + a, 0xff, t, a); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strchr_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcmp.c b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c new file mode 100644 index 0000000..14e2e9c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_strcmp.c,v 1.4 2012/03/25 08:17:54 joerg Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strcmp_basic); +ATF_TC_HEAD(strcmp_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #1"); +} + +ATF_TC_BODY(strcmp_basic, tc) +{ + /* try to trick the compiler */ + int (*f)(const char *, const char *s) = strcmp; + + unsigned int a0, a1, t; + char buf0[64]; + char buf1[64]; + int ret; + + struct tab { + const char* val0; + const char* val1; + int ret; + }; + + const struct tab tab[] = { + { "", "", 0 }, + + { "a", "a", 0 }, + { "a", "b", -1 }, + { "b", "a", +1 }, + { "", "a", -1 }, + { "a", "", +1 }, + + { "aa", "aa", 0 }, + { "aa", "ab", -1 }, + { "ab", "aa", +1 }, + { "a", "aa", -1 }, + { "aa", "a", +1 }, + + { "aaa", "aaa", 0 }, + { "aaa", "aab", -1 }, + { "aab", "aaa", +1 }, + { "aa", "aaa", -1 }, + { "aaa", "aa", +1 }, + + { "aaaa", "aaaa", 0 }, + { "aaaa", "aaab", -1 }, + { "aaab", "aaaa", +1 }, + { "aaa", "aaaa", -1 }, + { "aaaa", "aaa", +1 }, + + { "aaaaa", "aaaaa", 0 }, + { "aaaaa", "aaaab", -1 }, + { "aaaab", "aaaaa", +1 }, + { "aaaa", "aaaaa", -1 }, + { "aaaaa", "aaaa", +1 }, + + { "aaaaaa", "aaaaaa", 0 }, + { "aaaaaa", "aaaaab", -1 }, + { "aaaaab", "aaaaaa", +1 }, + { "aaaaa", "aaaaaa", -1 }, + { "aaaaaa", "aaaaa", +1 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t = 0; t < __arraycount(tab); ++t) { + memcpy(&buf0[a0], tab[t].val0, + strlen(tab[t].val0) + 1); + memcpy(&buf1[a1], tab[t].val1, + strlen(tab[t].val1) + 1); + + ret = f(&buf0[a0], &buf1[a1]); + + if ((ret == 0 && tab[t].ret != 0) || + (ret < 0 && tab[t].ret >= 0) || + (ret > 0 && tab[t].ret <= 0)) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + fprintf(stderr, "\"%s\" \"%s\" %d\n", + &buf0[a0], &buf1[a1], ret); + atf_tc_fail("Check stderr for details"); + } + } + } + } +} + +ATF_TC(strcmp_simple); +ATF_TC_HEAD(strcmp_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #2"); +} + +ATF_TC_BODY(strcmp_simple, tc) +{ + char buf1[10] = "xxx"; + char buf2[10] = "xxy"; + + ATF_CHECK(strcmp(buf1, buf1) == 0); + ATF_CHECK(strcmp(buf2, buf2) == 0); + + ATF_CHECK(strcmp("x\xf6x", "xox") > 0); + ATF_CHECK(strcmp("xxx", "xxxyyy") < 0); + ATF_CHECK(strcmp("xxxyyy", "xxx") > 0); + + ATF_CHECK(strcmp(buf1 + 0, buf2 + 0) < 0); + ATF_CHECK(strcmp(buf1 + 1, buf2 + 1) < 0); + ATF_CHECK(strcmp(buf1 + 2, buf2 + 2) < 0); + ATF_CHECK(strcmp(buf1 + 3, buf2 + 3) == 0); + + ATF_CHECK(strcmp(buf2 + 0, buf1 + 0) > 0); + ATF_CHECK(strcmp(buf2 + 1, buf1 + 1) > 0); + ATF_CHECK(strcmp(buf2 + 2, buf1 + 2) > 0); + ATF_CHECK(strcmp(buf2 + 3, buf1 + 3) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcmp_basic); + ATF_TP_ADD_TC(tp, strcmp_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcpy.c b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c new file mode 100644 index 0000000..285371e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c @@ -0,0 +1,124 @@ +/* $NetBSD: t_strcpy.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strcpy_basic); +ATF_TC_HEAD(strcpy_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcpy(3) results"); +} + +ATF_TC_BODY(strcpy_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(char *, const char *s) = strcpy; + + unsigned int a0, a1, t; + char buf0[64]; + char buf1[64]; + char *ret; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + + memcpy(&buf1[a1], tab[t].val, tab[t].len + 1); + ret = f(&buf0[a0], &buf1[a1]); + + /* + * verify strcpy returns address of + * first parameter + */ + if (&buf0[a0] != ret) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + atf_tc_fail("strcpy did not return " + "its first arg"); + } + + /* + * verify string was copied correctly + */ + if (memcmp(&buf0[a0], &buf1[a1], + tab[t].len + 1) != 0) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + atf_tc_fail("not correctly copied"); + } + } + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcpy_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcspn.c b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c new file mode 100644 index 0000000..d38cdb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <string.h> + +ATF_TC(strcspn); +ATF_TC_HEAD(strcspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcspn(3)"); +} + +ATF_TC_BODY(strcspn, tc) +{ + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", ""), 16); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "a"), 0); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "b"), 1); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "cd"), 2); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "qrstuvwxyz"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strerror.c b/contrib/netbsd-tests/lib/libc/string/t_strerror.c new file mode 100644 index 0000000..c0e9c06 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strerror.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <locale.h> +#include <string.h> + +ATF_TC(strerror_basic); +ATF_TC_HEAD(strerror_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strerror(3)"); +} + +ATF_TC_BODY(strerror_basic, tc) +{ + int i; + + for (i = 1; i < sys_nerr; i++) + ATF_REQUIRE(strstr(strerror(i), "Unknown error:") == NULL); + + for (; i < sys_nerr + 10; i++) + ATF_REQUIRE(strstr(strerror(i), "Unknown error:") != NULL); +} + +ATF_TC(strerror_err); +ATF_TC_HEAD(strerror_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from strerror(3)"); +} + +ATF_TC_BODY(strerror_err, tc) +{ + + errno = 0; + + ATF_REQUIRE(strstr(strerror(INT_MAX), "Unknown error:") != NULL); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(strstr(strerror(INT_MIN), "Unknown error:") != NULL); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(strerror_r_basic); +ATF_TC_HEAD(strerror_r_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strerror_r(3)"); +} + +ATF_TC_BODY(strerror_r_basic, tc) +{ + char buf[512]; + int i; + + for (i = 1; i < sys_nerr; i++) { + ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == 0); + ATF_REQUIRE(strstr(buf, "Unknown error:") == NULL); + } + + for (; i < sys_nerr + 10; i++) { + ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); + } +} + +ATF_TC(strerror_r_err); +ATF_TC_HEAD(strerror_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from strerror_r(3)"); +} + +ATF_TC_BODY(strerror_r_err, tc) +{ + char buf[512]; + int rv; + + rv = strerror_r(EPERM, buf, 1); + ATF_REQUIRE(rv == ERANGE); + + rv = strerror_r(INT_MAX, buf, sizeof(buf)); + + ATF_REQUIRE(rv == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); + + rv = strerror_r(INT_MIN, buf, sizeof(buf)); + + ATF_REQUIRE(rv == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)setlocale(LC_ALL, "C"); + + ATF_TP_ADD_TC(tp, strerror_basic); + ATF_TP_ADD_TC(tp, strerror_err); + ATF_TP_ADD_TC(tp, strerror_r_basic); + ATF_TP_ADD_TC(tp, strerror_r_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_stresep.c b/contrib/netbsd-tests/lib/libc/string/t_stresep.c new file mode 100644 index 0000000..4678e55 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_stresep.c @@ -0,0 +1,72 @@ +/* $NetBSD: t_stresep.c,v 1.3 2013/02/15 23:56:32 christos Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define expect(a) \ + if ((p = stresep(&q, " ", '\\')) == NULL || strcmp(p, a)) { \ + fprintf(stderr, "failed on line %d: %s != %s\n", \ + __LINE__, p, a); \ + atf_tc_fail("Check stderr for test id/line"); \ + } + +ATF_TC(stresep_basic); +ATF_TC_HEAD(stresep_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test stresep results"); +} + +ATF_TC_BODY(stresep_basic, tc) +{ + char brkstr[] = "foo\\ \\ bar baz bar\\ foo\\ bar\\ \\ foo \\ \\ \\ " + "baz bar\\ \\ "; + char *p, *q = brkstr; + + expect("foo bar"); + expect("baz"); + expect("bar foo "); + expect("bar foo"); + expect(" baz"); + expect("bar "); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, stresep_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strlen.c b/contrib/netbsd-tests/lib/libc/string/t_strlen.c new file mode 100644 index 0000000..66158fd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strlen.c @@ -0,0 +1,199 @@ +/* $NetBSD: t_strlen.c,v 1.5 2011/07/14 07:33:20 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> +#include <unistd.h> + +static void write_num(int); + +static void +write_num(int val) +{ + char buf[20]; + int i; + + for (i = sizeof buf; --i >= 0;) { + buf[i] = '0' + val % 10; + val /= 10; + if (val == 0) { + write(2, buf + i, sizeof buf - i); + return; + } + } + write(2, "overflow", 8); +} + +ATF_TC(strlen_basic); +ATF_TC_HEAD(strlen_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strlen(3) results"); +} + +ATF_TC_BODY(strlen_basic, tc) +{ + /* try to trick the compiler */ + size_t (*strlen_fn)(const char *); + + unsigned int a, t; + size_t len; + char buf[64]; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + /* + * During testing it is useful have the rest of the program + * use a known good version! + */ + strlen_fn = dlsym(dlopen(NULL, RTLD_LAZY), "test_strlen"); + if (!strlen_fn) + strlen_fn = strlen; + + for (a = 0; a < sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + + memcpy(&buf[a], tab[t].val, tab[t].len + 1); + len = strlen_fn(&buf[a]); + + if (len != tab[t].len) { + /* Write error without using printf / strlen */ + write(2, "alignment ", 10); + write_num(a); + write(2, ", test ", 7); + write_num(t); + write(2, ", got len ", 10); + write_num(len); + write(2, ", not ", 6); + write_num(tab[t].len); + write(2, ", for '", 7); + write(2, tab[t].val, tab[t].len); + write(2, "'\n", 2); + atf_tc_fail("See stderr for details"); + } + } + } +} + +ATF_TC(strlen_huge); +ATF_TC_HEAD(strlen_huge, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings"); +} + +ATF_TC_BODY(strlen_huge, tc) +{ + long page; + char *str; + size_t i; + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + for (i = 1; i < 1000; i = i + 100) { + + str = malloc(i * page + 1); + + if (str == NULL) + continue; + + (void)memset(str, 'x', i * page); + str[i * page] = '\0'; + + ATF_REQUIRE(strlen(str) == i * page); + free(str); + } +} + +ATF_TC(strnlen_basic); +ATF_TC_HEAD(strnlen_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)"); +} + +ATF_TC_BODY(strnlen_basic, tc) +{ + char buf[1]; + + buf[0] = '\0'; + + ATF_CHECK(strnlen(buf, 000) == 0); + ATF_CHECK(strnlen(buf, 111) == 0); + + ATF_CHECK(strnlen("xxx", 0) == 0); + ATF_CHECK(strnlen("xxx", 1) == 1); + ATF_CHECK(strnlen("xxx", 2) == 2); + ATF_CHECK(strnlen("xxx", 3) == 3); + ATF_CHECK(strnlen("xxx", 9) == 3); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strlen_basic); + ATF_TP_ADD_TC(tp, strlen_huge); + ATF_TP_ADD_TC(tp, strnlen_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c new file mode 100644 index 0000000..d0f2d9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c @@ -0,0 +1,62 @@ +/* $NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <string.h> + +ATF_TC(strpbrk); +ATF_TC_HEAD(strpbrk, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strpbrk(3)"); +} + +ATF_TC_BODY(strpbrk, tc) +{ + static const char s[] = "abcdefghijklmnop"; + + ATF_CHECK_EQ(strpbrk(s, ""), NULL); + ATF_CHECK_EQ(strpbrk(s, "qrst"), NULL); + ATF_CHECK_EQ(strpbrk(s, "a"), s); + ATF_CHECK_EQ(strpbrk(s, "b"), s + 1); + ATF_CHECK_EQ(strpbrk(s, "ab"), s); + ATF_CHECK_EQ(strpbrk(s, "cdef"), s + 2); + ATF_CHECK_EQ(strpbrk(s, "fedc"), s + 2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strpbrk); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strrchr.c b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c new file mode 100644 index 0000000..038daff --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c @@ -0,0 +1,257 @@ +/* $NetBSD: t_strrchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strrchr_basic); +ATF_TC_HEAD(strrchr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strrchr(3) results"); +} + +ATF_TC_BODY(strrchr_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(const char *, int) = strrchr; + + unsigned int a, t; + char *off, *off2; + char buf[32]; + + struct tab { + const char* val; + char match; + ssize_t f_off; /* offset of first match */ + ssize_t l_off; /* offset of last match */ + }; + + const struct tab tab[] = { + { "", 0, 0, 0 }, + { "a", 0, 0, 0 }, + { "aa", 0, 0, 0 }, + { "abc", 0, 0, 0 }, + { "abcd", 0, 0, 0 }, + { "abcde", 0, 0, 0 }, + { "abcdef", 0, 0, 0 }, + { "abcdefg", 0, 0, 0 }, + { "abcdefgh", 0, 0, 0 }, + + { "/", 1, 0, 0 }, + { "//", 1, 0, 1 }, + { "/a", 1, 0, 0 }, + { "/a/", 1, 0, 2 }, + { "/ab", 1, 0, 0 }, + { "/ab/", 1, 0, 3 }, + { "/abc", 1, 0, 0 }, + { "/abc/", 1, 0, 4 }, + { "/abcd", 1, 0, 0 }, + { "/abcd/", 1, 0, 5 }, + { "/abcde", 1, 0, 0 }, + { "/abcde/", 1, 0, 6 }, + { "/abcdef", 1, 0, 0 }, + { "/abcdef/", 1, 0, 7 }, + { "/abcdefg", 1, 0, 0 }, + { "/abcdefg/", 1, 0, 8 }, + { "/abcdefgh", 1, 0, 0 }, + { "/abcdefgh/", 1, 0, 9 }, + + { "a/", 1, 1, 1 }, + { "a//", 1, 1, 2 }, + { "a/a", 1, 1, 1 }, + { "a/a/", 1, 1, 3 }, + { "a/ab", 1, 1, 1 }, + { "a/ab/", 1, 1, 4 }, + { "a/abc", 1, 1, 1 }, + { "a/abc/", 1, 1, 5 }, + { "a/abcd", 1, 1, 1 }, + { "a/abcd/", 1, 1, 6 }, + { "a/abcde", 1, 1, 1 }, + { "a/abcde/", 1, 1, 7 }, + { "a/abcdef", 1, 1, 1 }, + { "a/abcdef/", 1, 1, 8 }, + { "a/abcdefg", 1, 1, 1 }, + { "a/abcdefg/", 1, 1, 9 }, + { "a/abcdefgh", 1, 1, 1 }, + { "a/abcdefgh/", 1, 1, 10 }, + + { "ab/", 1, 2, 2 }, + { "ab//", 1, 2, 3 }, + { "ab/a", 1, 2, 2 }, + { "ab/a/", 1, 2, 4 }, + { "ab/ab", 1, 2, 2 }, + { "ab/ab/", 1, 2, 5 }, + { "ab/abc", 1, 2, 2 }, + { "ab/abc/", 1, 2, 6 }, + { "ab/abcd", 1, 2, 2 }, + { "ab/abcd/", 1, 2, 7 }, + { "ab/abcde", 1, 2, 2 }, + { "ab/abcde/", 1, 2, 8 }, + { "ab/abcdef", 1, 2, 2 }, + { "ab/abcdef/", 1, 2, 9 }, + { "ab/abcdefg", 1, 2, 2 }, + { "ab/abcdefg/", 1, 2, 10 }, + { "ab/abcdefgh", 1, 2, 2 }, + { "ab/abcdefgh/", 1, 2, 11 }, + + { "abc/", 1, 3, 3 }, + { "abc//", 1, 3, 4 }, + { "abc/a", 1, 3, 3 }, + { "abc/a/", 1, 3, 5 }, + { "abc/ab", 1, 3, 3 }, + { "abc/ab/", 1, 3, 6 }, + { "abc/abc", 1, 3, 3 }, + { "abc/abc/", 1, 3, 7 }, + { "abc/abcd", 1, 3, 3 }, + { "abc/abcd/", 1, 3, 8 }, + { "abc/abcde", 1, 3, 3 }, + { "abc/abcde/", 1, 3, 9 }, + { "abc/abcdef", 1, 3, 3 }, + { "abc/abcdef/", 1, 3, 10 }, + { "abc/abcdefg", 1, 3, 3 }, + { "abc/abcdefg/", 1, 3, 11 }, + { "abc/abcdefgh", 1, 3, 3 }, + { "abc/abcdefgh/", 1, 3, 12 }, + + { "abcd/", 1, 4, 4 }, + { "abcd//", 1, 4, 5 }, + { "abcd/a", 1, 4, 4 }, + { "abcd/a/", 1, 4, 6 }, + { "abcd/ab", 1, 4, 4 }, + { "abcd/ab/", 1, 4, 7 }, + { "abcd/abc", 1, 4, 4 }, + { "abcd/abc/", 1, 4, 8 }, + { "abcd/abcd", 1, 4, 4 }, + { "abcd/abcd/", 1, 4, 9 }, + { "abcd/abcde", 1, 4, 4 }, + { "abcd/abcde/", 1, 4, 10 }, + { "abcd/abcdef", 1, 4, 4 }, + { "abcd/abcdef/", 1, 4, 11 }, + { "abcd/abcdefg", 1, 4, 4 }, + { "abcd/abcdefg/", 1, 4, 12 }, + { "abcd/abcdefgh", 1, 4, 4 }, + { "abcd/abcdefgh/", 1, 4, 13 }, + + { "abcde/", 1, 5, 5 }, + { "abcde//", 1, 5, 6 }, + { "abcde/a", 1, 5, 5 }, + { "abcde/a/", 1, 5, 7 }, + { "abcde/ab", 1, 5, 5 }, + { "abcde/ab/", 1, 5, 8 }, + { "abcde/abc", 1, 5, 5 }, + { "abcde/abc/", 1, 5, 9 }, + { "abcde/abcd", 1, 5, 5 }, + { "abcde/abcd/", 1, 5, 10 }, + { "abcde/abcde", 1, 5, 5 }, + { "abcde/abcde/", 1, 5, 11 }, + { "abcde/abcdef", 1, 5, 5 }, + { "abcde/abcdef/", 1, 5, 12 }, + { "abcde/abcdefg", 1, 5, 5 }, + { "abcde/abcdefg/", 1, 5, 13 }, + { "abcde/abcdefgh", 1, 5, 5 }, + { "abcde/abcdefgh/", 1, 5, 14 }, + + { "abcdef/", 1, 6, 6 }, + { "abcdef//", 1, 6, 7 }, + { "abcdef/a", 1, 6, 6 }, + { "abcdef/a/", 1, 6, 8 }, + { "abcdef/ab", 1, 6, 6 }, + { "abcdef/ab/", 1, 6, 9 }, + { "abcdef/abc", 1, 6, 6 }, + { "abcdef/abc/", 1, 6, 10 }, + { "abcdef/abcd", 1, 6, 6 }, + { "abcdef/abcd/", 1, 6, 11 }, + { "abcdef/abcde", 1, 6, 6 }, + { "abcdef/abcde/", 1, 6, 12 }, + { "abcdef/abcdef", 1, 6, 6 }, + { "abcdef/abcdef/", 1, 6, 13 }, + { "abcdef/abcdefg", 1, 6, 6 }, + { "abcdef/abcdefg/", 1, 6, 14 }, + { "abcdef/abcdefgh", 1, 6, 6 }, + { "abcdef/abcdefgh/", 1, 6, 15 }, + + { "abcdefg/", 1, 7, 7 }, + { "abcdefg//", 1, 7, 8 }, + { "abcdefg/a", 1, 7, 7 }, + { "abcdefg/a/", 1, 7, 9 }, + { "abcdefg/ab", 1, 7, 7 }, + { "abcdefg/ab/", 1, 7, 10 }, + { "abcdefg/abc", 1, 7, 7 }, + { "abcdefg/abc/", 1, 7, 11 }, + { "abcdefg/abcd", 1, 7, 7 }, + { "abcdefg/abcd/", 1, 7, 12 }, + { "abcdefg/abcde", 1, 7, 7 }, + { "abcdefg/abcde/", 1, 7, 13 }, + { "abcdefg/abcdef", 1, 7, 7 }, + { "abcdefg/abcdef/", 1, 7, 14 }, + { "abcdefg/abcdefg", 1, 7, 7 }, + { "abcdefg/abcdefg/", 1, 7, 15 }, + { "abcdefg/abcdefgh", 1, 7, 7 }, + { "abcdefg/abcdefgh/", 1, 7, 16 }, + + { "abcdefgh/", 1, 8, 8 }, + { "abcdefgh//", 1, 8, 9 }, + { "abcdefgh/a", 1, 8, 8 }, + { "abcdefgh/a/", 1, 8, 10 }, + { "abcdefgh/ab", 1, 8, 8 }, + { "abcdefgh/ab/", 1, 8, 11 }, + { "abcdefgh/abc", 1, 8, 8 }, + { "abcdefgh/abc/", 1, 8, 12 }, + { "abcdefgh/abcd", 1, 8, 8 }, + { "abcdefgh/abcd/", 1, 8, 13 }, + { "abcdefgh/abcde", 1, 8, 8 }, + { "abcdefgh/abcde/", 1, 8, 14 }, + { "abcdefgh/abcdef", 1, 8, 8 }, + { "abcdefgh/abcdef/", 1, 8, 15 }, + { "abcdefgh/abcdefg", 1, 8, 8 }, + { "abcdefgh/abcdefg/", 1, 8, 16 }, + { "abcdefgh/abcdefgh", 1, 8, 8 }, + { "abcdefgh/abcdefgh/", 1, 8, 17 }, + }; + + for (a = 0; a < sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + strcpy(&buf[a], tab[t].val); + + off = f(&buf[a], '/'); + if (tab[t].match == 0) { + if (off != 0) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("strrchr should not have " + "found the character"); + } + } else if (tab[t].match == 1) { + if (tab[t].l_off != (off - &buf[a])) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("strrchr returns wrong " + "offset"); + } + } else { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("bad test case data"); + } + + /* check zero extension of char arg */ + off2 = f(&buf[a], 0xffffff00 | '/'); + if (off != off2) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("zero extension of char arg fails"); + } + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strrchr_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strspn.c b/contrib/netbsd-tests/lib/libc/string/t_strspn.c new file mode 100644 index 0000000..6782181 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strspn.c @@ -0,0 +1,60 @@ +/* $NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <string.h> + +ATF_TC(strspn); +ATF_TC_HEAD(strspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strspn(3)"); +} + +ATF_TC_BODY(strspn, tc) +{ + ATF_CHECK_EQ(strspn("abcdefghijklmnop", ""), 0); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "a"), 1); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "b"), 0); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "ab"), 2); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abc"), 3); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abce"), 3); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abcdefghijklmnop"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_swab.c b/contrib/netbsd-tests/lib/libc/string/t_swab.c new file mode 100644 index 0000000..797397a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_swab.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_swab.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <err.h> + +#define MAXCHK 100 + +static void +build(char *a, char *b, size_t n) { + size_t i; + + n >>= 1; + for (i = 0; i < n; i += 2) { + b[i+1] = a[i] = (char)i; + b[i] = a[i+1] = (char)(i+1); + } + for (n <<= 1; n < MAXCHK; n++) + a[n] = b[n] = (char)~0; +} + +static void +dump(const char *f, char *b, size_t l) +{ + + printf("%s ", f); + while (l--) + printf("%.2x ", (unsigned char)*b++); + printf("\n"); +} + +ATF_TC(swab_basic); +ATF_TC_HEAD(swab_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test swab results"); +} + +ATF_TC_BODY(swab_basic, tc) +{ + char a[MAXCHK], b[MAXCHK], r[MAXCHK]; + size_t i; + + for (i = 0; i < MAXCHK; i += 2) { + build(a, b, i); + (void)memset(r, ~0, MAXCHK); + swab(a, r, i); + if (memcmp(b, r, MAXCHK) != 0) { + fprintf(stderr, "pattern mismatch at %lu bytes", + (unsigned long)i); + dump("expect:", b, MAXCHK); + dump("result:", r, MAXCHK); + atf_tc_fail("Check stderr for details"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swab_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c new file mode 100644 index 0000000..0f2068a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c @@ -0,0 +1,168 @@ +/* $NetBSD: all_sync_ops_linkable.c,v 1.4 2014/02/21 10:26:25 martin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is a simple link-time test to verify all builtin atomic sync + * operations are available. Depending on the exact cpu/arch code generator + * options, some of these need support functions (which on NetBSD we + * typically provide in src/common/lib/libc/atomic). + * + * The list of operations has been extracted from sync-builtins.def file + * in the gcc distribution (as of gcc 4.8.2). + */ + +#include <machine/types.h> +#include <sys/inttypes.h> + +volatile uint8_t u8 = 0; +volatile uint16_t u16 = 0; +volatile uint32_t u32 = 0; + +#ifdef __HAVE_ATOMIC64_OPS +volatile uint64_t u64 = 0; +#endif + +int +main(int argc, char **argv) +{ + __sync_synchronize(); + __sync_add_and_fetch(&u8, 1); + __sync_add_and_fetch_1(&u8, 1); + __sync_add_and_fetch_2(&u16, 1); + __sync_add_and_fetch_4(&u32, 1); +#ifdef __HAVE_ATOMIC64_OPS + __sync_add_and_fetch_8(&u64, 1); +#endif + __sync_bool_compare_and_swap(&u8, 1, 2); + __sync_bool_compare_and_swap_1(&u8, 1, 2); + __sync_bool_compare_and_swap_2(&u16, 1, 2); + __sync_bool_compare_and_swap_4(&u32, 1, 2); +#ifdef __HAVE_ATOMIC64_OPS + __sync_bool_compare_and_swap_8(&u64, 1, 2); +#endif + __sync_fetch_and_add(&u8, 1); + __sync_fetch_and_add_1(&u8, 1); + __sync_fetch_and_add_2(&u16, 1); + __sync_fetch_and_add_4(&u32, 1); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_add_8(&u64, 1); +#endif + __sync_fetch_and_and(&u8, 0x80); + __sync_fetch_and_and_1(&u8, 0x80); + __sync_fetch_and_and_2(&u16, 0x80); + __sync_fetch_and_and_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_and_8(&u64, 0x80); +#endif +#ifndef __clang__ + __sync_fetch_and_nand(&u8, 0x80); + __sync_fetch_and_nand_1(&u8, 0x80); + __sync_fetch_and_nand_2(&u16, 0x80); + __sync_fetch_and_nand_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_nand_8(&u64, 0x80); +#endif +#endif + __sync_fetch_and_or(&u8, 0x80); + __sync_fetch_and_or_1(&u8, 0x80); + __sync_fetch_and_or_2(&u16, 0x80); + __sync_fetch_and_or_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_or_8(&u64, 0x80); +#endif + __sync_fetch_and_sub(&u8, 0x80); + __sync_fetch_and_sub_1(&u8, 0x80); + __sync_fetch_and_sub_2(&u16, 0x80); + __sync_fetch_and_sub_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_sub_8(&u64, 0x80); +#endif + __sync_fetch_and_xor(&u8, 0x80); + __sync_fetch_and_xor_1(&u8, 0x80); + __sync_fetch_and_xor_2(&u16, 0x80); + __sync_fetch_and_xor_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_xor_8(&u64, 0x80); +#endif + __sync_lock_release(&u8); + __sync_lock_release_1(&u8); + __sync_lock_release_2(&u16); + __sync_lock_release_4(&u32); +#ifdef __HAVE_ATOMIC64_OPS + __sync_lock_release_8(&u64); +#endif + __sync_lock_test_and_set(&u8, 5); + __sync_lock_test_and_set_1(&u8, 5); + __sync_lock_test_and_set_2(&u16, 5); + __sync_lock_test_and_set_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_lock_test_and_set_8(&u64, 5); +#endif +#ifndef __clang__ + __sync_nand_and_fetch(&u8, 5); + __sync_nand_and_fetch_1(&u8, 5); + __sync_nand_and_fetch_2(&u16, 5); + __sync_nand_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_nand_and_fetch_8(&u64, 5); +#endif +#endif + __sync_or_and_fetch(&u8, 5); + __sync_or_and_fetch_1(&u8, 5); + __sync_or_and_fetch_2(&u16, 5); + __sync_or_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_or_and_fetch_8(&u64, 5); +#endif + __sync_sub_and_fetch(&u8, 5); + __sync_sub_and_fetch_1(&u8, 5); + __sync_sub_and_fetch_2(&u16, 5); + __sync_sub_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_sub_and_fetch_8(&u64, 5); +#endif + __sync_val_compare_and_swap(&u8, 5, 9); + __sync_val_compare_and_swap_1(&u8, 5, 9); + __sync_val_compare_and_swap_2(&u16, 5, 9); + __sync_val_compare_and_swap_4(&u32, 5, 9); +#ifdef __HAVE_ATOMIC64_OPS + __sync_val_compare_and_swap_8(&u64, 5, 9); +#endif + __sync_xor_and_fetch(&u8, 5); + __sync_xor_and_fetch_1(&u8, 5); + __sync_xor_and_fetch_2(&u16, 5); + __sync_xor_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_xor_and_fetch_8(&u64, 5); +#endif + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_access.c b/contrib/netbsd-tests/lib/libc/sys/t_access.c new file mode 100644 index 0000000..f15afc2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c @@ -0,0 +1,210 @@ +/* $NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +static const char path[] = "access"; +static const int mode[4] = { R_OK, W_OK, X_OK, F_OK }; + +ATF_TC_WITH_CLEANUP(access_access); +ATF_TC_HEAD(access_access, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(access_access, tc) +{ + const int perm[3] = { 0200, 0400, 0000 }; + size_t i; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + + if (fd < 0) + return; + + for (i = 0; i < __arraycount(mode) - 1; i++) { + + ATF_REQUIRE(fchmod(fd, perm[i]) == 0); + + errno = 0; + + ATF_REQUIRE(access(path, mode[i]) != 0); + ATF_REQUIRE(errno == EACCES); + } + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(access_access, tc) +{ + (void)unlink(path); +} + +ATF_TC(access_fault); +ATF_TC_HEAD(access_fault, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT"); +} + +ATF_TC_BODY(access_fault, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access(NULL, mode[i]) != 0); + ATF_REQUIRE(errno == EFAULT); + + errno = 0; + + ATF_REQUIRE(access((char *)-1, mode[i]) != 0); + ATF_REQUIRE(errno == EFAULT); + } +} + +ATF_TC(access_inval); +ATF_TC_HEAD(access_inval, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL"); +} + +ATF_TC_BODY(access_inval, tc) +{ + + errno = 0; + + ATF_REQUIRE(access("/usr", -1) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(access_notdir); +ATF_TC_HEAD(access_notdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR"); +} + +ATF_TC_BODY(access_notdir, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + /* + * IEEE Std 1003.1-2008 about ENOTDIR: + * + * "A component of the path prefix is not a directory, + * or the path argument contains at least one non-<slash> + * character and ends with one or more trailing <slash> + * characters and the last pathname component names an + * existing file that is neither a directory nor a symbolic + * link to a directory." + */ + ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0); + ATF_REQUIRE(errno == ENOTDIR); + } +} + +ATF_TC(access_notexist); +ATF_TC_HEAD(access_notexist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT"); +} + +ATF_TC_BODY(access_notexist, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access("", mode[i]) != 0); + ATF_REQUIRE(errno == ENOENT); + } +} + +ATF_TC(access_toolong); +ATF_TC_HEAD(access_toolong, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG"); +} + +ATF_TC_BODY(access_toolong, tc) +{ + char *buf; + size_t i; + + buf = malloc(PATH_MAX); + + if (buf == NULL) + return; + + for (i = 0; i < PATH_MAX; i++) + buf[i] = 'x'; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access(buf, mode[i]) != 0); + ATF_REQUIRE(errno == ENAMETOOLONG); + } + + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, access_access); + ATF_TP_ADD_TC(tp, access_fault); + ATF_TP_ADD_TC(tp, access_inval); + ATF_TP_ADD_TC(tp, access_notdir); + ATF_TP_ADD_TC(tp, access_notexist); + ATF_TP_ADD_TC(tp, access_toolong); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_chroot.c b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c new file mode 100644 index 0000000..ce71708 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c @@ -0,0 +1,313 @@ +/* $NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <pwd.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(chroot_basic); +ATF_TC_HEAD(chroot_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(chroot_basic, tc) +{ + char buf[PATH_MAX]; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + (void)getcwd(buf, sizeof(buf)); + (void)strlcat(buf, "/dir", sizeof(buf)); + + ATF_REQUIRE(mkdir(buf, 0500) == 0); + ATF_REQUIRE(chdir(buf) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (chroot(buf) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (chroot("/root") != -1) + _exit(EXIT_FAILURE); + + if (errno != ENOENT) + _exit(EXIT_FAILURE); + + fd = open("file", O_RDONLY | O_CREAT, 0600); + + if (fd < 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("chroot(2) failed"); + + (void)chdir("/"); + (void)strlcat(buf, "/file", sizeof(buf)); + + fd = open(buf, O_RDONLY); + + if (fd < 0) + atf_tc_fail("chroot(2) did not change the root directory"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(buf) == 0); +} + +ATF_TC(chroot_err); +ATF_TC_HEAD(chroot_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(chroot_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, chroot(buf) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, chroot((void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, chroot("/a/b/c/d/e/f/g/h/i/j") == -1); +} + +ATF_TC(chroot_perm); +ATF_TC_HEAD(chroot_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(chroot_perm, tc) +{ + static char buf[LINE_MAX]; + pid_t pid; + int sta; + + (void)memset(buf, '\0', sizeof(buf)); + ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + + if (chroot(buf) != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("chroot(2) succeeded as unprivileged user"); +} + +ATF_TC(fchroot_basic); +ATF_TC_HEAD(fchroot_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_basic, tc) +{ + char buf[PATH_MAX]; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + (void)getcwd(buf, sizeof(buf)); + (void)strlcat(buf, "/dir", sizeof(buf)); + + ATF_REQUIRE(mkdir(buf, 0500) == 0); + ATF_REQUIRE(chdir(buf) == 0); + + fd = open(buf, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (fchroot(fd) != 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + fd = open("file", O_RDONLY | O_CREAT, 0600); + + if (fd < 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("fchroot(2) failed"); + + (void)chdir("/"); + (void)strlcat(buf, "/file", sizeof(buf)); + + fd = open(buf, O_RDONLY); + + if (fd < 0) + atf_tc_fail("fchroot(2) did not change the root directory"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(buf) == 0); +} + +ATF_TC(fchroot_err); +ATF_TC_HEAD(fchroot_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fchroot(-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOTDIR, fchroot(fd) == -1); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(fchroot_perm); +ATF_TC_HEAD(fchroot_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_perm, tc) +{ + static char buf[LINE_MAX]; + struct passwd *pw; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL); + + pw = getpwnam("nobody"); + fd = open(buf, O_RDONLY); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pw != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setuid(pw->pw_uid); + + errno = 0; + + if (fchroot(fd) != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("fchroot(2) succeeded as unprivileged user"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, chroot_basic); + ATF_TP_ADD_TC(tp, chroot_err); + ATF_TP_ADD_TC(tp, chroot_perm); + ATF_TP_ADD_TC(tp, fchroot_basic); + ATF_TP_ADD_TC(tp, fchroot_err); + ATF_TP_ADD_TC(tp, fchroot_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c new file mode 100644 index 0000000..69890fd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c @@ -0,0 +1,212 @@ +/* $NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Frank Kardel. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 2006 Frank Kardel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/sysctl.h> + +#include <machine/int_limits.h> + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "../../../h_macros.h" + +#define MINPOSDIFF 15000000 /* 15 ms for now */ +#define TIMEOUT 5 + +#define TC_HARDWARE "kern.timecounter.hardware" +#define TC_CHOICE "kern.timecounter.choice" + +static void +check_timecounter(void) +{ + struct timespec tsa, tsb, tsl, res; + long long mindiff = INTMAX_MAX; + time_t endlimit; + +#define CL(x) \ + do { \ + if ((x) != -1) \ + break; \ + atf_tc_fail_nonfatal("%s: %s", #x, strerror(errno)); \ + return; \ + } while (0) + + CL(clock_gettime(CLOCK_REALTIME, &tsa)); + tsl = tsa; + + CL(time(&endlimit)); + endlimit += TIMEOUT + 1; + + while ((time_t)tsa.tv_sec < endlimit) { + long long diff; + + CL(clock_gettime(CLOCK_REALTIME, &tsb)); + diff = 1000000000LL * (tsb.tv_sec - tsa.tv_sec) + + tsb.tv_nsec - tsa.tv_nsec; + + if (diff > 0 && mindiff > diff) + mindiff = diff; + + if (diff < 0 || diff > MINPOSDIFF) { + long long elapsed; + (void)printf("%stime TSA: 0x%jx.%08jx, TSB: 0x%jx.%08jx, " + "diff = %lld nsec, ", (diff < 0) ? "BAD " : "", + (uintmax_t)tsa.tv_sec, (uintmax_t)tsa.tv_nsec, + (uintmax_t)tsb.tv_sec, (uintmax_t)tsb.tv_nsec, diff); + + elapsed = 1000000000LL * (tsb.tv_sec - tsl.tv_sec) + + tsb.tv_nsec - tsl.tv_nsec; + + + (void)printf("%lld nsec\n", elapsed); + tsl = tsb; + + ATF_CHECK(diff >= 0); + if (diff < 0) + return; + } + + tsa.tv_sec = tsb.tv_sec; + tsa.tv_nsec = tsb.tv_nsec; + } + + if (clock_getres(CLOCK_REALTIME, &res) == 0) { + long long r = res.tv_sec * 1000000000 + res.tv_nsec; + + (void)printf("Claimed resolution: %lld nsec (%f Hz) or " + "better\n", r, 1.0 / r * 1e9); + (void)printf("Observed minimum non zero delta: %lld " + "nsec\n", mindiff); + } + +#undef CL +} + +ATF_TC(clock_gettime_real); +ATF_TC_HEAD(clock_gettime_real, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Checks the monotonicity of the CLOCK_REALTIME implementation"); + atf_tc_set_md_var(tc, "timeout", "300"); +} + +ATF_TC_BODY(clock_gettime_real, tc) +{ + char name[128], cbuf[512], ctrbuf[10240]; + size_t cbufsiz = sizeof(cbuf); + size_t ctrbufsiz = sizeof(ctrbuf); + const char *p; + char *save; + int quality, n; + + if (sysctlbyname(TC_HARDWARE, cbuf, &cbufsiz, NULL, 0) != 0) { + (void)printf("\nChecking legacy time implementation " + "for %d seconds\n", TIMEOUT); + check_timecounter(); + return; + /* NOTREACHED */ + } + (void)printf("%s = %s\n", TC_HARDWARE, cbuf); + REQUIRE_LIBC(save = strdup(cbuf), NULL); + + RL(sysctlbyname(TC_CHOICE, ctrbuf, &ctrbufsiz, NULL, 0)); + (void)printf("%s = %s\n", TC_CHOICE, ctrbuf); + + for (p = ctrbuf, n = 0; sscanf(p, "%127[^(](q=%d, f=%*u Hz)%*[ ]%n", + name, &quality, &n) == 2; p += n) { + struct timespec ts; + int ret; + + if (quality < 0) + continue; + + (void)printf("\nChecking %s for %d seconds\n", name, TIMEOUT); + CHECK_LIBC(ret = sysctlbyname(TC_HARDWARE, NULL, 0, + name, strlen(name)), -1); + if (ret == -1) + continue; + + /* wait a bit to select new counter in clockinterrupt */ + ts.tv_sec = 0; + ts.tv_nsec = 100000000; + (void)nanosleep(&ts, NULL); + + check_timecounter(); + } + + RL(sysctlbyname(TC_HARDWARE, NULL, 0, save, strlen(save))); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clock_gettime_real); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clone.c b/contrib/netbsd-tests/lib/libc/sys/t_clone.c new file mode 100644 index 0000000..ea33f32 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clone.c @@ -0,0 +1,252 @@ +/* $NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $"); + +#include <sys/mman.h> +#include <sys/resource.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <errno.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#define STACKSIZE (8 * 1024) +#define FROBVAL 41973 +#define CHILDEXIT 0xa5 + +static int +dummy(void *arg) +{ + + return 0; +} + +static int +clone_func(void *arg) +{ + long *frobp = arg, diff; + + printf("child: stack ~= %p, frobme = %p\n", &frobp, frobp); + fflush(stdout); + + if (frobp[0] != getppid()) + return 1; + + if (frobp[0] == getpid()) + return 2; + + diff = labs(frobp[1] - (long) &frobp); + + if (diff > 1024) + return 3; + + frobp[1] = FROBVAL; + + return (CHILDEXIT); +} + +ATF_TC(clone_basic); +ATF_TC_HEAD(clone_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks clone(2)"); +} + +ATF_TC_BODY(clone_basic, tc) +{ + sigset_t mask; + void *allocstack, *stack; + pid_t pid; + volatile long frobme[2]; + int stat; + + allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANON, -1, (off_t) 0); + + ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED); + + stack = allocstack; +#ifndef __MACHINE_STACK_GROWS_UP + stack = (char *)stack + STACKSIZE; +#endif + + printf("parent: stack = %p, frobme = %p\n", stack, frobme); + fflush(stdout); + + frobme[0] = (long)getpid(); + frobme[1] = (long)stack; + + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + + ATF_REQUIRE_ERRNO(errno, sigprocmask(SIG_BLOCK, &mask, NULL) != -1); + + switch (pid = __clone(clone_func, stack, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGUSR1, + __UNVOLATILE(frobme))) { + case 0: + atf_tc_fail("clone() returned 0"); + /*NOTREACHED*/ + case -1: + atf_tc_fail("clone() failed: %s", strerror(errno)); + /*NOTREACHED*/ + default: + while (waitpid(pid, &stat, __WCLONE) != pid) + continue; + } + + ATF_REQUIRE_MSG(WIFEXITED(stat) != 0, "child didn't exit"); + + printf("parent: childexit = 0x%x, frobme = %ld\n", + WEXITSTATUS(stat), frobme[1]); + + switch (WEXITSTATUS(stat)) { + case CHILDEXIT: + ATF_REQUIRE_EQ(frobme[1], FROBVAL); + break; + case 1: + atf_tc_fail("child: argument does not contain parent's pid"); + /*NOTREACHED*/ + case 2: + atf_tc_fail("child: called in parent's pid"); + /*NOTREACHED*/ + case 3: + atf_tc_fail("child: called with bad stack"); + /*NOTREACHED*/ + default: + atf_tc_fail("child returned unknown code: %d", + WEXITSTATUS(stat)); + /*NOTREACHED*/ + } + + ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1); +} + +ATF_TC(clone_null_stack); +ATF_TC_HEAD(clone_null_stack, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when stack pointer is NULL"); +} + +ATF_TC_BODY(clone_null_stack, tc) +{ + int rv; + + rv = __clone(dummy, NULL, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EINVAL); +} + +ATF_TC(clone_null_func); +ATF_TC_HEAD(clone_null_func, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when function pointer is NULL"); +} + +ATF_TC_BODY(clone_null_func, tc) +{ + void *allocstack, *stack; + int rv; + + allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANON, -1, (off_t) 0); + ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED); + stack = allocstack; +#ifndef __MACHINE_STACK_GROWS_UP + stack = (char *)stack + STACKSIZE; +#endif + + errno = 0; + rv = __clone(0, stack, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EINVAL); + + ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1); +} + +ATF_TC(clone_out_of_proc); +ATF_TC_HEAD(clone_out_of_proc, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when running out of processes"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(clone_out_of_proc, tc) +{ + struct rlimit rl; + int rv; + + ATF_REQUIRE_ERRNO(errno, getrlimit(RLIMIT_NPROC, &rl) != -1); + + rl.rlim_cur = 0; + rl.rlim_max = 0; + + ATF_REQUIRE_ERRNO(errno, setrlimit(RLIMIT_NPROC, &rl) != -1); + + errno = 0; + rv = __clone(dummy, malloc(10240), + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, (void *)&rl); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EAGAIN); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clone_basic); + ATF_TP_ADD_TC(tp, clone_null_stack); + ATF_TP_ADD_TC(tp, clone_null_func); + ATF_TP_ADD_TC(tp, clone_out_of_proc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_connect.c b/contrib/netbsd-tests/lib/libc/sys/t_connect.c new file mode 100644 index 0000000..d161ee3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_connect.c @@ -0,0 +1,99 @@ +/* $NetBSD: t_connect.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */ +/* + * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <err.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include <atf-c.h> + +ATF_TC(connect_low_port); +ATF_TC_HEAD(connect_low_port, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that low-port allocation " + "works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(connect_low_port, tc) +{ + struct sockaddr_in sin, sinlist; + int sd, val, slist; + socklen_t slen; + + slist = socket(AF_INET, SOCK_STREAM, 0); + sd = socket(AF_INET, SOCK_STREAM, 0); + + /* bind listening socket */ + memset(&sinlist, 0, sizeof(sinlist)); + sinlist.sin_family = AF_INET; + sinlist.sin_port = htons(31522); + sinlist.sin_addr.s_addr = inet_addr("127.0.0.1"); + + ATF_REQUIRE_EQ(bind(slist, + (struct sockaddr *)&sinlist, sizeof(sinlist)), 0); + ATF_REQUIRE_EQ(listen(slist, 1), 0); + + val = IP_PORTRANGE_LOW; + if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val, + sizeof(val)) == -1) + atf_tc_fail("setsockopt failed: %s", strerror(errno)); + + memset(&sin, 0, sizeof(sin)); + + sin.sin_port = htons(31522); + sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + sin.sin_family = AF_INET; + + if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + int serrno = errno; + atf_tc_fail("connect failed: %s%s", + strerror(serrno), + serrno != EACCES ? "" : + " (see http://mail-index.netbsd.org/" + "source-changes/2007/12/16/0011.html)"); + } + + slen = sizeof(sin); + ATF_REQUIRE_EQ(getsockname(sd, (struct sockaddr *)&sin, &slen), 0); + ATF_REQUIRE_EQ(slen, sizeof(sin)); + ATF_REQUIRE(ntohs(sin.sin_port) <= IPPORT_RESERVEDMAX); + + close(sd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, connect_low_port); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_dup.c b/contrib/netbsd-tests/lib/libc/sys/t_dup.c new file mode 100644 index 0000000..a2623c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_dup.c @@ -0,0 +1,385 @@ +/* $NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); + +#include <sys/resource.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sysexits.h> + +static char path[] = "dup"; +static void check_mode(bool, bool, bool); + +static void +check_mode(bool _dup, bool _dup2, bool _dup3) +{ + int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR }; + int perm[5] = { 0700, 0400, 0600, 0444, 0666 }; + struct stat st, st1; + int fd, fd1, fd2; + size_t i, j; + + /* + * Check that a duplicated descriptor + * retains the mode of the original file. + */ + for (i = 0; i < __arraycount(mode); i++) { + + for (j = 0; j < __arraycount(perm); j++) { + + fd1 = open(path, mode[i] | O_CREAT, perm[j]); + fd2 = open("/etc/passwd", O_RDONLY); + + ATF_REQUIRE(fd1 >= 0); + ATF_REQUIRE(fd2 >= 0); + + if (_dup != false) + fd = dup(fd1); + else if (_dup2 != false) + fd = dup2(fd1, fd2); + else if (_dup3 != false) + fd = dup3(fd1, fd2, O_CLOEXEC); + else { + fd = -1; + } + + ATF_REQUIRE(fd >= 0); + + (void)memset(&st, 0, sizeof(struct stat)); + (void)memset(&st1, 0, sizeof(struct stat)); + + ATF_REQUIRE(fstat(fd, &st) == 0); + ATF_REQUIRE(fstat(fd1, &st1) == 0); + + if (st.st_mode != st1.st_mode) + atf_tc_fail("invalid mode"); + + (void)close(fd); + (void)close(fd1); + (void)close(fd2); + (void)unlink(path); + } + } +} + +ATF_TC(dup2_basic); +ATF_TC_HEAD(dup2_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); +} + +ATF_TC_BODY(dup2_basic, tc) +{ + int fd, fd1, fd2; + + fd1 = open("/etc/passwd", O_RDONLY); + fd2 = open("/etc/passwd", O_RDONLY); + + ATF_REQUIRE(fd1 >= 0); + ATF_REQUIRE(fd2 >= 0); + + fd = dup2(fd1, fd2); + ATF_REQUIRE(fd >= 0); + + if (fd != fd2) + atf_tc_fail("invalid descriptor"); + + (void)close(fd); + (void)close(fd1); + + ATF_REQUIRE(close(fd2) != 0); +} + +ATF_TC(dup2_err); +ATF_TC_HEAD(dup2_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)"); +} + +ATF_TC_BODY(dup2_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1); + + /* + * Note that this should not fail with EINVAL. + */ + ATF_REQUIRE(dup2(fd, fd) != -1); + + (void)close(fd); +} + +ATF_TC(dup2_max); +ATF_TC_HEAD(dup2_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup2(2) against limits"); +} + +ATF_TC_BODY(dup2_max, tc) +{ + struct rlimit res; + + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(STDERR_FILENO, res.rlim_cur + 1) == -1); +} + +ATF_TC_WITH_CLEANUP(dup2_mode); +ATF_TC_HEAD(dup2_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); +} + +ATF_TC_BODY(dup2_mode, tc) +{ + check_mode(false, true, false); +} + +ATF_TC_CLEANUP(dup2_mode, tc) +{ + (void)unlink(path); +} + + +ATF_TC(dup3_err); +ATF_TC_HEAD(dup3_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of dup3(2) (PR lib/45148)"); +} + +ATF_TC_BODY(dup3_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1); + + (void)close(fd); +} + +ATF_TC(dup3_max); +ATF_TC_HEAD(dup3_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup3(2) against limits"); +} + +ATF_TC_BODY(dup3_max, tc) +{ + struct rlimit res; + + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(STDERR_FILENO, + res.rlim_cur + 1, O_CLOEXEC) == -1); +} + +ATF_TC_WITH_CLEANUP(dup3_mode); +ATF_TC_HEAD(dup3_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)"); +} + +ATF_TC_BODY(dup3_mode, tc) +{ + check_mode(false, false, true); +} + +ATF_TC_CLEANUP(dup3_mode, tc) +{ + (void)unlink(path); +} + +ATF_TC(dup_err); +ATF_TC_HEAD(dup_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of dup(2)"); +} + +ATF_TC_BODY(dup_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1); +} + +ATF_TC_WITH_CLEANUP(dup_max); +ATF_TC_HEAD(dup_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup(2) against limits"); +} + +ATF_TC_BODY(dup_max, tc) +{ + struct rlimit res; + int *buf, fd, sta; + size_t i, n; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Open a temporary file until the + * maximum number of open files is + * reached. Ater that dup(2) family + * should fail with EMFILE. + */ + (void)closefrom(0); + (void)memset(&res, 0, sizeof(struct rlimit)); + + n = 10; + res.rlim_cur = res.rlim_max = n; + if (setrlimit(RLIMIT_NOFILE, &res) != 0) + _exit(EX_OSERR); + + buf = calloc(n, sizeof(int)); + + if (buf == NULL) + _exit(EX_OSERR); + + buf[0] = mkstemp(path); + + if (buf[0] < 0) + _exit(EX_OSERR); + + for (i = 1; i < n; i++) { + + buf[i] = open(path, O_RDONLY); + + if (buf[i] < 0) + _exit(EX_OSERR); + } + + errno = 0; + fd = dup(buf[0]); + + if (fd != -1 || errno != EMFILE) + _exit(EX_DATAERR); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EX_OSERR) + atf_tc_fail("system call error"); + + if (WEXITSTATUS(sta) == EX_DATAERR) + atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE"); + + atf_tc_fail("unknown error"); + } + + (void)unlink(path); +} + +ATF_TC_CLEANUP(dup_max, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(dup_mode); +ATF_TC_HEAD(dup_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup(2)"); +} + +ATF_TC_BODY(dup_mode, tc) +{ + check_mode(true, false, false); +} + +ATF_TC_CLEANUP(dup_mode, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, dup2_basic); + ATF_TP_ADD_TC(tp, dup2_err); + ATF_TP_ADD_TC(tp, dup2_max); + ATF_TP_ADD_TC(tp, dup2_mode); + ATF_TP_ADD_TC(tp, dup3_err); + ATF_TP_ADD_TC(tp, dup3_max); + ATF_TP_ADD_TC(tp, dup3_mode); + ATF_TP_ADD_TC(tp, dup_err); + ATF_TP_ADD_TC(tp, dup_max); + ATF_TP_ADD_TC(tp, dup_mode); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_fsync.c b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c new file mode 100644 index 0000000..e61ea7e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $"); + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(fsync_err); +ATF_TC_HEAD(fsync_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of fsync(2) (PR kern/30)"); +} + +ATF_TC_BODY(fsync_err, tc) +{ + int i, fd[2]; + + /* + * The fsync(2) call should fail with EBADF + * when the 'fd' is not a valid descriptor. + */ + for (i = 1; i < 1024; i = i + 128) { + + errno = 0; + + ATF_REQUIRE(fsync(-i) == -1); + ATF_REQUIRE(errno == EBADF); + } + + /* + * On the other hand, EINVAL should follow + * if the operation is not possible with + * the file descriptor. + */ + ATF_REQUIRE(pipe(fd) == 0); + + errno = 0; + + ATF_REQUIRE(fsync(fd[0]) == -1); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(fsync(fd[1]) == -1); + ATF_REQUIRE(errno == EINVAL); + + ATF_REQUIRE(close(fd[0]) == 0); + ATF_REQUIRE(close(fd[1]) == 0); +} + +ATF_TC(fsync_sync); +ATF_TC_HEAD(fsync_sync, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fsync(2)"); +} + +ATF_TC_BODY(fsync_sync, tc) +{ + char buf[128]; + int fd, i; + + for (i = 0; i < 10; i++) { + + (void)snprintf(buf, sizeof(buf), "t_fsync-%d", i); + + fd = mkstemp(buf); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(write(fd, "0", 1) == 1); + ATF_REQUIRE(fsync(fd) == 0); + + ATF_REQUIRE(unlink(buf) == 0); + ATF_REQUIRE(close(fd) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fsync_err); + ATF_TP_ADD_TC(tp, fsync_sync); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c new file mode 100644 index 0000000..3a2d9f7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c @@ -0,0 +1,129 @@ +/* $NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdarg.h> +#include <stdlib.h> +#include <ucontext.h> + +#define STACKSZ (10*1024) +#define DEPTH 3 + +static int calls; + +static void +run(int n, ...) +{ + va_list va; + int i, ia; + + ATF_REQUIRE_EQ(n, DEPTH - calls - 1); + + va_start(va, n); + for (i = 0; i < 9; i++) { + ia = va_arg(va, int); + ATF_REQUIRE_EQ(i, ia); + } + va_end(va); + + calls++; +} + +ATF_TC(getcontext_err); +ATF_TC_HEAD(getcontext_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getcontext(2)"); +} + +ATF_TC_BODY(getcontext_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, getcontext((void *)-1) == -1); +} + +ATF_TC(setcontext_err); +ATF_TC_HEAD(setcontext_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setcontext(2)"); +} + +ATF_TC_BODY(setcontext_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, setcontext((void *)-1) == -1); +} + +ATF_TC(setcontext_link); +ATF_TC_HEAD(setcontext_link, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks get/make/setcontext(), context linking via uc_link(), " + "and argument passing to the new context"); +} + +ATF_TC_BODY(setcontext_link, tc) +{ + ucontext_t uc[DEPTH]; + ucontext_t save; + volatile int i = 0; /* avoid longjmp clobbering */ + + for (i = 0; i < DEPTH; ++i) { + ATF_REQUIRE_EQ(getcontext(&uc[i]), 0); + + uc[i].uc_stack.ss_sp = malloc(STACKSZ); + uc[i].uc_stack.ss_size = STACKSZ; + uc[i].uc_link = (i > 0) ? &uc[i - 1] : &save; + + makecontext(&uc[i], (void *)run, 10, i, + 0, 1, 2, 3, 4, 5, 6, 7, 8); + } + + ATF_REQUIRE_EQ(getcontext(&save), 0); + + if (calls == 0) + ATF_REQUIRE_EQ(setcontext(&uc[DEPTH-1]), 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getcontext_err); + ATF_TP_ADD_TC(tp, setcontext_err); + ATF_TP_ADD_TC(tp, setcontext_link); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c new file mode 100644 index 0000000..9a8ec8e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c @@ -0,0 +1,171 @@ +/* $NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(getgroups_err); +ATF_TC_HEAD(getgroups_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in getgroups(2)"); +} + +ATF_TC_BODY(getgroups_err, tc) +{ + gid_t gidset[NGROUPS_MAX]; + + errno = 0; + + ATF_REQUIRE(getgroups(10, (gid_t *)-1) == -1); + ATF_REQUIRE(errno == EFAULT); + + errno = 0; + + ATF_REQUIRE(getgroups(-1, gidset) == -1); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(getgroups_getgid); +ATF_TC_HEAD(getgroups_getgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getgid(2) from getgroups(2)"); +} + +ATF_TC_BODY(getgroups_getgid, tc) +{ + gid_t gidset[NGROUPS_MAX]; + gid_t gid = getgid(); + int i, n; + + /* + * Check that getgid(2) is found from + * the GIDs returned by getgroups(2). + */ + n = getgroups(NGROUPS_MAX, gidset); + + for (i = 0; i < n; i++) { + + if (gidset[i] == gid) + return; + } + + atf_tc_fail("getgid(2) not found from getgroups(2)"); +} + +ATF_TC(getgroups_setgid); +ATF_TC_HEAD(getgroups_setgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setgid(2) from getgroups(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(getgroups_setgid, tc) +{ + gid_t gidset[NGROUPS_MAX]; + int i, n, rv, sta; + pid_t pid; + + /* + * Check that we can setgid(2) + * to the returned group IDs. + */ + n = getgroups(NGROUPS_MAX, gidset); + ATF_REQUIRE(n >= 0); + + for (i = 0; i < n; i++) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = setgid(gidset[i]); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("getgroups(2) is inconsistent"); + } +} + +ATF_TC(getgroups_zero); +ATF_TC_HEAD(getgroups_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getgroups(2) with zero param"); +} + +ATF_TC_BODY(getgroups_zero, tc) +{ + const gid_t val = 123456789; + gid_t gidset[NGROUPS_MAX]; + size_t i; + + /* + * If the first parameter is zero, the number + * of groups should be returned but the supplied + * buffer should remain intact. + */ + for (i = 0; i < __arraycount(gidset); i++) + gidset[i] = val; + + ATF_REQUIRE(getgroups(0, gidset) >= 0); + + for (i = 0; i < __arraycount(gidset); i++) { + + if (gidset[i] != val) + atf_tc_fail("getgroups(2) modified the buffer"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgroups_err); + ATF_TP_ADD_TC(tp, getgroups_getgid); + ATF_TP_ADD_TC(tp, getgroups_setgid); + ATF_TP_ADD_TC(tp, getgroups_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c new file mode 100644 index 0000000..b384541 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c @@ -0,0 +1,211 @@ +/* $NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $"); + +#include <sys/time.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +static bool fail; +static void sighandler(int); + +static void +sighandler(int signo) +{ + + if (signo == SIGALRM || signo == SIGVTALRM) + fail = false; +} + +ATF_TC(getitimer_empty); +ATF_TC_HEAD(getitimer_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "getitimer(2) before setitimer(2)"); +} + +ATF_TC_BODY(getitimer_empty, tc) +{ + struct itimerval it; + + /* + * Verify that the passed structure remains + * empty after calling getitimer(2) but before + * actually arming the timer with setitimer(2). + */ + (void)memset(&it, 0, sizeof(struct itimerval)); + + ATF_REQUIRE(getitimer(ITIMER_REAL, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + ATF_REQUIRE(getitimer(ITIMER_VIRTUAL, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + ATF_REQUIRE(getitimer(ITIMER_PROF, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + return; + +fail: + atf_tc_fail("getitimer(2) modfied the timer before it was armed"); +} + +ATF_TC(getitimer_err); +ATF_TC_HEAD(getitimer_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getitimer(2)"); +} + +ATF_TC_BODY(getitimer_err, tc) +{ + struct itimerval it; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, getitimer(-1, &it) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, getitimer(INT_MAX, &it) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, getitimer(ITIMER_REAL, (void *)-1) == -1); +} + +ATF_TC(setitimer_basic); +ATF_TC_HEAD(setitimer_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setitimer(2)"); +} + +ATF_TC_BODY(setitimer_basic, tc) +{ + struct itimerval it; + + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 100; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + fail = true; + + ATF_REQUIRE(signal(SIGALRM, sighandler) != SIG_ERR); + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0); + + /* + * Although the interaction between + * setitimer(2) and sleep(3) can be + * unspecified, it is assumed that one + * second suspension will be enough for + * the timer to fire. + */ + (void)sleep(1); + + if (fail != false) + atf_tc_fail("timer did not fire"); +} + +ATF_TC(setitimer_err); +ATF_TC_HEAD(setitimer_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setitimer(2)" + " (PR standards/44927)"); +} + +ATF_TC_BODY(setitimer_err, tc) +{ + struct itimerval it, ot; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, setitimer(-1, &it, &ot) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, setitimer(INT_MAX, &it, &ot) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, setitimer(ITIMER_REAL,(void*)-1, &ot) == -1); +} + +ATF_TC(setitimer_old); +ATF_TC_HEAD(setitimer_old, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test old values from setitimer(2)"); +} + +ATF_TC_BODY(setitimer_old, tc) +{ + struct itimerval it, ot; + + /* + * Make two calls; the second one + * should store the old values. + */ + it.it_value.tv_sec = 4; + it.it_value.tv_usec = 3; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0); + + it.it_value.tv_sec = 2; + it.it_value.tv_usec = 1; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0); + + if (ot.it_value.tv_sec != 4 || ot.it_value.tv_usec != 3) + atf_tc_fail("setitimer(2) did not store old values"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getitimer_empty); + ATF_TP_ADD_TC(tp, getitimer_err); + ATF_TP_ADD_TC(tp, setitimer_basic); + ATF_TP_ADD_TC(tp, setitimer_err); + ATF_TP_ADD_TC(tp, setitimer_old); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c new file mode 100644 index 0000000..8c2b199 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c @@ -0,0 +1,237 @@ +/* $NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(getlogin_r_err); +ATF_TC_HEAD(getlogin_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getlogin_r(2)"); +} + +ATF_TC_BODY(getlogin_r_err, tc) +{ + char small[0]; + + ATF_REQUIRE(getlogin_r(small, sizeof(small)) == ERANGE); +} + +ATF_TC(getlogin_same); +ATF_TC_HEAD(getlogin_same, tc) +{ + atf_tc_set_md_var(tc, "descr", "getlogin(2) vs. getlogin_r(2)"); +} + +ATF_TC_BODY(getlogin_same, tc) +{ + char buf[MAXLOGNAME]; + char *str; + + str = getlogin(); + + if (str == NULL) + return; + + ATF_REQUIRE(getlogin_r(buf, sizeof(buf)) == 0); + + if (strcmp(str, buf) != 0) + atf_tc_fail("getlogin(2) and getlogin_r(2) differ"); +} + +ATF_TC(setlogin_basic); +ATF_TC_HEAD(setlogin_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that setlogin(2) works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setlogin_basic, tc) +{ + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setsid(); + + if (setlogin("foobar") != 0) + _exit(EXIT_FAILURE); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("setlogin(2) failed to set login name"); +} + +ATF_TC(setlogin_err); +ATF_TC_HEAD(setlogin_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setlogin(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setlogin_err, tc) +{ + char buf[MAXLOGNAME + 1]; + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + + if (pid == 0) { + + (void)setsid(); + + errno = 0; + + if (setlogin(buf) != -1) + _exit(EINVAL); + + if (errno != EINVAL) + _exit(EINVAL); + + errno = 0; + + if (setlogin((void *)-1) != -1) + _exit(EFAULT); + + if (errno != EFAULT) + _exit(EFAULT); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EFAULT) + atf_tc_fail("expected EFAULT, but the call succeeded"); + + if (WEXITSTATUS(sta) == EINVAL) + atf_tc_fail("expected EINVAL, but the call succeeded"); + + atf_tc_fail("setlogin(2) failed, but login name was set"); + } +} + +ATF_TC(setlogin_perm); +ATF_TC_HEAD(setlogin_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setlogin(2) as normal user"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setlogin_perm, tc) +{ + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setsid(); + + errno = 0; + + if (setlogin("foobar") != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("login name was set as an unprivileged user"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getlogin_r_err); + ATF_TP_ADD_TC(tp, getlogin_same); + ATF_TP_ADD_TC(tp, setlogin_basic); + ATF_TP_ADD_TC(tp, setlogin_err); + ATF_TP_ADD_TC(tp, setlogin_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getpid.c b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c new file mode 100644 index 0000000..b3ed393 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c @@ -0,0 +1,134 @@ +/* $NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <stdlib.h> +#include <pthread.h> +#include <unistd.h> + +#include <atf-c.h> + +static int maxiter = 10; +static void *threadfunc(void *); + +static void * +threadfunc(void *arg) +{ + *(pid_t *)arg = getpid(); + + return NULL; +} + +ATF_TC(getpid_process); +ATF_TC_HEAD(getpid_process, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getpid(2) with processes"); +} + +ATF_TC_BODY(getpid_process, tc) +{ + pid_t ppid, fpid, cpid, tpid, wpid; + int i, sta; + + for (i = 0; i < maxiter; i++) { + + tpid = getpid(); + fpid = fork(); + + ATF_REQUIRE(fpid >= 0); + + if (fpid == 0) { + + cpid = getpid(); + ppid = getppid(); + + if (tpid != ppid) + _exit(EXIT_FAILURE); + + if (cpid == ppid) + _exit(EXIT_FAILURE); + + if (tpid == fpid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + wpid = wait(&sta); + + if (wpid != fpid) + atf_tc_fail("PID mismatch"); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + + if (WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("PID mismatch"); + } +} + +ATF_TC(getpid_thread); +ATF_TC_HEAD(getpid_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getpid(2) with threads"); +} + +ATF_TC_BODY(getpid_thread, tc) +{ + pid_t pid, tpid; + pthread_t tid; + int i, rv; + + for (i = 0; i < maxiter; i++) { + + pid = getpid(); + + rv = pthread_create(&tid, NULL, threadfunc, &tpid); + ATF_REQUIRE(rv == 0); + + rv = pthread_join(tid, NULL); + ATF_REQUIRE(rv == 0); + + if (pid != tpid) + atf_tc_fail("Unequal PIDs"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getpid_process); + ATF_TP_ADD_TC(tp, getpid_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c new file mode 100644 index 0000000..6c4218a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c @@ -0,0 +1,197 @@ +/* $NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $"); + +#include <sys/resource.h> +#include <sys/time.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <stdint.h> +#include <string.h> + +static void work(void); +static void sighandler(int); + +static const size_t maxiter = 2000; + +static void +sighandler(int signo) +{ + /* Nothing. */ +} + +static void +work(void) +{ + size_t n = UINT16_MAX * 10; + + while (n > 0) { +#ifdef __or1k__ + asm volatile("l.nop"); /* Do something. */ +#else + asm volatile("nop"); /* Do something. */ +#endif + n--; + } +} + +ATF_TC(getrusage_err); +ATF_TC_HEAD(getrusage_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions"); +} + +ATF_TC_BODY(getrusage_err, tc) +{ + struct rusage ru; + + errno = 0; + + ATF_REQUIRE(getrusage(INT_MAX, &ru) != 0); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(getrusage(RUSAGE_SELF, (void *)0) != 0); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TC(getrusage_sig); +ATF_TC_HEAD(getrusage_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test signal count with getrusage(2)"); +} + +ATF_TC_BODY(getrusage_sig, tc) +{ + struct rusage ru; + const long n = 5; + int i; + + /* + * Test that signals are recorded. + */ + ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR); + + for (i = 0; i < n; i++) + ATF_REQUIRE(raise(SIGUSR1) == 0); + + (void)memset(&ru, 0, sizeof(struct rusage)); + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); + + if (n != ru.ru_nsignals) + atf_tc_fail("getrusage(2) did not record signals"); +} + +ATF_TC(getrusage_utime_back); +ATF_TC_HEAD(getrusage_utime_back, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bogus values from getrusage(2)"); +} + +ATF_TC_BODY(getrusage_utime_back, tc) +{ + struct rusage ru1, ru2; + size_t i; + + /* + * Test that two consecutive calls are sane. + */ + atf_tc_expect_fail("PR kern/30115"); + + for (i = 0; i < maxiter; i++) { + + (void)memset(&ru1, 0, sizeof(struct rusage)); + (void)memset(&ru2, 0, sizeof(struct rusage)); + + work(); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru1) == 0); + + work(); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru2) == 0); + + if (timercmp(&ru2.ru_utime, &ru1.ru_utime, <) != 0) + atf_tc_fail("user time went backwards"); + } + + atf_tc_fail("anticipated error did not occur"); +} + +ATF_TC(getrusage_utime_zero); +ATF_TC_HEAD(getrusage_utime_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test zero utime from getrusage(2)"); +} + +ATF_TC_BODY(getrusage_utime_zero, tc) +{ + struct rusage ru; + size_t i; + + /* + * Test that getrusage(2) does not return + * zero user time for the calling process. + * + * See also (duplicate) PR port-amd64/41734. + */ + atf_tc_expect_fail("PR kern/30115"); + + for (i = 0; i < maxiter; i++) { + + work(); + + (void)memset(&ru, 0, sizeof(struct rusage)); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); + + if (ru.ru_utime.tv_sec == 0 && ru.ru_utime.tv_usec == 0) + atf_tc_fail("zero user time from getrusage(2)"); + } + + atf_tc_fail("anticipated error did not occur"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getrusage_err); + ATF_TP_ADD_TC(tp, getrusage_sig); + ATF_TP_ADD_TC(tp, getrusage_utime_back); + ATF_TP_ADD_TC(tp, getrusage_utime_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getsid.c b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c new file mode 100644 index 0000000..76b54ab --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c @@ -0,0 +1,119 @@ +/* $NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(getsid_current); +ATF_TC_HEAD(getsid_current, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getsid(0)"); +} + +ATF_TC_BODY(getsid_current, tc) +{ + pid_t sid; + + sid = getsid(0); + ATF_REQUIRE(sid != -1); + + if (sid != getsid(getpid())) + atf_tc_fail("getsid(0) did not match the calling process"); +} + +ATF_TC(getsid_err); +ATF_TC_HEAD(getsid_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in getsid(2)"); +} + +ATF_TC_BODY(getsid_err, tc) +{ + + errno = 0; + + ATF_REQUIRE(getsid(-1) == -1); + ATF_REQUIRE(errno == ESRCH); +} + +ATF_TC(getsid_process); +ATF_TC_HEAD(getsid_process, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getsid(2) with processes"); +} + +ATF_TC_BODY(getsid_process, tc) +{ + pid_t csid, pid, ppid, sid; + int sta; + + sid = getsid(0); + pid = fork(); + + ATF_REQUIRE(pid >= 0); + ATF_REQUIRE(sid != -1); + + if (pid == 0) { + + csid = getsid(0); + ppid = getppid(); + + if (sid != csid) + _exit(EXIT_FAILURE); + + if (getsid(ppid) != csid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("invalid session ID"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getsid_current); + ATF_TP_ADD_TC(tp, getsid_err); + ATF_TP_ADD_TC(tp, getsid_process); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c new file mode 100644 index 0000000..1cf303b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c @@ -0,0 +1,86 @@ +/* $NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/time.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> + +ATF_TC(gettimeofday_err); +ATF_TC_HEAD(gettimeofday_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from gettimeofday(2)"); +} + +ATF_TC_BODY(gettimeofday_err, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, gettimeofday((void *)-1, NULL) != 0); +} + +ATF_TC(gettimeofday_mono); +ATF_TC_HEAD(gettimeofday_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test monotonicity of gettimeofday(2)"); +} + +ATF_TC_BODY(gettimeofday_mono, tc) +{ + static const size_t maxiter = 100; + struct timeval tv1, tv2; + size_t i; + + for (i = 0; i < maxiter; i++) { + + (void)memset(&tv1, 0, sizeof(struct timeval)); + (void)memset(&tv2, 0, sizeof(struct timeval)); + + ATF_REQUIRE(gettimeofday(&tv1, NULL) == 0); + ATF_REQUIRE(gettimeofday(&tv2, NULL) == 0); + + if (timercmp(&tv2, &tv1, <) != 0) + atf_tc_fail("time went backwards"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, gettimeofday_err); + ATF_TP_ADD_TC(tp, gettimeofday_mono); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c new file mode 100644 index 0000000..b76ba39 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdlib.h> +#include <unistd.h> + +static bool check(int (*fuid)(uid_t), int (*fgid)(gid_t)); + +static bool +check(int (*fuid)(uid_t), int (*fgid)(gid_t)) +{ + struct passwd *pw; + pid_t pid; + int sta; + + pw = getpwnam("nobody"); + + if (pw == NULL) + return false; + + pid = fork(); + + if (pid < 0) + return false; + + if (pid == 0) { + + if (fuid != NULL && (*fuid)(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + if (fgid != NULL && (*fgid)(pw->pw_gid) != 0) + _exit(EXIT_FAILURE); + + if (issetugid() != 1) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + return false; + + return true; +} + +ATF_TC(issetugid_egid); +ATF_TC_HEAD(issetugid_egid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. GID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_egid, tc) +{ + + if (check(NULL, setegid) != true) + atf_tc_fail("issetugid(2) failed with effective GID"); +} + +ATF_TC(issetugid_euid); +ATF_TC_HEAD(issetugid_euid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. UID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_euid, tc) +{ + + if (check(seteuid, NULL) != true) + atf_tc_fail("issetugid(2) failed with effective UID"); +} + +ATF_TC(issetugid_rgid); +ATF_TC_HEAD(issetugid_rgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real GID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_rgid, tc) +{ + + if (check(NULL, setgid) != true) + atf_tc_fail("issetugid(2) failed with real GID"); +} + +ATF_TC(issetugid_ruid); +ATF_TC_HEAD(issetugid_ruid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real UID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_ruid, tc) +{ + + if (check(setuid, NULL) != true) + atf_tc_fail("issetugid(2) failed with real UID"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, issetugid_egid); + ATF_TP_ADD_TC(tp, issetugid_euid); + ATF_TP_ADD_TC(tp, issetugid_rgid); + ATF_TP_ADD_TC(tp, issetugid_ruid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c new file mode 100644 index 0000000..73ffbf8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c @@ -0,0 +1,180 @@ +/* $NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundatiom + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $"); + +#include <sys/types.h> +#include <sys/event.h> + +#include <atf-c.h> +#include <errno.h> +#include <time.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <err.h> +#include <sys/drvctlio.h> +#include <sys/event.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/wait.h> + +ATF_TC(kevent_zerotimer); +ATF_TC_HEAD(kevent_zerotimer, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that kevent with a 0 timer " + "does not crash the system (PR lib/45618)"); +} + +ATF_TC_BODY(kevent_zerotimer, tc) +{ + struct kevent ev; + int kq; + + ATF_REQUIRE((kq = kqueue()) != -1); + EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0); + ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, &ev, 1, NULL) == 1); +} + +ATF_TC(kqueue_desc_passing); +ATF_TC_HEAD(kqueue_desc_passing, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that passing a kqueue to " + "another process does not crash the kernel (PR 46463)"); +} + +ATF_TC_BODY(kqueue_desc_passing, tc) +{ + pid_t child; + int s[2], storage, status, kq; + struct cmsghdr *msg; + struct iovec iov; + struct msghdr m; + struct kevent ev; + + ATF_REQUIRE((kq = kqueue()) != -1); + + // atf_tc_skip("crashes kernel (PR 46463)"); + + ATF_REQUIRE(socketpair(AF_LOCAL, SOCK_STREAM, 0, s) != -1); + msg = malloc(CMSG_SPACE(sizeof(int))); + m.msg_iov = &iov; + m.msg_iovlen = 1; + m.msg_name = NULL; + m.msg_namelen = 0; + m.msg_control = msg; + m.msg_controllen = CMSG_SPACE(sizeof(int)); + + child = fork(); + if (child == 0) { + close(s[0]); + + iov.iov_base = &storage; + iov.iov_len = sizeof(int); + m.msg_iov = &iov; + m.msg_iovlen = 1; + + if (recvmsg(s[1], &m, 0) == -1) + err(1, "child: could not recvmsg"); + + kq = *(int *)CMSG_DATA(msg); + printf("child (pid %d): received kq fd %d\n", getpid(), kq); + exit(0); + } + + close(s[1]); + + iov.iov_base = &storage; + iov.iov_len = sizeof(int); + + msg->cmsg_level = SOL_SOCKET; + msg->cmsg_type = SCM_RIGHTS; + msg->cmsg_len = CMSG_LEN(sizeof(int)); + + *(int *)CMSG_DATA(msg) = kq; + + EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0); + ATF_CHECK(kevent(kq, &ev, 1, NULL, 0, NULL) != -1); + + printf("parent (pid %d): sending kq fd %d\n", getpid(), kq); + if (sendmsg(s[0], &m, 0) == -1) { + ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno); + atf_tc_skip("PR kern/46523"); + } + + close(kq); + + waitpid(child, &status, 0); + ATF_CHECK(WIFEXITED(status) && WEXITSTATUS(status)==0); +} + +ATF_TC(kqueue_unsupported_fd); +ATF_TC_HEAD(kqueue_unsupported_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that watching an fd whose" + " type is not supported does not crash the kernel"); +} + +ATF_TC_BODY(kqueue_unsupported_fd, tc) +{ + /* mqueue and semaphore use fnullop_kqueue also */ + int fd, kq; + struct kevent ev; + + fd = open(DRVCTLDEV, O_RDONLY); + if (fd == -1 && errno == ENOENT) + atf_tc_skip("no " DRVCTLDEV " available for testing"); + ATF_REQUIRE(fd != -1); + ATF_REQUIRE((kq = kqueue()) != -1); + + EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK| + NOTE_RENAME|NOTE_REVOKE, 0, 0); + + ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == -1); + ATF_REQUIRE_ERRNO(EOPNOTSUPP, true); + + (void)close(fd); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, kevent_zerotimer); + ATF_TP_ADD_TC(tp, kqueue_desc_passing); + ATF_TP_ADD_TC(tp, kqueue_unsupported_fd); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kill.c b/contrib/netbsd-tests/lib/libc/sys/t_kill.c new file mode 100644 index 0000000..2f42862 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_kill.c @@ -0,0 +1,312 @@ +/* $NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <errno.h> +#include <limits.h> +#include <pwd.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(kill_basic); +ATF_TC_HEAD(kill_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that kill(2) works"); +} + +ATF_TC_BODY(kill_basic, tc) +{ + const int sig[] = { SIGHUP, SIGINT, SIGKILL, SIGTERM }; + pid_t pid; + size_t i; + int sta; + + for (i = 0; i < __arraycount(sig); i++) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + switch (pid) { + + case 0: + pause(); + break; + + default: + ATF_REQUIRE(kill(pid, sig[i]) == 0); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != sig[i]) + atf_tc_fail("kill(2) failed to kill child"); + } +} + +ATF_TC(kill_err); +ATF_TC_HEAD(kill_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of kill(2)"); +} + +ATF_TC_BODY(kill_err, tc) +{ + int rv, sta; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + rv = kill(getpid(), -1); + + if (rv == 0 || errno != EINVAL) + _exit(EINVAL); + + errno = 0; + rv = kill(INT_MAX, SIGUSR1); + + if (rv == 0 || errno != ESRCH) + _exit(ESRCH); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EINVAL) + atf_tc_fail("expected EINVAL, but kill(2) succeeded"); + + if (WEXITSTATUS(sta) == ESRCH) + atf_tc_fail("expected ESRCH, but kill(2) succeeded"); + + atf_tc_fail("unknown error from kill(2)"); + } +} + +ATF_TC(kill_perm); +ATF_TC_HEAD(kill_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) permissions"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(kill_perm, tc) +{ + struct passwd *pw; + pid_t cpid, ppid; + uid_t cuid = 0; + uid_t puid = 0; + int sta; + + /* + * Test that kill(2) fails when called + * for a PID owned by another user. + */ + pw = getpwnam("operator"); + + if (pw != NULL) + cuid = pw->pw_uid; + + pw = getpwnam("nobody"); + + if (pw != NULL) + puid = pw->pw_uid; + + if (cuid == 0 || puid == 0 || cuid == puid) + atf_tc_fail("getpwnam(3) failed"); + + ppid = fork(); + + if (ppid < 0) + _exit(EXIT_FAILURE); + + if (ppid == 0) { + + cpid = fork(); + + if (cpid < 0) + _exit(EXIT_FAILURE); + + if (cpid == 0) { + + if (setuid(cuid) < 0) + _exit(EXIT_FAILURE); + else { + (void)sleep(1); + } + + _exit(EXIT_SUCCESS); + } + + /* + * Try to kill the child after having + * set the real and effective UID. + */ + if (setuid(puid) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (kill(cpid, SIGKILL) == 0) + _exit(EPERM); + + if (errno != EPERM) + _exit(EPERM); + + (void)waitpid(cpid, &sta, 0); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) == EPERM) + atf_tc_fail("killed a process of another user"); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("unknown error from kill(2)"); +} + +ATF_TC(kill_pgrp_neg); +ATF_TC_HEAD(kill_pgrp_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #2"); +} + +ATF_TC_BODY(kill_pgrp_neg, tc) +{ + const int maxiter = 3; + pid_t cpid, ppid; + int i, sta; + + ppid = fork(); + ATF_REQUIRE(ppid >= 0); + + if (ppid == 0) { + + ATF_REQUIRE(setpgid(0, 0) == 0); + + for (i = 0; i < maxiter; i++) { + + cpid = fork(); + ATF_REQUIRE(cpid >= 0); + + if (cpid == 0) + pause(); + } + + /* + * Test the variant of killpg(3); if the process number + * is negative but not -1, the signal should be sent to + * all processes whose process group ID is equal to the + * absolute value of the process number. + */ + ATF_REQUIRE(kill(-getpgrp(), SIGKILL) == 0); + + (void)sleep(1); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("failed to kill(2) a process group"); +} + +ATF_TC(kill_pgrp_zero); +ATF_TC_HEAD(kill_pgrp_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #1"); +} + +ATF_TC_BODY(kill_pgrp_zero, tc) +{ + const int maxiter = 3; + pid_t cpid, ppid; + int i, sta; + + ppid = fork(); + ATF_REQUIRE(ppid >= 0); + + if (ppid == 0) { + + ATF_REQUIRE(setpgid(0, 0) == 0); + + for (i = 0; i < maxiter; i++) { + + cpid = fork(); + ATF_REQUIRE(cpid >= 0); + + if (cpid == 0) + pause(); + } + + /* + * If the supplied process number is zero, + * the signal should be sent to all processes + * under the current process group. + */ + ATF_REQUIRE(kill(0, SIGKILL) == 0); + + (void)sleep(1); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("failed to kill(2) a process group"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, kill_basic); + ATF_TP_ADD_TC(tp, kill_err); + ATF_TP_ADD_TC(tp, kill_perm); + ATF_TP_ADD_TC(tp, kill_pgrp_neg); + ATF_TP_ADD_TC(tp, kill_pgrp_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_link.c b/contrib/netbsd-tests/lib/libc/sys/t_link.c new file mode 100644 index 0000000..b58c4c9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_link.c @@ -0,0 +1,229 @@ +/* $NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $"); + +#include <sys/param.h> +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static const char *getpath(void); +static char path[] = "link"; +static const char *pathl; + +static const char * +getpath(void) +{ + static char buf[LINE_MAX]; + + (void)memset(buf, '\0', sizeof(buf)); + + if (getcwd(buf, sizeof(buf)) == NULL) + return NULL; + + (void)strlcat(buf, path, sizeof(buf)); + (void)strlcat(buf, ".link", sizeof(buf)); + + return buf; +} + +ATF_TC_WITH_CLEANUP(link_count); +ATF_TC_HEAD(link_count, tc) +{ + atf_tc_set_md_var(tc, "descr", "link(2) counts are incremented?"); +} + +ATF_TC_BODY(link_count, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (sa.st_nlink != sb.st_nlink - 1) + atf_tc_fail("incorrect link(2) count"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_count, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TC_WITH_CLEANUP(link_err); +ATF_TC_HEAD(link_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of link(2)"); +} + +ATF_TC_BODY(link_err, tc) +{ + char buf[MAXPATHLEN + 1]; + int fd; + + (void)memset(buf, 'x', sizeof(buf)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + errno = 0; + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE_ERRNO(EEXIST, link(path, pathl) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, link(buf, "xxx") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link(path, "/d/c/b/a") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", path) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", "/d/c/b/a") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, link(path, (const char *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, link((const char *)-1, "xxx") == -1); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_err, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TC(link_perm); +ATF_TC_HEAD(link_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with link(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(link_perm, tc) +{ + int rv; + + errno = 0; + rv = link("/root", "/root.link"); + ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM), + "link to a directory did not fail with EPERM or EACCESS; link() " + "returned %d, errno %d", rv, errno); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, + link("/root/.profile", "/root/.profile.link") == -1); +} + +ATF_TC_WITH_CLEANUP(link_stat); +ATF_TC_HEAD(link_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check stat(2) of a linked file"); +} + +ATF_TC_BODY(link_stat, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(lstat(pathl, &sb) == 0); + + if (sa.st_uid != sb.st_uid) + atf_tc_fail("unequal UIDs"); + + if (sa.st_mode != sb.st_mode) + atf_tc_fail("unequal modes"); + + if (sa.st_ino != sb.st_ino) + atf_tc_fail("unequal inodes"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_stat, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, link_count); + ATF_TP_ADD_TC(tp, link_err); + ATF_TP_ADD_TC(tp, link_perm); + ATF_TP_ADD_TC(tp, link_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_listen.c b/contrib/netbsd-tests/lib/libc/sys/t_listen.c new file mode 100644 index 0000000..71201d3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_listen.c @@ -0,0 +1,134 @@ +/* $NetBSD: t_listen.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */ +/* + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +static const char *path = "listen"; + +ATF_TC_WITH_CLEANUP(listen_err); +ATF_TC_HEAD(listen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks errors from listen(2) (PR standards/46150)"); +} + +ATF_TC_BODY(listen_err, tc) +{ + static const size_t siz = sizeof(struct sockaddr_in); + struct sockaddr_in sina, sinb; + int fda, fdb, fdc; + + (void)memset(&sina, 0, sizeof(struct sockaddr_in)); + (void)memset(&sinb, 0, sizeof(struct sockaddr_in)); + + sina.sin_family = AF_INET; + sina.sin_port = htons(31522); + sina.sin_addr.s_addr = inet_addr("127.0.0.1"); + + sinb.sin_family = AF_INET; + sinb.sin_port = htons(31522); + sinb.sin_addr.s_addr = inet_addr("127.0.0.1"); + + fda = socket(AF_INET, SOCK_STREAM, 0); + fdb = socket(AF_INET, SOCK_STREAM, 0); + fdc = open("listen", O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fda >= 0 && fdb >= 0 && fdc >= 0); + ATF_REQUIRE_ERRNO(ENOTSOCK, listen(fdc, 1) == -1); + + (void)close(fdc); + (void)unlink(path); + + ATF_REQUIRE(bind(fda, (struct sockaddr *)&sina, siz) == 0); + ATF_REQUIRE(listen(fda, 1) == 0); + + /* + * According to IEEE Std 1003.1-2008: if the socket is + * already connected, the call should fail with EINVAL. + */ + ATF_REQUIRE(connect(fdb, (struct sockaddr *)&sinb, siz) == 0); + ATF_REQUIRE_ERRNO(EINVAL, listen(fdb, 1) == -1); + + (void)close(fda); + (void)close(fdb); + + ATF_REQUIRE_ERRNO(EBADF, connect(fdb, + (struct sockaddr *)&sinb, siz) == -1); +} + +ATF_TC_CLEANUP(listen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC(listen_low_port); +ATF_TC_HEAD(listen_low_port, tc) +{ + atf_tc_set_md_var(tc, "descr", "Does low-port allocation work?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(listen_low_port, tc) +{ + int sd, val; + + sd = socket(AF_INET, SOCK_STREAM, 0); + + val = IP_PORTRANGE_LOW; + if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val, + sizeof(val)) == -1) + atf_tc_fail("setsockopt failed: %s", strerror(errno)); + + if (listen(sd, 5) == -1) { + int serrno = errno; + atf_tc_fail("listen failed: %s%s", + strerror(serrno), + serrno != EACCES ? "" : + " (see http://mail-index.netbsd.org/" + "source-changes/2007/12/16/0011.html)"); + } + + close(sd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, listen_err); + ATF_TP_ADD_TC(tp, listen_low_port); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c new file mode 100644 index 0000000..02545fe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c @@ -0,0 +1,247 @@ +/* $NetBSD: t_lwp_create.c,v 1.2 2012/05/22 09:23:39 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This code is partly based on code by Joel Sing <joel at sing.id.au> + */ + +#include <atf-c.h> +#include <lwp.h> +#include <stdio.h> +#include <stdlib.h> +#include <ucontext.h> +#include <inttypes.h> +#include <errno.h> + +#ifdef __alpha__ +#include <machine/alpha_cpu.h> +#endif +#ifdef __amd64__ +#include <machine/vmparam.h> +#include <machine/psl.h> +#endif +#ifdef __hppa__ +#include <machine/psl.h> +#endif +#ifdef __i386__ +#include <machine/segments.h> +#include <machine/psl.h> +#endif +#if defined(__m68k__) || defined(__sh3__) || defined __vax__ +#include <machine/psl.h> +#endif + +volatile lwpid_t the_lwp_id = 0; + +static void lwp_main_func(void* arg) +{ + the_lwp_id = _lwp_self(); + _lwp_exit(); +} + +/* + * Hard to document - see usage examples below. + */ +#define INVALID_UCONTEXT(ARCH,NAME,DESC) \ +static void ARCH##_##NAME(ucontext_t *); \ +ATF_TC(lwp_create_##ARCH##_fail_##NAME); \ +ATF_TC_HEAD(lwp_create_##ARCH##_fail_##NAME, tc) \ +{ \ + atf_tc_set_md_var(tc, "descr", "verify rejection of invalid ucontext " \ + "on " #ARCH " due to " DESC); \ +} \ + \ +ATF_TC_BODY(lwp_create_##ARCH##_fail_##NAME, tc) \ +{ \ + ucontext_t uc; \ + lwpid_t lid; \ + int error; \ + \ + getcontext(&uc); \ + uc.uc_flags = _UC_CPU; \ + ARCH##_##NAME(&uc); \ + \ + error = _lwp_create(&uc, 0, &lid); \ + ATF_REQUIRE(error != 0 && errno == EINVAL); \ +} \ +static void ARCH##_##NAME(ucontext_t *uc) \ +{ + + +ATF_TC(lwp_create_works); +ATF_TC_HEAD(lwp_create_works, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify creation of a lwp and waiting" + " for it to finish"); +} + +ATF_TC_BODY(lwp_create_works, tc) +{ + ucontext_t uc; + lwpid_t lid; + int error; + void *stack; + static const size_t ssize = 16*1024; + + stack = malloc(ssize); + _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); + + error = _lwp_create(&uc, 0, &lid); + ATF_REQUIRE(error == 0); + + error = _lwp_wait(lid, NULL); + ATF_REQUIRE(error == 0); + ATF_REQUIRE(lid == the_lwp_id); +} + +INVALID_UCONTEXT(generic, no_uc_cpu, "not setting cpu registers") + uc->uc_flags &= ~_UC_CPU; +} + +#ifdef __alpha__ +INVALID_UCONTEXT(alpha, pslset, "trying to clear the USERMODE flag") + uc->uc_mcontext.__gregs[_REG_PS] &= ~ALPHA_PSL_USERMODE; +} +INVALID_UCONTEXT(alpha, pslclr, "trying to set a 'must be zero' flag") + uc->uc_mcontext.__gregs[_REG_PS] |= ALPHA_PSL_IPL_HIGH; +} +#endif +#ifdef __amd64__ +INVALID_UCONTEXT(amd64, untouchable_rflags, "forbidden rflags changed") + uc->uc_mcontext.__gregs[_REG_RFLAGS] |= PSL_MBZ; +} +/* + * XXX: add invalid GS/DS selector tests + */ +INVALID_UCONTEXT(amd64, pc_too_high, + "instruction pointer outside userland address space") + uc->uc_mcontext.__gregs[_REG_RIP] = VM_MAXUSER_ADDRESS; +} +#endif +#ifdef __arm__ +INVALID_UCONTEXT(arm, invalid_mode, "psr or r15 set to non-user-mode") + uc->uc_mcontext.__gregs[_REG_PC] |= 0x1f /*PSR_SYS32_MODE*/; + uc->uc_mcontext.__gregs[_REG_CPSR] |= 0x03 /*R15_MODE_SVC*/; +} +#endif +#ifdef __hppa__ +INVALID_UCONTEXT(hppa, invalid_1, "set illegal bits in psw") + uc->uc_mcontext.__gregs[_REG_PSW] |= PSW_MBZ; +} +INVALID_UCONTEXT(hppa, invalid_0, "clear illegal bits in psw") + uc->uc_mcontext.__gregs[_REG_PSW] &= ~PSW_MBS; +} +#endif +#ifdef __i386__ +INVALID_UCONTEXT(i386, untouchable_eflags, "changing forbidden eflags") + uc->uc_mcontext.__gregs[_REG_EFL] |= PSL_IOPL; +} +INVALID_UCONTEXT(i386, priv_escalation, "modifying priviledge level") + uc->uc_mcontext.__gregs[_REG_CS] &= ~SEL_RPL; +} +#endif +#ifdef __m68k__ +INVALID_UCONTEXT(m68k, invalid_ps_bits, + "setting forbidden bits in the ps register") + uc->uc_mcontext.__gregs[_REG_PS] |= (PSL_MBZ|PSL_IPL|PSL_S); +} +#endif +#ifdef __sh3__ +INVALID_UCONTEXT(sh3, modify_userstatic, + "modifying illegal bits in the status register") + uc->uc_mcontext.__gregs[_REG_SR] |= PSL_MD; +} +#endif +#ifdef __sparc__ +INVALID_UCONTEXT(sparc, pc_odd, "mis-aligned instruction pointer") + uc->uc_mcontext.__gregs[_REG_PC] = 0x100002; +} +INVALID_UCONTEXT(sparc, npc_odd, "mis-aligned next instruction pointer") + uc->uc_mcontext.__gregs[_REG_nPC] = 0x100002; +} +INVALID_UCONTEXT(sparc, pc_null, "NULL instruction pointer") + uc->uc_mcontext.__gregs[_REG_PC] = 0; +} +INVALID_UCONTEXT(sparc, npc_null, "NULL next instruction pointer") + uc->uc_mcontext.__gregs[_REG_nPC] = 0; +} +#endif +#ifdef __vax__ +INVALID_UCONTEXT(vax, psl_0, "clearing forbidden bits in psl") + uc->uc_mcontext.__gregs[_REG_PSL] &= ~(PSL_U | PSL_PREVU); +} +INVALID_UCONTEXT(vax, psl_1, "setting forbidden bits in psl") + uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_IPL | PSL_IS; +} +INVALID_UCONTEXT(vax, psl_cm, "setting CM bit in psl") + uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_CM; +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lwp_create_works); + ATF_TP_ADD_TC(tp, lwp_create_generic_fail_no_uc_cpu); +#ifdef __alpha__ + ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslset); + ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslclr); +#endif +#ifdef __amd64__ + ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_untouchable_rflags); + ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_pc_too_high); +#endif +#ifdef __arm__ + ATF_TP_ADD_TC(tp, lwp_create_arm_fail_invalid_mode); +#endif +#ifdef __hppa__ + ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_1); + ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_0); +#endif +#ifdef __i386__ + ATF_TP_ADD_TC(tp, lwp_create_i386_fail_untouchable_eflags); + ATF_TP_ADD_TC(tp, lwp_create_i386_fail_priv_escalation); +#endif +#ifdef __m68k__ + ATF_TP_ADD_TC(tp, lwp_create_m68k_fail_invalid_ps_bits); +#endif +#ifdef __sh3__ + ATF_TP_ADD_TC(tp, lwp_create_sh3_fail_modify_userstatic); +#endif +#ifdef __sparc__ + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_odd); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_odd); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_null); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_null); +#endif +#ifdef __vax__ + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_0); + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_1); + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_cm); +#endif + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c new file mode 100644 index 0000000..1b28f75 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c @@ -0,0 +1,74 @@ +/* $NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $"); + +#include <sys/lwpctl.h> + +#include <atf-c.h> +#include <lwp.h> +#include <stdio.h> +#include <time.h> + +ATF_TC(lwpctl_counter); +ATF_TC_HEAD(lwpctl_counter, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks lwpctl preemption counter"); +} + +ATF_TC_BODY(lwpctl_counter, tc) +{ + lwpctl_t *lc; + struct timespec ts; + int ctr1, ctr2; + + ATF_REQUIRE(_lwp_ctl(LWPCTL_FEATURE_PCTR, &lc) == 0); + + /* Ensure that preemption is reported. */ + ctr1 = lc->lc_pctr; + (void)printf("pctr = %d\n", ctr1); + ts.tv_nsec = 10*1000000; + ts.tv_sec = 0; + + ATF_REQUIRE(nanosleep(&ts, 0) != -1); + + ctr2 = lc->lc_pctr; + (void)printf("pctr = %d\n", ctr2); + + ATF_REQUIRE_MSG(ctr1 != ctr2, "counters match"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lwpctl_counter); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mincore.c b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c new file mode 100644 index 0000000..553207a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c @@ -0,0 +1,318 @@ +/* $NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $"); + +#include <sys/mman.h> +#include <sys/shm.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <kvm.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/resource.h> + +static long page = 0; +static const char path[] = "mincore"; +static size_t check_residency(void *, size_t); + +static size_t +check_residency(void *addr, size_t npgs) +{ + size_t i, resident; + char *vec; + + vec = malloc(npgs); + + ATF_REQUIRE(vec != NULL); + ATF_REQUIRE(mincore(addr, npgs * page, vec) == 0); + + for (i = resident = 0; i < npgs; i++) { + + if (vec[i] != 0) + resident++; + +#if 0 + (void)fprintf(stderr, "page 0x%p is %sresident\n", + (char *)addr + (i * page), vec[i] ? "" : "not "); +#endif + } + + free(vec); + + return resident; +} + +ATF_TC(mincore_err); +ATF_TC_HEAD(mincore_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from mincore(2)"); +} + +ATF_TC_BODY(mincore_err, tc) +{ + char *map, *vec; + + map = mmap(NULL, page, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + vec = malloc(page); + + ATF_REQUIRE(vec != NULL); + ATF_REQUIRE(map != MAP_FAILED); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mincore(map, 0, vec) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mincore(0, page, vec) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mincore(map, page, (void *)-1) == -1); + + free(vec); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TC_WITH_CLEANUP(mincore_resid); +ATF_TC_HEAD(mincore_resid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test page residency with mincore(2)"); +} + +ATF_TC_BODY(mincore_resid, tc) +{ + void *addr, *addr2, *addr3, *buf; + size_t npgs = 0, resident; + struct stat st; + int fd, rv; + struct rlimit rlim; + + ATF_REQUIRE(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0); + rlim.rlim_cur = rlim.rlim_max; + ATF_REQUIRE(setrlimit(RLIMIT_MEMLOCK, &rlim) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + + fd = open(path, O_RDWR | O_CREAT, 0700); + buf = malloc(page * 5); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(buf != NULL); + + rv = write(fd, buf, page * 5); + ATF_REQUIRE(rv >= 0); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + addr = mmap(NULL, (size_t)st.st_size, PROT_READ, + MAP_FILE | MAP_SHARED, fd, (off_t) 0); + + ATF_REQUIRE(addr != MAP_FAILED); + + (void)close(fd); + + npgs = st.st_size / page; + + if (st.st_size % page != 0) + npgs++; + + (void)check_residency(addr, npgs); + + rv = mlock(addr, npgs * page); + if (rv == -1 && errno == EAGAIN) + atf_tc_skip("hit process resource limits"); + ATF_REQUIRE(munmap(addr, st.st_size) == 0); + + npgs = 128; + + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_WIRED, -1, (off_t)0); + + if (addr == MAP_FAILED) + atf_tc_skip("could not mmap wired anonymous test area, system " + "might be low on memory"); + + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(munmap(addr, npgs * page) == 0); + + npgs = 128; + + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, (off_t)0); + + ATF_REQUIRE(addr != MAP_FAILED); + + /* + * Check that the in-core pages match the locked pages. + */ + ATF_REQUIRE(check_residency(addr, npgs) == 0); + + errno = 0; + if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0 && errno != ENOMEM) + atf_tc_fail("mlockall(2) failed"); + if (errno == ENOMEM) + atf_tc_skip("mlockall() exceeded process resource limits"); + + resident = check_residency(addr, npgs); + if (resident < npgs) + atf_tc_fail("mlockall(MCL_FUTURE) succeeded, still only " + "%zu pages of the newly mapped %zu pages are resident", + resident, npgs); + + addr2 = mmap(NULL, npgs * page, PROT_READ, MAP_ANON, -1, (off_t)0); + addr3 = mmap(NULL, npgs * page, PROT_NONE, MAP_ANON, -1, (off_t)0); + + if (addr2 == MAP_FAILED || addr3 == MAP_FAILED) + atf_tc_skip("could not mmap more anonymous test pages with " + "mlockall(MCL_FUTURE) in effect, system " + "might be low on memory"); + + ATF_REQUIRE(check_residency(addr2, npgs) == npgs); + ATF_REQUIRE(check_residency(addr3, npgs) == 0); + ATF_REQUIRE(mprotect(addr3, npgs * page, PROT_READ) == 0); + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(check_residency(addr2, npgs) == npgs); + + (void)munlockall(); + + ATF_REQUIRE(madvise(addr2, npgs * page, MADV_FREE) == 0); + ATF_REQUIRE(check_residency(addr2, npgs) == 0); + + (void)memset(addr, 0, npgs * page); + + ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0); + ATF_REQUIRE(check_residency(addr, npgs) == 0); + + (void)munmap(addr, npgs * page); + (void)munmap(addr2, npgs * page); + (void)munmap(addr3, npgs * page); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mincore_resid, tc) +{ + (void)unlink(path); +} + +ATF_TC(mincore_shmseg); +ATF_TC_HEAD(mincore_shmseg, tc) +{ + atf_tc_set_md_var(tc, "descr", "residency of shared memory"); +} + +ATF_TC_BODY(mincore_shmseg, tc) +{ + size_t npgs = 128; + void *addr = NULL; + int shmid; + + shmid = shmget(IPC_PRIVATE, npgs * page, + IPC_CREAT | S_IRUSR | S_IWUSR); + + ATF_REQUIRE(shmid != -1); + + addr = shmat(shmid, NULL, 0); + + ATF_REQUIRE(addr != NULL); + ATF_REQUIRE(check_residency(addr, npgs) == 0); + + (void)memset(addr, 0xff, npgs * page); + + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0); + + /* + * NOTE! Even though we have MADV_FREE'd the range, + * there is another reference (the kernel's) to the + * object which owns the pages. In this case, the + * kernel does not simply free the pages, as haphazardly + * freeing pages when there are still references to + * an object can cause data corruption (say, the other + * referencer doesn't expect the pages to be freed, + * and is surprised by the subsequent ZFOD). + * + * Because of this, we simply report the number of + * pages still resident, for information only. + */ + npgs = check_residency(addr, npgs); + + (void)fprintf(stderr, "%zu pages still resident\n", npgs); + + ATF_REQUIRE(shmdt(addr) == 0); + ATF_REQUIRE(shmctl(shmid, IPC_RMID, NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mincore_err); + ATF_TP_ADD_TC(tp, mincore_resid); + ATF_TP_ADD_TC(tp, mincore_shmseg); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_minherit.c b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c new file mode 100644 index 0000000..0bdf6bc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c @@ -0,0 +1,200 @@ +/* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $"); + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +static long page; + +static void * +makemap(int v, int f) { + void *map = mmap(NULL, page, PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + memset(map, v, page); + if (f != 666) + ATF_REQUIRE(minherit(map, page, f) == 0); + else + ATF_REQUIRE(minherit(map, page, f) == -1); + return map; +} + +ATF_TC(minherit_copy); +ATF_TC_HEAD(minherit_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_COPY from minherit(2)"); +} + +ATF_TC_BODY(minherit_copy, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_COPY); + void *map2 = makemap(1, MAP_INHERIT_COPY); + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 0, page); + exit(0); + } +} + +ATF_TC(minherit_share); +ATF_TC_HEAD(minherit_share, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_SHARE from minherit(2)"); +} + +ATF_TC_BODY(minherit_share, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_SHARE); + void *map2 = makemap(1, MAP_INHERIT_SHARE); + + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + memset(map2, 0, page); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 0, page); + exit(0); + } +} + +static void +segv(int n) { + _exit(n); +} + +ATF_TC(minherit_none); +ATF_TC_HEAD(minherit_none, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_NONE from minherit(2)"); +} + +ATF_TC_BODY(minherit_none, tc) +{ + void *map1 = makemap(0, MAP_INHERIT_NONE); + int status; + + switch (fork()) { + default: + ATF_REQUIRE(wait(&status) != -1); + ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR); + memset(map1, 0, page); + exit(0); + } +} + +ATF_TC(minherit_zero); +ATF_TC_HEAD(minherit_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_ZERO from minherit(2)"); +} + +ATF_TC_BODY(minherit_zero, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_ZERO); + void *map2 = makemap(0, MAP_INHERIT_SHARE); + + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + memset(map2, 1, page); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 2, page); + exit(0); + } +} + +ATF_TC(minherit_bad); +ATF_TC_HEAD(minherit_bad, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for bad minherit(2)"); +} + +ATF_TC_BODY(minherit_bad, tc) +{ + (void)makemap(0, 666); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, minherit_copy); + ATF_TP_ADD_TC(tp, minherit_share); + ATF_TP_ADD_TC(tp, minherit_none); + ATF_TP_ADD_TC(tp, minherit_zero); + ATF_TP_ADD_TC(tp, minherit_bad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c new file mode 100644 index 0000000..d97a20b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c @@ -0,0 +1,210 @@ +/* $NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $ */ + +/*- + * Copyright (c) 2008, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe and Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(mkdir_err); +ATF_TC_HEAD(mkdir_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks errors from mkdir(2)"); +} + +ATF_TC_BODY(mkdir_err, tc) +{ + char buf[PATH_MAX + 1]; + int fd; + + (void)memset(buf, 'x', sizeof(buf)); + + fd = open("/etc", O_RDONLY); + + if (fd >= 0) { + + (void)close(fd); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkdir("/etc", 0500) == -1); + } + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mkdir((void *)-1, 0500) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkdir(buf, 0500) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mkdir("/a/b/c/d/e/f/g/h/i/j/k", 0500) == -1); +} + +ATF_TC_WITH_CLEANUP(mkdir_perm); +ATF_TC_HEAD(mkdir_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks permissions with mkdir(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mkdir_perm, tc) +{ + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, mkdir("/usr/__nonexistent__", 0500) == -1); +} + +ATF_TC_CLEANUP(mkdir_perm, tc) +{ + (void)rmdir("/usr/__nonexistent__"); +} + +ATF_TC_WITH_CLEANUP(mkdir_mode); +ATF_TC_HEAD(mkdir_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that UIDs and GIDs are right " + "for a directory created with mkdir(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mkdir_mode, tc) +{ + static const char *path = "/tmp/mkdir"; + struct stat st_a, st_b; + struct passwd *pw; + pid_t pid; + int sta; + + (void)memset(&st_a, 0, sizeof(struct stat)); + (void)memset(&st_b, 0, sizeof(struct stat)); + + pw = getpwnam("nobody"); + + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(stat("/tmp", &st_a) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + if (mkdir(path, 0500) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create '%s'", path); + + ATF_REQUIRE(stat(path, &st_b) == 0); + ATF_REQUIRE(rmdir(path) == 0); + + /* + * The directory's owner ID should be set to the + * effective UID, whereas the group ID should be + * set to that of the parent directory. + */ + if (st_b.st_uid != pw->pw_uid) + atf_tc_fail("invalid UID for '%s'", path); + + if (st_b.st_gid != st_a.st_gid) + atf_tc_fail("GID did not follow the parent directory"); +} + +ATF_TC_CLEANUP(mkdir_mode, tc) +{ + (void)rmdir("/tmp/mkdir"); +} + +ATF_TC(mkdir_trail); +ATF_TC_HEAD(mkdir_trail, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mkdir(2) for trailing slashes"); +} + +ATF_TC_BODY(mkdir_trail, tc) +{ + const char *tests[] = { + /* + * IEEE 1003.1 second ed. 2.2.2.78: + * + * If the pathname refers to a directory, it may also have + * one or more trailing slashes. Multiple successive slashes + * are considered to be the same as one slash. + */ + "dir1/", + "dir2//", + + NULL, + }; + + const char **test; + + for (test = &tests[0]; *test != NULL; ++test) { + + (void)printf("Checking \"%s\"\n", *test); + (void)rmdir(*test); + + ATF_REQUIRE(mkdir(*test, 0777) == 0); + ATF_REQUIRE(rename(*test, "foo") == 0); + ATF_REQUIRE(rename("foo/", *test) == 0); + ATF_REQUIRE(rmdir(*test) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkdir_err); + ATF_TP_ADD_TC(tp, mkdir_perm); + ATF_TP_ADD_TC(tp, mkdir_mode); + ATF_TP_ADD_TC(tp, mkdir_trail); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c new file mode 100644 index 0000000..56bc4c8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c @@ -0,0 +1,276 @@ +/* $NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +static const char path[] = "fifo"; +static void support(void); + +static void +support(void) +{ + + errno = 0; + + if (mkfifo(path, 0600) == 0) { + ATF_REQUIRE(unlink(path) == 0); + return; + } + + if (errno == EOPNOTSUPP) + atf_tc_skip("the kernel does not support FIFOs"); + else { + atf_tc_fail("mkfifo(2) failed"); + } +} + +ATF_TC_WITH_CLEANUP(mkfifo_block); +ATF_TC_HEAD(mkfifo_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that FIFOs block"); +} + +ATF_TC_BODY(mkfifo_block, tc) +{ + int sta, fd = -1; + pid_t pid; + + support(); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * If we open the FIFO as read-only (write-only), + * the call should block until another process + * opens the FIFO for writing (reading). + */ + fd = open(path, O_RDONLY); + + _exit(EXIT_FAILURE); /* NOTREACHED */ + } + + (void)sleep(1); + + ATF_REQUIRE(kill(pid, SIGKILL) == 0); + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("FIFO did not block"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mkfifo_block, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_err); +ATF_TC_HEAD(mkfifo_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erros from mkfifo(2)"); +} + +ATF_TC_BODY(mkfifo_err, tc) +{ + char buf[PATH_MAX + 1]; + + support(); + + (void)memset(buf, 'x', sizeof(buf)); + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mkfifo((char *)-1, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkfifo("/etc/passwd", 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkfifo(path, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkfifo(buf, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mkfifo("/a/b/c/d/e/f/g", 0600) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_nonblock); +ATF_TC_HEAD(mkfifo_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test O_NONBLOCK with FIFOs"); +} + +ATF_TC_BODY(mkfifo_nonblock, tc) +{ + int fd, sta; + pid_t pid; + + support(); + + fd = -1; + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * If we open the FIFO as O_NONBLOCK, the O_RDONLY + * call should return immediately, whereas the call + * for write-only should fail with ENXIO. + */ + fd = open(path, O_RDONLY | O_NONBLOCK); + + if (fd >= 0) + _exit(EXIT_SUCCESS); + + (void)pause(); /* NOTREACHED */ + } + + (void)sleep(1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENXIO, open(path, O_WRONLY | O_NONBLOCK) == -1); + + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL) + atf_tc_fail("FIFO blocked for O_NONBLOCK open(2)"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mkfifo_nonblock, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_perm); +ATF_TC_HEAD(mkfifo_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with mkfifo(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mkfifo_perm, tc) +{ + + support(); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, mkfifo("/root/fifo", 0600) == -1); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + /* + * For some reason this fails with EFTYPE... + */ + errno = 0; + ATF_REQUIRE_ERRNO(EFTYPE, chmod(path, 1777) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_stat); +ATF_TC_HEAD(mkfifo_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mkfifo(2) with stat"); +} + +ATF_TC_BODY(mkfifo_stat, tc) +{ + struct stat st; + + support(); + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISFIFO(st.st_mode) == 0) + atf_tc_fail("invalid mode from mkfifo(2)"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_stat, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkfifo_block); + ATF_TP_ADD_TC(tp, mkfifo_err); + ATF_TP_ADD_TC(tp, mkfifo_nonblock); + ATF_TP_ADD_TC(tp, mkfifo_perm); + ATF_TP_ADD_TC(tp, mkfifo_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mknod.c b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c new file mode 100644 index 0000000..b394b31 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c @@ -0,0 +1,192 @@ +/* $NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static char path[] = "node"; + +ATF_TC_WITH_CLEANUP(mknod_err); +ATF_TC_HEAD(mknod_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of mknod(2) (PR kern/45111)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mknod(path, S_IFCHR, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mknod(buf, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mknod((char *)-1, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mknod("/a/b/c/d/e/f/g", S_IFCHR, 0) == -1); +} + +ATF_TC_CLEANUP(mknod_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_exist); +ATF_TC_HEAD(mknod_exist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EEXIST from mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_exist, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + + (void)close(fd); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, + mknod("/etc/passwd", S_IFCHR, 0) == -1); + } + + ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mknod(path, S_IFCHR, 0) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mknod_exist, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_perm); +ATF_TC_HEAD(mknod_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions of mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mknod_perm, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFBLK, 0) == -1); +} + +ATF_TC_CLEANUP(mknod_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_stat); +ATF_TC_HEAD(mknod_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_stat, tc) +{ + struct stat st; + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISCHR(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFCHR)"); + + ATF_REQUIRE(unlink(path) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mknod(path, S_IFBLK, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISBLK(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFBLK)"); + + ATF_REQUIRE(unlink(path) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mknod(path, S_IFREG, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISREG(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFREG)"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mknod_stat, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mknod_err); + ATF_TP_ADD_TC(tp, mknod_exist); + ATF_TP_ADD_TC(tp, mknod_perm); + ATF_TP_ADD_TC(tp, mknod_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mlock.c b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c new file mode 100644 index 0000000..52576f7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c @@ -0,0 +1,244 @@ +/* $NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $"); + +#include <sys/mman.h> +#include <sys/resource.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <errno.h> +#include <atf-c.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +static long page = 0; + +ATF_TC(mlock_clip); +ATF_TC_HEAD(mlock_clip, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test with mlock(2) that UVM only " + "clips if the clip address is within the entry (PR kern/44788)"); +} + +ATF_TC_BODY(mlock_clip, tc) +{ + void *buf; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + if (page < 1024) + atf_tc_skip("page size too small"); + + for (size_t i = page; i >= 1; i = i - 1024) { + (void)mlock(buf, page - i); + (void)munlock(buf, page - i); + } + + free(buf); +} + +ATF_TC(mlock_err); +ATF_TC_HEAD(mlock_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions in mlock(2) and munlock(2)"); +} + +ATF_TC_BODY(mlock_err, tc) +{ + unsigned long vmin = 0; + size_t len = sizeof(vmin); + void *invalid_ptr; + int null_errno = ENOMEM; /* error expected for NULL */ + + if (sysctlbyname("vm.minaddress", &vmin, &len, NULL, 0) != 0) + atf_tc_fail("failed to read vm.minaddress"); + + if (vmin > 0) + null_errno = EINVAL; /* NULL is not inside user VM */ + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, mlock(NULL, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, mlock((char *)0, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, munlock(NULL, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, munlock((char *)0, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1); + + /* + * Try to create a pointer to an unmapped page - first after current + * brk will likely do. + */ + invalid_ptr = (void*)(((uintptr_t)sbrk(0)+page) & ~(page-1)); + printf("testing with (hopefully) invalid pointer %p\n", invalid_ptr); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock(invalid_ptr, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock(invalid_ptr, page) == -1); +} + +ATF_TC(mlock_limits); +ATF_TC_HEAD(mlock_limits, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test system limits with mlock(2)"); +} + +ATF_TC_BODY(mlock_limits, tc) +{ + struct rlimit res; + void *buf; + pid_t pid; + int sta; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (ssize_t i = page; i >= 2; i -= 100) { + + res.rlim_cur = i - 1; + res.rlim_max = i - 1; + + (void)fprintf(stderr, "trying to lock %zd bytes " + "with %zu byte limit\n", i, (size_t)res.rlim_cur); + + if (setrlimit(RLIMIT_MEMLOCK, &res) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (mlock(buf, i) != -1 || errno != EAGAIN) { + (void)munlock(buf, i); + _exit(EXIT_FAILURE); + } + } + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("mlock(2) locked beyond system limits"); + + free(buf); +} + +ATF_TC(mlock_mmap); +ATF_TC_HEAD(mlock_mmap, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction"); +} + +ATF_TC_BODY(mlock_mmap, tc) +{ + static const int flags = MAP_ANON | MAP_PRIVATE | MAP_WIRED; + void *buf; + + /* + * Make a wired RW mapping and check that mlock(2) + * does not fail for the (already locked) mapping. + */ + buf = mmap(NULL, page, PROT_READ | PROT_WRITE, flags, -1, 0); + + ATF_REQUIRE(buf != MAP_FAILED); + ATF_REQUIRE(mlock(buf, page) == 0); + ATF_REQUIRE(munlock(buf, page) == 0); + ATF_REQUIRE(munmap(buf, page) == 0); + ATF_REQUIRE(munlock(buf, page) != 0); + + /* + * But it should be impossible to mlock(2) a PROT_NONE mapping. + */ + buf = mmap(NULL, page, PROT_NONE, flags, -1, 0); + + ATF_REQUIRE(buf != MAP_FAILED); + ATF_REQUIRE(mlock(buf, page) != 0); + ATF_REQUIRE(munmap(buf, page) == 0); +} + +ATF_TC(mlock_nested); +ATF_TC_HEAD(mlock_nested, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that consecutive mlock(2) calls succeed"); +} + +ATF_TC_BODY(mlock_nested, tc) +{ + const size_t maxiter = 100; + void *buf; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + for (size_t i = 0; i < maxiter; i++) + ATF_REQUIRE(mlock(buf, page) == 0); + + ATF_REQUIRE(munlock(buf, page) == 0); + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mlock_clip); + ATF_TP_ADD_TC(tp, mlock_err); + ATF_TP_ADD_TC(tp, mlock_limits); + ATF_TP_ADD_TC(tp, mlock_mmap); + ATF_TP_ADD_TC(tp, mlock_nested); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mmap.c b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c new file mode 100644 index 0000000..c6b97b1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c @@ -0,0 +1,505 @@ +/* $NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $"); + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/socket.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <paths.h> +#include <machine/disklabel.h> + +static long page = 0; +static char path[] = "mmap"; +static void map_check(void *, int); +static void map_sighandler(int); +static void testloan(void *, void *, char, int); + +#define BUFSIZE (32 * 1024) /* enough size to trigger sosend_loan */ + +static void +map_check(void *map, int flag) +{ + + if (flag != 0) { + ATF_REQUIRE(map == MAP_FAILED); + return; + } + + ATF_REQUIRE(map != MAP_FAILED); + ATF_REQUIRE(munmap(map, page) == 0); +} + +void +testloan(void *vp, void *vp2, char pat, int docheck) +{ + char buf[BUFSIZE]; + char backup[BUFSIZE]; + ssize_t nwritten; + ssize_t nread; + int fds[2]; + int val; + + val = BUFSIZE; + + if (docheck != 0) + (void)memcpy(backup, vp, BUFSIZE); + + if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds) != 0) + atf_tc_fail("socketpair() failed"); + + val = BUFSIZE; + + if (setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0) + atf_tc_fail("setsockopt() failed, SO_RCVBUF"); + + val = BUFSIZE; + + if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0) + atf_tc_fail("setsockopt() failed, SO_SNDBUF"); + + if (fcntl(fds[0], F_SETFL, O_NONBLOCK) != 0) + atf_tc_fail("fcntl() failed"); + + nwritten = write(fds[0], (char *)vp + page, BUFSIZE - page); + + if (nwritten == -1) + atf_tc_fail("write() failed"); + + /* Break loan. */ + (void)memset(vp2, pat, BUFSIZE); + + nread = read(fds[1], buf + page, BUFSIZE - page); + + if (nread == -1) + atf_tc_fail("read() failed"); + + if (nread != nwritten) + atf_tc_fail("too short read"); + + if (docheck != 0 && memcmp(backup, buf + page, nread) != 0) + atf_tc_fail("data mismatch"); + + ATF_REQUIRE(close(fds[0]) == 0); + ATF_REQUIRE(close(fds[1]) == 0); +} + +static void +map_sighandler(int signo) +{ + _exit(signo); +} + +ATF_TC(mmap_block); +ATF_TC_HEAD(mmap_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) with a block device"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mmap_block, tc) +{ + static const int mib[] = { CTL_HW, HW_DISKNAMES }; + static const unsigned int miblen = __arraycount(mib); + char *map, *dk, *drives, dev[PATH_MAX]; + size_t len; + int fd = -1; + + atf_tc_skip("The test case causes a panic (PR kern/38889, kern/46592)"); + + ATF_REQUIRE(sysctl(mib, miblen, NULL, &len, NULL, 0) == 0); + drives = malloc(len); + ATF_REQUIRE(drives != NULL); + ATF_REQUIRE(sysctl(mib, miblen, drives, &len, NULL, 0) == 0); + for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) { + sprintf(dev, _PATH_DEV "%s%c", dk, 'a'+RAW_PART); + fprintf(stderr, "trying: %s\n", dev); + + if ((fd = open(dev, O_RDONLY)) >= 0) { + (void)fprintf(stderr, "using %s\n", dev); + break; + } + } + free(drives); + + if (fd < 0) + atf_tc_skip("failed to find suitable block device"); + + map = mmap(NULL, 4096, PROT_READ, MAP_FILE, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + (void)fprintf(stderr, "first byte %x\n", *map); + ATF_REQUIRE(close(fd) == 0); + (void)fprintf(stderr, "first byte %x\n", *map); + + ATF_REQUIRE(munmap(map, 4096) == 0); +} + +ATF_TC(mmap_err); +ATF_TC_HEAD(mmap_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of mmap(2)"); +} + +ATF_TC_BODY(mmap_err, tc) +{ + size_t addr = SIZE_MAX; + void *map; + + errno = 0; + map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, -1, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EBADF); + + errno = 0; + map = mmap(&addr, page, PROT_READ, MAP_FIXED|MAP_PRIVATE, -1, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + map = mmap(NULL, page, PROT_READ, MAP_ANON|MAP_PRIVATE, INT_MAX, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC_WITH_CLEANUP(mmap_loan); +ATF_TC_HEAD(mmap_loan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test uvm page loanout with mmap(2)"); +} + +ATF_TC_BODY(mmap_loan, tc) +{ + char buf[BUFSIZE]; + char *vp, *vp2; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + (void)write(fd, buf, sizeof(buf)); + + vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_PRIVATE, fd, 0); + + ATF_REQUIRE(vp != MAP_FAILED); + + vp2 = vp; + + testloan(vp, vp2, 'A', 0); + testloan(vp, vp2, 'B', 1); + + ATF_REQUIRE(munmap(vp, BUFSIZE) == 0); + + vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + + vp2 = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + + ATF_REQUIRE(vp != MAP_FAILED); + ATF_REQUIRE(vp2 != MAP_FAILED); + + testloan(vp, vp2, 'E', 1); + + ATF_REQUIRE(munmap(vp, BUFSIZE) == 0); + ATF_REQUIRE(munmap(vp2, BUFSIZE) == 0); +} + +ATF_TC_CLEANUP(mmap_loan, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mmap_prot_1); +ATF_TC_HEAD(mmap_prot_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #1"); +} + +ATF_TC_BODY(mmap_prot_1, tc) +{ + void *map; + int fd; + + /* + * Open a file write-only and try to + * map it read-only. This should fail. + */ + fd = open(path, O_WRONLY | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "XXX", 3) == 3); + + map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); + map_check(map, 1); + + map = mmap(NULL, 3, PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0); + map_check(map, 0); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_prot_1, tc) +{ + (void)unlink(path); +} + +ATF_TC(mmap_prot_2); +ATF_TC_HEAD(mmap_prot_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #2"); +} + +ATF_TC_BODY(mmap_prot_2, tc) +{ + char buf[2]; + void *map; + pid_t pid; + int sta; + + /* + * Make a PROT_NONE mapping and try to access it. + * If we catch a SIGSEGV, all works as expected. + */ + map = mmap(NULL, page, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TC_WITH_CLEANUP(mmap_prot_3); +ATF_TC_HEAD(mmap_prot_3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #3"); +} + +ATF_TC_BODY(mmap_prot_3, tc) +{ + char buf[2]; + int fd, sta; + void *map; + pid_t pid; + + /* + * Open a file, change the permissions + * to read-only, and try to map it as + * PROT_NONE. This should succeed, but + * the access should generate SIGSEGV. + */ + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "XXX", 3) == 3); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(chmod(path, 0444) == 0); + + fd = open(path, O_RDONLY); + ATF_REQUIRE(fd != -1); + + map = mmap(NULL, 3, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + pid = fork(); + + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, 3) == 0); +} + +ATF_TC_CLEANUP(mmap_prot_3, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mmap_truncate); +ATF_TC_HEAD(mmap_truncate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) and ftruncate(2)"); +} + +ATF_TC_BODY(mmap_truncate, tc) +{ + char *map; + long i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + /* + * See that ftruncate(2) works + * while the file is mapped. + */ + ATF_REQUIRE(ftruncate(fd, page) == 0); + + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE, + fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + for (i = 0; i < page; i++) + map[i] = 'x'; + + ATF_REQUIRE(ftruncate(fd, 0) == 0); + ATF_REQUIRE(ftruncate(fd, page / 8) == 0); + ATF_REQUIRE(ftruncate(fd, page / 4) == 0); + ATF_REQUIRE(ftruncate(fd, page / 2) == 0); + ATF_REQUIRE(ftruncate(fd, page / 12) == 0); + ATF_REQUIRE(ftruncate(fd, page / 64) == 0); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_truncate, tc) +{ + (void)unlink(path); +} + +ATF_TC(mmap_va0); +ATF_TC_HEAD(mmap_va0, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) and vm.user_va0_disable"); +} + +ATF_TC_BODY(mmap_va0, tc) +{ + int flags = MAP_ANON | MAP_FIXED | MAP_PRIVATE; + size_t len = sizeof(int); + void *map; + int val; + + /* + * Make an anonymous fixed mapping at zero address. If the address + * is restricted as noted in security(7), the syscall should fail. + */ + if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0) + atf_tc_fail("failed to read vm.user_va0_disable"); + + map = mmap(NULL, page, PROT_EXEC, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_READ, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_WRITE, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_READ|PROT_WRITE, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_EXEC|PROT_READ|PROT_WRITE, flags, -1, 0); + map_check(map, val); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mmap_block); + ATF_TP_ADD_TC(tp, mmap_err); + ATF_TP_ADD_TC(tp, mmap_loan); + ATF_TP_ADD_TC(tp, mmap_prot_1); + ATF_TP_ADD_TC(tp, mmap_prot_2); + ATF_TP_ADD_TC(tp, mmap_prot_3); + ATF_TP_ADD_TC(tp, mmap_truncate); + ATF_TP_ADD_TC(tp, mmap_va0); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c new file mode 100644 index 0000000..c534e11 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c @@ -0,0 +1,359 @@ +/* $NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $"); + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../common/exec_prot.h" + +static long page = 0; +static int pax_global = -1; +static int pax_enabled = -1; +static char path[] = "mmap"; + +static void sighandler(int); +static bool paxinit(void); +static bool paxset(int, int); + +static void +sighandler(int signo) +{ + _exit(signo); +} + +static bool +paxinit(void) +{ + size_t len = sizeof(int); + int rv; + + rv = sysctlbyname("security.pax.mprotect.global", + &pax_global, &len, NULL, 0); + + if (rv != 0) + return false; + + rv = sysctlbyname("security.pax.mprotect.enabled", + &pax_enabled, &len, NULL, 0); + + if (rv != 0) + return false; + + return paxset(1, 1); +} + +static bool +paxset(int global, int enabled) +{ + size_t len = sizeof(int); + int rv; + + rv = sysctlbyname("security.pax.mprotect.global", + NULL, NULL, &global, len); + + if (rv != 0) + return false; + + rv = sysctlbyname("security.pax.mprotect.enabled", + NULL, NULL, &enabled, len); + + if (rv != 0) + return false; + + return true; +} + + +ATF_TC_WITH_CLEANUP(mprotect_access); +ATF_TC_HEAD(mprotect_access, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test for EACCES from mprotect(2)"); +} + +ATF_TC_BODY(mprotect_access, tc) +{ + int prot[2] = { PROT_NONE, PROT_READ }; + void *map; + size_t i; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + /* + * The call should fail with EACCES if we try to mark + * a PROT_NONE or PROT_READ file/section as PROT_WRITE. + */ + for (i = 0; i < __arraycount(prot); i++) { + + map = mmap(NULL, page, prot[i], MAP_SHARED, fd, 0); + + if (map == MAP_FAILED) + continue; + + errno = 0; + + ATF_REQUIRE(mprotect(map, page, PROT_WRITE) != 0); + ATF_REQUIRE(errno == EACCES); + ATF_REQUIRE(munmap(map, page) == 0); + } + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mprotect_access, tc) +{ + (void)unlink(path); +} + +ATF_TC(mprotect_err); +ATF_TC_HEAD(mprotect_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of mprotect(2)"); +} + +ATF_TC_BODY(mprotect_err, tc) +{ + errno = 0; + + ATF_REQUIRE(mprotect((char *)-1, 1, PROT_READ) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(mprotect_exec); +ATF_TC_HEAD(mprotect_exec, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mprotect(2) executable space protections"); +} + +/* + * Trivial function -- should fit into a page + */ +ATF_TC_BODY(mprotect_exec, tc) +{ + pid_t pid; + void *map; + int sta, xp_support; + + xp_support = exec_prot_support(); + + switch (xp_support) { + case NOTIMPL: + atf_tc_skip( + "Execute protection callback check not implemented"); + break; + case NO_XP: + atf_tc_skip( + "Host does not support executable space protection"); + break; + case PARTIAL_XP: case PERPAGE_XP: default: + break; + } + + /* + * Map a page read/write and copy a trivial assembly function inside. + * We will then change the mapping rights: + * - first by setting the execution right, and check that we can + * call the code found in the allocated page. + * - second by removing the execution right. This should generate + * a SIGSEGV on architectures that can enforce --x permissions. + */ + + map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + memcpy(map, (void *)return_one, + (uintptr_t)return_one_end - (uintptr_t)return_one); + + /* give r-x rights then call code in page */ + ATF_REQUIRE(mprotect(map, page, PROT_EXEC|PROT_READ) == 0); + ATF_REQUIRE(((int (*)(void))map)() == 1); + + /* remove --x right */ + ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); + ATF_CHECK(((int (*)(void))map)() == 1); + _exit(0); + } + + (void)wait(&sta); + + ATF_REQUIRE(munmap(map, page) == 0); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + + switch (xp_support) { + case PARTIAL_XP: + /* Partial protection might fail; skip the test when it does */ + if (WEXITSTATUS(sta) != SIGSEGV) { + atf_tc_skip("Host only supports " + "partial executable space protection"); + } + break; + case PERPAGE_XP: default: + /* Per-page --x protection should not fail */ + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + break; + } +} + +ATF_TC(mprotect_pax); +ATF_TC_HEAD(mprotect_pax, tc) +{ + atf_tc_set_md_var(tc, "descr", "PaX restrictions and mprotect(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mprotect_pax, tc) +{ + const int prot[4] = { PROT_NONE, PROT_READ, PROT_WRITE }; + const char *str = NULL; + void *map; + size_t i; + int rv; + + if (paxinit() != true) + return; + + /* + * As noted in the original PaX documentation [1], + * the following restrictions should apply: + * + * (1) creating executable anonymous mappings + * + * (2) creating executable/writable file mappings + * + * (3) making a non-executable mapping executable + * + * (4) making an executable/read-only file mapping + * writable except for performing relocations + * on an ET_DYN ELF file (non-PIC shared library) + * + * The following will test only the case (3). + * + * [1] http://pax.grsecurity.net/docs/mprotect.txt + * + * (Sun Apr 3 11:06:53 EEST 2011.) + */ + for (i = 0; i < __arraycount(prot); i++) { + + map = mmap(NULL, page, prot[i], MAP_ANON, -1, 0); + + if (map == MAP_FAILED) + continue; + + rv = mprotect(map, 1, prot[i] | PROT_EXEC); + + (void)munmap(map, page); + + if (rv == 0) { + str = "non-executable mapping made executable"; + goto out; + } + } + +out: + if (pax_global != -1 && pax_enabled != -1) + (void)paxset(pax_global, pax_enabled); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(mprotect_write); +ATF_TC_HEAD(mprotect_write, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mprotect(2) write protections"); +} + +ATF_TC_BODY(mprotect_write, tc) +{ + pid_t pid; + void *map; + int sta; + + /* + * Map a page read/write, change the protection + * to read-only with mprotect(2), and try to write + * to the page. This should generate a SIGSEGV. + */ + map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + ATF_REQUIRE(strlcpy(map, "XXX", 3) == 3); + ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(map, "XXX", 3) == 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mprotect_access); + ATF_TP_ADD_TC(tp, mprotect_err); + ATF_TP_ADD_TC(tp, mprotect_exec); + ATF_TP_ADD_TC(tp, mprotect_pax); + ATF_TP_ADD_TC(tp, mprotect_write); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c new file mode 100644 index 0000000..1e74d60 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c @@ -0,0 +1,358 @@ +/* $NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#define MSG_KEY 12345689 +#define MSG_MTYPE_1 0x41 + +struct msg { + long mtype; + char buf[3]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgctl_err); +ATF_TC_HEAD(msgctl_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)"); +} + +ATF_TC_BODY(msgctl_err, tc) +{ + const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID }; + struct msqid_ds msgds; + size_t i; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1); + + for (i = 0; i < __arraycount(cmd); i++) { + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_err, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_perm); +ATF_TC_HEAD(msgctl_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgctl_perm, tc) +{ + struct msqid_ds msgds; + struct passwd *pw; + pid_t pid; + int sta; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EX_OSERR); + + msgds.msg_perm.uid = getuid(); + msgds.msg_perm.gid = getgid(); + + errno = 0; + + if (msgctl(id, IPC_SET, &msgds) == 0) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + if (msgctl(id, IPC_STAT, &msgds) != 0) + _exit(EX_OSERR); + + msgds.msg_qbytes = 1; + + if (msgctl(id, IPC_SET, &msgds) == 0) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0) { + + if (WEXITSTATUS(sta) == EX_OSERR) + atf_tc_fail("system call failed"); + + if (WEXITSTATUS(sta) == EXIT_FAILURE) + atf_tc_fail("UID %u manipulated root's " + "message queue", pw->pw_uid); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_perm, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_pid); +ATF_TC_HEAD(msgctl_pid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated"); +} + +ATF_TC_BODY(msgctl_pid, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds msgds; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + if (pid != msgds.msg_lspid) + atf_tc_fail("the PID of last msgsnd(2) was not updated"); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)msgrcv(id, &msg, + sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + if (pid != msgds.msg_lrpid) + atf_tc_fail("the PID of last msgrcv(2) was not updated"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_pid, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_set); +ATF_TC_HEAD(msgctl_set, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgctl_set, tc) +{ + struct msqid_ds msgds; + struct passwd *pw; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + msgds.msg_perm.uid = pw->pw_uid; + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change the UID of message queue"); + + msgds.msg_perm.uid = getuid(); + msgds.msg_perm.gid = pw->pw_gid; + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change the GID of message queue"); + + /* + * Note: setting the qbytes to zero fails even as root. + */ + msgds.msg_qbytes = 1; + msgds.msg_perm.gid = getgid(); + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change qbytes of message queue"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_set, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_time); +ATF_TC_HEAD(msgctl_time, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that access times are updated"); +} + +ATF_TC_BODY(msgctl_time, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds msgds; + time_t t; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + t = time(NULL); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + (void)msgctl(id, IPC_STAT, &msgds); + + if (llabs(t - msgds.msg_stime) > 1) + atf_tc_fail("time of last msgsnd(2) was not updated"); + + if (msgds.msg_rtime != 0) + atf_tc_fail("time of last msgrcv(2) was updated incorrectly"); + + t = time(NULL); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + (void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT); + (void)msgctl(id, IPC_STAT, &msgds); + + if (llabs(t - msgds.msg_rtime) > 1) + atf_tc_fail("time of last msgrcv(2) was not updated"); + + /* + * Note: this is non-zero even after the memset(3). + */ + if (msgds.msg_stime == 0) + atf_tc_fail("time of last msgsnd(2) was updated incorrectly"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_time, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgctl_err); + ATF_TP_ADD_TC(tp, msgctl_perm); + ATF_TP_ADD_TC(tp, msgctl_pid); + ATF_TP_ADD_TC(tp, msgctl_set); + ATF_TP_ADD_TC(tp, msgctl_time); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgget.c b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c new file mode 100644 index 0000000..e26cde2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c @@ -0,0 +1,292 @@ +/* $NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#define MSG_KEY 12345689 + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgget_excl); +ATF_TC_HEAD(msgget_excl, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgget(2) with IPC_EXCL"); +} + +ATF_TC_BODY(msgget_excl, tc) +{ + int id; + + /* + * Create a message queue and re-open it with + * O_CREAT and IPC_EXCL set. This should fail. + */ + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + if (id < 0) + atf_tc_fail("failed to create message queue"); + + errno = 0; + + if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) != -1) + atf_tc_fail("msgget(2) failed for IPC_EXCL"); + + ATF_REQUIRE(errno == EEXIST); + + /* + * However, the same call should succeed + * when IPC_EXCL is not set in the flags. + */ + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + if (id < 0) + atf_tc_fail("msgget(2) failed to re-open"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_excl, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgget_exit); +ATF_TC_HEAD(msgget_exit, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that XSI message queues are " + "not removed when the process exits"); +} + +ATF_TC_BODY(msgget_exit, tc) +{ + int id, sta; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) == -1) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create message queue"); + + id = msgget(MSG_KEY, 0); + + if (id == -1) + atf_tc_fail("message queue was removed on process exit"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_exit, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgget_init); +ATF_TC_HEAD(msgget_init, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that msgget(2) initializes data structures properly"); +} + +ATF_TC_BODY(msgget_init, tc) +{ + const uid_t uid = geteuid(); + const gid_t gid = getegid(); + struct msqid_ds msgds; + time_t t; + int id; + + (void)memset(&msgds, 0x9, sizeof(struct msqid_ds)); + + t = time(NULL); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id !=-1); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + ATF_CHECK(msgds.msg_qnum == 0); + ATF_CHECK(msgds.msg_lspid == 0); + ATF_CHECK(msgds.msg_lrpid == 0); + ATF_CHECK(msgds.msg_rtime == 0); + ATF_CHECK(msgds.msg_stime == 0); + ATF_CHECK(msgds.msg_perm.uid == uid); + ATF_CHECK(msgds.msg_perm.gid == gid); + ATF_CHECK(msgds.msg_perm.cuid == uid); + ATF_CHECK(msgds.msg_perm.cgid == gid); + ATF_CHECK(msgds.msg_perm.mode == 0600); + + if (llabs(t - msgds.msg_ctime) > 5) + atf_tc_fail("msgget(2) initialized current time incorrectly"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_init, tc) +{ + clean(); +} + +ATF_TC(msgget_limit); +ATF_TC_HEAD(msgget_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgget(2) against system limits"); +} + +ATF_TC_BODY(msgget_limit, tc) +{ + size_t len = sizeof(int); + bool fail = false; + int i, lim = 0; + int *buf; + + if (sysctlbyname("kern.ipc.msgmni", &lim, &len, NULL, 0) != 0) + atf_tc_skip("failed to read kern.ipc.msgmni sysctl"); + + buf = calloc(lim + 1, sizeof(*buf)); + ATF_REQUIRE(buf != NULL); + + for (i = 0; i < lim; i++) { + + buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600); + + (void)fprintf(stderr, "key[%d] = %d\n", i, buf[i]); + + /* + * This test only works when there are zero existing + * message queues. Thus, bypass the unit test when + * this precondition is not met, for reason or another. + */ + if (buf[i] == -1) + goto out; + } + + i++; + errno = 0; + + buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600); + + if (buf[i] != -1 || errno != ENOSPC) + fail = true; + +out: /* Remember to clean-up. */ + for (i = 0; i < lim; i++) + (void)msgctl(buf[i], IPC_RMID, 0); + + free(buf); + + if (fail != false) + atf_tc_fail("msgget(2) opened more than %d queues", lim); +} + +ATF_TC_WITH_CLEANUP(msgget_mode); +ATF_TC_HEAD(msgget_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test different modes with msgget(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgget_mode, tc) +{ + static const mode_t mode[] = { + S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, + S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH + }; + + struct msqid_ds msgds; + size_t i; + int id; + + for (i = 0; i < __arraycount(mode); i++) { + + (void)fprintf(stderr, "testing mode %d\n", mode[i]); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + id = msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | (int)mode[i]); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + ATF_REQUIRE(msgds.msg_perm.mode == mode[i]); + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); + } +} + +ATF_TC_CLEANUP(msgget_mode, tc) +{ + clean(); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgget_excl); + ATF_TP_ADD_TC(tp, msgget_exit); + ATF_TP_ADD_TC(tp, msgget_init); + ATF_TP_ADD_TC(tp, msgget_limit); + ATF_TP_ADD_TC(tp, msgget_mode); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c new file mode 100644 index 0000000..e32be26 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c @@ -0,0 +1,342 @@ +/* $NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#define MSG_KEY 1234 +#define MSG_MTYPE_1 0x41 +#define MSG_MTYPE_2 0x42 +#define MSG_MTYPE_3 0x43 +#define MSG_LEN 3 + +struct msg { + long mtype; + char buf[MSG_LEN]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgrcv_basic); +ATF_TC_HEAD(msgrcv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_basic, tc) +{ + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msg msg2 = { MSG_MTYPE_1, { 'x', 'y', 'z' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + ATF_CHECK(msg1.buf[2] == msg2.buf[2]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_basic, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_block); +ATF_TC_HEAD(msgrcv_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that msgrcv(2) blocks"); +} + +ATF_TC_BODY(msgrcv_block, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, 0) < 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + /* + * Below msgsnd(2) should unblock the child, + * and hence kill(2) should fail with ESRCH. + */ + (void)sleep(1); + (void)msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT); + (void)sleep(1); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0) + atf_tc_fail("msgrcv(2) did not block"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_block, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_err); +ATF_TC_HEAD(msgrcv_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_err, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, r = 0; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(ENOMSG, msgrcv(id, &msg, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, msgrcv(id, (void *)-1, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg, + SSIZE_MAX, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + + errno = 0; + + ATF_REQUIRE_ERRNO(E2BIG, msgrcv(id, &r, + MSG_LEN - 1, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_err, tc) +{ + clean(); +} + + +ATF_TC_WITH_CLEANUP(msgrcv_mtype); +ATF_TC_HEAD(msgrcv_mtype, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test message types with msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_mtype, tc) +{ + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msg msg2 = { MSG_MTYPE_3, { 'x', 'y', 'z' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_2, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] != msg2.buf[0]); /* Different mtype. */ + ATF_CHECK(msg1.buf[1] != msg2.buf[1]); + ATF_CHECK(msg1.buf[2] != msg2.buf[2]); + + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); /* Same mtype. */ + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + ATF_CHECK(msg1.buf[2] == msg2.buf[2]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_mtype, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_nonblock); +ATF_TC_HEAD(msgrcv_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with IPC_NOWAIT"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgrcv_nonblock, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + const ssize_t n = 10; + int id, sta; + ssize_t i; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + for (i = 0; i < n; i++) { + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + } + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + while (i != 0) { + + if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, + IPC_NOWAIT) == -1) + _exit(EXIT_FAILURE); + + i--; + } + + _exit(EXIT_SUCCESS); + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL) + atf_tc_fail("msgrcv(2) blocked with IPC_NOWAIT"); + + if (WIFEXITED(sta) == 0 && WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("msgrcv(2) failed"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_nonblock, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_truncate); +ATF_TC_HEAD(msgrcv_truncate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with MSG_NOERROR"); +} + +ATF_TC_BODY(msgrcv_truncate, tc) +{ +#define MSG_SMALLLEN 2 + struct msgsmall { + long mtype; + char buf[MSG_SMALLLEN]; + }; + + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msgsmall msg2 = { MSG_MTYPE_1, { 'x', 'y' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_SMALLLEN, + MSG_MTYPE_1, IPC_NOWAIT | MSG_NOERROR); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_truncate, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgrcv_basic); + ATF_TP_ADD_TC(tp, msgrcv_block); + ATF_TP_ADD_TC(tp, msgrcv_err); + ATF_TP_ADD_TC(tp, msgrcv_mtype); + ATF_TP_ADD_TC(tp, msgrcv_nonblock); + ATF_TP_ADD_TC(tp, msgrcv_truncate); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c new file mode 100644 index 0000000..5493789 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c @@ -0,0 +1,338 @@ +/* $NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#define MSG_KEY 1234 +#define MSG_MTYPE_1 0x41 +#define MSG_MTYPE_2 0x42 +#define MSG_MTYPE_3 0x43 + +struct msg { + long mtype; + char buf[3]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgsnd_block); +ATF_TC_HEAD(msgsnd_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that msgsnd(2) blocks"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_block, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Enqueue messages until some limit (e.g. the maximum + * number of messages in the queue or the maximum number + * of bytes in the queue) is reached. After this the call + * should block when the IPC_NOWAIT is not set. + */ + for (;;) { + + if (msgsnd(id, &msg, sizeof(struct msg), 0) < 0) + _exit(EXIT_FAILURE); + } + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) != 0 || WIFSIGNALED(sta) == 0) + atf_tc_fail("msgsnd(2) did not block"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_block, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_count); +ATF_TC_HEAD(msgsnd_count, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that msgsnd(2) increments the amount of " + "message in the queue, as given by msgctl(2)"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_count, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds ds; + size_t i = 0; + int id, rv; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + for (;;) { + + errno = 0; + rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + + if (rv == 0) { + i++; + continue; + } + + if (rv == -1 && errno == EAGAIN) + break; + + atf_tc_fail("failed to enqueue a message"); + } + + (void)memset(&ds, 0, sizeof(struct msqid_ds)); + (void)msgctl(id, IPC_STAT, &ds); + + if (ds.msg_qnum != i) + atf_tc_fail("incorrect message count"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_count, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_err); +ATF_TC_HEAD(msgsnd_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgsnd(2)"); +} + +ATF_TC_BODY(msgsnd_err, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, msgsnd(id, (void *)-1, + sizeof(struct msg), IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg, + sizeof(struct msg), IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg, + SSIZE_MAX, IPC_NOWAIT) == -1); + + errno = 0; + msg.mtype = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(id, &msg, + sizeof(struct msg), IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_err, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_nonblock); +ATF_TC_HEAD(msgsnd_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgsnd(2) with IPC_NOWAIT"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_nonblock, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, rv, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (;;) { + + errno = 0; + rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + + if (rv == -1 && errno == EAGAIN) + _exit(EXIT_SUCCESS); + } + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0) + atf_tc_fail("msgsnd(2) blocked with IPC_NOWAIT"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_nonblock, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_perm); +ATF_TC_HEAD(msgsnd_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with msgsnd(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgsnd_perm, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct passwd *pw; + int id, sta; + pid_t pid; + uid_t uid; + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + + uid = pw->pw_uid; + ATF_REQUIRE(uid != 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Try to enqueue a message to the queue + * created by root as RW for owner only. + */ + if (setuid(uid) != 0) + _exit(EX_OSERR); + + id = msgget(MSG_KEY, 0); + + if (id == -1) + _exit(EX_OSERR); + + errno = 0; + + if (msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT) == 0) + _exit(EXIT_FAILURE); + + if (errno != EACCES) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (errno == EX_OSERR) + atf_tc_fail("system call failed"); + + atf_tc_fail("UID %u enqueued message to root's queue", uid); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_perm, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgsnd_block); + ATF_TP_ADD_TC(tp, msgsnd_count); + ATF_TP_ADD_TC(tp, msgsnd_err); + ATF_TP_ADD_TC(tp, msgsnd_nonblock); + ATF_TP_ADD_TC(tp, msgsnd_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msync.c b/contrib/netbsd-tests/lib/libc/sys/t_msync.c new file mode 100644 index 0000000..9743300 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msync.c @@ -0,0 +1,237 @@ +/* $NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $"); + +#include <sys/mman.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static long page = 0; +static const off_t off = 512; +static const char path[] = "msync"; + +static const char *msync_sync(const char *, int); + +static const char * +msync_sync(const char *garbage, int flags) +{ + char *buf, *map = MAP_FAILED; + const char *str = NULL; + size_t i, len; + ssize_t tot; + int fd, rv; + + /* + * Create a temporary file, write + * one page to it, and map the file. + */ + buf = malloc(page); + + if (buf == NULL) + return NULL; + + for (i = 0; i < (size_t)page; i++) + buf[i] = 'x'; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) { + str = "failed to open"; + goto out; + } + + tot = 0; + + while (tot < page) { + + rv = write(fd, buf, sizeof(buf)); + + if (rv < 0) { + str = "failed to write"; + goto out; + } + + tot += rv; + } + + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE, + fd, 0); + + if (map == MAP_FAILED) { + str = "failed to map"; + goto out; + } + + /* + * Seek to an arbitrary offset and + * write garbage to this position. + */ + if (lseek(fd, off, SEEK_SET) != off) { + str = "failed to seek"; + goto out; + } + + len = strlen(garbage); + rv = write(fd, garbage, len); + + if (rv != (ssize_t)len) { + str = "failed to write garbage"; + goto out; + } + + /* + * Synchronize the mapping and verify + * that garbage is at the given offset. + */ + if (msync(map, page, flags) != 0) { + str = "failed to msync"; + goto out; + } + + if (memcmp(map + off, garbage, len) != 0) { + str = "msync did not synchronize"; + goto out; + } + +out: + free(buf); + + (void)close(fd); + (void)unlink(path); + + if (map != MAP_FAILED) + (void)munmap(map, page); + + return str; +} + +ATF_TC(msync_async); +ATF_TC_HEAD(msync_async, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_ASYNC"); +} + +ATF_TC_BODY(msync_async, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_ASYNC); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(msync_err); +ATF_TC_HEAD(msync_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in msync(2)"); +} + +ATF_TC_BODY(msync_err, tc) +{ + + char *map = MAP_FAILED; + + /* + * Test that invalid flags error out. + */ + ATF_REQUIRE(msync_sync("error", -1) != NULL); + ATF_REQUIRE(msync_sync("error", INT_MAX) != NULL); + + errno = 0; + + /* + * Map a page and then unmap to get an unmapped address. + */ + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, + -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + (void)munmap(map, page); + + ATF_REQUIRE(msync(map, page, MS_SYNC) != 0); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TC(msync_invalidate); +ATF_TC_HEAD(msync_invalidate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_INVALIDATE"); +} + +ATF_TC_BODY(msync_invalidate, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_INVALIDATE); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(msync_sync); +ATF_TC_HEAD(msync_sync, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_SYNC"); +} + +ATF_TC_BODY(msync_sync, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_SYNC); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + + ATF_REQUIRE(page >= 0); + ATF_REQUIRE(page > off); + + ATF_TP_ADD_TC(tp, msync_async); + ATF_TP_ADD_TC(tp, msync_err); + ATF_TP_ADD_TC(tp, msync_invalidate); + ATF_TP_ADD_TC(tp, msync_sync); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c new file mode 100644 index 0000000..317d667 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c @@ -0,0 +1,187 @@ +/* $NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $"); + +#include <sys/time.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <time.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> + +static void +handler(int signo) +{ + /* Nothing. */ +} + +ATF_TC(nanosleep_basic); +ATF_TC_HEAD(nanosleep_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that nanosleep(2) works"); +} + +ATF_TC_BODY(nanosleep_basic, tc) +{ + static const size_t maxiter = 10; + struct timespec ts1, ts2, tsn; + size_t i; + + for (i = 1; i < maxiter; i++) { + + tsn.tv_sec = 0; + tsn.tv_nsec = i; + + (void)memset(&ts1, 0, sizeof(struct timespec)); + (void)memset(&ts2, 0, sizeof(struct timespec)); + + ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts1) == 0); + ATF_REQUIRE(nanosleep(&tsn, NULL) == 0); + ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts2) == 0); + + /* + * Verify that we slept at least one nanosecond. + */ + if (timespeccmp(&ts2, &ts1, <=) != 0) { + + (void)fprintf(stderr, + "sleep time:: sec %llu, nsec %lu\n\t\t" + "ts1: sec %llu, nsec %lu\n\t\t" + "ts2: sec %llu, nsec %lu\n", + (unsigned long long)tsn.tv_sec, tsn.tv_nsec, + (unsigned long long)ts1.tv_sec, ts1.tv_nsec, + (unsigned long long)ts2.tv_sec, ts2.tv_nsec); + + atf_tc_fail_nonfatal("inaccuracies in sleep time " + "(resolution = %lu nsec)", tsn.tv_nsec); + } + } +} + +ATF_TC(nanosleep_err); +ATF_TC_HEAD(nanosleep_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test errors from nanosleep(2) (PR bin/14558)"); +} + +ATF_TC_BODY(nanosleep_err, tc) +{ + struct timespec ts; + + ts.tv_sec = 1; + ts.tv_nsec = -1; + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1); + + ts.tv_sec = 1; + ts.tv_nsec = 1000000000; + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1); + + ts.tv_sec = -1; + ts.tv_nsec = 0; + errno = 0; + ATF_REQUIRE_ERRNO(0, nanosleep(&ts, NULL) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, nanosleep((void *)-1, NULL) == -1); +} + +ATF_TC(nanosleep_sig); +ATF_TC_HEAD(nanosleep_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test signal for nanosleep(2)"); +} + +ATF_TC_BODY(nanosleep_sig, tc) +{ + struct timespec tsn, tsr; + pid_t pid; + int sta; + + /* + * Test that a signal interrupts nanosleep(2). + * + * (In which case the return value should be -1 and the + * second parameter should contain the unslept time.) + */ + pid = fork(); + + ATF_REQUIRE(pid >= 0); + ATF_REQUIRE(signal(SIGINT, handler) == 0); + + if (pid == 0) { + + tsn.tv_sec = 10; + tsn.tv_nsec = 0; + + tsr.tv_sec = 0; + tsr.tv_nsec = 0; + + errno = 0; + + if (nanosleep(&tsn, &tsr) != -1) + _exit(EXIT_FAILURE); + + if (errno != EINTR) + _exit(EXIT_FAILURE); + + if (tsr.tv_sec == 0 && tsr.tv_nsec == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)kill(pid, SIGINT); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("signal did not interrupt nanosleep(2)"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nanosleep_basic); + ATF_TP_ADD_TC(tp, nanosleep_err); + ATF_TP_ADD_TC(tp, nanosleep_sig); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c new file mode 100644 index 0000000..b30b94d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_pipe.c,v 1.3 2011/10/31 15:41:31 christos Exp $ */ + +/*- + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pipe.c,v 1.3 2011/10/31 15:41:31 christos Exp $"); + +#include <sys/types.h> +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <poll.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +static pid_t pid; +static int nsiginfo = 0; + +/* + * This is used for both parent and child. Handle parent's SIGALRM, + * the childs SIGINFO doesn't need anything. + */ +static void +sighand(int sig) +{ + if (sig == SIGALRM) { + kill(pid, SIGINFO); + } + if (sig == SIGINFO) { + nsiginfo++; + } +} + +ATF_TC(pipe_restart); +ATF_TC_HEAD(pipe_restart, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that writing to pipe " + "works correctly after being interrupted and restarted " + "(kern/14087)"); +} + +ATF_TC_BODY(pipe_restart, tc) +{ + int pp[2], st; + ssize_t sz, todo, done; + char *f; + sigset_t asigset, osigset, emptysigset; + + /* Initialise signal masks */ + RL(sigemptyset(&emptysigset)); + RL(sigemptyset(&asigset)); + RL(sigaddset(&asigset, SIGINFO)); + + /* Register signal handlers for both read and writer */ + REQUIRE_LIBC(signal(SIGINFO, sighand), SIG_ERR); + REQUIRE_LIBC(signal(SIGALRM, sighand), SIG_ERR); + + todo = 2 * 1024 * 1024; + REQUIRE_LIBC(f = malloc(todo), NULL); + + RL(pipe(pp)); + + RL(pid = fork()); + if (pid == 0) { + /* child */ + RL(close(pp[1])); + + /* Do inital write. This should succeed, make + * the other side do partial write and wait for us to pick + * rest up. + */ + RL(done = read(pp[0], f, 128 * 1024)); + + /* Wait until parent is alarmed and awakens us */ + RL(sigprocmask(SIG_BLOCK, &asigset, &osigset)); + while (nsiginfo == 0) { + if (sigsuspend(&emptysigset) != -1 || errno != EINTR) + atf_tc_fail("sigsuspend(&emptysigset): %s", + strerror(errno)); + } + RL(sigprocmask(SIG_SETMASK, &osigset, NULL)); + + /* Read all what parent wants to give us */ + while((sz = read(pp[0], f, 1024 * 1024)) > 0) + done += sz; + + /* + * Exit with 1 if number of bytes read doesn't match + * number of expected bytes + */ + printf("Read: %#zx\n", (size_t)done); + printf("Expected: %#zx\n", (size_t)todo); + + exit(done != todo); + + /* NOTREACHED */ + } else { + RL(close(pp[0])); + + /* + * Arrange for alarm after two seconds. Since we have + * handler setup for SIGARLM, the write(2) call should + * be restarted internally by kernel. + */ + (void)alarm(2); + + /* We write exactly 'todo' bytes. The very first write(2) + * should partially succeed, block and eventually + * be restarted by kernel + */ + while(todo > 0 && ((sz = write(pp[1], f, todo)) > 0)) + todo -= sz; + + /* Close the pipe, so that child would stop reading */ + RL(close(pp[1])); + + /* And pickup child's exit status */ + RL(waitpid(pid, &st, 0)); + + ATF_REQUIRE_EQ(WEXITSTATUS(st), 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pipe_restart); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c new file mode 100644 index 0000000..51f2240 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c @@ -0,0 +1,188 @@ +/* $NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $"); + +#include <atf-c.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/resource.h> + +static void +run(int flags) +{ + int fd[2], i; + + while ((i = open("/", O_RDONLY)) < 3) + ATF_REQUIRE(i != -1); + + ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1); + + ATF_REQUIRE(pipe2(fd, flags) == 0); + + ATF_REQUIRE(fd[0] == 3); + ATF_REQUIRE(fd[1] == 4); + + if (flags & O_CLOEXEC) { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0); + } + + if (flags & O_NONBLOCK) { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0); + } + + if (flags & O_NOSIGPIPE) { + ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) != 0); + ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) != 0); + } else { + ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) == 0); + ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) == 0); + } + + ATF_REQUIRE(close(fd[0]) != -1); + ATF_REQUIRE(close(fd[1]) != -1); +} + +ATF_TC(pipe2_basic); +ATF_TC_HEAD(pipe2_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_basic, tc) +{ + run(0); +} + +ATF_TC(pipe2_consume); +ATF_TC_HEAD(pipe2_consume, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that consuming file descriptors " + "with pipe2(2) does not crash the system (PR kern/46457)"); +} + +ATF_TC_BODY(pipe2_consume, tc) +{ + struct rlimit rl; + int err, filedes[2]; + + err = fcntl(4, F_CLOSEM); + ATF_REQUIRE(err == 0); + + err = getrlimit(RLIMIT_NOFILE, &rl); + ATF_REQUIRE(err == 0); + /* + * The heart of this test is to run against the number of open + * file descriptor limit in the middle of a pipe2() call - i.e. + * before the call only a single descriptor may be openend. + */ + rl.rlim_cur = 4; + err = setrlimit(RLIMIT_NOFILE, &rl); + ATF_REQUIRE(err == 0); + + err = pipe2(filedes, O_CLOEXEC); + ATF_REQUIRE(err == -1); +} + +ATF_TC(pipe2_nonblock); +ATF_TC_HEAD(pipe2_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "A non-blocking test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_nonblock, tc) +{ + run(O_NONBLOCK); +} + +ATF_TC(pipe2_cloexec); +ATF_TC_HEAD(pipe2_cloexec, tc) +{ + atf_tc_set_md_var(tc, "descr", "A close-on-exec test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_cloexec, tc) +{ + run(O_CLOEXEC); +} + +ATF_TC(pipe2_nosigpipe); +ATF_TC_HEAD(pipe2_nosigpipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "A no sigpipe test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_nosigpipe, tc) +{ + run(O_NOSIGPIPE); +} + +ATF_TC(pipe2_einval); +ATF_TC_HEAD(pipe2_einval, tc) +{ + atf_tc_set_md_var(tc, "descr", "A error check of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_einval, tc) +{ + int fd[2]; + ATF_REQUIRE_ERRNO(EINVAL, pipe2(fd, O_ASYNC) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pipe2_basic); + ATF_TP_ADD_TC(tp, pipe2_consume); + ATF_TP_ADD_TC(tp, pipe2_nonblock); + ATF_TP_ADD_TC(tp, pipe2_cloexec); + ATF_TP_ADD_TC(tp, pipe2_nosigpipe); + ATF_TP_ADD_TC(tp, pipe2_einval); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_poll.c b/contrib/netbsd-tests/lib/libc/sys/t_poll.c new file mode 100644 index 0000000..7a786d2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_poll.c @@ -0,0 +1,392 @@ +/* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/time.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <poll.h> +#include <stdio.h> +#include <signal.h> +#include <unistd.h> + +static int desc; + +static void +child1(void) +{ + struct pollfd pfd; + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)poll(&pfd, 1, 2000); + (void)printf("child1 exit\n"); +} + +static void +child2(void) +{ + struct pollfd pfd; + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)sleep(1); + (void)poll(&pfd, 1, INFTIM); + (void)printf("child2 exit\n"); +} + +static void +child3(void) +{ + struct pollfd pfd; + + (void)sleep(5); + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)poll(&pfd, 1, INFTIM); + (void)printf("child3 exit\n"); +} + +ATF_TC(poll_3way); +ATF_TC_HEAD(poll_3way, tc) +{ + atf_tc_set_md_var(tc, "timeout", "15"); + atf_tc_set_md_var(tc, "descr", + "Check for 3-way collision for descriptor. First child comes " + "and polls on descriptor, second child comes and polls, first " + "child times out and exits, third child comes and polls. When " + "the wakeup event happens, the two remaining children should " + "both be awaken. (kern/17517)"); +} + +ATF_TC_BODY(poll_3way, tc) +{ + int pf[2]; + int status, i; + pid_t pid; + + pipe(pf); + desc = pf[0]; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child1(); + _exit(0); + /* NOTREACHED */ + } + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child2(); + _exit(0); + /* NOTREACHED */ + } + + pid = fork(); + ATF_REQUIRE( pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child3(); + _exit(0); + /* NOTREACHED */ + } + + (void)sleep(10); + + (void)printf("parent write\n"); + + ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6); + + for(i = 0; i < 3; ++i) + (void)wait(&status); + + (void)printf("parent terminated\n"); +} + +ATF_TC(poll_basic); +ATF_TC_HEAD(poll_basic, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Basis functionality test for poll(2)"); +} + +ATF_TC_BODY(poll_basic, tc) +{ + int fds[2]; + struct pollfd pfds[2]; + int ret; + + ATF_REQUIRE_EQ(pipe(fds), 0); + + pfds[0].fd = fds[0]; + pfds[0].events = POLLIN; + pfds[1].fd = fds[1]; + pfds[1].events = POLLOUT; + + /* + * Check that we get a timeout waiting for data on the read end + * of our pipe. + */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); + + /* Check that the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ + pfds[1].revents); + + /* Check that only the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + /* Write data to our pipe. */ + ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + + /* Check that both ends of our pipe are reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", + pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + ATF_REQUIRE_EQ(close(fds[0]), 0); + ATF_REQUIRE_EQ(close(fds[1]), 0); +} + +ATF_TC(poll_err); +ATF_TC_HEAD(poll_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)"); +} + +ATF_TC_BODY(poll_err, tc) +{ + struct pollfd pfd; + int fd = 0; + + pfd.fd = fd; + pfd.events = POLLIN; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1); +} + +ATF_TC(pollts_basic); +ATF_TC_HEAD(pollts_basic, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Basis functionality test for pollts(2)"); +} + +ATF_TC_BODY(pollts_basic, tc) +{ + int fds[2]; + struct pollfd pfds[2]; + struct timespec timeout; + int ret; + + ATF_REQUIRE_EQ(pipe(fds), 0); + + pfds[0].fd = fds[0]; + pfds[0].events = POLLIN; + pfds[1].fd = fds[1]; + pfds[1].events = POLLOUT; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* + * Check that we get a timeout waiting for data on the read end + * of our pipe. + */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); + + /* Check that the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ + pfds[1].revents); + + /* Check that only the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + /* Write data to our pipe. */ + ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + + /* Check that both ends of our pipe are reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", + pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + ATF_REQUIRE_EQ(close(fds[0]), 0); + ATF_REQUIRE_EQ(close(fds[1]), 0); +} + +ATF_TC(pollts_err); +ATF_TC_HEAD(pollts_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)"); +} + +ATF_TC_BODY(pollts_err, tc) +{ + struct timespec timeout; + struct pollfd pfd; + int fd = 0; + + pfd.fd = fd; + pfd.events = POLLIN; + + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1); + + timeout.tv_sec = -1; + timeout.tv_nsec = -1; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1); +} + +ATF_TC(pollts_sigmask); +ATF_TC_HEAD(pollts_sigmask, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Check that pollts(2) restores the signal mask (PR kern/44986)"); +} + +ATF_TC_BODY(pollts_sigmask, tc) +{ + int fd; + struct pollfd pfd; + struct timespec timeout; + sigset_t mask; + int ret; + + fd = open(_PATH_DEVNULL, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + pfd.fd = fd; + pfd.events = POLLIN; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* Unblock all signals. */ + ATF_REQUIRE_EQ(sigfillset(&mask), 0); + ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0); + + /* + * Check that pollts(2) immediately returns. We block *all* + * signals during pollts(2). + */ + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1, + "got: %d", ret); + + /* Check that signals are now longer blocked. */ + ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0); + ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0, + "signal mask was changed."); + + ATF_REQUIRE_EQ(close(fd), 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, poll_3way); + ATF_TP_ADD_TC(tp, poll_basic); + ATF_TP_ADD_TC(tp, poll_err); + ATF_TP_ADD_TC(tp, pollts_basic); + ATF_TP_ADD_TC(tp, pollts_err); + ATF_TP_ADD_TC(tp, pollts_sigmask); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c new file mode 100644 index 0000000..da4e746 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_posix_fadvise.c,v 1.1 2011/10/15 06:10:26 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by YAMAMOTO Takashi. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2005 YAMAMOTO Takashi, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_posix_fadvise.c,v 1.1 2011/10/15 06:10:26 jruoho Exp $"); + +#include <sys/fcntl.h> + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +ATF_TC(posix_fadvise); +ATF_TC_HEAD(posix_fadvise, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2)"); +} + +ATF_TC(posix_fadvise_reg); +ATF_TC_HEAD(posix_fadvise_reg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2) " + "for regular files"); +} + +ATF_TC_BODY(posix_fadvise, tc) +{ + int fd; + int pipe_fds[2]; + int badfd = 10; + int ret; + + RL(fd = open("/dev/null", O_RDWR)); + + (void)close(badfd); + RL(pipe(pipe_fds)); + + /* + * it's hard to check if posix_fadvise is working properly. + * only check return values here. + */ + + /* posix_fadvise shouldn't affect errno. */ + +#define CE(x, exp) \ + do { \ + int save = errno; \ + errno = 999; \ + ATF_CHECK_EQ_MSG(ret = (x), exp, "got: %d", ret); \ + ATF_CHECK_EQ_MSG(errno, 999, "got: %s", strerror(errno)); \ + errno = save; \ + } while (0); + + CE(posix_fadvise(fd, 0, 0, -1), EINVAL); + CE(posix_fadvise(pipe_fds[0], 0, 0, POSIX_FADV_NORMAL), ESPIPE); + CE(posix_fadvise(badfd, 0, 0, POSIX_FADV_NORMAL), EBADF); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NORMAL), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE), 0); +} + +ATF_TC_BODY(posix_fadvise_reg, tc) +{ + int rfd, ret; + + rump_init(); + RL(rfd = rump_sys_open("/a_file", O_CREAT, 0666)); + + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NORMAL), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_SEQUENTIAL), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_RANDOM), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_WILLNEED), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NOREUSE), 0); + + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NORMAL), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_SEQUENTIAL), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_RANDOM), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_WILLNEED), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NOREUSE), 0); + + //atf_tc_expect_signal(-1, "http://mail-index.netbsd.org/source-changes-d/2010/11/11/msg002508.html"); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_DONTNEED), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_DONTNEED), 0); +#undef CE +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, posix_fadvise); + ATF_TP_ADD_TC(tp, posix_fadvise_reg); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c new file mode 100644 index 0000000..76bc7dd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c @@ -0,0 +1,161 @@ +/* $NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jared McNeill and Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $"); + +#include <atf-c.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/wait.h> + +#include <string.h> +#include <time.h> +#include <stdint.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sched.h> + +#define BUFSIZE 65536 +#define NPKTS 50 + +#define min(a, b) ((a) < (b) ? (a) : (b)) +static int debug; + + +ATF_TC(recvmmsg_basic); +ATF_TC_HEAD(recvmmsg_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of recvmmsg(2)"); +} + +ATF_TC_BODY(recvmmsg_basic, tc) +{ + int fd[2], error, i, cnt; + uint8_t *buf; + struct mmsghdr *mmsghdr; + struct iovec *iov; + unsigned int mmsgcnt, n; + int status; + off_t off; + uint8_t DGRAM[1316] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, }; + + error = socketpair(AF_UNIX, SOCK_DGRAM, 0, fd); + ATF_REQUIRE_MSG(error != -1, "socketpair failed (%s)", strerror(errno)); + + buf = malloc(BUFSIZE); + ATF_REQUIRE_MSG(buf != NULL, "malloc failed (%s)", strerror(errno)); + + mmsgcnt = BUFSIZE / sizeof(DGRAM); + mmsghdr = malloc(sizeof(*mmsghdr) * mmsgcnt); + ATF_REQUIRE_MSG(mmsghdr != NULL, "malloc failed (%s)", strerror(errno)); + iov = malloc(sizeof(*iov) * mmsgcnt); + ATF_REQUIRE_MSG(iov != NULL, "malloc failed (%s)", strerror(errno)); + + for (off = 0, n = 0; n < mmsgcnt; n++) { + iov[n].iov_base = buf + off; + iov[n].iov_len = sizeof(DGRAM); + off += iov[n].iov_len; + mmsghdr[n].msg_hdr.msg_iov = &iov[n]; + mmsghdr[n].msg_hdr.msg_iovlen = 1; + mmsghdr[n].msg_hdr.msg_name = NULL; + mmsghdr[n].msg_hdr.msg_namelen = 0; + } + + switch (fork()) { + case -1: + ATF_REQUIRE_MSG(0, "fork failed (%s)", strerror(errno)); + break; + + case 0: + n = NPKTS; + if (debug) + printf("waiting for %u messages (max %u per syscall)\n", n, + mmsgcnt); + while (n > 0) { + struct timespec ts = { 1, 0 }; + cnt = recvmmsg(fd[1], mmsghdr, min(mmsgcnt, n), + MSG_WAITALL, &ts); + ATF_REQUIRE_MSG(cnt != -1, "recvmmsg failed (%s)", + strerror(errno)); + ATF_REQUIRE_MSG(cnt != 0, "recvmmsg timeout"); + if (debug) + printf("recvmmsg: got %u messages\n", cnt); + for (i = 0; i < cnt; i++) { + ATF_CHECK_EQ_MSG(mmsghdr[i].msg_len, + sizeof(DGRAM), "packet length"); + ATF_CHECK_EQ_MSG( + ((uint8_t *)iov[i].iov_base)[0], + NPKTS - n + i, "packet contents"); + } + n -= cnt; + } + if (debug) + printf("done!\n"); + exit(0); + /*NOTREACHED*/ + default: + sched_yield(); + + for (n = 0; n < NPKTS; n++) { + if (debug) + printf("sending packet %u/%u...\n", (n+1), + NPKTS); + do { + DGRAM[0] = n; + error = send(fd[0], DGRAM, sizeof(DGRAM), 0); + } while (error == -1 && errno == ENOBUFS); + if (error == -1) + ATF_REQUIRE_MSG(error != -1, "send failed (%s)", + strerror(errno)); + } + error = wait(&status); + ATF_REQUIRE_MSG(error != -1, "wait failed (%s)", + strerror(errno)); + break; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, recvmmsg_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_revoke.c b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c new file mode 100644 index 0000000..10fd6d6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c @@ -0,0 +1,186 @@ +/* $NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $"); + +#include <sys/resource.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const char path[] = "revoke"; + +ATF_TC_WITH_CLEANUP(revoke_basic); +ATF_TC_HEAD(revoke_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of revoke(2)"); +} + +ATF_TC_BODY(revoke_basic, tc) +{ + struct rlimit res; + char tmp[10]; + size_t i, n; + int *buf; + + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + if ((n = res.rlim_cur / 10) == 0) + n = 10; + + buf = calloc(n, sizeof(int)); + ATF_REQUIRE(buf != NULL); + + buf[0] = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(buf[0] >= 0); + + for (i = 1; i < n; i++) { + buf[i] = open(path, O_RDWR); + ATF_REQUIRE(buf[i] >= 0); + } + + ATF_REQUIRE(revoke(path) == 0); + + for (i = 0; i < n; i++) { + + ATF_REQUIRE(read(buf[i], tmp, sizeof(tmp)) == -1); + + (void)close(buf[i]); + } + + free(buf); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(revoke_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(revoke_err); +ATF_TC_HEAD(revoke_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from revoke(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(revoke_err, tc) +{ + char buf[1024 + 1]; /* XXX: From the manual page... */ + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, revoke((char *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, revoke(buf) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, revoke("/etc/passwd") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, revoke("/etc/xxx/yyy") == -1); +} + +ATF_TC_WITH_CLEANUP(revoke_perm); +ATF_TC_HEAD(revoke_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions revoke(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(revoke_perm, tc) +{ + struct passwd *pw; + int fd, sta; + pid_t pid; + + pw = getpwnam("nobody"); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(revoke(path) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (revoke(path) == 0) + _exit(EXIT_FAILURE); + + if (errno != EACCES) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("revoke(2) did not obey permissions"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(revoke_perm, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, revoke_basic); + ATF_TP_ADD_TC(tp, revoke_err); + ATF_TP_ADD_TC(tp, revoke_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_select.c b/contrib/netbsd-tests/lib/libc/sys/t_select.c new file mode 100644 index 0000000..4316acf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_select.c @@ -0,0 +1,215 @@ +/* $NetBSD: t_select.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundatiom + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <sys/types.h> +#include <sys/select.h> +#include <sys/wait.h> +#include <err.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + +#include <atf-c.h> + +static sig_atomic_t keep_going = 1; + +static void +sig_handler(int signum) +{ + keep_going = 0; +} + +static void +sigchld(int signum) +{ +} + +static char +xtoa(uint8_t n) +{ + static const char xarray[] = "0123456789abcdef"; + assert(n < sizeof(xarray)); + return xarray[n]; +} + +static const char * +prmask(const sigset_t *m, char *buf, size_t len) +{ + size_t j = 2; + assert(len >= 3 + sizeof(*m)); + buf[0] = '0'; + buf[1] = 'x'; +#define N(p, a) (((p) >> ((a) * 4)) & 0xf) + for (size_t i = __arraycount(m->__bits); i > 0; i--) { + uint32_t p = m->__bits[i - 1]; + for (size_t k = sizeof(p); k > 0; k--) + buf[j++] = xtoa(N(p, k - 1)); + } + buf[j] = '\0'; + return buf; +} + +static void +child(const struct timespec *ts) +{ + struct sigaction sa; + sigset_t set, oset, nset; + char obuf[sizeof(oset) + 3], nbuf[sizeof(nset) + 3]; + int fd; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sig_handler; + if ((fd = open("/dev/null", O_RDONLY)) == -1) + err(1, "open"); + + if (sigaction(SIGTERM, &sa, NULL) == -1) + err(1, "sigaction"); + + sigfillset(&set); + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) + err(1, "sigprocmask"); + + if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1) + err(1, "sigprocmask"); + + sigemptyset(&set); + + for (;;) { + fd_set rset; + FD_ZERO(&rset); + FD_SET(fd, &rset); + if (pselect(1, &rset, NULL, NULL, ts, &set) == -1) { + if(errno == EINTR) { + if (!keep_going) + break; + } + } + if (ts) + break; + } + if (sigprocmask(SIG_BLOCK, NULL, &nset) == -1) + err(1, "sigprocmask"); + if (memcmp(&oset, &nset, sizeof(oset)) != 0) + atf_tc_fail("pselect() masks don't match " + "after timeout %s != %s", + prmask(&nset, nbuf, sizeof(nbuf)), + prmask(&oset, obuf, sizeof(obuf))); +} + +ATF_TC(pselect_sigmask); +ATF_TC_HEAD(pselect_sigmask, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask " + "setting when a signal is received (PR lib/43625)"); +} + +ATF_TC_BODY(pselect_sigmask, tc) +{ + pid_t pid; + int status; + + signal(SIGCHLD, sigchld); + + switch (pid = fork()) { + case 0: + child(NULL); + case -1: + err(1, "fork"); + default: + sleep(1); + if (kill(pid, SIGTERM) == -1) + err(1, "kill"); + sleep(1); + switch (waitpid(pid, &status, WNOHANG)) { + case -1: + err(1, "wait"); + case 0: + if (kill(pid, SIGKILL) == -1) + err(1, "kill"); + atf_tc_fail("pselect() did not receive signal"); + break; + default: + break; + } + } +} + +ATF_TC(pselect_timeout); +ATF_TC_HEAD(pselect_timeout, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask " + "setting when a timeout occurs"); +} + +ATF_TC_BODY(pselect_timeout, tc) +{ + pid_t pid; + int status; + static const struct timespec zero = { 0, 0 }; + + signal(SIGCHLD, sigchld); + + switch (pid = fork()) { + case 0: + child(&zero); + break; + case -1: + err(1, "fork"); + default: + sleep(1); + switch (waitpid(pid, &status, WNOHANG)) { + case -1: + err(1, "wait"); + case 0: + if (kill(pid, SIGKILL) == -1) + err(1, "kill"); + atf_tc_fail("pselect() did not receive signal"); + break; + default: + break; + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pselect_sigmask); + ATF_TP_ADD_TC(tp, pselect_timeout); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c new file mode 100644 index 0000000..c760cfb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c @@ -0,0 +1,522 @@ +/* $NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $"); + +#include <sys/resource.h> +#include <sys/mman.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <lwp.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ucontext.h> +#include <unistd.h> + +static void sighandler(int); +static const char path[] = "setrlimit"; + +static const int rlimit[] = { + RLIMIT_AS, + RLIMIT_CORE, + RLIMIT_CPU, + RLIMIT_DATA, + RLIMIT_FSIZE, + RLIMIT_MEMLOCK, + RLIMIT_NOFILE, + RLIMIT_NPROC, + RLIMIT_RSS, + RLIMIT_SBSIZE, + RLIMIT_STACK +}; + +ATF_TC(setrlimit_basic); +ATF_TC_HEAD(setrlimit_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic soft limit test"); +} + +ATF_TC_BODY(setrlimit_basic, tc) +{ + struct rlimit res; + int *buf, lim; + size_t i; + + buf = calloc(__arraycount(rlimit), sizeof(int)); + + if (buf == NULL) + atf_tc_fail("initialization failed"); + + for (i = lim = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + if (getrlimit(rlimit[i], &res) != 0) + continue; + + if (res.rlim_cur == RLIM_INFINITY || res.rlim_cur == 0) + continue; + + if (res.rlim_cur == res.rlim_max) /* An unprivileged run. */ + continue; + + buf[i] = res.rlim_cur; + res.rlim_cur = res.rlim_cur - 1; + + if (setrlimit(rlimit[i], &res) != 0) { + lim = rlimit[i]; + goto out; + } + } + +out: + for (i = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + if (buf[i] == 0) + continue; + + if (getrlimit(rlimit[i], &res) != 0) + continue; + + res.rlim_cur = buf[i]; + + (void)setrlimit(rlimit[i], &res); + } + + if (lim != 0) + atf_tc_fail("failed to set limit (%d)", lim); +} + +ATF_TC(setrlimit_current); +ATF_TC_HEAD(setrlimit_current, tc) +{ + atf_tc_set_md_var(tc, "descr", "setrlimit(3) with current limits"); +} + +ATF_TC_BODY(setrlimit_current, tc) +{ + struct rlimit res; + size_t i; + + for (i = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0); + ATF_REQUIRE(setrlimit(rlimit[i], &res) == 0); + } +} + +ATF_TC(setrlimit_err); +ATF_TC_HEAD(setrlimit_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions"); +} + +ATF_TC_BODY(setrlimit_err, tc) +{ + struct rlimit res; + size_t i; + + for (i = 0; i < __arraycount(rlimit); i++) { + + errno = 0; + + ATF_REQUIRE(getrlimit(rlimit[i], (void *)0) != 0); + ATF_REQUIRE(errno == EFAULT); + } + + errno = 0; + + ATF_REQUIRE(getrlimit(INT_MAX, &res) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC_WITH_CLEANUP(setrlimit_fsize); +ATF_TC_HEAD(setrlimit_fsize, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_FSIZE"); +} + +ATF_TC_BODY(setrlimit_fsize, tc) +{ + struct rlimit res; + int fd, sta; + pid_t pid; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + atf_tc_fail("initialization failed"); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + res.rlim_cur = 2; + res.rlim_max = 2; + + if (setrlimit(RLIMIT_FSIZE, &res) != 0) + _exit(EXIT_FAILURE); + + if (signal(SIGXFSZ, sighandler) == SIG_ERR) + _exit(EXIT_FAILURE); + + /* + * The third call should generate a SIGXFSZ. + */ + (void)write(fd, "X", 1); + (void)write(fd, "X", 1); + (void)write(fd, "X", 1); + + _exit(EXIT_FAILURE); + } + + (void)close(fd); + (void)wait(&sta); + (void)unlink(path); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_FSIZE not enforced"); +} + +ATF_TC_CLEANUP(setrlimit_fsize, tc) +{ + (void)unlink(path); +} + +static void +sighandler(int signo) +{ + + if (signo != SIGXFSZ) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); +} + +ATF_TC(setrlimit_memlock); +ATF_TC_HEAD(setrlimit_memlock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK"); +} + +ATF_TC_BODY(setrlimit_memlock, tc) +{ + struct rlimit res; + void *buf; + long page; + pid_t pid; + int sta; + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + buf = malloc(page); + pid = fork(); + + if (buf == NULL || pid < 0) + atf_tc_fail("initialization failed"); + + if (pid == 0) { + + /* + * Try to lock a page while + * RLIMIT_MEMLOCK is zero. + */ + if (mlock(buf, page) != 0) + _exit(EXIT_FAILURE); + + if (munlock(buf, page) != 0) + _exit(EXIT_FAILURE); + + res.rlim_cur = 0; + res.rlim_max = 0; + + if (setrlimit(RLIMIT_MEMLOCK, &res) != 0) + _exit(EXIT_FAILURE); + + if (mlock(buf, page) != 0) + _exit(EXIT_SUCCESS); + + (void)munlock(buf, page); + + _exit(EXIT_FAILURE); + } + + free(buf); + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_MEMLOCK not enforced"); +} + +ATF_TC(setrlimit_nofile_1); +ATF_TC_HEAD(setrlimit_nofile_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #1"); +} + +ATF_TC_BODY(setrlimit_nofile_1, tc) +{ + struct rlimit res; + int fd, i, rv, sta; + pid_t pid; + + res.rlim_cur = 0; + res.rlim_max = 0; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Close all descriptors, set RLIMIT_NOFILE + * to zero, and try to open a random file. + * This should fail with EMFILE. + */ + for (i = 0; i < 1024; i++) + (void)close(i); + + rv = setrlimit(RLIMIT_NOFILE, &res); + + if (rv != 0) + _exit(EXIT_FAILURE); + + errno = 0; + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0 || errno != EMFILE) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NOFILE not enforced"); +} + +ATF_TC(setrlimit_nofile_2); +ATF_TC_HEAD(setrlimit_nofile_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #2"); +} + +ATF_TC_BODY(setrlimit_nofile_2, tc) +{ + static const rlim_t lim = 12; + struct rlimit res; + int fd, i, rv, sta; + pid_t pid; + + /* + * See that an arbitrary limit on + * open files is being enforced. + */ + res.rlim_cur = lim; + res.rlim_max = lim; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (i = 0; i < 1024; i++) + (void)close(i); + + rv = setrlimit(RLIMIT_NOFILE, &res); + + if (rv != 0) + _exit(EXIT_FAILURE); + + for (i = 0; i < (int)lim; i++) { + + fd = open("/etc/passwd", O_RDONLY); + + if (fd < 0) + _exit(EXIT_FAILURE); + } + + /* + * After the limit has been reached, + * EMFILE should again follow. + */ + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0 || errno != EMFILE) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NOFILE not enforced"); +} + +ATF_TC(setrlimit_nproc); +ATF_TC_HEAD(setrlimit_nproc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NPROC"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_nproc, tc) +{ + struct rlimit res; + pid_t pid, cpid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Set RLIMIT_NPROC to zero and try to fork. + */ + res.rlim_cur = 0; + res.rlim_max = 0; + + if (setrlimit(RLIMIT_NPROC, &res) != 0) + _exit(EXIT_FAILURE); + + cpid = fork(); + + if (cpid < 0) + _exit(EXIT_SUCCESS); + + _exit(EXIT_FAILURE); + } + + (void)waitpid(pid, &sta, 0); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NPROC not enforced"); +} + +ATF_TC(setrlimit_nthr); +ATF_TC_HEAD(setrlimit_nthr, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NTHR"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +static void +func(lwpid_t *id) +{ + printf("thread %d\n", *id); + fflush(stdout); + _lwp_exit(); +} + +ATF_TC_BODY(setrlimit_nthr, tc) +{ + struct rlimit res; + lwpid_t lwpid; + ucontext_t c; + + /* + * Set RLIMIT_NTHR to zero and try to create a thread. + */ + res.rlim_cur = 0; + res.rlim_max = 0; + ATF_REQUIRE(setrlimit(RLIMIT_NTHR, &res) == 0); + ATF_REQUIRE(getcontext(&c) == 0); + c.uc_link = NULL; + sigemptyset(&c.uc_sigmask); + c.uc_stack.ss_flags = 0; + c.uc_stack.ss_size = 4096; + ATF_REQUIRE((c.uc_stack.ss_sp = malloc(c.uc_stack.ss_size)) != NULL); + makecontext(&c, func, 1, &lwpid); + ATF_CHECK_ERRNO(EAGAIN, _lwp_create(&c, 0, &lwpid) == -1); +} + +ATF_TC(setrlimit_perm); +ATF_TC_HEAD(setrlimit_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2) for EPERM"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_perm, tc) +{ + struct rlimit res; + size_t i; + + /* + * Try to raise the maximum limits as an user. + */ + for (i = 0; i < __arraycount(rlimit); i++) { + + ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0); + + if (res.rlim_max == UINT64_MAX) /* Overflow. */ + continue; + + errno = 0; + res.rlim_max = res.rlim_max + 1; + + ATF_CHECK_ERRNO(EPERM, setrlimit(rlimit[i], &res) != 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, setrlimit_basic); + ATF_TP_ADD_TC(tp, setrlimit_current); + ATF_TP_ADD_TC(tp, setrlimit_err); + ATF_TP_ADD_TC(tp, setrlimit_fsize); + ATF_TP_ADD_TC(tp, setrlimit_memlock); + ATF_TP_ADD_TC(tp, setrlimit_nofile_1); + ATF_TP_ADD_TC(tp, setrlimit_nofile_2); + ATF_TP_ADD_TC(tp, setrlimit_nproc); + ATF_TP_ADD_TC(tp, setrlimit_perm); + ATF_TP_ADD_TC(tp, setrlimit_nthr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setuid.c b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c new file mode 100644 index 0000000..d2bf523 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c @@ -0,0 +1,122 @@ +/* $NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdlib.h> +#include <unistd.h> + +ATF_TC(setuid_perm); +ATF_TC_HEAD(setuid_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setuid(0) as normal user"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setuid_perm, tc) +{ + errno = 0; + + ATF_REQUIRE(setuid(0) == -1); + ATF_REQUIRE(errno == EPERM); +} + +ATF_TC(setuid_real); +ATF_TC_HEAD(setuid_real, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setuid(2) with real UID"); +} + +ATF_TC_BODY(setuid_real, tc) +{ + uid_t uid = getuid(); + + ATF_REQUIRE(setuid(uid) == 0); + + ATF_REQUIRE(getuid() == uid); + ATF_REQUIRE(geteuid() == uid); +} + +ATF_TC(setuid_root); +ATF_TC_HEAD(setuid_root, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setuid(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setuid_root, tc) +{ + struct passwd *pw; + int rv, sta; + pid_t pid; + uid_t uid; + + while ((pw = getpwent()) != NULL) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = setuid(pw->pw_uid); + + if (rv != 0) + _exit(EXIT_FAILURE); + + uid = getuid(); + + if (uid != pw->pw_uid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to change UID to %u", pw->pw_uid); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, setuid_perm); + ATF_TP_ADD_TC(tp, setuid_real); + ATF_TP_ADD_TC(tp, setuid_root); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c new file mode 100644 index 0000000..8022353 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c @@ -0,0 +1,154 @@ +/* $NetBSD: t_sigaction.c,v 1.2 2012/11/07 16:51:16 pgoyette Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigaction.c,v 1.2 2012/11/07 16:51:16 pgoyette Exp $"); + +#include <sys/wait.h> + +#include <signal.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include "../../../h_macros.h" + +static bool handler_called = false; + +static void +handler(int signo) +{ + handler_called = true; +} + +static void +sa_resethand_child(const int flags) +{ + struct sigaction sa; + + sa.sa_flags = flags; + sa.sa_handler = &handler; + sigemptyset(&sa.sa_mask); + + sigaction(SIGUSR1, &sa, NULL); + kill(getpid(), SIGUSR1); + exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE); +} + +static void +wait_and_check_child(const pid_t pid, const char *fail_message) +{ + int status; + + (void)waitpid(pid, &status, 0); + + if (WIFEXITED(status)) + ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); + else + atf_tc_fail("%s; raw exit status was %d", fail_message, status); +} + +static void +catch(int sig) +{ + return; +} + +ATF_TC(sigaction_basic); +ATF_TC_HEAD(sigaction_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache" + "synchronization after copying out the trampoline code."); +} + +ATF_TC_BODY(sigaction_basic, tc) +{ + static struct sigaction sa; + + sa.sa_handler = catch; + + sigaction(SIGUSR1, &sa, 0); + kill(getpid(), SIGUSR1); + atf_tc_pass(); +} + +ATF_TC(sigaction_noflags); +ATF_TC_HEAD(sigaction_noflags, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks programming a signal with " + "sigaction(2) but without any flags"); +} + +ATF_TC_BODY(sigaction_noflags, tc) +{ + const pid_t pid = fork(); + if (pid == -1) + atf_tc_fail_errno("fork(2) failed"); + else if (pid == 0) + sa_resethand_child(0); + else + wait_and_check_child(pid, "Child process did not exit cleanly;" + " it failed to process the signal"); +} + +ATF_TC(sigaction_resethand); +ATF_TC_HEAD(sigaction_resethand, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works"); +} + +ATF_TC_BODY(sigaction_resethand, tc) +{ + const pid_t pid = fork(); + if (pid == -1) + atf_tc_fail_errno("fork(2) failed"); + else if (pid == 0) + sa_resethand_child(SA_RESETHAND); + else { + wait_and_check_child(pid, "Child process did not exit cleanly;" + " it either failed to process the signal or SA_RESETHAND" + " is broken"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigaction_basic); + ATF_TP_ADD_TC(tp, sigaction_noflags); + ATF_TP_ADD_TC(tp, sigaction_resethand); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c new file mode 100644 index 0000000..f9e0c63 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c @@ -0,0 +1,103 @@ +/* $NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $"); + + +#include <atf-c.h> +#include <errno.h> +#include <signal.h> +#include <stdlib.h> +#include <sched.h> +#include <unistd.h> + +static void handler(int, siginfo_t *, void *); + +#define VALUE (int)0xc001dad1 +static int value; + +static void +handler(int signo, siginfo_t *info, void *data) +{ + value = info->si_value.sival_int; + kill(0, SIGINFO); +} + +ATF_TC(sigqueue_basic); +ATF_TC_HEAD(sigqueue_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigqueue(3) sigval delivery"); +} + +ATF_TC_BODY(sigqueue_basic, tc) +{ + struct sigaction sa; + union sigval sv; + + sa.sa_sigaction = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + if (sigaction(SIGUSR1, &sa, NULL) != 0) + atf_tc_fail("sigaction failed"); + + sv.sival_int = VALUE; + + if (sigqueue(0, SIGUSR1, sv) != 0) + atf_tc_fail("sigqueue failed"); + + sched_yield(); + ATF_REQUIRE_EQ(sv.sival_int, value); +} + +ATF_TC(sigqueue_err); +ATF_TC_HEAD(sigqueue_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from sigqueue(3)"); +} + +ATF_TC_BODY(sigqueue_err, tc) +{ + union sigval sv; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, sigqueue(getpid(), -1, sv) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigqueue_basic); + ATF_TP_ADD_TC(tp, sigqueue_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c new file mode 100644 index 0000000..64b68d9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c @@ -0,0 +1,126 @@ +/* $NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $"); + +#include <sys/time.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <atf-c.h> + + +ATF_TC(sigtimedwait_all0timeout); + +ATF_TC_HEAD(sigtimedwait_all0timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", "Test for PR kern/47625: sigtimedwait" + " with a timeout value of all zero should return imediately"); +} + +ATF_TC_BODY(sigtimedwait_all0timeout, tc) +{ + sigset_t block; + struct timespec ts, before, after, len; + siginfo_t info; + int r; + + sigemptyset(&block); + ts.tv_sec = 0; + ts.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &before); + r = sigtimedwait(&block, &info, &ts); + clock_gettime(CLOCK_MONOTONIC, &after); + ATF_REQUIRE(r == -1); + ATF_REQUIRE_ERRNO(EAGAIN, errno); + timespecsub(&after, &before, &len); + ATF_REQUIRE(len.tv_sec < 1); +} + +ATF_TC(sigtimedwait_NULL_timeout); + +ATF_TC_HEAD(sigtimedwait_NULL_timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", "Test sigtimedwait() without timeout"); +} + +ATF_TC_BODY(sigtimedwait_NULL_timeout, tc) +{ + sigset_t sig; + siginfo_t info; + struct itimerval it; + int r; + + /* arrange for a SIGALRM signal in a few seconds */ + memset(&it, 0, sizeof it); + it.it_value.tv_sec = 5; + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0); + + /* wait without timeout */ + sigemptyset(&sig); + sigaddset(&sig, SIGALRM); + r = sigtimedwait(&sig, &info, NULL); + ATF_REQUIRE(r == SIGALRM); +} + +ATF_TC(sigtimedwait_small_timeout); + +ATF_TC_HEAD(sigtimedwait_small_timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "15"); + atf_tc_set_md_var(tc, "descr", "Test sigtimedwait with a small " + "timeout"); +} + +ATF_TC_BODY(sigtimedwait_small_timeout, tc) +{ + sigset_t block; + struct timespec ts; + siginfo_t info; + int r; + + sigemptyset(&block); + ts.tv_sec = 5; + ts.tv_nsec = 0; + r = sigtimedwait(&block, &info, &ts); + ATF_REQUIRE(r == -1); + ATF_REQUIRE_ERRNO(EAGAIN, errno); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sigtimedwait_all0timeout); + ATF_TP_ADD_TC(tp, sigtimedwait_NULL_timeout); + ATF_TP_ADD_TC(tp, sigtimedwait_small_timeout); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c new file mode 100644 index 0000000..532629c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c @@ -0,0 +1,137 @@ +/* $NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $"); + +#include <atf-c.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <errno.h> + +static void +connected(int fd) +{ + struct sockaddr_un addr; + socklen_t len = (socklen_t)sizeof(addr); + ATF_REQUIRE(getpeername(fd, (struct sockaddr*)(void *)&addr, + &len) == 0); +} + +static void +run(int flags) +{ + int fd[2], i; + + while ((i = open("/", O_RDONLY)) < 3) + ATF_REQUIRE(i != -1); + + ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1); + + ATF_REQUIRE(socketpair(AF_UNIX, SOCK_DGRAM | flags, 0, fd) == 0); + + ATF_REQUIRE(fd[0] == 3); + ATF_REQUIRE(fd[1] == 4); + + connected(fd[0]); + connected(fd[1]); + + if (flags & SOCK_CLOEXEC) { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0); + } + + if (flags & SOCK_NONBLOCK) { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0); + } + + ATF_REQUIRE(close(fd[0]) != -1); + ATF_REQUIRE(close(fd[1]) != -1); +} + +ATF_TC(socketpair_basic); +ATF_TC_HEAD(socketpair_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_basic, tc) +{ + run(0); +} + +ATF_TC(socketpair_nonblock); +ATF_TC_HEAD(socketpair_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "A non-blocking test of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_nonblock, tc) +{ + run(SOCK_NONBLOCK); +} + +ATF_TC(socketpair_cloexec); +ATF_TC_HEAD(socketpair_cloexec, tc) +{ + atf_tc_set_md_var(tc, "descr", "A close-on-exec of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_cloexec, tc) +{ + run(SOCK_CLOEXEC); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, socketpair_basic); + ATF_TP_ADD_TC(tp, socketpair_nonblock); + ATF_TP_ADD_TC(tp, socketpair_cloexec); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_stat.c b/contrib/netbsd-tests/lib/libc/sys/t_stat.c new file mode 100644 index 0000000..0312e2f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_stat.c @@ -0,0 +1,417 @@ +/* $NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/types.h> + +#include <arpa/inet.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <fts.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +#include <stdio.h> + +static const char *path = "stat"; + +ATF_TC_WITH_CLEANUP(stat_chflags); +ATF_TC_HEAD(stat_chflags, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)"); +} + +ATF_TC_BODY(stat_chflags, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(chflags(path, UF_NODUMP) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (sa.st_flags == sb.st_flags) + atf_tc_fail("stat(2) did not detect chflags(2)"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_chflags, tc) +{ + (void)unlink(path); +} + +ATF_TC(stat_dir); +ATF_TC_HEAD(stat_dir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories"); +} + +ATF_TC_BODY(stat_dir, tc) +{ + const short depth = 2; + struct stat sa, sb; + char *argv[2]; + FTSENT *ftse; + FTS *fts; + int ops; + + argv[1] = NULL; + argv[0] = __UNCONST("/"); + + ops = FTS_NOCHDIR; + ops |= FTS_PHYSICAL; + + fts = fts_open(argv, ops, NULL); + ATF_REQUIRE(fts != NULL); + + while ((ftse = fts_read(fts)) != NULL) { + + if (ftse->fts_level < 1) + continue; + + if (ftse->fts_level > depth) { + (void)fts_set(fts, ftse, FTS_SKIP); + continue; + } + + switch(ftse->fts_info) { + + case FTS_DP: + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0); + ATF_REQUIRE(chdir(ftse->fts_path) == 0); + ATF_REQUIRE(stat(".", &sb) == 0); + + /* + * The previous two stat(2) calls + * should be for the same directory. + */ + if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino) + atf_tc_fail("inconsistent stat(2)"); + + /* + * Check that fts(3)'s stat(2) + * call equals the manual one. + */ + if (sb.st_ino != ftse->fts_statp->st_ino) + atf_tc_fail("stat(2) and fts(3) differ"); + + break; + + default: + break; + } + } + + (void)fts_close(fts); +} + +ATF_TC(stat_err); +ATF_TC_HEAD(stat_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family"); +} + +ATF_TC_BODY(stat_err, tc) +{ + char buf[NAME_MAX + 1]; + struct stat st; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); +} + +ATF_TC_WITH_CLEANUP(stat_mtime); +ATF_TC_HEAD(stat_mtime, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)"); +} + +ATF_TC_BODY(stat_mtime, tc) +{ + struct stat sa, sb; + int fd[3]; + size_t i; + + for (i = 0; i < __arraycount(fd); i++) { + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd[i] = open(path, O_WRONLY | O_CREAT); + + ATF_REQUIRE(fd[i] != -1); + ATF_REQUIRE(write(fd[i], "X", 1) == 1); + ATF_REQUIRE(stat(path, &sa) == 0); + + (void)sleep(1); + + ATF_REQUIRE(write(fd[i], "X", 1) == 1); + ATF_REQUIRE(stat(path, &sb) == 0); + + ATF_REQUIRE(close(fd[i]) == 0); + ATF_REQUIRE(unlink(path) == 0); + + if (sa.st_mtime == sb.st_mtime) + atf_tc_fail("mtimes did not change"); + } +} + +ATF_TC_CLEANUP(stat_mtime, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(stat_perm); +ATF_TC_HEAD(stat_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(stat_perm, tc) +{ + struct stat sa, sb; + gid_t gid; + uid_t uid; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + uid = getuid(); + gid = getgid(); + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(fstat(fd, &sa) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (gid != sa.st_gid || sa.st_gid != sb.st_gid) + atf_tc_fail("invalid GID"); + + if (uid != sa.st_uid || sa.st_uid != sb.st_uid) + atf_tc_fail("invalid UID"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(stat_size); +ATF_TC_HEAD(stat_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)"); +} + +ATF_TC_BODY(stat_size, tc) +{ + struct stat sa, sb, sc; + const size_t n = 10; + size_t i; + int fd; + + fd = open(path, O_WRONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < n; i++) { + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + (void)memset(&sc, 0, sizeof(struct stat)); + + ATF_REQUIRE(fstat(fd, &sa) == 0); + ATF_REQUIRE(write(fd, "X", 1) == 1); + ATF_REQUIRE(fstat(fd, &sb) == 0); + ATF_REQUIRE(stat(path, &sc) == 0); + + if (sa.st_size + 1 != sb.st_size) + atf_tc_fail("invalid file size"); + + if (sb.st_size != sc.st_size) + atf_tc_fail("stat(2) and fstat(2) mismatch"); + } + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_size, tc) +{ + (void)unlink(path); +} + +ATF_TC(stat_socket); +ATF_TC_HEAD(stat_socket, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fstat(2) with " + "a socket (PR kern/46077)"); +} + +ATF_TC_BODY(stat_socket, tc) +{ + struct sockaddr_in addr; + struct stat st; + uint32_t iaddr; + int fd, flags; + + (void)memset(&st, 0, sizeof(struct stat)); + (void)memset(&addr, 0, sizeof(struct sockaddr_in)); + + fd = socket(AF_INET, SOCK_STREAM, 0); + ATF_REQUIRE(fd >= 0); + + flags = fcntl(fd, F_GETFL); + + ATF_REQUIRE(flags != -1); + ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1); + ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1); + + addr.sin_port = htons(42); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = iaddr; + + errno = 0; + + ATF_REQUIRE_ERRNO(EINPROGRESS, + connect(fd, (struct sockaddr *)&addr, + sizeof(struct sockaddr_in)) == -1); + + errno = 0; + + if (fstat(fd, &st) != 0 || errno != 0) + atf_tc_fail("fstat(2) failed for a EINPROGRESS socket"); + + (void)close(fd); +} + +ATF_TC_WITH_CLEANUP(stat_symlink); +ATF_TC_HEAD(stat_symlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)"); +} + +ATF_TC_BODY(stat_symlink, tc) +{ + const char *pathlink = "pathlink"; + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd = open(path, O_WRONLY | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(symlink(path, pathlink) == 0); + ATF_REQUIRE(stat(pathlink, &sa) == 0); + ATF_REQUIRE(lstat(pathlink, &sb) == 0); + + if (S_ISLNK(sa.st_mode) != 0) + atf_tc_fail("stat(2) detected symbolic link"); + + if (S_ISLNK(sb.st_mode) == 0) + atf_tc_fail("lstat(2) did not detect symbolic link"); + + if (sa.st_mode == sb.st_mode) + atf_tc_fail("inconsistencies between stat(2) and lstat(2)"); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathlink) == 0); +} + +ATF_TC_CLEANUP(stat_symlink, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, stat_chflags); + ATF_TP_ADD_TC(tp, stat_dir); + ATF_TP_ADD_TC(tp, stat_err); + ATF_TP_ADD_TC(tp, stat_mtime); + ATF_TP_ADD_TC(tp, stat_perm); + ATF_TP_ADD_TC(tp, stat_size); + ATF_TP_ADD_TC(tp, stat_socket); + ATF_TP_ADD_TC(tp, stat_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c new file mode 100644 index 0000000..de36c88 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c @@ -0,0 +1,133 @@ +/* $NetBSD: t_swapcontext.c,v 1.3 2013/05/05 10:28:11 skrll Exp $ */ + +/* + * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD"); + +#include <ucontext.h> +#include <stdio.h> +#include <stdlib.h> +#include <lwp.h> + +#include <atf-c.h> + +#define STACKSIZE 65536 + +char stack[STACKSIZE]; +ucontext_t nctx; +ucontext_t octx; +void *otls; +void *ntls; +int val1, val2; +int alter_tlsbase; + +/* ARGSUSED0 */ +static void +swapfunc(void *arg) +{ + ntls = _lwp_getprivate(); + printf("after swapcontext TLS pointer = %p\n", ntls); + + if (alter_tlsbase) { + ATF_REQUIRE_EQ(ntls, &val1); + printf("TLS pointer modified by swapcontext()\n"); + } else { + ATF_REQUIRE_EQ(ntls, &val2); + printf("TLS pointer left untouched by swapcontext()\n"); + } + + /* Go back in main */ + ATF_REQUIRE(swapcontext(&nctx, &octx)); + + /* NOTREACHED */ + return; +} + +static void +mainfunc(void) +{ + printf("Testing if swapcontext() alters TLS pointer if _UC_TLSBASE " + "is %s\n", (alter_tlsbase) ? "left set" : "cleared"); + + _lwp_setprivate(&val1); + printf("before swapcontext TLS pointer = %p\n", &val1); + + ATF_REQUIRE(getcontext(&nctx) == 0); + + nctx.uc_stack.ss_sp = stack; + nctx.uc_stack.ss_size = sizeof(stack); + +#ifndef _UC_TLSBASE + ATF_REQUIRE_MSG(0, "_UC_TLSBASE is not defined"); +#else /* _UC_TLSBASE */ + ATF_REQUIRE(nctx.uc_flags & _UC_TLSBASE); + if (!alter_tlsbase) + nctx.uc_flags &= ~_UC_TLSBASE; +#endif /* _UC_TLSBASE */ + + makecontext(&nctx, swapfunc, 0); + + _lwp_setprivate(&val2); + otls = _lwp_getprivate(); + printf("before swapcontext TLS pointer = %p\n", otls); + ATF_REQUIRE(swapcontext(&octx, &nctx) == 0); + + printf("Test completed\n"); +} + + +ATF_TC(swapcontext1); +ATF_TC_HEAD(swapcontext1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can let " + "TLS pointer untouched"); +} +ATF_TC_BODY(swapcontext1, tc) +{ + alter_tlsbase = 0; + mainfunc(); +} + +ATF_TC(swapcontext2); +ATF_TC_HEAD(swapcontext2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can " + "modify TLS pointer"); +} +ATF_TC_BODY(swapcontext2, tc) +{ + alter_tlsbase = 1; + mainfunc(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swapcontext1); + ATF_TP_ADD_TC(tp, swapcontext2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c new file mode 100644 index 0000000..ce1fb99 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c @@ -0,0 +1,207 @@ +/* $NetBSD: t_timer_create.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <signal.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +static timer_t t; +static bool fail = true; + +static void +timer_signal_handler(int signo, siginfo_t *si, void *osi) +{ + timer_t *tp; + + tp = si->si_value.sival_ptr; + + if (*tp == t && signo == SIGALRM) + fail = false; + + (void)fprintf(stderr, "%s: %s\n", __func__, strsignal(signo)); +} + +static void +timer_signal_create(clockid_t cid, bool expire) +{ + struct itimerspec tim; + struct sigaction act; + struct sigevent evt; + sigset_t set; + + t = 0; + fail = true; + + (void)memset(&evt, 0, sizeof(struct sigevent)); + (void)memset(&act, 0, sizeof(struct sigaction)); + (void)memset(&tim, 0, sizeof(struct itimerspec)); + + /* + * Set handler. + */ + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = timer_signal_handler; + + ATF_REQUIRE(sigemptyset(&set) == 0); + ATF_REQUIRE(sigemptyset(&act.sa_mask) == 0); + + /* + * Block SIGALRM while configuring the timer. + */ + ATF_REQUIRE(sigaction(SIGALRM, &act, NULL) == 0); + ATF_REQUIRE(sigaddset(&set, SIGALRM) == 0); + ATF_REQUIRE(sigprocmask(SIG_SETMASK, &set, NULL) == 0); + + /* + * Create the timer (SIGEV_SIGNAL). + */ + evt.sigev_signo = SIGALRM; + evt.sigev_value.sival_ptr = &t; + evt.sigev_notify = SIGEV_SIGNAL; + + ATF_REQUIRE(timer_create(cid, &evt, &t) == 0); + + /* + * Start the timer. After this, unblock the signal. + */ + tim.it_value.tv_sec = expire ? 5 : 1; + tim.it_value.tv_nsec = 0; + + ATF_REQUIRE(timer_settime(t, 0, &tim, NULL) == 0); + + (void)sigprocmask(SIG_UNBLOCK, &set, NULL); + (void)sleep(2); + + if (expire) { + if (!fail) + atf_tc_fail("timer fired too soon"); + } else { + if (fail) + atf_tc_fail("timer failed to fire"); + } + + ATF_REQUIRE(timer_delete(t) == 0); +} + +ATF_TC(timer_create_err); +ATF_TC_HEAD(timer_create_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check errors from timer_create(2) (PR lib/42434"); +} + +ATF_TC_BODY(timer_create_err, tc) +{ + struct sigevent ev; + + (void)memset(&ev, 0, sizeof(struct sigevent)); + + errno = 0; + ev.sigev_signo = -1; + ev.sigev_notify = SIGEV_SIGNAL; + + ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1); + + errno = 0; + ev.sigev_signo = SIGUSR1; + ev.sigev_notify = SIGEV_THREAD + 100; + + ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1); +} + +ATF_TC(timer_create_real); +ATF_TC_HEAD(timer_create_real, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_SIGNAL"); +} + +ATF_TC_BODY(timer_create_real, tc) +{ + timer_signal_create(CLOCK_REALTIME, false); +} + +ATF_TC(timer_create_mono); +ATF_TC_HEAD(timer_create_mono, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_SIGNAL"); +} + +ATF_TC_BODY(timer_create_mono, tc) +{ + timer_signal_create(CLOCK_MONOTONIC, false); +} + +ATF_TC(timer_create_real_expire); +ATF_TC_HEAD(timer_create_real_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_SIGNAL, with expiration"); +} + +ATF_TC_BODY(timer_create_real_expire, tc) +{ + timer_signal_create(CLOCK_REALTIME, true); +} + +ATF_TC(timer_create_mono_expire); +ATF_TC_HEAD(timer_create_mono_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_SIGNAL, with expiration"); +} + +ATF_TC_BODY(timer_create_mono_expire, tc) +{ + timer_signal_create(CLOCK_MONOTONIC, true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, timer_create_err); + ATF_TP_ADD_TC(tp, timer_create_real); + ATF_TP_ADD_TC(tp, timer_create_mono); + ATF_TP_ADD_TC(tp, timer_create_real_expire); + ATF_TP_ADD_TC(tp, timer_create_mono_expire); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_truncate.c b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c new file mode 100644 index 0000000..50a9cba --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c @@ -0,0 +1,175 @@ +/* $NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static const char path[] = "truncate"; +static const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 }; + +ATF_TC_WITH_CLEANUP(ftruncate_basic); +ATF_TC_HEAD(ftruncate_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)"); +} + +ATF_TC_BODY(ftruncate_basic, tc) +{ + struct stat st; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < __arraycount(sizes); i++) { + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); + + if (sizes[i] != (size_t)st.st_size) + atf_tc_fail("ftruncate(2) did not truncate"); + } + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(ftruncate_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(ftruncate_err); +ATF_TC_HEAD(ftruncate_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(ftruncate_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY, 0400); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1); + + (void)close(fd); +} + +ATF_TC_WITH_CLEANUP(truncate_basic); +ATF_TC_HEAD(truncate_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)"); +} + +ATF_TC_BODY(truncate_basic, tc) +{ + struct stat st; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < __arraycount(sizes); i++) { + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(truncate(path, sizes[i]) == 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); + + if (sizes[i] != (size_t)st.st_size) + atf_tc_fail("truncate(2) did not truncate"); + } + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(truncate_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(truncate_err); +ATF_TC_HEAD(truncate_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(truncate_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EISDIR, truncate("/etc", 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, truncate("/usr/bin/fpr", 999) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ftruncate_basic); + ATF_TP_ADD_TC(tp, ftruncate_err); + ATF_TP_ADD_TC(tp, truncate_basic); + ATF_TP_ADD_TC(tp, truncate_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c new file mode 100644 index 0000000..27d6740 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c @@ -0,0 +1,76 @@ +/* $NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <ucontext.h> + +ATF_TC(ucontext_basic); +ATF_TC_HEAD(ucontext_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks {get,set}context(2)"); +} + +ATF_TC_BODY(ucontext_basic, tc) +{ + ucontext_t u, v, w; + volatile int x, y; + + x = 0; + y = 0; + + printf("Start\n"); + + getcontext(&u); + y++; + + printf("x == %d\n", x); + + getcontext(&v); + + if ( x < 20 ) { + x++; + getcontext(&w); + setcontext(&u); + } + + printf("End, y = %d\n", y); + ATF_REQUIRE_EQ(y, 21); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ucontext_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_umask.c b/contrib/netbsd-tests/lib/libc/sys/t_umask.c new file mode 100644 index 0000000..748cbdc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_umask.c @@ -0,0 +1,205 @@ +/* $NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const char path[] = "umask"; +static const mode_t mask[] = { + S_IRWXU, + S_IRUSR, + S_IWUSR, + S_IXUSR, + S_IRWXG, + S_IRGRP, + S_IWGRP, + S_IXGRP, + S_IRWXO, + S_IROTH, + S_IWOTH, + S_IXOTH +}; + +ATF_TC_WITH_CLEANUP(umask_fork); +ATF_TC_HEAD(umask_fork, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that umask(2) is inherited"); +} + +ATF_TC_BODY(umask_fork, tc) +{ + mode_t mode; + pid_t pid; + size_t i; + int sta; + + for (i = 0; i < __arraycount(mask) - 1; i++) { + + (void)umask(mask[i] | mask[i + 1]); + + pid = fork(); + + if (pid < 0) + continue; + + if (pid == 0) { + + mode = umask(mask[i]); + + if (mode != (mask[i] | mask[i + 1])) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + goto fail; + } + + return; + +fail: + (void)umask(S_IWGRP | S_IWOTH); + + atf_tc_fail("umask(2) was not inherited"); +} + +ATF_TC_CLEANUP(umask_fork, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); +} + +ATF_TC_WITH_CLEANUP(umask_open); +ATF_TC_HEAD(umask_open, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of open(2) and umask(2)"); +} + +ATF_TC_BODY(umask_open, tc) +{ + const char *str = NULL; + struct stat st; + size_t i; + int fd; + + for (i = 0; i < __arraycount(mask); i++) { + + (void)umask(mask[i]); + + fd = open(path, O_RDWR | O_CREAT, 0777); + + if (fd < 0) + continue; + + (void)memset(&st, 0, sizeof(struct stat)); + + if (stat(path, &st) != 0) { + str = "failed to stat(2)"; + goto out; + } + + if ((st.st_mode & mask[i]) != 0) { + str = "invalid umask(2)"; + goto out; + } + + if (unlink(path) != 0) { + str = "failed to unlink(2)"; + goto out; + } + + } + +out: + (void)umask(S_IWGRP | S_IWOTH); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC_CLEANUP(umask_open, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(umask_previous); +ATF_TC_HEAD(umask_previous, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test the return value from umask(2)"); +} + +ATF_TC_BODY(umask_previous, tc) +{ + mode_t mode; + size_t i; + + for (i = 0; i < __arraycount(mask); i++) { + + mode = umask(mask[i]); + mode = umask(mask[i]); + + if (mode != mask[i]) + goto fail; + } + + return; + +fail: + (void)umask(S_IWGRP | S_IWOTH); + + atf_tc_fail("umask(2) did not return the previous mask"); +} + +ATF_TC_CLEANUP(umask_previous, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, umask_fork); + ATF_TP_ADD_TC(tp, umask_open); + ATF_TP_ADD_TC(tp, umask_previous); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c new file mode 100644 index 0000000..38bff4c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c @@ -0,0 +1,158 @@ +/* $NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +static char path[] = "unlink"; + +ATF_TC_WITH_CLEANUP(unlink_basic); +ATF_TC_HEAD(unlink_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of unlink(2)"); +} + +ATF_TC_BODY(unlink_basic, tc) +{ + const size_t n = 512; + size_t i; + int fd; + + for (i = 0; i < n; i++) { + + fd = open(path, O_RDWR | O_CREAT, 0666); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1); + } +} + +ATF_TC_CLEANUP(unlink_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_err); +ATF_TC_HEAD(unlink_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of unlink(2)"); +} + +ATF_TC_BODY(unlink_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, unlink(buf) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, unlink("/a/b/c/d/e/f/g/h/i/j/k/l/m") == -1); +} + +ATF_TC_CLEANUP(unlink_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_fifo); +ATF_TC_HEAD(unlink_fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unlink(2) for a FIFO"); +} + +ATF_TC_BODY(unlink_fifo, tc) +{ + + ATF_REQUIRE(mkfifo(path, 0666) == 0); + ATF_REQUIRE(unlink(path) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1); +} + +ATF_TC_CLEANUP(unlink_fifo, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_perm); +ATF_TC_HEAD(unlink_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with unlink(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(unlink_perm, tc) +{ + int rv; + + errno = 0; + rv = unlink("/etc"); + ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM), + "unlinking a directory did not fail with EPERM or EACCESS; " + "unlink() returned %d, errno %d", rv, errno); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, unlink("/root/.profile") == -1); +} + +ATF_TC_CLEANUP(unlink_perm, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, unlink_basic); + ATF_TP_ADD_TC(tp, unlink_err); + ATF_TP_ADD_TC(tp, unlink_fifo); + ATF_TP_ADD_TC(tp, unlink_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_write.c b/contrib/netbsd-tests/lib/libc/sys/t_write.c new file mode 100644 index 0000000..2b1324a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c @@ -0,0 +1,226 @@ +/* $NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $ */ + +/*- + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $"); + +#include <sys/uio.h> +#include <sys/syslimits.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +static void sighandler(int); + +static bool fail = false; +static const char *path = "write"; + +static void +sighandler(int signo) +{ + fail = false; +} + +ATF_TC_WITH_CLEANUP(write_err); +ATF_TC_HEAD(write_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)"); +} + +ATF_TC_BODY(write_err, tc) +{ + char rbuf[3] = { 'a', 'b', 'c' }; + char wbuf[3] = { 'x', 'y', 'z' }; + int fd; + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1); + + fd = open(path, O_RDWR | O_CREAT); + + if (fd >= 0) { + + errno = 0; + ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1); + + /* + * Check that the above bogus write(2) + * calls did not corrupt the file. + */ + ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0); + ATF_REQUIRE(read(fd, rbuf, 3) == 3); + ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0); + + (void)close(fd); + (void)unlink(path); + } +} + +ATF_TC_CLEANUP(write_err, tc) +{ + (void)unlink(path); +} + +ATF_TC(write_pipe); +ATF_TC_HEAD(write_pipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)"); +} + +ATF_TC_BODY(write_pipe, tc) +{ + int fds[2]; + + ATF_REQUIRE(pipe(fds) == 0); + ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0); + + ATF_REQUIRE(write(fds[1], "x", 1) != -1); + ATF_REQUIRE(close(fds[0]) == 0); + + errno = 0; + fail = true; + + if (write(fds[1], "x", 1) != -1 || errno != EPIPE) + atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded"); + + ATF_REQUIRE(close(fds[1]) == 0); + + if (fail != false) + atf_tc_fail_nonfatal("SIGPIPE was not raised"); +} + +ATF_TC_WITH_CLEANUP(write_pos); +ATF_TC_HEAD(write_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that write(2) " + "updates the file position"); +} + +ATF_TC_BODY(write_pos, tc) +{ + const size_t n = 123; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < n; i++) { + ATF_REQUIRE(write(fd, "x", 1) == 1); + ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1)); + } + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(write_pos, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(write_ret); +ATF_TC_HEAD(write_ret, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)"); +} + +ATF_TC_BODY(write_ret, tc) +{ + const size_t n = 99; + char buf[123]; + size_t i, j; + int fd; + + fd = open(path, O_WRONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + + for (i = j = 0; i < n; i++) + j += write(fd, buf, sizeof(buf)); + + if (j != n * 123) + atf_tc_fail("inconsistent return values from write(2)"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(write_ret, tc) +{ + (void)unlink(path); +} + +ATF_TC(writev_iovmax); +ATF_TC_HEAD(writev_iovmax, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Checks that file descriptor is properly FILE_UNUSE()d " + "when iovcnt is greater than IOV_MAX"); +} + +ATF_TC_BODY(writev_iovmax, tc) +{ + ssize_t retval; + + (void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n"); + + errno = 0; + retval = writev(2, NULL, IOV_MAX + 1); + + ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval); + ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, write_err); + ATF_TP_ADD_TC(tp, write_pipe); + ATF_TP_ADD_TC(tp, write_pos); + ATF_TP_ADD_TC(tp, write_ret); + ATF_TP_ADD_TC(tp, writev_iovmax); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/t_cdb.c b/contrib/netbsd-tests/lib/libc/t_cdb.c new file mode 100644 index 0000000..5e88e65 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_cdb.c @@ -0,0 +1,158 @@ +/* $NetBSD: t_cdb.c,v 1.1 2012/09/27 00:38:57 joerg Exp $ */ +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_cdb.c,v 1.1 2012/09/27 00:38:57 joerg Exp $"); + +#include <atf-c.h> +#include <assert.h> +#include <cdbr.h> +#include <cdbw.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define MAXKEYS 16384 + +static const char database_name[] = "test.cdb"; + +uint32_t keys[MAXKEYS]; + +static int +cmp_keys(const void *a_, const void *b_) +{ + uint32_t a = *(const uint32_t *)a_; + uint32_t b = *(const uint32_t *)b_; + + return a > b ? 1 : (a < b ? 1 : 0); +} + +static void +init_keys(size_t len) +{ + uint32_t sorted_keys[MAXKEYS]; + size_t i; + + assert(len <= MAXKEYS); + + if (len == 0) + return; + + do { + for (i = 0; i < len; ++i) + sorted_keys[i] = keys[i] = arc4random(); + + qsort(sorted_keys, len, sizeof(*sorted_keys), cmp_keys); + for (i = 1; i < len; ++i) { + if (sorted_keys[i - 1] == sorted_keys[i]) + break; + } + } while (i != len); +} + +static void +write_database(size_t len) +{ + struct cdbw *db; + int fd; + size_t i; + uint32_t buf[2]; + + ATF_REQUIRE((db = cdbw_open()) != NULL); + ATF_REQUIRE((fd = creat(database_name, S_IRUSR|S_IWUSR)) != -1); + for (i = 0; i < len; ++i) { + buf[0] = i; + buf[1] = keys[i]; + ATF_REQUIRE(cdbw_put(db, &keys[i], sizeof(keys[i]), + buf, sizeof(buf)) == 0); + } + ATF_REQUIRE(cdbw_output(db, fd, "test database", arc4random) == 0); + cdbw_close(db); + ATF_REQUIRE(close(fd) == 0); +} + +static void +check_database(size_t len) +{ + struct cdbr *db; + size_t i, data_len; + const void *data; + uint32_t buf[2]; + + ATF_REQUIRE((db = cdbr_open(database_name, CDBR_DEFAULT)) != NULL); + ATF_REQUIRE_EQ(cdbr_entries(db), len); + for (i = 0; i < len; ++i) { + ATF_REQUIRE(cdbr_find(db, &keys[i], sizeof(keys[i]), + &data, &data_len) != -1); + ATF_REQUIRE_EQ(data_len, sizeof(buf)); + memcpy(buf, data, sizeof(buf)); + ATF_REQUIRE_EQ(buf[0], i); + ATF_REQUIRE_EQ(buf[1], keys[i]); + } + cdbr_close(db); +} + +ATF_TC_WITH_CLEANUP(cdb); + +ATF_TC_HEAD(cdb, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test cdb(5) reading and writing"); +} + +ATF_TC_BODY(cdb, tc) +{ + size_t i, sizes[] = { 0, 16, 64, 1024, 2048 }; + for (i = 0; i < __arraycount(sizes); ++i) { + init_keys(sizes[i]); + write_database(sizes[i]); + check_database(sizes[i]); + unlink(database_name); + } +} + +ATF_TC_CLEANUP(cdb, tc) +{ + + unlink(database_name); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cdb); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/lib/libc/t_convfp.c b/contrib/netbsd-tests/lib/libc/t_convfp.c new file mode 100644 index 0000000..de68690 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_convfp.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_convfp.c,v 1.7 2011/06/14 11:58:22 njoly Exp $ */ + +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> + +/* + * This value is representable as an unsigned int, but not as an int. + * According to ISO C it must survive the convsion back from a double + * to an unsigned int (everything > -1 and < UINT_MAX+1 has to) + */ +#define UINT_TESTVALUE (INT_MAX+42U) + +/* The same for unsigned long */ +#define ULONG_TESTVALUE (LONG_MAX+42UL) + + +ATF_TC(conv_uint); +ATF_TC_HEAD(conv_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test conversions to unsigned int"); +} + +ATF_TC_BODY(conv_uint, tc) +{ + unsigned int ui; + double d; + + /* unsigned int test */ + d = UINT_TESTVALUE; + ui = (unsigned int)d; + + if (ui != UINT_TESTVALUE) + atf_tc_fail("FAILED: unsigned int %u (0x%x) != %u (0x%x)", + ui, ui, UINT_TESTVALUE, UINT_TESTVALUE); +} + +ATF_TC(conv_ulong); + +ATF_TC_HEAD(conv_ulong, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test conversions to unsigned long"); +} + +ATF_TC_BODY(conv_ulong, tc) +{ + unsigned long ul; + long double dt; + double d; + + /* unsigned long vs. {long} double test */ + if (sizeof(d) > sizeof(ul)) { + d = ULONG_TESTVALUE; + ul = (unsigned long)d; + printf("testing double vs. long\n"); + } else if (sizeof(dt) > sizeof(ul)) { + dt = ULONG_TESTVALUE; + ul = (unsigned long)dt; + printf("testing long double vs. long\n"); + } else { + printf("sizeof(long) = %zu, sizeof(double) = %zu, " + "sizeof(long double) = %zu\n", + sizeof(ul), sizeof(d), sizeof(dt)); + atf_tc_skip("no suitable {long} double type found"); + } + + if (ul != ULONG_TESTVALUE) + atf_tc_fail("unsigned long %lu (0x%lx) != %lu (0x%lx)", + ul, ul, ULONG_TESTVALUE, ULONG_TESTVALUE); +} + +ATF_TC(cast_ulong); + +ATF_TC_HEAD(cast_ulong, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test double to unsigned long cast"); +} + +ATF_TC_BODY(cast_ulong, tc) +{ + double nv; + unsigned long uv; + + nv = 5.6; + uv = (unsigned long)nv; + + ATF_CHECK_EQ_MSG(uv, 5, + "%.3f casted to unsigned long is %lu", nv, uv); +} + +ATF_TC(cast_ulong2); + +ATF_TC_HEAD(cast_ulong2, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test double/long double casts to unsigned long"); +} + +ATF_TC_BODY(cast_ulong2, tc) +{ + double dv = 1.9; + long double ldv = dv; + unsigned long l1 = dv; + unsigned long l2 = ldv; + + ATF_CHECK_EQ_MSG(l1, 1, + "double 1.9 casted to unsigned long should be 1, but is %lu", l1); + + ATF_CHECK_EQ_MSG(l2, 1, + "long double 1.9 casted to unsigned long should be 1, but is %lu", + l2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, conv_uint); + ATF_TP_ADD_TC(tp, conv_ulong); + ATF_TP_ADD_TC(tp, cast_ulong); + ATF_TP_ADD_TC(tp, cast_ulong2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/t_gdtoa.c b/contrib/netbsd-tests/lib/libc/t_gdtoa.c new file mode 100644 index 0000000..e040603 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_gdtoa.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_gdtoa.c,v 1.4 2012/09/27 08:19:18 martin Exp $"); + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> + +/* reported by Maksymilian Arciemowicz */ + +ATF_TC(long_format); + +ATF_TC_HEAD(long_format, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test printf with %%1.262159f format"); +} + +ATF_TC_BODY(long_format, tc) +{ + char *buf; + ATF_REQUIRE_EQ(262161, asprintf(&buf, "%1.262159f", 1.1)); + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, long_format); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c new file mode 100644 index 0000000..66b1735 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +ATF_TC(tcsetpgrp_err); +ATF_TC_HEAD(tcsetpgrp_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from tcsetpgrp(3)" + " (PR lib/41673)"); +} + +ATF_TC_BODY(tcsetpgrp_err, tc) +{ + int rv, sta; + pid_t pid; + + if (isatty(STDIN_FILENO) == 0) + return; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * The child process ID doesn't match any active + * process group ID, so the following call should + * fail with EPERM (and not EINVAL). + */ + errno = 0; + rv = tcsetpgrp(STDIN_FILENO, getpid()); + + if (rv == 0 || errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("wrong errno"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tcsetpgrp_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/time/t_mktime.c b/contrib/netbsd-tests/lib/libc/time/t_mktime.c new file mode 100644 index 0000000..8092361 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/time/t_mktime.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_mktime.c,v 1.5 2012/03/18 07:33:58 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <err.h> +#include <errno.h> +#include <string.h> +#include <time.h> + +ATF_TC(localtime_r_gmt); +ATF_TC_HEAD(localtime_r_gmt, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that localtime_r(3) " + "returns localtime, not GMT (PR lib/28324)"); +} + +ATF_TC_BODY(localtime_r_gmt, tc) +{ + struct tm *t; + struct tm tt; + time_t x; + + x = time(NULL); + localtime_r(&x, &tt); + t = localtime(&x); + + if (t->tm_sec != tt.tm_sec || t->tm_min != tt.tm_min || + t->tm_hour != tt.tm_hour || t->tm_mday != tt.tm_mday) + atf_tc_fail("inconsistencies between " + "localtime(3) and localtime_r(3)"); +} + +ATF_TC(mktime_negyear); +ATF_TC_HEAD(mktime_negyear, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mktime(3) with negative year"); +} + +ATF_TC_BODY(mktime_negyear, tc) +{ + struct tm tms; + time_t t; + + (void)memset(&tms, 0, sizeof(tms)); + tms.tm_year = ~0; + + errno = 0; + t = mktime(&tms); + ATF_REQUIRE_ERRNO(0, t != (time_t)-1); +} + +ATF_TC(timegm_epoch); +ATF_TC_HEAD(timegm_epoch, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test timegm(3) close to the epoch"); +} + +ATF_TC_BODY(timegm_epoch, tc) +{ + struct tm tms; + time_t t; + + /* midnight on 1 Jan 1970 */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)0); + + /* one second after midnight on 1 Jan 1970 */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = 1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)1); + + /* + * 1969-12-31 23:59:59 = one second before the epoch. + * Result should be -1 with errno = 0. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1969 - 1900; + tms.tm_mon = 12 - 1; + tms.tm_mday = 31; + tms.tm_hour = 23; + tms.tm_min = 59; + tms.tm_sec = 59; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-1); + + /* + * Another way of getting one second before the epoch: + * Set date to 1 Jan 1970, and time to -1 second. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = -1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-1); + + /* + * Two seconds before the epoch. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = -2; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-2); + +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, localtime_r_gmt); + ATF_TP_ADD_TC(tp, mktime_negyear); + ATF_TP_ADD_TC(tp, timegm_epoch); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/time/t_strptime.c b/contrib/netbsd-tests/lib/libc/time/t_strptime.c new file mode 100644 index 0000000..c0f9cdf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/time/t_strptime.c @@ -0,0 +1,252 @@ +/* $NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $ */ + +/*- + * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David Laight. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $"); + +#include <time.h> + +#include <atf-c.h> + +static void +h_pass(const char *buf, const char *fmt, int len, + int tm_sec, int tm_min, int tm_hour, int tm_mday, + int tm_mon, int tm_year, int tm_wday, int tm_yday) +{ + struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL }; + const char *ret, *exp; + + exp = buf + len; + ret = strptime(buf, fmt, &tm); + + ATF_REQUIRE_MSG(ret == exp, + "strptime(\"%s\", \"%s\", tm): incorrect return code: " + "expected: %p, got: %p", buf, fmt, exp, ret); + +#define H_REQUIRE_FIELD(field) \ + ATF_REQUIRE_MSG(tm.field == field, \ + "strptime(\"%s\", \"%s\", tm): incorrect %s: " \ + "expected: %d, but got: %d", buf, fmt, \ + ___STRING(field), field, tm.field) + + H_REQUIRE_FIELD(tm_sec); + H_REQUIRE_FIELD(tm_min); + H_REQUIRE_FIELD(tm_hour); + H_REQUIRE_FIELD(tm_mday); + H_REQUIRE_FIELD(tm_mon); + H_REQUIRE_FIELD(tm_year); + H_REQUIRE_FIELD(tm_wday); + H_REQUIRE_FIELD(tm_yday); + +#undef H_REQUIRE_FIELD +} + +static void +h_fail(const char *buf, const char *fmt) +{ + struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL }; + + ATF_REQUIRE_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", " + "\"%s\", &tm) should fail, but it didn't", buf, fmt); +} + +ATF_TC(common); + +ATF_TC_HEAD(common, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks strptime(3): various checks"); +} + +ATF_TC_BODY(common, tc) +{ + + h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %T %Y", + 24, 46, 27, 23, 20, 0, 98, 2, -1); + h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %H:%M:%S %Y", + 24, 46, 27, 23, 20, 0, 98, 2, -1); + h_pass("Tue Jan 20 23:27:46 1998", "%c", + 24, 46, 27, 23, 20, 0, 98, 2, -1); + h_pass("Fri Mar 4 20:05:34 2005", "%a %b %e %H:%M:%S %Y", + 24, 34, 5, 20, 4, 2, 105, 5, -1); + h_pass("5\t3 4 8pm:05:34 2005", "%w%n%m%t%d%n%k%p:%M:%S %Y", + 21, 34, 5, 20, 4, 2, 105, 5, -1); + h_pass("Fri Mar 4 20:05:34 2005", "%c", + 24, 34, 5, 20, 4, 2, 105, 5, -1); + + h_pass("x20y", "x%Cy", 4, -1, -1, -1, -1, -1, 100, -1, -1); + h_pass("x84y", "x%yy", 4, -1, -1, -1, -1, -1, 84, -1, -1); + h_pass("x2084y", "x%C%yy", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_pass("x8420y", "x%y%Cy", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_pass("%20845", "%%%C%y5", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_fail("%", "%E%"); + + h_pass("1980", "%Y", 4, -1, -1, -1, -1, -1, 80, -1, -1); + h_pass("1980", "%EY", 4, -1, -1, -1, -1, -1, 80, -1, -1); + + h_pass("0", "%S", 1, 0, -1, -1, -1, -1, -1, -1, -1); + h_pass("59", "%S", 2, 59, -1, -1, -1, -1, -1, -1, -1); + h_pass("60", "%S", 2, 60, -1, -1, -1, -1, -1, -1, -1); + h_pass("61", "%S", 2, 61, -1, -1, -1, -1, -1, -1, -1); + h_fail("62", "%S"); +} + +ATF_TC(day); + +ATF_TC_HEAD(day, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks strptime(3): day names"); +} + +ATF_TC_BODY(day, tc) +{ + + h_pass("Sun", "%a", 3, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Sunday", "%a", 6, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Monday", "%a", 6, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Tue", "%a", 3, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Tuesday", "%a", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Wed", "%a", 3, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Wednesday", "%a", 9, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Thu", "%a", 3, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Thursday", "%a", 8, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Fri", "%a", 3, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Friday", "%a", 6, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Sat", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturday", "%a", 8, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturn", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_fail("Moon", "%a"); + h_pass("Sun", "%A", 3, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Mon", "%A", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Monday", "%A", 6, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Tue", "%A", 3, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Tuesday", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Wed", "%A", 3, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Wednesday", "%A", 9, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Thu", "%A", 3, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Thursday", "%A", 8, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Fri", "%A", 3, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Friday", "%A", 6, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Sat", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturday", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturn", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_fail("Moon", "%A"); + + h_pass("mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("tueSDay", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1); + h_fail("sunday", "%EA"); + h_pass("SaturDay", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1); + h_fail("SaturDay", "%OA"); +} + +ATF_TC(month); + +ATF_TC_HEAD(month, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks strptime(3): month names"); +} + +ATF_TC_BODY(month, tc) +{ + + h_pass("Jan", "%b", 3, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("January", "%b", 7, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("Feb", "%b", 3, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("February", "%b", 8, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("Mar", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("March", "%b", 5, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("Apr", "%b", 3, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("April", "%b", 5, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("May", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Jun", "%b", 3, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("June", "%b", 4, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("Jul", "%b", 3, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("July", "%b", 4, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("Aug", "%b", 3, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("August", "%b", 6, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("Sep", "%b", 3, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("September", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("Oct", "%b", 3, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("October", "%b", 7, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("Nov", "%b", 3, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("November", "%b", 8, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("Dec", "%b", 3, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("December", "%b", 8, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("Mayor", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Mars", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_fail("Rover", "%b"); + h_pass("Jan", "%B", 3, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("January", "%B", 7, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("Feb", "%B", 3, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("February", "%B", 8, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("Mar", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("March", "%B", 5, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("Apr", "%B", 3, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("April", "%B", 5, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("May", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Jun", "%B", 3, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("June", "%B", 4, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("Jul", "%B", 3, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("July", "%B", 4, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("Aug", "%B", 3, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("August", "%B", 6, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("Sep", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("September", "%B", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("Oct", "%B", 3, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("October", "%B", 7, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("Nov", "%B", 3, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("November", "%B", 8, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("Dec", "%B", 3, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("December", "%B", 8, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("Mayor", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Mars", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_fail("Rover", "%B"); + + h_pass("september", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("septembe", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, common); + ATF_TP_ADD_TC(tp, day); + ATF_TP_ADD_TC(tp, month); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c new file mode 100644 index 0000000..c455d33 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c @@ -0,0 +1,60 @@ +/* $NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $"); + +#include <atf-c.h> +#include <unistd.h> +#include <sys/tls.h> + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +extern __thread int var1; +extern __thread int var2; +extern __thread int *var3; +__thread int var5 = 1; +static __thread pid_t (*local_var)(void) = getpid; + +void testf_dso_helper(int x, int y); + +void +testf_dso_helper(int x, int y) +{ + var1 = x; + var2 = y; + var3 = &optind; + ATF_CHECK_EQ(local_var, getpid); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c new file mode 100644 index 0000000..591823e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c @@ -0,0 +1,113 @@ +/* $NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); + +#include <atf-c.h> +#include <dlfcn.h> +#include <pthread.h> +#include <unistd.h> + +#include <sys/tls.h> + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_dlopen); + +ATF_TC_HEAD(t_tls_dlopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables and dlopen"); +} + +void (*testf_helper)(int, int); + +__thread int var1 = 1; +__thread int var2; +__thread int *var3 = &optind; +int var4_helper; +__thread int *var4 = &var4_helper; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + ATF_CHECK_EQ(var3, &optind); + ATF_CHECK_EQ(var4, &var4_helper); + testf_helper(2, 2); + ATF_CHECK_EQ(var1, 2); + ATF_CHECK_EQ(var2, 2); + testf_helper(3, 3); + ATF_CHECK_EQ(var1, 3); + ATF_CHECK_EQ(var2, 3); + ATF_CHECK_EQ(var3, &optind); + + return NULL; +} + +ATF_TC_BODY(t_tls_dlopen, tc) +{ + void *handle; + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + handle = dlopen("h_tls_dlopen.so", RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE(handle != NULL); + + testf_helper = dlsym(handle, "testf_dso_helper"); + ATF_REQUIRE(testf_helper != NULL); + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + dlclose(handle); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_dlopen); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c new file mode 100644 index 0000000..9d242ae --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c @@ -0,0 +1,105 @@ +/* $NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); + +#include <atf-c.h> +#include <pthread.h> +#include <unistd.h> + +#include <sys/tls.h> + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_dynamic); + +ATF_TC_HEAD(t_tls_dynamic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables in dynamic binaries"); +} + +void testf_dso_helper(int, int); + +extern __thread int var1; +extern __thread int var2; +extern __thread pid_t (*dso_var1)(void); + +__thread int *var3 = &optind; +int var4_helper; +__thread int *var4 = &var4_helper; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + testf_dso_helper(2, 2); + ATF_CHECK_EQ(var1, 2); + ATF_CHECK_EQ(var2, 2); + testf_dso_helper(3, 3); + ATF_CHECK_EQ(var1, 3); + ATF_CHECK_EQ(var2, 3); + ATF_CHECK_EQ(var3, &optind); + ATF_CHECK_EQ(var4, &var4_helper); + ATF_CHECK_EQ(dso_var1, getpid); + + return NULL; +} + +ATF_TC_BODY(t_tls_dynamic, tc) +{ + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_dynamic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c new file mode 100644 index 0000000..7751a16 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); + +#include <atf-c.h> +#include <pthread.h> + +#include <sys/tls.h> + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_static); + +ATF_TC_HEAD(t_tls_static, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables in static binaries"); +} + +void testf_helper(void); + +__thread int var1 = 1; +__thread int var2; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + testf_helper(); + ATF_CHECK_EQ(var1, -1); + ATF_CHECK_EQ(var2, -1); + + return NULL; +} + +ATF_TC_BODY(t_tls_static, tc) +{ + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_static); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c new file mode 100644 index 0000000..da3b6f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c @@ -0,0 +1,53 @@ +/* $NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); + +#include <sys/tls.h> + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +extern __thread int var1; +extern __thread int var2; + +void testf_helper(void); + +void +testf_helper(void) +{ + var1 = -1; + var2 = -1; +} diff --git a/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c new file mode 100644 index 0000000..a12e07a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c @@ -0,0 +1,56 @@ +/* $NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $"); + +#include <unistd.h> +#include <sys/tls.h> + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +__thread int var1 = 1; +__thread int var2; + +__thread pid_t (*dso_var1)(void) = getpid; + +void testf_dso_helper(int x, int y); + +void +testf_dso_helper(int x, int y) +{ + var1 = x; + var2 = y; +} diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c new file mode 100644 index 0000000..5346898 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $ */ + +/* + * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $"); + +#include <sys/ioctl.h> +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> +#include <grp.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x, v) \ + ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno)) + +ATF_TC(ptm); + +ATF_TC_HEAD(ptm, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks /dev/ptm device"); +} + +ATF_TC_BODY(ptm, tc) +{ + struct stat stm, sts; + struct ptmget ptm; + int fdm; + struct group *gp; + + if ((fdm = open("/dev/ptm", O_RDWR)) == -1) { + if (errno == ENOENT || errno == ENODEV) + atf_tc_skip("/dev/ptm: %s", strerror(errno)); + atf_tc_fail("/dev/ptm: %s", strerror(errno)); + } + + REQUIRE_ERRNO(fstat(fdm, &stm), -1); + ATF_REQUIRE_EQ(major(stm.st_rdev), 165); + REQUIRE_ERRNO(ioctl(fdm, TIOCPTMGET, &ptm), -1); + + ATF_REQUIRE_MSG(strncmp(ptm.cn, "/dev/pty", 8) == 0 + || strncmp(ptm.cn, "/dev/null", 9) == 0, + "bad master name: %s", ptm.cn); + + ATF_REQUIRE_MSG(strncmp(ptm.sn, "/dev/tty", 8) == 0 + || strncmp(ptm.sn, "/dev/pts/", 9) == 0, + "bad slave name: %s", ptm.sn); + + if (strncmp(ptm.cn, "/dev/null", 9) != 0) { + REQUIRE_ERRNO(fstat(ptm.cfd, &stm), -1); + REQUIRE_ERRNO(stat(ptm.cn, &sts), -1); + ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev); + } + + REQUIRE_ERRNO(fstat(ptm.sfd, &stm), -1); + REQUIRE_ERRNO(stat(ptm.sn, &sts), -1); + ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev); + + ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid"); + + ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL, + "cannot find `tty' group"); + ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave grid"); + + (void)close(ptm.sfd); + (void)close(ptm.cfd); + (void)close(fdm); +} + +/* + * On NetBSD /dev/ptyp0 == /dev/pts/0 so we can check for major + * and minor device numbers. This check is non-portable. This + * check is now disabled because we might not have /dev/ptyp0 + * at all. + */ + +/* + * #define PTY_DEVNO_CHECK + */ + +ATF_TC(ptmx); + +ATF_TC_HEAD(ptmx, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks /dev/ptmx device"); +} + +ATF_TC_BODY(ptmx, tc) +{ + struct stat stm, sts; + char *pty; + int fdm, fds; + struct group *gp; + + if ((fdm = posix_openpt(O_RDWR|O_NOCTTY)) == -1) { + if (errno == ENOENT || errno == ENODEV) + atf_tc_skip("/dev/ptmx: %s", strerror(errno)); + + atf_tc_fail("/dev/ptmx: %s", strerror(errno)); + } + + REQUIRE_ERRNO(fstat(fdm, &stm), -1); + +#ifdef PTY_DEVNO_CHECK + REQUIRE_ERRNO(stat("/dev/ptyp0", &sts), -1); + + ATF_REQUIRE_EQ_MSG(major(stm.st_rdev), major(sts.st_rdev), + "bad master major number"); +#endif + + REQUIRE_ERRNO(grantpt(fdm), -1); + REQUIRE_ERRNO(unlockpt(fdm), -1); + REQUIRE_ERRNO((pty = ptsname(fdm)), NULL); + + REQUIRE_ERRNO((fds = open(pty, O_RDWR|O_NOCTTY)), -1); + REQUIRE_ERRNO(fstat(fds, &sts), -1); + +#ifdef PTY_DEVNO_CHECK + ATF_REQUIRE_EQ_MSG(minor(stm.st_rdev), minor(sts.st_rdev), + "bad slave minor number"); +#endif + + ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid"); + ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL, + "cannot find `tty' group"); + + ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave gid"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ptm); + ATF_TP_ADD_TC(tp, ptmx); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c new file mode 100644 index 0000000..5a5ec0f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $ */ + +/* + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Brown. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $"); + +#include <sys/types.h> +#include <sys/wait.h> + +#include <err.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> + +#if defined(__NetBSD__) +#include <util.h> +#elif defined(__bsdi__) +int openpty(int *, int *, char *, struct termios *, struct winsize *); +#elif defined(__FreeBSD__) +#include <libutil.h> +#else +#error where openpty? +#endif + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x, v) ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno)) + +ATF_TC(ioctl); +ATF_TC_HEAD(ioctl, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that ioctl calls are restarted " + "properly after being interrupted"); +} + +/* ARGSUSED */ +static void +sigchld(int nsig) +{ + REQUIRE_ERRNO(wait(NULL), -1); +} + +ATF_TC_BODY(ioctl, tc) +{ + int m, s, rc; + char name[128], buf[128]; + struct termios term; + struct sigaction sa; + + /* unbuffer stdout */ + setbuf(stdout, NULL); + + /* + * Create default termios settings for later use + */ + memset(&term, 0, sizeof(term)); + term.c_iflag = TTYDEF_IFLAG; + term.c_oflag = TTYDEF_OFLAG; + term.c_cflag = TTYDEF_CFLAG; + term.c_lflag = TTYDEF_LFLAG; + cfsetspeed(&term, TTYDEF_SPEED); + + /* get a tty */ + REQUIRE_ERRNO(openpty(&m, &s, name, &term, NULL), -1); + + switch (fork()) { + case -1: + atf_tc_fail("fork(): %s", strerror(errno)); + /* NOTREACHED */ + case 0: + /* wait for parent to get set up */ + (void)sleep(1); + (void)printf("child1: exiting\n"); + exit(0); + /* NOTREACHED */ + default: + (void)printf("parent: spawned child1\n"); + break; + } + + switch (fork()) { + case -1: + atf_tc_fail("fork(): %s", strerror(errno)); + /* NOTREACHED */ + case 0: + /* wait for parent to get upset */ + (void)sleep(2); + /* drain the tty q */ + if (read(m, buf, sizeof(buf)) == -1) + err(1, "read"); + (void)printf("child2: exiting\n"); + exit(0); + /* NOTREACHED */ + default: + (void)printf("parent: spawned child2\n"); + break; + } + + /* set up a restarting signal handler */ + (void)sigemptyset(&sa.sa_mask); + sa.sa_handler = sigchld; + sa.sa_flags = SA_RESTART; + REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1); + + /* put something in the output q */ + REQUIRE_ERRNO(write(s, "Hello world\n", 12), -1); + + /* ask for output to drain but don't drain it */ + rc = 0; + if (tcsetattr(s, TCSADRAIN, &term) == -1) { + (void)printf("parent: tcsetattr: %s\n", strerror(errno)); + rc = 1; + } + + /* wait for last child */ + sa.sa_handler = SIG_DFL; + REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1); + (void) wait(NULL); + + ATF_REQUIRE_EQ(rc, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ioctl); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libcrypt/t_crypt.c b/contrib/netbsd-tests/lib/libcrypt/t_crypt.c new file mode 100644 index 0000000..1a192cb --- /dev/null +++ b/contrib/netbsd-tests/lib/libcrypt/t_crypt.c @@ -0,0 +1,145 @@ +/* $NetBSD: t_crypt.c,v 1.3 2011/12/28 22:07:40 christos Exp $ */ + +/* + * This version is derived from the original implementation of FreeSec + * (release 1.1) by David Burren. I've reviewed the changes made in + * OpenBSD (as of 2.7) and modified the original code in a similar way + * where applicable. I've also made it reentrant and made a number of + * other changes. + * - Solar Designer <solar at openwall.com> + */ + +/* + * FreeSec: libcrypt for NetBSD + * + * Copyright (c) 1994 David Burren + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $ + * Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren <davidb at werj.com.au>. + * + * An excellent reference on the underlying algorithm (and related + * algorithms) is: + * + * B. Schneier, Applied Cryptography: protocols, algorithms, + * and source code in C, John Wiley & Sons, 1994. + * + * Note that in that book's description of DES the lookups for the initial, + * pbox, and final permutations are inverted (this has been brought to the + * attention of the author). A list of errata for this book has been + * posted to the sci.crypt newsgroup by the author and is available for FTP. + * + * ARCHITECTURE ASSUMPTIONS: + * This code used to have some nasty ones, but these have been removed + * by now. The code requires a 32-bit integer type, though. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_crypt.c,v 1.3 2011/12/28 22:07:40 christos Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +static const struct { + const char *hash; + const char *pw; +} tests[] = { +/* "new"-style */ +/* 0 */ { "_J9..CCCCXBrJUJV154M", "U*U*U*U*" }, +/* 1 */ { "_J9..CCCCXUhOBTXzaiE", "U*U***U" }, +/* 2 */ { "_J9..CCCC4gQ.mB/PffM", "U*U***U*" }, +/* 3 */ { "_J9..XXXXvlzQGqpPPdk", "*U*U*U*U" }, +/* 4 */ { "_J9..XXXXsqM/YSSP..Y", "*U*U*U*U*" }, +/* 5 */ { "_J9..XXXXVL7qJCnku0I", "*U*U*U*U*U*U*U*U" }, +/* 6 */ { "_J9..XXXXAj8cFbP5scI", "*U*U*U*U*U*U*U*U*" }, +/* 7 */ { "_J9..SDizh.vll5VED9g", "ab1234567" }, +/* 8 */ { "_J9..SDizRjWQ/zePPHc", "cr1234567" }, +/* 9 */ { "_J9..SDizxmRI1GjnQuE", "zxyDPWgydbQjgq" }, +/* 10 */ { "_K9..SaltNrQgIYUAeoY", "726 even" }, +/* 11 */ { "_J9..SDSD5YGyRCr4W4c", "" }, +/* "old"-style, valid salts */ +/* 12 */ { "CCNf8Sbh3HDfQ", "U*U*U*U*" }, +/* 13 */ { "CCX.K.MFy4Ois", "U*U***U" }, +/* 14 */ { "CC4rMpbg9AMZ.", "U*U***U*" }, +/* 15 */ { "XXxzOu6maQKqQ", "*U*U*U*U" }, +/* 16 */ { "SDbsugeBiC58A", "" }, +/* 17 */ { "./xZjzHv5vzVE", "password" }, +/* 18 */ { "0A2hXM1rXbYgo", "password" }, +/* 19 */ { "A9RXdR23Y.cY6", "password" }, +/* 20 */ { "ZziFATVXHo2.6", "password" }, +/* 21 */ { "zZDDIZ0NOlPzw", "password" }, +/* "old"-style, "reasonable" invalid salts, UFC-crypt behavior expected */ +/* 22 */ { "\001\002wyd0KZo65Jo", "password" }, +/* 23 */ { "a_C10Dk/ExaG.", "password" }, +/* 24 */ { "~\377.5OTsRVjwLo", "password" }, +/* The below are erroneous inputs, so NULL return is expected/required */ +/* 25 */ { "", "" }, /* no salt */ +/* 26 */ { " ", "" }, /* setting string is too short */ +/* 27 */ { "a:", "" }, /* unsafe character */ +/* 28 */ { "\na", "" }, /* unsafe character */ +/* 29 */ { "_/......", "" }, /* setting string is too short for its type */ +/* 30 */ { "_........", "" }, /* zero iteration count */ +/* 31 */ { "_/!......", "" }, /* invalid character in count */ +/* 32 */ { "_/......!", "" }, /* invalid character in salt */ +/* 33 */ { NULL, NULL } +}; + +ATF_TC(crypt_salts); + +ATF_TC_HEAD(crypt_salts, tc) +{ + + atf_tc_set_md_var(tc, "descr", "crypt(3) salt consistency checks"); +} + +ATF_TC_BODY(crypt_salts, tc) +{ + for (size_t i = 0; tests[i].hash; i++) { + char *hash = crypt(tests[i].pw, tests[i].hash); + if (!hash) { + ATF_CHECK_MSG(0, "Test %zu NULL\n", i); + continue; + } + if (strcmp(hash, "*0") == 0 && strlen(tests[i].hash) < 13) + continue; /* expected failure */ + if (strcmp(hash, tests[i].hash)) + ATF_CHECK_MSG(0, "Test %zu %s != %s\n", + i, hash, tests[i].hash); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, crypt_salts); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libcurses/atf.terminfo b/contrib/netbsd-tests/lib/libcurses/atf.terminfo new file mode 100644 index 0000000..fcd34b6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/atf.terminfo @@ -0,0 +1,44 @@ +# Based on xterm capabilities +atf|atf automatic test frame pseudo terminal, + am, bce, ccc, km, mc5i, mir, msgr, npc, xenl, + colors#8, cols#80, it#8, lines#24, pairs#64, + acsc=++\,\,--..00``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, + bel=bel, blink=blink, bold=bold, cbt=cbt, civis=civis, clear=clear, + cnorm=cnorm, cr=^M, csr=csr%i%p1%d;%p2%dX, cub=cub%p1%dX, + cub1=^H, cud=cud%p1%dX, cud1=^J, cuf=cuf%p1%dX, cuf1=, + cup=cup%i%p1%d;%p2%dX, cuu=cuu%p1%dX, cuu1=, cvvis=cvvis, + dch=dch%p1%dX, dch1=, dl=dl%p1%dX, dl1=, dim=dim, ech=ech%p1%dX, + ed=ed, el=el, el1=el1, enacs=enacs, flash=flash, home=home, + hpa=hpa%i%p1%dX, ht=^I, hts=hts, ich=ich%p1%dX, il=il%p1%dX, + il1=il1, ind=^M, indn=indn%p1%dX, invis=invis, + is2=is2, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H, + kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~, + kRIT=\E[1;2C, kb2=\EOE, kbs=^H, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB, + kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kend=\EOF, kent=\EOM, + kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P, + kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~, + kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, + kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, + kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S, + kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, + kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, + kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS, + kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, + kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, + kf48=\E[24;6~, kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, + kf51=\E[1;3R, kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~, + kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~, + kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\E[1;4P, + kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, + khome=\EOH, kich1=\E[2~, kind=\E[1;2B, kmous=\E[M, knp=\E[6~, + kpp=\E[5~, kri=\E[1;2A, mc0=mc0, mc4=mc4, mc5=mc5, + op=op, rc=rc, rev=rev, ri=ri, rin=rin%p1%dX, rmacs=rmacs, + rmam=rmam, rmcup=rmcup, rmir=rmir, rmkx=rmkx, + rmm=rmm, rmso=rmso, rmul=rmul, rs1=rs1, + rs2=rs2, sc=sc, setab=setab%p1%dX, + setaf=setaf%p1%dX, setb=setb%p1%dX, setf=setf%p1%dX, + sgr=sgr%p1%d;%p2%d;%p3%d;%p4%d;%p5%d;%p6%d;%p7%d;%p8;%d;%p9%dX, + sgr0=sgr0, smacs=smacs, smam=smam, smcup=smcup, + smir=smir, smkx=smkx, smm=smm, smso=smso, smul=smul, + tbc=tbc, u6=u6%d;%dX, u7=u7, u8=u8, u9=u9, + vpa=vpa%p1%dX diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk new file mode 100644 index 0000000..3e2c6bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk @@ -0,0 +1 @@ +smsotrmso
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk new file mode 100644 index 0000000..42286d0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk @@ -0,0 +1 @@ +revabcdehomesgr0
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk new file mode 100644 index 0000000..6a81654 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk @@ -0,0 +1 @@ +abcde
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk b/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk new file mode 100644 index 0000000..be35b56 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk @@ -0,0 +1 @@ +smsoblinkhellormsosgr0
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk new file mode 100644 index 0000000..e52e439 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk @@ -0,0 +1 @@ +smulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup2;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup3;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup4;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup5;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup6;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup7;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup8;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup9;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup10;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup11;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup12;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup13;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup14;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup15;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup16;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup17;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup18;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup19;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup20;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup21;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup22;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup23;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup24;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup1;1Xrmul
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk new file mode 100644 index 0000000..55a2163 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk @@ -0,0 +1 @@ +smula test stringrmul
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk new file mode 100644 index 0000000..732f4cc --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk @@ -0,0 +1 @@ +cup3;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk new file mode 100644 index 0000000..05698e2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk @@ -0,0 +1,6 @@ +cup1;14Xcup3;6Xrevwindow
+B1BBBB
+BBBBBB
+BBBBBB
+BBBBBB
+BBBBBBcup4;8Xsgr0
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk new file mode 100644 index 0000000..6c37975 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk @@ -0,0 +1,3 @@ +cup1;14Xcup4;8Xrevhell
+o worl
+dsgr0
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk b/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk new file mode 100644 index 0000000..f4d3c21 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk @@ -0,0 +1 @@ +bel
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk b/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk new file mode 100644 index 0000000..5bd91e1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk @@ -0,0 +1,5 @@ +revsmacsqqqqrmacs
+sgr0smsosmacsxrmacssmacsxrmacs
+smacsxrmacssmacsxrmacs
+smacsxrmacssmacsxrmacs
+smacsxrmacssmacsxrmacscup8;7Xrmsorevsmacsqqqqrmacscup3;6Xsgr0
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk new file mode 100644 index 0000000..e9b8b58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk @@ -0,0 +1 @@ +setaf7Xsetab0Xdsetaf3Xsetab6Xrev homesgr0
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk new file mode 100644 index 0000000..cadfb37 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk @@ -0,0 +1 @@ +setaf7Xsetab0Xeop
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk new file mode 100644 index 0000000..7d57a90 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk @@ -0,0 +1 @@ +homesetaf3Xsetab6Xsmulde cup1;1Xrmulop
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk new file mode 100644 index 0000000..9c7d34f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk @@ -0,0 +1 @@ +clear
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk new file mode 100644 index 0000000..1baa2a5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk @@ -0,0 +1 @@ +cup7;7X
EEEEE
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk new file mode 100644 index 0000000..f25000b --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk @@ -0,0 +1 @@ +cup6;6Xabcdecup21;6Xfghijcup11;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk new file mode 100644 index 0000000..dfdd90d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk @@ -0,0 +1 @@ +cup21;6Xelcup11;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk new file mode 100644 index 0000000..abe5be8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk @@ -0,0 +1 @@ +elhome
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk new file mode 100644 index 0000000..d9df62d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk @@ -0,0 +1,23 @@ +homeel
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+elhome
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk new file mode 100644 index 0000000..ff815d3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk @@ -0,0 +1 @@ +abccup7;7Xefgcup4;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk new file mode 100644 index 0000000..8b392c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk @@ -0,0 +1 @@ +cup7;7Xelcup4;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk new file mode 100644 index 0000000..9c9354e --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk @@ -0,0 +1,6 @@ +cup4;6X
+EEEEE
+EEEEE
+EEEEE
+EEEEE
+EEEEE cup3;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk new file mode 100644 index 0000000..c5834a1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk @@ -0,0 +1,6 @@ +cup3;6X
+EEEEE
+EEEEE
+EEEEE
+EEEEE
+EEEEE cup3;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk new file mode 100644 index 0000000..42ad0e2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk @@ -0,0 +1,24 @@ +opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xelhomeop
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk new file mode 100644 index 0000000..5c02e4d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk @@ -0,0 +1,24 @@ +opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xelhome
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk new file mode 100644 index 0000000..d23ddaf --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk @@ -0,0 +1,24 @@ +opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopelhomeop
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk new file mode 100644 index 0000000..3ad4513 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk @@ -0,0 +1,24 @@ +opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xelhomeop
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk new file mode 100644 index 0000000..d8363b7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk @@ -0,0 +1 @@ +setaf1Xsetab2Xtestingop
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk new file mode 100644 index 0000000..d314d07 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk @@ -0,0 +1 @@ +op
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk new file mode 100644 index 0000000..826062a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk @@ -0,0 +1 @@ +cup11;15X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk new file mode 100644 index 0000000..d5c8ea5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk @@ -0,0 +1 @@ +cup11;15Xt s i cup12;15Xg e t cup13;15Xn t s cup14;15X n t scup15;15Xt n t cup16;15X t n t
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk new file mode 100644 index 0000000..9315b76 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk @@ -0,0 +1,4 @@ +cup3;6Xel
+ el
+ elcup6;7Xel
+ elcup8;7Xelcup3;6Xcup11;15Xelcup12;15Xelcup13;15Xelcup14;16Xelcup15;15Xelcup16;16Xelcup11;15X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk new file mode 100644 index 0000000..bc1a526 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk @@ -0,0 +1,4 @@ +cup3;6Xt s i
+ g e t
+ n t scup6;7Xn t s
+ t n tcup8;7Xt n tcup8;11X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk new file mode 100644 index 0000000..f2a8913 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk @@ -0,0 +1 @@ +cup11;16Xe t ncup12;16Xt s icup13;16Xg e tcup14;15Xi g ecup15;16Xi g ecup16;15Xs i g
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk new file mode 100644 index 0000000..e7fd505 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk @@ -0,0 +1 @@ +cup11;15Xtesticup12;15Xgtestcup13;15Xngtescup14;16Xngtescup15;15Xtingtcup16;16Xtingt
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk new file mode 100644 index 0000000..aac0671 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk @@ -0,0 +1,6 @@ +cup3;6Xtestin
+ gtesti
+ ngtest
+ ingtes
+ tingte
+ stingtcup8;11X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk new file mode 100644 index 0000000..317cd93 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk @@ -0,0 +1 @@ +cup12;16Xtestincup13;16Xgtesticup14;16Xngtestcup15;16Xingtescup16;16Xtingtecup17;16Xstingt
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk new file mode 100644 index 0000000..4fa78a9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk @@ -0,0 +1,6 @@ +cup3;6Xel
+ el
+ el
+ el
+ el
+ elcup12;16Xelcup13;16Xelcup14;16Xelcup15;16Xelcup16;16Xelcup17;16Xelcup11;15X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk new file mode 100644 index 0000000..4f0d7da --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk @@ -0,0 +1 @@ +testingtecup12;15Xstingtestcup13;15Xingtestincup14;15Xgtestingtcup15;15Xestingtescup16;15Xtingtesticup16;23X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk new file mode 100644 index 0000000..314dac8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk @@ -0,0 +1,6 @@ +cup3;6Xtestin
+ stingt
+ ingtes
+ gtesti
+ esting
+ tingtecup8;11X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk new file mode 100644 index 0000000..d10a7c2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk @@ -0,0 +1,6 @@ +cup3;6Xel
+ el
+ el
+ el
+ el
+ elcup11;15Xelcup12;15Xelcup13;15Xelcup14;15Xelcup15;15Xelcup16;15Xel
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk new file mode 100644 index 0000000..bc1a526 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk @@ -0,0 +1,4 @@ +cup3;6Xt s i
+ g e t
+ n t scup6;7Xn t s
+ t n tcup8;7Xt n tcup8;11X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk new file mode 100644 index 0000000..f2a8913 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk @@ -0,0 +1 @@ +cup11;16Xe t ncup12;16Xt s icup13;16Xg e tcup14;15Xi g ecup15;16Xi g ecup16;15Xs i g
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk new file mode 100644 index 0000000..81a818c --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk @@ -0,0 +1 @@ +civis
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk new file mode 100644 index 0000000..7682463 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk @@ -0,0 +1 @@ +cnorm
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk new file mode 100644 index 0000000..0f3e744 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk @@ -0,0 +1 @@ +cvvis
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk new file mode 100644 index 0000000..7c4f92c --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk @@ -0,0 +1 @@ +enacsenacssmcupcnormclearclear
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk b/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk new file mode 100644 index 0000000..2d89374 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk @@ -0,0 +1,23 @@ +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEhome
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/home.chk b/contrib/netbsd-tests/lib/libcurses/check_files/home.chk new file mode 100644 index 0000000..0247178 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/home.chk @@ -0,0 +1 @@ +home
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk b/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk new file mode 100644 index 0000000..6463b1e --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk @@ -0,0 +1 @@ +asmkx diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk new file mode 100644 index 0000000..50857fa --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk @@ -0,0 +1,6 @@ +smacslqqqqkrmacs
+ smacsxrmacs smacsxrmacs
+ smacsxrmacs smacsxrmacs
+ smacsxrmacs smacsxrmacs
+ smacsxrmacs smacsxrmacs
+ smacsmqqqqjrmacscup3;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk new file mode 100644 index 0000000..0247178 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk @@ -0,0 +1 @@ +home
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk new file mode 100644 index 0000000..770eab4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk @@ -0,0 +1 @@ +input
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk new file mode 100644 index 0000000..e8bbed5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk @@ -0,0 +1,2 @@ +
+
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/window.chk b/contrib/netbsd-tests/lib/libcurses/check_files/window.chk new file mode 100644 index 0000000..732f4cc --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/window.chk @@ -0,0 +1 @@ +cup3;6X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk new file mode 100644 index 0000000..53794ad --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk @@ -0,0 +1 @@ +cup3;6Xhellocup3;10X
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk new file mode 100644 index 0000000..627141d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk @@ -0,0 +1 @@ +cup4;7Xxxxxhome
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk new file mode 100644 index 0000000..ee36e55 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk @@ -0,0 +1 @@ +cup4;7Xelcup6;7Xxxxxhome
\ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/director/director.c b/contrib/netbsd-tests/lib/libcurses/director/director.c new file mode 100644 index 0000000..c73ddae --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/director.c @@ -0,0 +1,279 @@ +/* $NetBSD: director.c,v 1.10 2012/06/03 23:19:11 joerg Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <ctype.h> +#include <termios.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <util.h> +#include <err.h> +#include "returns.h" + +void yyparse(void); +#define DEF_TERMPATH "." +#define DEF_TERM "atf" +#define DEF_SLAVE "./slave" + +const char *def_check_path = "./"; /* default check path */ +const char *def_include_path = "./"; /* default include path */ + +extern size_t nvars; /* In testlang_conf.y */ +saved_data_t saved_output; /* In testlang_conf.y */ +int cmdpipe[2]; /* command pipe between director and slave */ +int slvpipe[2]; /* reply pipe back from slave */ +int master; /* pty to the slave */ +int verbose; /* control verbosity of tests */ +const char *check_path; /* path to prepend to check files for output + validation */ +const char *include_path; /* path to prepend to include files */ +char *cur_file; /* name of file currently being read */ + +void init_parse_variables(int); /* in testlang_parse.y */ + +/* + * Handle the slave exiting unexpectedly, try to recover the exit message + * and print it out. + */ +static void +slave_died(int param) +{ + char last_words[256]; + size_t count; + + fprintf(stderr, "ERROR: Slave has exited\n"); + if (saved_output.count > 0) { + fprintf(stderr, "output from slave: "); + for (count = 0; count < saved_output.count; count ++) { + if (isprint((unsigned char)saved_output.data[count])) + fprintf(stderr, "%c", saved_output.data[count]); + } + fprintf(stderr, "\n"); + } + + if ((count = read(master, &last_words, 255)) > 0) { + last_words[count] = '\0'; + fprintf(stderr, "slave exited with message \"%s\"\n", + last_words); + } + + exit(2); +} + + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s [-v] [-I include-path] [-C check-path] " + "[-T terminfo-file] [-s pathtoslave] [-t term] " + "commandfile\n", getprogname()); + fprintf(stderr, " where:\n"); + fprintf(stderr, " -v enables verbose test output\n"); + fprintf(stderr, " -T is a directory containing the terminfo.cdb " + "file, or a file holding the terminfo description n"); + fprintf(stderr, " -s is the path to the slave executable\n"); + fprintf(stderr, " -t is value to set TERM to for the test\n"); + fprintf(stderr, " -I is the directory to include files\n"); + fprintf(stderr, " -C is the directory for config files\n"); + fprintf(stderr, " commandfile is a file of test directives\n"); + exit(1); +} + + +int +main(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + const char *termpath, *term, *slave; + int ch; + pid_t slave_pid; + extern FILE *yyin; + char *arg1, *arg2, *arg3, *arg4; + struct termios term_attr; + struct stat st; + + termpath = term = slave = NULL; + verbose = 0; + + while ((ch = getopt(argc, argv, "vC:I:p:s:t:T:")) != -1) { + switch(ch) { + case 'I': + include_path = optarg; + break; + case 'C': + check_path = optarg; + break; + case 'T': + termpath = optarg; + break; + case 'p': + termpath = optarg; + break; + case 's': + slave = optarg; + break; + case 't': + term = optarg; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + usage(); + break; + } + } + + argc -= optind; + argv += optind; + if (argc < 1) + usage(); + + if (termpath == NULL) + termpath = DEF_TERMPATH; + + if (slave == NULL) + slave = DEF_SLAVE; + + if (term == NULL) + term = DEF_TERM; + + if (check_path == NULL) + check_path = getenv("CHECK_PATH"); + if ((check_path == NULL) || (check_path[0] == '\0')) { + warn("$CHECK_PATH not set, defaulting to %s", def_check_path); + check_path = def_check_path; + } + + if (include_path == NULL) + include_path = getenv("INCLUDE_PATH"); + if ((include_path == NULL) || (include_path[0] == '\0')) { + warn("$INCLUDE_PATH not set, defaulting to %s", + def_include_path); + include_path = def_include_path; + } + + signal(SIGCHLD, slave_died); + + if (setenv("TERM", term, 1) != 0) + err(2, "Failed to set TERM variable"); + + if (stat(termpath, &st) == -1) + err(1, "Cannot stat %s", termpath); + + if (S_ISDIR(st.st_mode)) { + char tinfo[MAXPATHLEN]; + int l = snprintf(tinfo, sizeof(tinfo), "%s/%s", termpath, + "terminfo.cdb"); + if (stat(tinfo, &st) == -1) + err(1, "Cannot stat `%s'", tinfo); + if (l >= 4) + tinfo[l - 4] = '\0'; + if (setenv("TERMINFO", tinfo, 1) != 0) + err(1, "Failed to set TERMINFO variable"); + } else { + int fd; + char *tinfo; + if ((fd = open(termpath, O_RDONLY)) == -1) + err(1, "Cannot open `%s'", termpath); + if ((tinfo = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE, + fd, 0)) == MAP_FAILED) + err(1, "Cannot map `%s'", termpath); + if (setenv("TERMINFO", tinfo, 1) != 0) + err(1, "Failed to set TERMINFO variable"); + close(fd); + munmap(tinfo, (size_t)st.st_size); + } + + if (pipe(cmdpipe) < 0) + err(1, "Command pipe creation failed"); + + if (pipe(slvpipe) < 0) + err(1, "Slave pipe creation failed"); + + /* + * Create default termios settings for later use + */ + memset(&term_attr, 0, sizeof(term_attr)); + term_attr.c_iflag = TTYDEF_IFLAG; + term_attr.c_oflag = TTYDEF_OFLAG; + term_attr.c_cflag = TTYDEF_CFLAG; + term_attr.c_lflag = TTYDEF_LFLAG; + cfsetspeed(&term_attr, TTYDEF_SPEED); + term_attr.c_cc[VERASE] = '\b'; + term_attr.c_cc[VKILL] = '\025'; /* ^U */ + + if ((slave_pid = forkpty(&master, NULL, &term_attr, NULL)) < 0) + err(1, "Fork of pty for slave failed\n"); + + if (slave_pid == 0) { + /* slave side, just exec the slave process */ + if (asprintf(&arg1, "%d", cmdpipe[0]) < 0) + err(1, "arg1 conversion failed"); + + if (asprintf(&arg2, "%d", cmdpipe[1]) < 0) + err(1, "arg2 conversion failed"); + + if (asprintf(&arg3, "%d", slvpipe[0]) < 0) + err(1, "arg3 conversion failed"); + + if (asprintf(&arg4, "%d", slvpipe[1]) < 0) + err(1, "arg4 conversion failed"); + + if (execl(slave, slave, arg1, arg2, arg3, arg4, NULL) < 0) + err(1, "Exec of slave %s failed", slave); + + /* NOT REACHED */ + } + + fcntl(master, F_SETFL, O_NONBLOCK); + + if ((yyin = fopen(argv[0], "r")) == NULL) + err(1, "Cannot open command file %s", argv[0]); + + if ((cur_file = strdup(argv[0])) == NULL) + err(2, "Failed to alloc memory for test file name"); + + init_parse_variables(1); + + yyparse(); + fclose(yyin); + + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libcurses/director/returns.h b/contrib/netbsd-tests/lib/libcurses/director/returns.h new file mode 100644 index 0000000..150e358 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/returns.h @@ -0,0 +1,66 @@ +/* $NetBSD: returns.h,v 1.1 2011/04/10 09:55:09 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ +#ifndef CTF_RETURNS_H +#define CTF_RETURNS_H 1 + + +typedef enum { + ret_number = 1, + ret_string, + ret_byte, + ret_err, + ret_ok, + ret_null, + ret_nonnull, + ret_var, + ret_ref, + ret_count, + ret_slave_error +} returns_enum_t; + +typedef struct { + returns_enum_t return_type; + void *return_value; /* used if return_type is ret_num or + or ret_byte or ret_string */ + size_t return_len; /* number of bytes in return_value iff + return_type is ret_byte */ + int return_index; /* index into var array for return + if return_type is ret_var */ +} returns_t; + +typedef struct { + size_t count; + size_t allocated; + size_t readp; + char *data; +} saved_data_t; + +#endif /* CTF_RETURNS_H */ diff --git a/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l b/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l new file mode 100644 index 0000000..a732afc --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l @@ -0,0 +1,437 @@ +%{ +/* $NetBSD: testlang_conf.l,v 1.7 2013/11/21 11:06:04 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <curses.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> +#include <err.h> +#include "returns.h" +#include "testlang_parse.h" + +#define MAX_INCLUDES 32 /* limit for the number of nested includes */ + +int yylex(void); + +extern size_t line; +extern char *include_path; /* from director.c */ +extern char *cur_file; /* from director.c */ + +static int include_stack[MAX_INCLUDES]; +static char *include_files[MAX_INCLUDES]; +static int include_ptr = 0; + +static char * +dequote(const char *s, size_t *len) +{ + const unsigned char *p; + char *buf, *q; + + *len = 0; + p = (const unsigned char *)s; + while (*p) { + if (*p == '\\' && *(p+1)) { + if (isdigit(*(p+1)) && *(p+2) && isdigit(*(p+2)) && + *(p+3) && isdigit(*(p+3))) + p += 3; + else + ++p; + } + ++(*len); + ++p; + } + + buf = malloc(*len + 1); + if (buf == NULL) + return NULL; + + p = (const unsigned char *)s; + q = buf; + while (*p) { + if (*p == '\\' && *(p+1)) { + ++p; + if (isdigit(*p)) { + if (*(p+1) && isdigit(*(p+1)) && *(p+2) && + isdigit(*(p+2))) { + *q++ = ((*p - '0') * 8 + (*(p+1) - '0')) * 8 + (*(p+2) - '0'); + p += 3; + } else { + *q++ = *p++; + } + } else { + switch (*p) { + case 'e': + /* escape */ + *q++ = '\e'; + p++; + break; + + case 'n': + /* newline */ + *q++ = '\n'; + p++; + break; + + case 'r': + /* carriage return */ + *q++ = '\r'; + p++; + break; + + case 't': + /* tab */ + *q++ = '\t'; + p++; + break; + + case '\\': + /* backslash */ + *q++ = '\\'; + p++; + break; + + default: + *q++ = *p++; + } + } + } else + *q++ = *p++; + } + *q++ = '\0'; + + return buf; +} +%} + +HEX 0[xX][0-9a-zA-Z]+ +STRING [0-9a-z!#-&(-^ \t%._\\]+ +numeric [-0-9]+ +PCHAR (\\.|[^ \t\n]) +ASSIGN [aA][sS][sS][iI][gG][nN] +CALL2 [cC][aA][lL][lL]2 +CALL3 [cC][aA][lL][lL]3 +CALL4 [cC][aA][lL][lL]4 +CALL [cC][aA][lL][lL] +CHECK [cC][hH][eE][cC][kK] +DELAY [dD][eE][lL][aA][yY] +INPUT [iI][nN][pP][uU][tT] +NOINPUT [nN][oO][iI][nN][pP][uU][tT] +OK_RET [oO][kK] +ERR_RET [eE][rR][rR] +COMPARE [cC][oO][mM][pP][aA][rR][eE] +COMPAREND [cC][oO][mM][pP][aA][rR][eE][Nn][Dd] +FILENAME [A-Za-z0-9.][A-Za-z0-9./_-]+ +VARNAME [A-Za-z][A-Za-z0-9_-]+ +NULL_RET NULL +NON_NULL NON_NULL +BYTE BYTE +OR \| +LHB \( +RHB \) + +%x incl +%option noinput nounput + +%% + +include BEGIN(incl); + +<incl>[ \t]* /* eat the whitespace */ +<incl>[^ \t\n]+ { /* got the include file name */ + char inc_file[MAXPATHLEN]; + + if (include_ptr > MAX_INCLUDES) { + fprintf(stderr, + "Maximum number of nested includes exceeded " + "at line %zu of file %s\n", line, cur_file); + exit(2); + } + + if (yytext[0] != '/') { + if (strlcpy(inc_file, include_path, sizeof(inc_file)) + >= sizeof(inc_file)) + err(2, "CHECK_PATH too long"); + if ((include_path[strlen(include_path) - 1] != '/') && + ((strlcat(inc_file, "/", sizeof(inc_file)) + >= sizeof(inc_file)))) + err(2, "Could not append / to include file path"); + } else { + inc_file[0] = '\0'; + } + + if (strlcat(inc_file, yytext, sizeof(inc_file)) + >= sizeof(inc_file)) + err(2, "Path to include file path overflowed"); + + yyin = fopen(inc_file, "r" ); + + if (!yyin) + err(1, "Error opening %s", inc_file); + + yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); + + include_stack[include_ptr] = line; + include_files[include_ptr++] = cur_file; + cur_file = strdup(inc_file); + if (cur_file == NULL) + err(2, "Cannot allocate new include file string"); + line = 0; + BEGIN(INITIAL); + } + +<<EOF>> { + yypop_buffer_state(); + + if ( !YY_CURRENT_BUFFER ) + { + yyterminate(); + } + + if (--include_ptr < 0) + err(2, "Include stack underflow"); + + free(cur_file); + cur_file = include_files[include_ptr]; + line = include_stack[include_ptr]; + } + +{ASSIGN} { + return ASSIGN; + } + +{CALL2} { + return CALL2; + } + +{CALL3} { + return CALL3; + } + +{CALL4} { + return CALL4; + } + +{CALL} { + return CALL; + } + +{CHECK} { + return CHECK; + } + +{DELAY} { + return DELAY; + } + +{INPUT} { + return INPUT; + } + +{NOINPUT} { + return NOINPUT; + } + +{COMPARE} { + return COMPARE; + } + +{COMPAREND} { + return COMPAREND; + } + +{NON_NULL} { + return NON_NULL; + } + +{NULL_RET} { + return NULL_RET; + } + +{OK_RET} { + return OK_RET; + } + +{ERR_RET} { + return ERR_RET; + } + +{OR} { + return OR; + } + +{LHB} { + return LHB; + } + +{RHB} { + return RHB; + } + +{HEX} { + /* Hex value, convert to decimal and return numeric */ + unsigned long val; + + if (sscanf(yytext, "%lx", &val) != 1) + err(1, "Bad hex conversion"); + + asprintf(&yylval.string, "%ld", val); + return numeric; + } + + +{numeric} { + if ((yylval.string = strdup(yytext)) == NULL) + err(1, "Cannot allocate numeric string"); + return numeric; +} + +{VARNAME} { + if ((yylval.string = strdup(yytext)) == NULL) + err(1, "Cannot allocate string for varname"); + return VARNAME; + } + +{FILENAME} { + size_t len; + + if ((yylval.string = dequote(yytext, &len)) == NULL) + err(1, "Cannot allocate filename string"); + return FILENAME; + } + + /* path */ +\/{PCHAR}+ { + size_t len; + if ((yylval.string = dequote(yytext, &len)) == NULL) + err(1, "Cannot allocate string"); + return PATH; + } + +\'{STRING}\' { + char *p; + size_t len; + + if ((yylval.retval = malloc(sizeof(returns_t))) == NULL) + err(1, "Cannot allocate return struct"); + p = yytext; + p++; /* skip the leading ' */ + if ((yylval.retval->return_value = dequote(p, &len)) + == NULL) + err(1, "Cannot allocate string"); + + yylval.retval->return_type = ret_byte; + /* trim trailing ' */ + yylval.retval->return_len = len - 1; + return BYTE; + } + +\`{STRING}\` { + char *p, *str; + size_t len, chlen; + size_t i; + chtype *rv; + + if ((yylval.retval = malloc(sizeof(returns_t))) == NULL) + err(1, "Cannot allocate return struct"); + p = yytext; + p++; /* skip the leading ' */ + if ((str = dequote(p, &len)) == NULL) + err(1, "Cannot allocate string"); + len--; /* trim trailing ` */ + if ((len % 2) != 0) + len--; + + chlen = ((len / 2) + 1) * sizeof(chtype); + if ((yylval.retval->return_value = malloc(chlen)) + == NULL) + err(1, "Cannot allocate chtype array"); + + rv = yylval.retval->return_value; + for (i = 0; i < len; i += 2) + *rv++ = (str[i] << 8) | str[i+1]; + *rv = __NORMAL | '\0'; /* terminates chtype array */ + yylval.retval->return_type = ret_byte; + yylval.retval->return_len = chlen; + return BYTE; + } + +\"{STRING}\" { + char *p; + size_t len; + + p = yytext; + p++; /* skip the leading " */ + if ((yylval.string = dequote(p, &len)) == NULL) + err(1, "Cannot allocate string"); + + /* remove trailing " */ + yylval.string[len - 1] = '\0'; + return STRING; + } + +\${VARNAME} { + char *p; + + p = yytext; + p++; /* skip $ before var name */ + if ((yylval.string = strdup(p)) == NULL) + err(1, "Cannot allocate string for varname"); + return VARIABLE; + } + + /* comments, white-outs */ +[ \t\r] | +#.* ; +^#.*\n | +#.*\n | +\\\n | +^\n { +line++; } + + /* eol on a line with data. need to process, return eol */ +\n { + line++; + return EOL; + } + +. { + } + +%% + +int +yywrap(void) +{ + return 1; +} diff --git a/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y b/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y new file mode 100644 index 0000000..37c813f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y @@ -0,0 +1,1617 @@ +%{ +/* $NetBSD: testlang_parse.y,v 1.13 2012/09/19 11:51:56 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ +#include <assert.h> +#include <curses.h> +#include <errno.h> +#include <fcntl.h> +#include <err.h> +#include <unistd.h> +#include <poll.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <sys/syslimits.h> +#include <time.h> +#include <vis.h> +#include <stdint.h> +#include "returns.h" + +#define YYDEBUG 1 + +extern int verbose; +extern int cmdpipe[2]; +extern int slvpipe[2]; +extern int master; +extern struct pollfd readfd; +extern char *check_path; +extern char *cur_file; /* from director.c */ + +int yylex(void); + +size_t line; + +static int input_delay; + +/* time delay between inputs chars - default to 0.1ms minimum to prevent + * problems with input tests + */ +#define DELAY_MIN 0.1 + +/* time delay after a function call - allows the slave time to + * run the function and output data before we do other actions. + * Set this to 50ms. + */ +#define POST_CALL_DELAY 50 + +static struct timespec delay_spec = {0, 1000 * DELAY_MIN}; +static struct timespec delay_post_call = {0, 1000 * POST_CALL_DELAY}; + +static char *input_str; /* string to feed in as input */ +static bool no_input; /* don't need more input */ + +#define READ_PIPE 0 +#define WRITE_PIPE 1 + +const char *returns_enum_names[] = { + "unused", "numeric", "string", "byte", "ERR", "OK", "NULL", "not NULL", + "variable", "reference", "returns count", "slave error" +}; + +typedef enum { + arg_static, + arg_byte, + arg_var, + arg_null +} args_state_t; + +static const char *args_enum_names[] = { + "static", "byte", "var", "NULL" +}; + +typedef struct { + args_state_t arg_type; + size_t arg_len; + char *arg_string; + int var_index; +} args_t; + +typedef struct { + char *function; + int nrets; /* number of returns */ + returns_t *returns; /* array of expected returns */ + int nargs; /* number of arguments */ + args_t *args; /* arguments for the call */ +} cmd_line_t; + +static cmd_line_t command; + +typedef struct { + char *name; + size_t len; + returns_enum_t type; + void *value; +} var_t; + +static size_t nvars; /* Number of declared variables */ +static var_t *vars; /* Variables defined during the test. */ + +static int check_function_table(char *, const char *[], int); +static int find_var_index(const char *); +static void assign_arg(args_state_t, void *); +static int assign_var(char *); +void init_parse_variables(int); +static void validate(int, void *); +static void validate_return(const char *, const char *, int); +static void validate_variable(int, returns_enum_t, const void *, int, int); +static void validate_byte(returns_t *, returns_t *, int); +static void write_cmd_pipe(char *); +static void write_cmd_pipe_args(args_state_t, void *); +static void read_cmd_pipe(returns_t *); +static void write_func_and_args(void); +static void compare_streams(char *, bool); +static void do_function_call(size_t); +static void save_slave_output(bool); +static void validate_type(returns_enum_t, returns_t *, int); +static void set_var(returns_enum_t, char *, void *); +static void validate_reference(int, void *); +static char *numeric_or(char *, char *); +static char *get_numeric_var(const char *); +static void perform_delay(struct timespec *); + +static const char *input_functions[] = { + "getch", "getnstr", "getstr", "mvgetnstr", "mvgetstr", "mvgetnstr", + "mvgetstr", "mvscanw", "mvwscanw", "scanw", "wgetch", "wgetnstr", + "wgetstr" +}; + +static const unsigned ninput_functions = + sizeof(input_functions) / sizeof(char *); + +saved_data_t saved_output; + +%} + +%union { + char *string; + returns_t *retval; +} + +%token <string> PATH +%token <string> STRING +%token <retval> BYTE +%token <string> VARNAME +%token <string> FILENAME +%token <string> VARIABLE +%token <string> REFERENCE +%token <string> NULL_RET +%token <string> NON_NULL +%token <string> ERR_RET +%token <string> OK_RET +%token <string> numeric +%token <string> DELAY +%token <string> INPUT +%token <string> COMPARE +%token <string> COMPAREND +%token <string> ASSIGN +%token EOL CALL CHECK NOINPUT OR LHB RHB +%token CALL2 CALL3 CALL4 DRAIN + +%nonassoc OR + +%% + +statement : /* empty */ + | assign statement + | call statement + | call2 statement + | call3 statement + | call4 statement + | check statement + | delay statement + | input statement + | noinput statement + | compare statement + | comparend statement + | eol statement + ; + +assign : ASSIGN VARNAME numeric {set_var(ret_number, $2, $3);} eol + | ASSIGN VARNAME LHB expr RHB {set_var(ret_number, $2, $<string>4);} eol + | ASSIGN VARNAME STRING {set_var(ret_string, $2, $3);} eol + | ASSIGN VARNAME BYTE {set_var(ret_byte, $2, $3);} eol + ; + +call : CALL result fn_name args eol { + do_function_call(1); +} + ; + +call2 : CALL2 result result fn_name args eol { + do_function_call(2); +} + ; + +call3 : CALL3 result result result fn_name args eol { + do_function_call(3); +} + ; + +call4 : CALL4 result result result result fn_name args eol { + do_function_call(4); + } + ; + +check : CHECK var returns eol { + returns_t retvar; + var_t *vptr; + if (command.returns[0].return_index == -1) + err(1, "Undefined variable in check statement, line %zu" + " of file %s", line, cur_file); + + if (verbose) { + fprintf(stderr, "Checking contents of variable %s for %s\n", + vars[command.returns[0].return_index].name, + returns_enum_names[command.returns[1].return_type]); + } + + if (((command.returns[1].return_type == ret_byte) && + (vars[command.returns[0].return_index].type != ret_byte)) || + vars[command.returns[0].return_index].type != ret_string) + err(1, "Var type %s (%d) does not match return type %s (%d)", + returns_enum_names[ + vars[command.returns[0].return_index].type], + vars[command.returns[0].return_index].type, + returns_enum_names[command.returns[1].return_type], + command.returns[1].return_type); + + switch (command.returns[1].return_type) { + case ret_err: + validate_variable(0, ret_string, "ERR", + command.returns[0].return_index, 0); + break; + + case ret_ok: + validate_variable(0, ret_string, "OK", + command.returns[0].return_index, 0); + break; + + case ret_null: + validate_variable(0, ret_string, "NULL", + command.returns[0].return_index, 0); + break; + + case ret_nonnull: + validate_variable(0, ret_string, "NULL", + command.returns[0].return_index, 1); + break; + + case ret_string: + case ret_number: + if (verbose) { + fprintf(stderr, " %s == returned %s\n", + (const char *)command.returns[1].return_value, + (const char *) + vars[command.returns[0].return_index].value); + } + validate_variable(0, ret_string, + command.returns[1].return_value, + command.returns[0].return_index, 0); + break; + + case ret_byte: + vptr = &vars[command.returns[0].return_index]; + retvar.return_len = vptr->len; + retvar.return_type = vptr->type; + retvar.return_value = vptr->value; + validate_byte(&retvar, &command.returns[1], 0); + break; + + default: + err(1, "Malformed check statement at line %zu " + "of file %s", line, cur_file); + break; + } + + init_parse_variables(0); + } + ; + +delay : DELAY numeric eol { + /* set the inter-character delay */ + if (sscanf($2, "%d", &input_delay) == 0) + err(1, "delay specification %s could not be converted to " + "numeric at line %zu of file %s", $2, line, cur_file); + if (verbose) { + fprintf(stderr, "Set input delay to %d ms\n", input_delay); + } + + if (input_delay < DELAY_MIN) + input_delay = DELAY_MIN; + /* + * Fill in the timespec structure now ready for use later. + * The delay is specified in milliseconds so convert to timespec + * values + */ + delay_spec.tv_sec = input_delay / 1000; + delay_spec.tv_nsec = (input_delay - 1000 * delay_spec.tv_sec) * 1000; + if (verbose) { + fprintf(stderr, "set delay to %jd.%jd\n", + (intmax_t)delay_spec.tv_sec, + (intmax_t)delay_spec.tv_nsec); + } + + init_parse_variables(0); + } + ; + +input : INPUT STRING eol { + if (input_str != NULL) { + warnx("%s, %zu: Discarding unused input string", + cur_file, line); + free(input_str); + } + + if ((input_str = malloc(strlen($2) + 1)) == NULL) + err(2, "Cannot allocate memory for input string"); + + strlcpy(input_str, $2, strlen($2) + 1); +} + ; + + +noinput : NOINPUT eol { + if (input_str != NULL) { + warnx("%s, %zu: Discarding unused input string", + cur_file, line); + free(input_str); + } + + no_input = true; + } + +compare : COMPARE PATH eol + | COMPARE FILENAME eol +{ + compare_streams($2, true); +} + ; + + +comparend : COMPAREND PATH eol + | COMPAREND FILENAME eol +{ + compare_streams($2, false); +} + ; + + +result : returns + | var + | reference + ; + +returns : numeric { assign_rets(ret_number, $1); } + | LHB expr RHB { assign_rets(ret_number, $<string>2); } + | STRING { assign_rets(ret_string, $1); } + | BYTE { assign_rets(ret_byte, (void *) $1); } + | ERR_RET { assign_rets(ret_err, NULL); } + | OK_RET { assign_rets(ret_ok, NULL); } + | NULL_RET { assign_rets(ret_null, NULL); } + | NON_NULL { assign_rets(ret_nonnull, NULL); } + ; + +var : VARNAME { + assign_rets(ret_var, $1); + } + ; + +reference : VARIABLE { + assign_rets(ret_ref, $1); + } + +fn_name : VARNAME { + if (command.function != NULL) + free(command.function); + + command.function = malloc(strlen($1) + 1); + if (command.function == NULL) + err(1, "Could not allocate memory for function name"); + strcpy(command.function, $1); + } + ; + +expr : numeric + | VARIABLE + { $<string>$ = get_numeric_var($1); } + | expr OR expr + { $<string>$ = numeric_or($<string>1, $<string>3); } + ; + +args : /* empty */ + | LHB expr RHB { assign_arg(arg_static, $<string>2); } args + | numeric { assign_arg(arg_static, $1); } args + | STRING { assign_arg(arg_static, $1); } args + | BYTE { assign_arg(arg_byte, $1); } args + | PATH { assign_arg(arg_static, $1); } args + | FILENAME { assign_arg(arg_static, $1); } args + | VARNAME { assign_arg(arg_static, $1); } args + | VARIABLE { assign_arg(arg_var, $1); } args + | NULL_RET { assign_arg(arg_null, $1); } args + ; + +eol : EOL + ; + +%% + +static void +excess(const char *fname, size_t lineno, const char *func, const char *comment, + const void *data, size_t datalen) +{ + size_t dstlen = datalen * 4 + 1; + char *dst = malloc(dstlen); + + if (dst == NULL) + err(1, "malloc"); + + if (strnvisx(dst, dstlen, data, datalen, VIS_WHITE | VIS_OCTAL) == -1) + err(1, "strnvisx"); + + warnx("%s, %zu: [%s] Excess %zu bytes%s [%s]", + fname, lineno, func, datalen, comment, dst); + free(dst); +} + +/* + * Get the value of a variable, error if the variable has not been set or + * is not a numeric type. + */ +static char * +get_numeric_var(const char *var) +{ + int i; + + if ((i = find_var_index(var)) < 0) + err(1, "Variable %s is undefined", var); + + if (vars[i].type != ret_number) + err(1, "Variable %s is not a numeric type", var); + + return vars[i].value; +} + +/* + * Perform a bitwise OR on two numbers and return the result. + */ +static char * +numeric_or(char *n1, char *n2) +{ + unsigned long i1, i2, result; + char *ret; + + i1 = strtoul(n1, NULL, 10); + i2 = strtoul(n2, NULL, 10); + + result = i1 | i2; + asprintf(&ret, "%lu", result); + + if (verbose) { + fprintf(stderr, "numeric or of 0x%lx (%s) and 0x%lx (%s)" + " results in 0x%lx (%s)\n", + i1, n1, i2, n2, result, ret); + } + + return ret; +} + +/* + * Sleep for the specified time, handle the sleep getting interrupted + * by a signal. + */ +static void +perform_delay(struct timespec *ts) +{ + struct timespec delay_copy, delay_remainder; + + delay_copy = *ts; + while (nanosleep(&delay_copy, &delay_remainder) < 0) { + if (errno != EINTR) + err(2, "nanosleep returned error"); + delay_copy = delay_remainder; + } +} + +/* + * Assign the value given to the named variable. + */ +static void +set_var(returns_enum_t type, char *name, void *value) +{ + int i; + char *number; + returns_t *ret; + + i = find_var_index(name); + if (i < 0) + i = assign_var(name); + + vars[i].type = type; + if ((type == ret_number) || (type == ret_string)) { + number = value; + vars[i].len = strlen(number) + 1; + vars[i].value = malloc(vars[i].len + 1); + if (vars[i].value == NULL) + err(1, "Could not malloc memory for assign string"); + strcpy(vars[i].value, number); + } else { + /* can only be a byte value */ + ret = value; + vars[i].len = ret->return_len; + vars[i].value = malloc(vars[i].len); + if (vars[i].value == NULL) + err(1, "Could not malloc memory to assign byte string"); + memcpy(vars[i].value, ret->return_value, vars[i].len); + } +} + +/* + * Add a new variable to the vars array, the value will be assigned later, + * when a test function call returns. + */ +static int +assign_var(char *varname) +{ + var_t *temp; + char *name; + + if ((name = malloc(strlen(varname) + 1)) == NULL) + err(1, "Alloc of varname failed"); + + if ((temp = realloc(vars, sizeof(*temp) * (nvars + 1))) == NULL) { + free(name); + err(1, "Realloc of vars array failed"); + } + + strcpy(name, varname); + vars = temp; + vars[nvars].name = name; + vars[nvars].len = 0; + vars[nvars].value = NULL; + nvars++; + + return (nvars - 1); +} + +/* + * Allocate and assign a new argument of the given type. + */ +static void +assign_arg(args_state_t arg_type, void *arg) +{ + args_t *temp, cur; + char *str = arg; + returns_t *ret; + + if (verbose) { + fprintf(stderr, "function is >%s<, adding arg >%s< type %s\n", + command.function, str, args_enum_names[arg_type]); + } + + cur.arg_type = arg_type; + switch (arg_type) { + case arg_var: + cur.var_index = find_var_index(arg); + if (cur.var_index < 0) + err(1, "Invalid variable %s at line %zu of file %s", + str, line, cur_file); + cur.arg_type = ret_string; + break; + + case arg_byte: + ret = arg; + cur.arg_len = ret->return_len; + cur.arg_string = malloc(cur.arg_len); + if (cur.arg_string == NULL) + err(1, "Could not malloc memory for arg bytes"); + memcpy(cur.arg_string, ret->return_value, cur.arg_len); + break; + + case arg_null: + cur.arg_len = 0; + cur.arg_string = NULL; + break; + + default: + cur.arg_len = strlen(str); + cur.arg_string = malloc(cur.arg_len + 1); + if (cur.arg_string == NULL) + err(1, "Could not malloc memory for arg string"); + strcpy(cur.arg_string, arg); + } + + temp = realloc(command.args, sizeof(*temp) * (command.nargs + 1)); + if (temp == NULL) + err(1, "Failed to reallocate args"); + command.args = temp; + memcpy(&command.args[command.nargs], &cur, sizeof(args_t)); + command.nargs++; +} + +/* + * Allocate and assign a new return. + */ +static void +assign_rets(returns_enum_t ret_type, void *ret) +{ + returns_t *temp, cur; + char *ret_str; + returns_t *ret_ret; + + cur.return_type = ret_type; + if (ret_type != ret_var) { + if ((ret_type == ret_number) || (ret_type == ret_string)) { + ret_str = ret; + cur.return_len = strlen(ret_str) + 1; + cur.return_value = malloc(cur.return_len + 1); + if (cur.return_value == NULL) + err(1, + "Could not malloc memory for arg string"); + strcpy(cur.return_value, ret_str); + } else if (ret_type == ret_byte) { + ret_ret = ret; + cur.return_len = ret_ret->return_len; + cur.return_value = malloc(cur.return_len); + if (cur.return_value == NULL) + err(1, + "Could not malloc memory for byte string"); + memcpy(cur.return_value, ret_ret->return_value, + cur.return_len); + } else if (ret_type == ret_ref) { + if ((cur.return_index = find_var_index(ret)) < 0) + err(1, "Undefined variable reference"); + } + } else { + cur.return_index = find_var_index(ret); + if (cur.return_index < 0) + cur.return_index = assign_var(ret); + } + + temp = realloc(command.returns, sizeof(*temp) * (command.nrets + 1)); + if (temp == NULL) + err(1, "Failed to reallocate returns"); + command.returns = temp; + memcpy(&command.returns[command.nrets], &cur, sizeof(returns_t)); + command.nrets++; +} + +/* + * Find the given variable name in the var array and return the i + * return -1 if var is not found. + */ +static int +find_var_index(const char *var_name) +{ + int result; + size_t i; + + result = -1; + + for (i = 0; i < nvars; i++) { + if (strcmp(var_name, vars[i].name) == 0) { + result = i; + break; + } + } + + return result; +} + +/* + * Check the given function name in the given table of names, return 1 if + * there is a match. + */ +static int check_function_table(char *function, const char *table[], + int nfunctions) +{ + int i; + + for (i = 0; i < nfunctions; i++) { + if ((strlen(function) == strlen(table[i])) && + (strcmp(function, table[i]) == 0)) + return 1; + } + + return 0; +} + +/* + * Compare the output from the slave against the given file and report + * any differences. + */ +static void +compare_streams(char *filename, bool discard) +{ + char check_file[PATH_MAX], drain[100], ref, data; + struct pollfd fds[2]; + int nfd, check_fd; + ssize_t result; + size_t offs; + + /* + * Don't prepend check path iff check file has an absolute + * path. + */ + if (filename[0] != '/') { + if (strlcpy(check_file, check_path, sizeof(check_file)) + >= sizeof(check_file)) + err(2, "CHECK_PATH too long"); + + if (strlcat(check_file, "/", sizeof(check_file)) + >= sizeof(check_file)) + err(2, "Could not append / to check file path"); + } else { + check_file[0] = '\0'; + } + + if (strlcat(check_file, filename, sizeof(check_file)) + >= sizeof(check_file)) + err(2, "Path to check file path overflowed"); + + if ((check_fd = open(check_file, O_RDONLY, 0)) < 0) + err(2, "failed to open file %s line %zu of file %s", + check_file, line, cur_file); + + fds[0].fd = check_fd; + fds[0].events = POLLIN; + fds[1].fd = master; + fds[1].events = POLLIN; + + nfd = 2; + /* + * if we have saved output then only check for data in the + * reference file since the slave data may already be drained. + */ + if (saved_output.count > 0) + nfd = 1; + + offs = 0; + while (poll(fds, nfd, 500) == nfd) { + if (fds[0].revents & POLLIN) { + if ((result = read(check_fd, &ref, 1)) < 1) { + if (result != 0) { + err(2, + "Bad read on file %s", check_file); + } else { + break; + } + } + } + + if (saved_output.count > 0) { + data = saved_output.data[saved_output.readp]; + saved_output.count--; + saved_output.readp++; + /* run out of saved data, switch to file */ + if (saved_output.count == 0) + nfd = 2; + } else { + if (fds[0].revents & POLLIN) { + if (read(master, &data, 1) < 1) + err(2, "Bad read on slave pty"); + } else + continue; + } + + if (verbose) { + fprintf(stderr, "Comparing reference byte 0x%x (%c)" + " against slave byte 0x%x (%c)\n", + ref, (ref >= ' ') ? ref : '-', + data, (data >= ' ' )? data : '-'); + } + + if (ref != data) { + errx(2, "%s, %zu: refresh data from slave does " + "not match expected from file %s offs %zu " + "[reference 0x%x (%c) != slave 0x%x (%c)]", + cur_file, line, check_file, offs, + ref, (ref >= ' ') ? ref : '-', + data, (data >= ' ') ? data : '-'); + } + + offs++; + } + + + if (saved_output.count > 0) + excess(cur_file, line, __func__, " from slave", + &saved_output.data[saved_output.readp], saved_output.count); + + /* discard any excess saved output if required */ + if (discard) { + saved_output.count = 0; + saved_output.readp = 0; + } + + if ((result = poll(&fds[0], 2, 0)) != 0) { + if (result == -1) + err(2, "poll of file descriptors failed"); + + if ((fds[1].revents & POLLIN) == POLLIN) { + save_slave_output(true); + } else if ((fds[0].revents & POLLIN) == POLLIN) { + /* + * handle excess in file if it exists. Poll + * says there is data until EOF is read. + * Check next read is EOF, if it is not then + * the file really has more data than the + * slave produced so flag this as a warning. + */ + result = read(check_fd, drain, sizeof(drain)); + if (result == -1) + err(1, "read of data file failed"); + + if (result > 0) { + excess(check_file, 0, __func__, "", drain, + result); + } + } + } + + close(check_fd); +} + +/* + * Pass a function call and arguments to the slave and wait for the + * results. The variable nresults determines how many returns we expect + * back from the slave. These results will be validated against the + * expected returns or assigned to variables. + */ +static void +do_function_call(size_t nresults) +{ +#define MAX_RESULTS 4 + char *p; + int do_input; + size_t i; + struct pollfd fds[3]; + returns_t response[MAX_RESULTS], returns_count; + assert(nresults <= MAX_RESULTS); + + do_input = check_function_table(command.function, input_functions, + ninput_functions); + + write_func_and_args(); + + /* + * We should get the number of returns back here, grab it before + * doing input otherwise it will confuse the input poll + */ + read_cmd_pipe(&returns_count); + if (returns_count.return_type != ret_count) + err(2, "expected return type of ret_count but received %s", + returns_enum_names[returns_count.return_type]); + + perform_delay(&delay_post_call); /* let slave catch up */ + + if (verbose) { + fprintf(stderr, "Expect %zu results from slave, slave " + "reported %zu\n", nresults, returns_count.return_len); + } + + if ((no_input == false) && (do_input == 1)) { + if (verbose) { + fprintf(stderr, "doing input with inputstr >%s<\n", + input_str); + } + + if (input_str == NULL) + errx(2, "%s, %zu: Call to input function " + "but no input defined", cur_file, line); + + fds[0].fd = slvpipe[READ_PIPE]; + fds[0].events = POLLIN; + fds[1].fd = master; + fds[1].events = POLLOUT; + p = input_str; + save_slave_output(false); + while(*p != '\0') { + perform_delay(&delay_spec); + + if (poll(fds, 2, 0) < 0) + err(2, "poll failed"); + if (fds[0].revents & POLLIN) { + warnx("%s, %zu: Slave function " + "returned before end of input string", + cur_file, line); + break; + } + if ((fds[1].revents & POLLOUT) == 0) + continue; + if (verbose) { + fprintf(stderr, "Writing char >%c< to slave\n", + *p); + } + if (write(master, p, 1) != 1) { + warn("%s, %zu: Slave function write error", + cur_file, line); + break; + } + p++; + + } + save_slave_output(false); + + if (verbose) { + fprintf(stderr, "Input done.\n"); + } + + /* done with the input string, free the resources */ + free(input_str); + input_str = NULL; + } + + if (verbose) { + fds[0].fd = slvpipe[READ_PIPE]; + fds[0].events = POLLIN; + + fds[1].fd = slvpipe[WRITE_PIPE]; + fds[1].events = POLLOUT; + + fds[2].fd = master; + fds[2].events = POLLIN | POLLOUT; + + i = poll(&fds[0], 3, 1000); + fprintf(stderr, "Poll returned %zu\n", i); + for (i = 0; i < 3; i++) { + fprintf(stderr, "revents for fd[%zu] = 0x%x\n", + i, fds[i].revents); + } + } + + /* drain any trailing output */ + save_slave_output(false); + + for (i = 0; i < returns_count.return_len; i++) { + read_cmd_pipe(&response[i]); + } + + /* + * Check for a slave error in the first return slot, if the + * slave errored then we may not have the number of returns we + * expect but in this case we should report the slave error + * instead of a return count mismatch. + */ + if ((returns_count.return_len > 0) && + (response[0].return_type == ret_slave_error)) + err(2, "Slave returned error: %s", + (const char *)response[0].return_value); + + if (returns_count.return_len != nresults) + err(2, "Incorrect number of returns from slave, expected %zu " + "but received %zu", nresults, returns_count.return_len); + + if (verbose) { + for (i = 0; i < nresults; i++) { + if ((response[i].return_type != ret_byte) && + (response[i].return_type != ret_err) && + (response[i].return_type != ret_ok)) + fprintf(stderr, + "received response >%s< " + "expected", + (const char *)response[i].return_value); + else + fprintf(stderr, "received"); + + fprintf(stderr, " return_type %s\n", + returns_enum_names[command.returns[i].return_type]); + } + } + + for (i = 0; i < nresults; i++) { + if (command.returns[i].return_type != ret_var) { + validate(i, &response[i]); + } else { + vars[command.returns[i].return_index].len = + response[i].return_len; + vars[command.returns[i].return_index].value = + response[i].return_value; + vars[command.returns[i].return_index].type = + response[i].return_type; + } + } + + if (verbose && (saved_output.count > 0)) + excess(cur_file, line, __func__, " from slave", + &saved_output.data[saved_output.readp], saved_output.count); + + init_parse_variables(0); +} + +/* + * Write the function and command arguments to the command pipe. + */ +static void +write_func_and_args(void) +{ + int i; + + if (verbose) { + fprintf(stderr, "calling function >%s<\n", command.function); + } + + write_cmd_pipe(command.function); + for (i = 0; i < command.nargs; i++) { + if (command.args[i].arg_type == arg_var) + write_cmd_pipe_args(command.args[i].arg_type, + &vars[command.args[i].var_index]); + else + write_cmd_pipe_args(command.args[i].arg_type, + &command.args[i]); + } + + write_cmd_pipe(NULL); /* signal end of arguments */ +} + +/* + * Initialise the command structure - if initial is non-zero then just set + * everything to sane values otherwise free any memory that was allocated + * when building the structure. + */ +void +init_parse_variables(int initial) +{ + int i, result; + struct pollfd slave_pty; + + if (initial == 0) { + free(command.function); + for (i = 0; i < command.nrets; i++) { + if (command.returns[i].return_type == ret_number) + free(command.returns[i].return_value); + } + free(command.returns); + + for (i = 0; i < command.nargs; i++) { + if (command.args[i].arg_type != arg_var) + free(command.args[i].arg_string); + } + free(command.args); + } else { + line = 0; + input_delay = 0; + vars = NULL; + nvars = 0; + input_str = NULL; + saved_output.allocated = 0; + saved_output.count = 0; + saved_output.readp = 0; + saved_output.data = NULL; + } + + no_input = false; + command.function = NULL; + command.nargs = 0; + command.args = NULL; + command.nrets = 0; + command.returns = NULL; + + /* + * Check the slave pty for stray output from the slave, at this + * point we should not see any data as it should have been + * consumed by the test functions. If we see data then we have + * either a bug or are not handling an output generating function + * correctly. + */ + slave_pty.fd = master; + slave_pty.events = POLLIN; + result = poll(&slave_pty, 1, 0); + + if (result < 0) + err(2, "Poll of slave pty failed"); + else if (result > 0) + warnx("%s, %zu: Unexpected data from slave", cur_file, line); +} + +/* + * Validate the response against the expected return. The variable + * i is the i into the rets array in command. + */ +static void +validate(int i, void *data) +{ + char *response; + returns_t *byte_response; + + byte_response = data; + if ((command.returns[i].return_type != ret_byte) && + (command.returns[i].return_type != ret_err) && + (command.returns[i].return_type != ret_ok)) { + if ((byte_response->return_type == ret_byte) || + (byte_response->return_type == ret_err) || + (byte_response->return_type == ret_ok)) + err(1, "%s: expecting type %s, received type %s" + " at line %zu of file %s", __func__, + returns_enum_names[command.returns[i].return_type], + returns_enum_names[byte_response->return_type], + line, cur_file); + + response = byte_response->return_value; + } + + switch (command.returns[i].return_type) { + case ret_err: + validate_type(ret_err, byte_response, 0); + break; + + case ret_ok: + validate_type(ret_ok, byte_response, 0); + break; + + case ret_null: + validate_return("NULL", response, 0); + break; + + case ret_nonnull: + validate_return("NULL", response, 1); + break; + + case ret_string: + case ret_number: + validate_return(command.returns[i].return_value, + response, 0); + break; + + case ret_ref: + validate_reference(i, response); + break; + + case ret_byte: + validate_byte(&command.returns[i], byte_response, 0); + break; + + default: + err(1, "Malformed statement at line %zu of file %s", + line, cur_file); + break; + } +} + +/* + * Validate the return against the contents of a variable. + */ +static void +validate_reference(int i, void *data) +{ + char *response; + returns_t *byte_response; + var_t *varp; + + varp = &vars[command.returns[i].return_index]; + + byte_response = data; + if (command.returns[i].return_type != ret_byte) + response = data; + + if (verbose) { + fprintf(stderr, + "%s: return type of %s, value %s \n", __func__, + returns_enum_names[varp->type], + (const char *)varp->value); + } + + switch (varp->type) { + case ret_string: + case ret_number: + validate_return(varp->value, response, 0); + break; + + case ret_byte: + validate_byte(varp->value, byte_response, 0); + break; + + default: + err(1, + "Invalid return type for reference at line %zu of file %s", + line, cur_file); + break; + } +} + +/* + * Validate the return type against the expected type, throw an error + * if they don't match. + */ +static void +validate_type(returns_enum_t expected, returns_t *value, int check) +{ + if (((check == 0) && (expected != value->return_type)) || + ((check == 1) && (expected == value->return_type))) + err(1, "Validate expected type %s %s %s line %zu of file %s", + returns_enum_names[expected], + (check == 0)? "matching" : "not matching", + returns_enum_names[value->return_type], line, cur_file); + + if (verbose) { + fprintf(stderr, "Validate expected type %s %s %s line %zu" + " of file %s\n", + returns_enum_names[expected], + (check == 0)? "matching" : "not matching", + returns_enum_names[value->return_type], line, cur_file); + } +} + +/* + * Validate the return value against the expected value, throw an error + * if they don't match. + */ +static void +validate_return(const char *expected, const char *value, int check) +{ + if (((check == 0) && strcmp(expected, value) != 0) || + ((check == 1) && strcmp(expected, value) == 0)) + errx(1, "Validate expected %s %s %s line %zu of file %s", + expected, + (check == 0)? "matching" : "not matching", value, + line, cur_file); + if (verbose) { + fprintf(stderr, "Validated expected value %s %s %s " + "at line %zu of file %s\n", expected, + (check == 0)? "matches" : "does not match", + value, line, cur_file); + } +} + +/* + * Validate the return value against the expected value, throw an error + * if they don't match expectations. + */ +static void +validate_byte(returns_t *expected, returns_t *value, int check) +{ + char *ch; + size_t i; + + if (verbose) { + ch = value->return_value; + fprintf(stderr, "checking returned byte stream: "); + for (i = 0; i < value->return_len; i++) + fprintf(stderr, "%s0x%x", (i != 0)? ", " : "", ch[i]); + fprintf(stderr, "\n"); + + fprintf(stderr, "%s byte stream: ", + (check == 0)? "matches" : "does not match"); + ch = (char *) expected->return_value; + for (i = 0; i < expected->return_len; i++) + fprintf(stderr, "%s0x%x", (i != 0)? ", " : "", ch[i]); + fprintf(stderr, "\n"); + } + + /* + * No chance of a match if lengths differ... + */ + if ((check == 0) && (expected->return_len != value->return_len)) + errx(1, "Byte validation failed, length mismatch, expected %zu," + "received %zu", expected->return_len, value->return_len); + + /* + * If check is 0 then we want to throw an error IFF the byte streams + * do not match, if check is 1 then throw an error if the byte + * streams match. + */ + if (((check == 0) && memcmp(expected->return_value, value->return_value, + value->return_len) != 0) || + ((check == 1) && (expected->return_len == value->return_len) && + memcmp(expected->return_value, value->return_value, + value->return_len) == 0)) + errx(1, "Validate expected %s byte stream at line %zu" + "of file %s", + (check == 0)? "matching" : "not matching", line, cur_file); + if (verbose) { + fprintf(stderr, "Validated expected %s byte stream " + "at line %zu of file %s\n", + (check == 0)? "matching" : "not matching", + line, cur_file); + } +} + +/* + * Validate the variable at i against the expected value, throw an + * error if they don't match, if check is non-zero then the match is + * negated. + */ +static void +validate_variable(int ret, returns_enum_t type, const void *value, int i, + int check) +{ + returns_t *retval; + var_t *varptr; + + retval = &command.returns[ret]; + varptr = &vars[command.returns[ret].return_index]; + + if (varptr->value == NULL) + err(1, "Variable %s has no value assigned to it", varptr->name); + + + if (varptr->type != type) + err(1, "Variable %s is not the expected type", varptr->name); + + if (type != ret_byte) { + if ((((check == 0) && strcmp(value, varptr->value) != 0)) + || ((check == 1) && strcmp(value, varptr->value) == 0)) + err(1, "Variable %s contains %s instead of %s" + " value %s at line %zu of file %s", + varptr->name, (const char *)varptr->value, + (check == 0)? "expected" : "not matching", + (const char *)value, + line, cur_file); + if (verbose) { + fprintf(stderr, "Variable %s contains %s value " + "%s at line %zu of file %s\n", + varptr->name, + (check == 0)? "expected" : "not matching", + (const char *)varptr->value, line, cur_file); + } + } else { + if ((check == 0) && (retval->return_len != varptr->len)) + err(1, "Byte validation failed, length mismatch"); + + /* + * If check is 0 then we want to throw an error IFF + * the byte streams do not match, if check is 1 then + * throw an error if the byte streams match. + */ + if (((check == 0) && memcmp(retval->return_value, varptr->value, + varptr->len) != 0) || + ((check == 1) && (retval->return_len == varptr->len) && + memcmp(retval->return_value, varptr->value, + varptr->len) == 0)) + err(1, "Validate expected %s byte stream at line %zu" + " of file %s", + (check == 0)? "matching" : "not matching", + line, cur_file); + if (verbose) { + fprintf(stderr, "Validated expected %s byte stream " + "at line %zu of file %s\n", + (check == 0)? "matching" : "not matching", + line, cur_file); + } + } +} + +/* + * Write a string to the command pipe - we feed the number of bytes coming + * down first to allow storage allocation and then follow up with the data. + * If cmd is NULL then feed a -1 down the pipe to say the end of the args. + */ +static void +write_cmd_pipe(char *cmd) +{ + args_t arg; + size_t len; + + if (cmd == NULL) + len = 0; + else + len = strlen(cmd); + + arg.arg_type = arg_static; + arg.arg_len = len; + arg.arg_string = cmd; + write_cmd_pipe_args(arg.arg_type, &arg); + +} + +static void +write_cmd_pipe_args(args_state_t type, void *data) +{ + var_t *var_data; + args_t *arg_data; + int len, send_type; + void *cmd; + + arg_data = data; + switch (type) { + case arg_var: + var_data = data; + len = var_data->len; + cmd = var_data->value; + if (type == arg_byte) + send_type = ret_byte; + else + send_type = ret_string; + break; + + case arg_null: + send_type = ret_null; + len = 0; + break; + + default: + if ((arg_data->arg_len == 0) && (arg_data->arg_string == NULL)) + len = -1; + else + len = arg_data->arg_len; + cmd = arg_data->arg_string; + if (type == arg_byte) + send_type = ret_byte; + else + send_type = ret_string; + } + + if (verbose) { + fprintf(stderr, "Writing type %s to command pipe\n", + returns_enum_names[send_type]); + } + + if (write(cmdpipe[WRITE_PIPE], &send_type, sizeof(int)) < 0) + err(1, "command pipe write for type failed"); + + if (verbose) { + fprintf(stderr, "Writing length %d to command pipe\n", len); + } + + if (write(cmdpipe[WRITE_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe write for length failed"); + + if (len > 0) { + if (verbose) { + fprintf(stderr, "Writing data >%s< to command pipe\n", + (const char *)cmd); + } + if (write(cmdpipe[WRITE_PIPE], cmd, len) < 0) + err(1, "command pipe write of data failed"); + } +} + +/* + * Read a response from the command pipe, first we will receive the + * length of the response then the actual data. + */ +static void +read_cmd_pipe(returns_t *response) +{ + int len, type; + struct pollfd rfd[2]; + char *str; + + /* + * Check if there is data to read - just in case slave has died, we + * don't want to block on the read and just hang. We also check + * output from the slave because the slave may be blocked waiting + * for a flush on its stdout. + */ + rfd[0].fd = slvpipe[READ_PIPE]; + rfd[0].events = POLLIN; + rfd[1].fd = master; + rfd[1].events = POLLIN; + + do { + if (poll(rfd, 2, 4000) == 0) + errx(2, "%s, %zu: Command pipe read timeout", + cur_file, line); + + if ((rfd[1].revents & POLLIN) == POLLIN) { + if (verbose) { + fprintf(stderr, + "draining output from slave\n"); + } + save_slave_output(false); + } + } + while((rfd[1].revents & POLLIN) == POLLIN); + + if (read(slvpipe[READ_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe read for type failed"); + response->return_type = type; + + if ((type != ret_ok) && (type != ret_err) && (type != ret_count)) { + if (read(slvpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe read for length failed"); + response->return_len = len; + + if (verbose) { + fprintf(stderr, + "Reading %d bytes from command pipe\n", len); + } + + if ((response->return_value = malloc(len + 1)) == NULL) + err(1, "Failed to alloc memory for cmd pipe read"); + + if (read(slvpipe[READ_PIPE], response->return_value, len) < 0) + err(1, "command pipe read of data failed"); + + if (response->return_type != ret_byte) { + str = response->return_value; + str[len] = '\0'; + + if (verbose) { + fprintf(stderr, "Read data >%s< from pipe\n", + (const char *)response->return_value); + } + } + } else { + response->return_value = NULL; + if (type == ret_count) { + if (read(slvpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe read for number of " + "returns failed"); + response->return_len = len; + } + + if (verbose) { + fprintf(stderr, "Read type %s from pipe\n", + returns_enum_names[type]); + } + } +} + +/* + * Check for writes from the slave on the pty, save the output into a + * buffer for later checking if discard is false. + */ +#define MAX_DRAIN 256 + +static void +save_slave_output(bool discard) +{ + char *new_data, drain[MAX_DRAIN]; + size_t to_allocate; + ssize_t result; + size_t i; + + result = 0; + for (;;) { + if (result == -1) + err(2, "poll of slave pty failed"); + result = MAX_DRAIN; + if ((result = read(master, drain, result)) < 0) { + if (errno == EAGAIN) + break; + else + err(2, "draining slave pty failed"); + } + if (result == 0) + abort(); + + if (!discard) { + if ((size_t)result > + (saved_output.allocated - saved_output.count)) { + to_allocate = 1024 * ((result / 1024) + 1); + + if ((new_data = realloc(saved_output.data, + saved_output.allocated + to_allocate)) + == NULL) + err(2, "Realloc of saved_output failed"); + saved_output.data = new_data; + saved_output.allocated += to_allocate; + } + + if (verbose) { + fprintf(stderr, "count = %zu, " + "allocated = %zu\n", saved_output.count, + saved_output.allocated); + for (i = 0; i < (size_t)result; i++) { + fprintf(stderr, "Saving slave output " + "at %zu: 0x%x (%c)\n", + saved_output.count + i, drain[i], + (drain[i] >= ' ')? drain[i] : '-'); + } + } + + memcpy(&saved_output.data[saved_output.count], drain, + result); + saved_output.count += result; + + if (verbose) { + fprintf(stderr, "count = %zu, " + "allocated = %zu\n", saved_output.count, + saved_output.allocated); + } + } else { + if (verbose) { + for (i = 0; i < (size_t)result; i++) { + fprintf(stderr, "Discarding slave " + "output 0x%x (%c)\n", + drain[i], + (drain[i] >= ' ')? drain[i] : '-'); + } + } + } + } +} + +static void +yyerror(const char *msg) +{ + warnx("%s in line %zu of file %s", msg, line, cur_file); +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/command_table.h b/contrib/netbsd-tests/lib/libcurses/slave/command_table.h new file mode 100644 index 0000000..ef57a00 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/command_table.h @@ -0,0 +1,397 @@ +/* $NetBSD: command_table.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#ifndef _COMMAND_TABLE_H_ +#define _COMMAND_TABLE_H_ + +#include "curses_commands.h" + +/* + * Curses commands + */ +struct command_def commands[] = { + {"DRAIN", cmd_DRAIN}, + {"addbytes", cmd_addbytes}, + {"addch", cmd_addch}, + {"addchnstr", cmd_addchnstr}, + {"addchstr", cmd_addchstr}, + {"addnstr", cmd_addnstr}, + {"addstr", cmd_addstr}, + {"attr_get", cmd_attr_get}, + {"attr_off", cmd_attr_off}, + {"attr_on", cmd_attr_on}, + {"attr_set", cmd_attr_set}, + {"attroff", cmd_attroff}, + {"attron", cmd_attron}, + {"attrset", cmd_attrset}, + {"bkgd", cmd_bkgd}, + {"bkgdset", cmd_bkgdset}, + {"border", cmd_border}, + {"clear", cmd_clear}, + {"clrtobot", cmd_clrtobot}, + {"clrtoeol", cmd_clrtoeol}, + {"color_set", cmd_color_set}, + {"delch", cmd_delch}, + {"deleteln", cmd_deleteln}, + {"echochar", cmd_echochar}, + {"erase", cmd_erase}, + {"getch", cmd_getch}, + {"getnstr", cmd_getnstr}, + {"getstr", cmd_getstr}, + {"inch", cmd_inch}, + {"inchnstr", cmd_inchnstr}, + {"inchstr", cmd_inchstr}, + {"innstr", cmd_innstr}, + {"insch", cmd_insch}, + {"insdelln", cmd_insdelln}, + {"insertln", cmd_insertln}, + {"instr", cmd_instr}, + {"move", cmd_move}, + {"refresh", cmd_refresh}, + {"scrl", cmd_scrl}, + {"setscrreg", cmd_setscrreg}, + {"standend", cmd_standend}, + {"standout", cmd_standout}, + {"timeout", cmd_timeout}, + {"underscore", cmd_underscore}, + {"underend", cmd_underend}, + {"waddbytes", cmd_waddbytes}, + {"waddstr", cmd_waddstr}, + {"mvaddbytes", cmd_mvaddbytes}, + {"mvaddch", cmd_mvaddch}, + {"mvaddchnstr", cmd_mvaddchnstr}, + {"mvaddchstr", cmd_mvaddchstr}, + {"mvaddnstr", cmd_mvaddnstr}, + {"mvaddstr", cmd_mvaddstr}, + {"mvdelch", cmd_mvdelch}, + {"mvgetch", cmd_mvgetch}, + {"mvgetnstr", cmd_mvgetnstr}, + {"mvgetstr", cmd_mvgetstr}, + {"mvinch", cmd_mvinch}, + {"mvinchnstr", cmd_mvinchnstr}, + {"mvinchstr", cmd_mvinchstr}, + {"mvinnstr", cmd_mvinnstr}, + {"mvinsch", cmd_mvinsch}, + {"mvinstr", cmd_mvinstr}, + {"mvwaddbytes", cmd_mvwaddbytes}, + {"mvwaddch", cmd_mvwaddch}, + {"mvwaddchnstr", cmd_mvwaddchnstr}, + {"mvwaddchstr", cmd_mvwaddchstr}, + {"mvwaddnstr", cmd_mvwaddnstr}, + {"mvwaddstr", cmd_mvwaddstr}, + {"mvwdelch", cmd_mvwdelch}, + {"mvwgetch", cmd_mvwgetch}, + {"mvwgetnstr", cmd_mvwgetnstr}, + {"mvwgetstr", cmd_mvwgetstr}, + {"mvwinch", cmd_mvwinch}, + {"mvwinsch", cmd_mvwinsch}, + {"assume_default_colors", cmd_assume_default_colors}, + {"baudrate", cmd_baudrate}, + {"beep", cmd_beep}, + {"box", cmd_box}, + {"can_change_color", cmd_can_change_color}, + {"cbreak", cmd_cbreak}, + {"clearok", cmd_clearok}, + {"color_content", cmd_color_content}, + {"copywin", cmd_copywin}, + {"curs_set", cmd_curs_set}, + {"def_prog_mode", cmd_def_prog_mode}, + {"def_shell_mode", cmd_def_shell_mode}, + {"define_key", cmd_define_key}, + {"delay_output", cmd_delay_output}, + {"delscreen", cmd_delscreen}, + {"delwin", cmd_delwin}, + {"derwin", cmd_derwin}, + {"dupwin", cmd_dupwin}, + {"doupdate", cmd_doupdate}, + {"echo", cmd_echo}, + {"endwin", cmd_endwin}, + {"erasechar", cmd_erasechar}, + {"flash", cmd_flash}, + {"flushinp", cmd_flushinp}, + {"flushok", cmd_flushok}, + {"fullname", cmd_fullname}, + {"getattrs", cmd_getattrs}, + {"getbkgd", cmd_getbkgd}, + {"getcury", cmd_getcury}, + {"getcurx", cmd_getcurx}, + {"getyx", cmd_getyx}, + {"getbegy", cmd_getbegy}, + {"getbegx", cmd_getbegx}, + {"getmaxy", cmd_getmaxy}, + {"getmaxx", cmd_getmaxx}, + {"getpary", cmd_getpary}, + {"getparx", cmd_getparx}, + {"getparyx", cmd_getparyx}, + {"gettmode", cmd_gettmode}, + {"getwin", cmd_getwin}, + {"halfdelay", cmd_halfdelay}, + {"has_colors", cmd_has_colors}, + {"has_ic", cmd_has_ic}, + {"has_il", cmd_has_il}, + {"hline", cmd_hline}, + {"idcok", cmd_idcok}, + {"idlok", cmd_idlok}, + {"init_color", cmd_init_color}, + {"init_pair", cmd_init_pair}, + {"initscr", cmd_initscr}, + {"intrflush", cmd_intrflush}, + {"isendwin", cmd_isendwin}, + {"is_linetouched", cmd_is_linetouched}, + {"is_wintouched", cmd_is_wintouched}, + {"keyok", cmd_keyok}, + {"keypad", cmd_keypad}, + {"keyname", cmd_keyname}, + {"killchar", cmd_killchar}, + {"leaveok", cmd_leaveok}, + {"meta", cmd_meta}, + {"mvcur", cmd_mvcur}, + {"mvderwin", cmd_mvderwin}, + {"mvhline", cmd_mvhline}, + {"mvprintw", cmd_mvprintw}, + {"mvscanw", cmd_mvscanw}, + {"mvvline", cmd_mvvline}, + {"mvwhline", cmd_mvwhline}, + {"mvwvline", cmd_mvwvline}, + {"mvwin", cmd_mvwin}, + {"mvwinchnstr", cmd_mvwinchnstr}, + {"mvwinchstr", cmd_mvwinchstr}, + {"mvwinnstr", cmd_mvwinnstr}, + {"mvwinstr", cmd_mvwinstr}, + {"mvwprintw", cmd_mvwprintw}, + {"mvwscanw", cmd_mvwscanw}, + {"napms", cmd_napms}, + {"newpad", cmd_newpad}, + {"newterm", cmd_newterm}, + {"newwin", cmd_newwin}, + {"nl", cmd_nl}, + {"no_color_attributes", cmd_no_color_attributes}, + {"nocbreak", cmd_nocbreak}, + {"nodelay", cmd_nodelay}, + {"noecho", cmd_noecho}, + {"nonl", cmd_nonl}, + {"noqiflush", cmd_noqiflush}, + {"noraw", cmd_noraw}, + {"notimeout", cmd_notimeout}, + {"overlay", cmd_overlay}, + {"overwrite", cmd_overwrite}, + {"pair_content", cmd_pair_content}, + {"pechochar", cmd_pechochar}, + {"pnoutrefresh", cmd_pnoutrefresh}, + {"prefresh", cmd_prefresh}, + {"printw", cmd_printw}, + {"putwin", cmd_putwin}, + {"qiflush", cmd_qiflush}, + {"raw", cmd_raw}, + {"redrawwin", cmd_redrawwin}, + {"reset_prog_mode", cmd_reset_prog_mode}, + {"reset_shell_mode", cmd_reset_shell_mode}, + {"resetty", cmd_resetty}, + {"resizeterm", cmd_resizeterm}, + {"savetty", cmd_savetty}, + {"scanw", cmd_scanw}, + {"scroll", cmd_scroll}, + {"scrollok", cmd_scrollok}, + {"setterm", cmd_setterm}, + {"set_term", cmd_set_term}, + {"start_color", cmd_start_color}, + {"subpad", cmd_subpad}, + {"subwin", cmd_subwin}, + {"termattrs", cmd_termattrs}, + {"term_attrs", cmd_term_attrs}, + {"touchline", cmd_touchline}, + {"touchoverlap", cmd_touchoverlap}, + {"touchwin", cmd_touchwin}, + {"ungetch", cmd_ungetch}, + {"untouchwin", cmd_untouchwin}, + {"use_default_colors", cmd_use_default_colors}, + {"vline", cmd_vline}, + {"vw_printw", cmd_vw_printw}, + {"vw_scanw", cmd_vw_scanw}, + {"vwprintw", cmd_vwprintw}, + {"vwscanw", cmd_vwscanw}, + {"waddch", cmd_waddch}, + {"waddchnstr", cmd_waddchnstr}, + {"waddchstr", cmd_waddchstr}, + {"waddnstr", cmd_waddnstr}, + {"wattr_get", cmd_wattr_get}, + {"wattr_off", cmd_wattr_off}, + {"wattr_on", cmd_wattr_on}, + {"wattr_set", cmd_wattr_set}, + {"wattroff", cmd_wattroff}, + {"wattron", cmd_wattron}, + {"wattrset", cmd_wattrset}, + {"wbkgd", cmd_wbkgd}, + {"wbkgdset", cmd_wbkgdset}, + {"wborder", cmd_wborder}, + {"wclear", cmd_wclear}, + {"wclrtobot", cmd_wclrtobot}, + {"wclrtoeol", cmd_wclrtoeol}, + {"wcolor_set", cmd_wcolor_set}, + {"wdelch", cmd_wdelch}, + {"wdeleteln", cmd_wdeleteln}, + {"wechochar", cmd_wechochar}, + {"werase", cmd_werase}, + {"wgetch", cmd_wgetch}, + {"wgetnstr", cmd_wgetnstr}, + {"wgetstr", cmd_wgetstr}, + {"whline", cmd_whline}, + {"winch", cmd_winch}, + {"winchnstr", cmd_winchnstr}, + {"winchstr", cmd_winchstr}, + {"winnstr", cmd_winnstr}, + {"winsch", cmd_winsch}, + {"winsdelln", cmd_winsdelln}, + {"winsertln", cmd_winsertln}, + {"winstr", cmd_winstr}, + {"wmove", cmd_wmove}, + {"wnoutrefresh", cmd_wnoutrefresh}, + {"wprintw", cmd_wprintw}, + {"wredrawln", cmd_wredrawln}, + {"wrefresh", cmd_wrefresh}, + {"wresize", cmd_wresize}, + {"wscanw", cmd_wscanw}, + {"wscrl", cmd_wscrl}, + {"wsetscrreg", cmd_wsetscrreg}, + {"wstandend", cmd_wstandend}, + {"wstandout", cmd_wstandout}, + {"wtimeout", cmd_wtimeout}, + {"wtouchln", cmd_wtouchln}, + {"wunderend", cmd_wunderend}, + {"wunderscore", cmd_wunderscore}, + {"wvline", cmd_wvline}, + {"insnstr", cmd_insnstr}, + {"insstr", cmd_insstr}, + {"mvinsnstr", cmd_mvinsnstr}, + {"mvinsstr", cmd_mvinsstr}, + {"mvwinsnstr", cmd_mvwinsnstr}, + {"mvwinsstr", cmd_mvwinsstr}, + {"winsnstr", cmd_winsnstr}, + {"winsstr", cmd_winsstr}, + {"chgat", cmd_chgat}, + {"wchgat", cmd_wchgat}, + {"mvchgat", cmd_mvchgat}, + {"mvwchgat", cmd_mvwchgat}, + {"add_wch", cmd_add_wch}, + {"wadd_wch", cmd_wadd_wch}, + {"mvadd_wch", cmd_mvadd_wch}, + {"mvwadd_wch", cmd_mvwadd_wch}, + {"add_wchnstr", cmd_add_wchnstr}, + {"add_wchstr", cmd_add_wchstr}, + {"wadd_wchnstr", cmd_wadd_wchnstr}, + {"wadd_wchstr", cmd_wadd_wchstr}, + {"mvadd_wchnstr", cmd_mvadd_wchnstr}, + {"mvadd_wchstr", cmd_mvadd_wchstr}, + {"mvwadd_wchnstr", cmd_mvwadd_wchnstr}, + {"mvwadd_wchstr", cmd_mvwadd_wchstr}, + {"addnwstr", cmd_addnwstr}, + {"addwstr", cmd_addwstr}, + {"mvaddnwstr", cmd_mvaddnwstr}, + {"mvaddwstr", cmd_mvaddwstr}, + {"mvwaddnwstr", cmd_mvwaddnwstr}, + {"mvwaddwstr", cmd_mvwaddwstr}, + {"waddnwstr", cmd_waddnwstr}, + {"waddwstr", cmd_waddwstr}, + {"echo_wchar", cmd_echo_wchar}, + {"wecho_wchar", cmd_wecho_wchar}, + {"pecho_wchar", cmd_pecho_wchar}, + {"ins_wch", cmd_ins_wch}, + {"wins_wch", cmd_wins_wch}, + {"mvins_wch", cmd_mvins_wch}, + {"mvwins_wch", cmd_mvwins_wch}, + {"ins_nwstr", cmd_ins_nwstr}, + {"ins_wstr", cmd_ins_wstr}, + {"mvins_nwstr", cmd_mvins_nwstr}, + {"mvins_wstr", cmd_mvins_wstr}, + {"mvwins_nwstr", cmd_mvwins_nwstr}, + {"mvwins_wstr", cmd_mvwins_wstr}, + {"wins_nwstr", cmd_wins_nwstr}, + {"wins_wstr", cmd_wins_wstr}, + {"get_wch", cmd_get_wch}, + {"unget_wch", cmd_unget_wch}, + {"mvget_wch", cmd_mvget_wch}, + {"mvwget_wch", cmd_mvwget_wch}, + {"wget_wch", cmd_wget_wch}, + {"getn_wstr", cmd_getn_wstr}, + {"get_wstr", cmd_get_wstr}, + {"mvgetn_wstr", cmd_mvgetn_wstr}, + {"mvget_wstr", cmd_mvget_wstr}, + {"mvwgetn_wstr", cmd_mvwgetn_wstr}, + {"mvwget_wstr", cmd_mvwget_wstr}, + {"wgetn_wstr", cmd_wgetn_wstr}, + {"wget_wstr", cmd_wget_wstr}, + {"in_wch", cmd_in_wch}, + {"mvin_wch", cmd_mvin_wch}, + {"mvwin_wch", cmd_mvwin_wch}, + {"win_wch", cmd_win_wch}, + {"in_wchnstr", cmd_in_wchnstr}, + {"in_wchstr", cmd_in_wchstr}, + {"mvin_wchnstr", cmd_mvin_wchnstr}, + {"mvin_wchstr", cmd_mvin_wchstr}, + {"mvwin_wchnstr", cmd_mvwin_wchnstr}, + {"mvwin_wchstr", cmd_mvwin_wchstr}, + {"win_wchnstr", cmd_win_wchnstr}, + {"win_wchstr", cmd_win_wchstr}, + {"innwstr", cmd_innwstr}, + {"inwstr", cmd_inwstr}, + {"mvinnwstr", cmd_mvinnwstr}, + {"mvinwstr", cmd_mvinwstr}, + {"mvwinnwstr", cmd_mvwinnwstr}, + {"mvwinwstr", cmd_mvwinwstr}, + {"winnwstr", cmd_winnwstr}, + {"winwstr", cmd_winwstr}, + {"setcchar", cmd_setcchar}, + {"getcchar", cmd_getcchar}, + {"key_name", cmd_key_name}, + {"border_set", cmd_border_set}, + {"wborder_set", cmd_wborder_set}, + {"box_set", cmd_box_set}, + {"erasewchar", cmd_erasewchar}, + {"killwchar", cmd_killwchar}, + {"hline_set", cmd_hline_set}, + {"mvhline_set", cmd_mvhline_set}, + {"mvvline_set", cmd_mvvline_set}, + {"mvwhline_set", cmd_mvwhline_set}, + {"mvwvline_set", cmd_mvwvline_set}, + {"vline_set", cmd_vline_set}, + {"whline_set", cmd_whline_set}, + {"wvline_set", cmd_wvline_set}, + {"bkgrnd", cmd_bkgrnd}, + {"bkgrndset", cmd_bkgrndset}, + {"getbkgrnd", cmd_getbkgrnd}, + {"wbkgrnd", cmd_wbkgrnd}, + {"wbkgrndset", cmd_wbkgrndset}, + {"wgetbkgrnd", cmd_wgetbkgrnd}, +}; + +size_t ncmds = sizeof(commands) / sizeof(struct command_def); + +#endif /* _COMMAND_TABLE_H */ diff --git a/contrib/netbsd-tests/lib/libcurses/slave/commands.c b/contrib/netbsd-tests/lib/libcurses/slave/commands.c new file mode 100644 index 0000000..2f26024 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/commands.c @@ -0,0 +1,243 @@ +/* $NetBSD: commands.c,v 1.4 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <curses.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <err.h> +#include <sys/types.h> +#include "returns.h" +#include "slave.h" +#include "command_table.h" + +extern int cmdpipe[2]; +extern int slvpipe[2]; + +static void report_type(returns_enum_t); +static void report_message(int, const char *); + +/* + * Match the passed command string and execute the associated test + * function. + */ +void +command_execute(char *func, int nargs, char **args) +{ + size_t i; + + i = 0; + while (i < ncmds) { + if (strcasecmp(func, commands[i].name) == 0) { + /* matched function */ + commands[i].func(nargs, args); + return; + } + i++; + } + + report_status("UNKNOWN_FUNCTION"); +} + +/* + * Report an pointer value back to the director + */ +void +report_ptr(void *ptr) +{ + char *string; + + if (ptr == NULL) + asprintf(&string, "NULL"); + else + asprintf(&string, "%p", ptr); + report_status(string); + free(string); +} + +/* + * Report an integer value back to the director + */ +void +report_int(int value) +{ + char *string; + + asprintf(&string, "%d", value); + report_status(string); + free(string); +} + +/* + * Report either an ERR or OK back to the director + */ +void +report_return(int status) +{ + if (status == ERR) + report_type(ret_err); + else if (status == OK) + report_type(ret_ok); + else + report_status("INVALID_RETURN"); +} + +/* + * Report the type back to the director via the command pipe + */ +static void +report_type(returns_enum_t return_type) +{ + int type; + + type = return_type; + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe write for status type failed"); + +} + +/* + * Report the number of returns back to the director via the command pipe + */ +void +report_count(int count) +{ + int type; + + type = ret_count; + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe write for count type failed"); + + if (write(slvpipe[WRITE_PIPE], &count, sizeof(int)) < 0) + err(1, "command pipe write for count"); +} + +/* + * Report the status back to the director via the command pipe + */ +void +report_status(const char *status) +{ + report_message(ret_string, status); +} + +/* + * Report an error message back to the director via the command pipe. + */ +void +report_error(const char *status) +{ + report_message(ret_slave_error, status); +} + +/* + * Report the message with the given type back to the director via the + * command pipe. + */ +static void +report_message(int type, const char *status) +{ + int len; + + len = strlen(status); + + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe write for message type failed"); + + if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe write for message length failed"); + + if (write(slvpipe[WRITE_PIPE], status, len) < 0) + err(1, "command pipe write of message data failed"); +} + +/* + * Report a string of chtype back to the director via the command pipe. + */ +void +report_byte(chtype c) +{ + chtype string[2]; + + string[0] = c; + string[1] = A_NORMAL | '\0'; + report_nstr(string); +} + +/* + * Report a string of chtype back to the director via the command pipe. + */ +void +report_nstr(chtype *string) +{ + int len, type; + chtype *p; + + len = 0; + p = string; + + while ((*p++ & __CHARTEXT) != 0) { + len++; + } + + len++; /* add in the termination chtype */ + len *= sizeof(chtype); + + type = ret_byte; + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "%s: command pipe write for status type failed", + __func__); + + if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) + err(1, "%s: command pipe write for status length failed", + __func__); + + if (write(slvpipe[WRITE_PIPE], string, len) < 0) + err(1, "%s: command pipe write of status data failed", + __func__); +} + +/* + * Check the number of args we received are what we expect. Return an + * error if they do not match. + */ +int +check_arg_count(int nargs, int expected) +{ + if (nargs != expected) { + report_count(1); + report_error("INCORRECT_ARGUMENT_NUMBER"); + return(1); + } + + return(0); +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c new file mode 100644 index 0000000..9a6679a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c @@ -0,0 +1,7165 @@ +/* $NetBSD: curses_commands.c,v 1.7 2012/09/19 11:51:08 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <curses.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <stdarg.h> + +#include "slave.h" +#include "curses_commands.h" + +void +cmd_DRAIN(int nargs, char **args) +{ + while (getch() != ERR); + report_count(1); + report_return(OK); +} + +void +cmd_addbytes(int nargs, char **args) +{ + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(addbytes(args[0], count)); +} + + +void +cmd_addch(int nargs, char **args) +{ + chtype *ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + ch = (chtype *) args[0]; + report_count(1); + report_return(addch(ch[0])); +} + + +void +cmd_addchnstr(int nargs, char **args) +{ + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(addchnstr((chtype *) args[0], count)); +} + + +void +cmd_addchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(addchstr((chtype *) args[0])); +} + + +void +cmd_addnstr(int nargs, char **args) +{ + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(addnstr(args[0], count)); +} + + +void +cmd_addstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(addstr(args[0])); +} + + +void +cmd_attr_get(int nargs, char **args) +{ + attr_t attrs; + short colours; + int retval; + + if (check_arg_count(nargs, 0) == 1) + return; + + retval = attr_get(&attrs, &colours, NULL); + + /* XXXX - call3 */ + report_count(3); + report_return(retval); + report_int(attrs); + report_int(colours); +} + + +void +cmd_attr_off(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attr_off(attrib, NULL)); +} + + +void +cmd_attr_on(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attr_on(attrib, NULL)); +} + + +void +cmd_attr_set(int nargs, char **args) +{ + int attrib; + short pair; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attr_set(attrib, pair, NULL)); +} + + +void +cmd_attroff(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attroff(attrib)); +} + + +void +cmd_attron(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attron(attrib)); +} + + +void +cmd_attrset(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attrset(attrib)); +} + + +void +cmd_bkgd(int nargs, char **args) +{ + chtype *ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + ch = (chtype *) args[0]; + report_count(1); + report_return(bkgd(ch[0])); +} + + +void +cmd_bkgdset(int nargs, char **args) +{ + chtype *ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + ch = (chtype *) args[0]; + bkgdset(ch[0]); /* returns void */ + report_count(1); + report_return(OK); +} + + +void +cmd_border(int nargs, char **args) +{ + int ls, rs, ts, bs, tl, tr, bl, br; + + if (check_arg_count(nargs, 8) == 1) + return; + + if (sscanf(args[0], "%d", &ls) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[1], "%d", &rs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[2], "%d", &ts) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[3], "%d", &bs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[4], "%d", &tl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[5], "%d", &tr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[6], "%d", &bl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[7], "%d", &br) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(border(ls, rs, ts, bs, tl, tr, bl, br)); +} + + +void +cmd_clear(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(clear()); +} + + +void +cmd_clrtobot(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(clrtobot()); +} + + +void +cmd_clrtoeol(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(clrtoeol()); +} + + +void +cmd_color_set(int nargs, char **args) +{ + short colour_pair; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%hd", &colour_pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(color_set(colour_pair, NULL)); +} + + +void +cmd_delch(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(delch()); +} + + +void +cmd_deleteln(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(deleteln()); +} + + +void +cmd_echochar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + /* XXX causes refresh */ + report_count(1); + report_return(echochar(args[0][0])); +} + + +void +cmd_erase(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(erase()); +} + + +void +cmd_getch(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX causes refresh */ + report_count(1); + report_int(getch()); +} + + +void +cmd_getnstr(int nargs, char **args) +{ + int limit; + char *string; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &limit) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(limit + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(getnstr(string, limit)); + report_status(string); + free(string); +} + + +void +cmd_getstr(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(getstr(string)); + report_status(string); +} + + +void +cmd_inch(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + + report_count(1); + report_byte(inch()); +} + + +void +cmd_inchnstr(int nargs, char **args) +{ + int limit; + chtype *string; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &limit) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc((limit + 1) * sizeof(chtype))) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(inchnstr(string, limit)); + report_nstr(string); + free(string); +} + + +void +cmd_inchstr(int nargs, char **args) +{ + chtype string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(inchstr(string)); + report_nstr(string); +} + + +void +cmd_innstr(int nargs, char **args) +{ + int limit; + char *string; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &limit) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(limit + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_int(innstr(string, limit)); + report_status(string); + free(string); +} + + +void +cmd_insch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(insch(args[0][0])); +} + + +void +cmd_insdelln(int nargs, char **args) +{ + int nlines; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &nlines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(insdelln(nlines)); +} + + +void +cmd_insertln(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(insertln()); +} + + +void +cmd_instr(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(instr(string)); + report_status(string); +} + + +void +cmd_move(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(move(y, x)); +} + + +void +cmd_refresh(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(refresh()); +} + + +void +cmd_scrl(int nargs, char **args) +{ + int nlines; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &nlines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(scrl(nlines)); +} + + +void +cmd_setscrreg(int nargs, char **args) +{ + int top, bottom; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &top) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &bottom) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(setscrreg(top, bottom)); +} + + +void +cmd_standend(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(standend()); +} + + +void +cmd_standout(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(standout()); +} + + +void +cmd_timeout(int nargs, char **args) +{ + int tval; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &tval) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + timeout(tval); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_underscore(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(underscore()); +} + + +void +cmd_underend(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(underend()); +} + + +void +cmd_waddbytes(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddbytes(win, args[1], count)); +} + + +void +cmd_waddstr(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddstr(win, args[1])); +} + + +void +cmd_mvaddbytes(int nargs, char **args) +{ + int y, x, count; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddbytes(y, x, args[2], count)); +} + + +void +cmd_mvaddch(int nargs, char **args) +{ + int y, x; + chtype *ch; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[2]; + report_count(1); + report_return(mvaddch(y, x, ch[0])); +} + + +void +cmd_mvaddchnstr(int nargs, char **args) +{ + int y, x, count; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddchnstr(y, x, (chtype *) args[2], count)); +} + + +void +cmd_mvaddchstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddchstr(y, x, (chtype *) args[2])); +} + + +void +cmd_mvaddnstr(int nargs, char **args) +{ + int y, x, count; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddnstr(y, x, args[2], count)); +} + + +void +cmd_mvaddstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddstr(y, x, args[2])); +} + + +void +cmd_mvdelch(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvdelch(y, x)); +} + + +void +cmd_mvgetch(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvgetch(y, x)); +} + + +void +cmd_mvgetnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvgetnstr(y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvgetstr(int nargs, char **args) +{ + int y, x; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvgetstr(y, x, string)); + report_status(string); +} + + +void +cmd_mvinch(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvinch(y, x)); +} + + +void +cmd_mvinchnstr(int nargs, char **args) +{ + int y, x, count; + chtype *string; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc((count + 1) * sizeof(chtype))) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvinchnstr(y, x, string, count)); + report_nstr(string); + free(string); +} + + +void +cmd_mvinchstr(int nargs, char **args) +{ + int y, x; + chtype string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvinchstr(y, x, string)); + report_nstr(string); +} + + +void +cmd_mvinnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvinnstr(y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvinsch(int nargs, char **args) +{ + int y, x, ch; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinsch(y, x, ch)); +} + + +void +cmd_mvinstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinstr(y, x, args[2])); +} + + + +void +cmd_mvwaddbytes(int nargs, char **args) +{ + int y, x, count; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddbytes(win, y, x, args[3], count)); +} + + +void +cmd_mvwaddch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddch(win, y, x, args[3][0])); +} + + +void +cmd_mvwaddchnstr(int nargs, char **args) +{ + int y, x, count; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddchnstr(win, y, x, (chtype *) args[3], count)); +} + + +void +cmd_mvwaddchstr(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddchstr(win, y, x, (chtype *) args[3])); +} + + +void +cmd_mvwaddnstr(int nargs, char **args) +{ + int y, x, count; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddnstr(win, y, x, args[3], count)); +} + + +void +cmd_mvwaddstr(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddstr(win, y, x, args[3])); +} + + +void +cmd_mvwdelch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwdelch(win, y, x)); +} + + +void +cmd_mvwgetch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - implicit refresh */ + report_count(1); + report_int(mvwgetch(win, y, x)); +} + + +void +cmd_mvwgetnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwgetnstr(win, y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvwgetstr(int nargs, char **args) +{ + int y, x; + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(mvwgetstr(win, y, x, string)); + report_status(string); +} + + +void +cmd_mvwinch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvwinch(win, y, x)); +} + + +void +cmd_mvwinsch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvwinsch(win, y, x, args[3][0])); +} + + +void +cmd_assume_default_colors(int nargs, char **args) +{ + short fore, back; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%hd", &fore) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &back) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(assume_default_colors(fore, back)); +} + + +void +cmd_baudrate(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(baudrate()); +} + + +void +cmd_beep(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(beep()); +} + + +void +cmd_box(int nargs, char **args) +{ + WINDOW *win; + chtype *vertical, *horizontal; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + vertical = (chtype *) args[1]; + horizontal = (chtype *) args[2]; + report_count(1); + report_return(box(win, vertical[0], horizontal[0])); +} + + +void +cmd_can_change_color(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(can_change_color()); +} + + +void +cmd_cbreak(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(cbreak()); +} + + +void +cmd_clearok(int nargs, char **args) +{ + WINDOW *win; + int flag; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(clearok(win, flag)); +} + + +void +cmd_color_content(int nargs, char **args) +{ + short colour, red, green, blue; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call4 */ + report_count(4); + report_return(color_content(colour, &red, &green, &blue)); + report_int(red); + report_int(green); + report_int(blue); +} + + +void +cmd_copywin(int nargs, char **args) +{ + int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, ovlay; + WINDOW *source, *destination; + + if (check_arg_count(nargs, 9) == 1) + return; + + if (sscanf(args[0], "%p", &source) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &destination) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &sminrow) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &smincol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &dminrow) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &dmincol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &dmaxrow) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[7], "%d", &dmaxcol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[8], "%d", &ovlay) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(copywin(source, destination, sminrow, smincol, dminrow, + dmincol, dmaxrow, dmaxcol, ovlay)); +} + + +void +cmd_curs_set(int nargs, char **args) +{ + int vis; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &vis) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(curs_set(vis)); +} + + +void +cmd_def_prog_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(def_prog_mode()); +} + + +void +cmd_def_shell_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(def_shell_mode()); +} + + +void +cmd_define_key(int nargs, char **args) +{ + int symbol; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &symbol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(define_key(args[0], symbol)); +} + + +void +cmd_delay_output(int nargs, char **args) +{ + int dtime; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &dtime) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(delay_output(dtime)); +} + + +void +cmd_delscreen(int nargs, char **args) +{ + SCREEN *scrn; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &scrn) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + delscreen(scrn); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_delwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(delwin(win)); +} + + +void +cmd_derwin(int nargs, char **args) +{ + int lines, cols, y, x; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(derwin(win, lines, cols, y, x)); +} + + +void +cmd_dupwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(dupwin(win)); +} + + +void +cmd_doupdate(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX - implicit refresh */ + report_count(1); + report_return(doupdate()); +} + + +void +cmd_echo(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(echo()); +} + + +void +cmd_endwin(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(endwin()); +} + + +void +cmd_erasechar(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(erasechar()); +} + + +void +cmd_flash(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(flash()); +} + + +void +cmd_flushinp(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(flushinp()); +} + + +void +cmd_flushok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(flushok(win, flag)); +} + + +void +cmd_fullname(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 1) == 1) + return; + + /* XXX - call2 */ + report_count(2); + report_status(fullname(args[0], string)); + report_status(string); +} + + +void +cmd_getattrs(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getattrs(win)); +} + + +void +cmd_getbkgd(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_byte(getbkgd(win)); +} + + +void +cmd_getcury(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getcury(win)); +} + + +void +cmd_getcurx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getcurx(win)); +} + + +void +cmd_getyx(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + getyx(win, y, x); + report_count(2); + report_int(y); + report_int(x); +} + + +void +cmd_getbegy(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getbegy(win)); +} + + +void +cmd_getbegx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getbegx(win)); +} + + +void +cmd_getmaxy(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getmaxy(win)); +} + + +void +cmd_getmaxx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getmaxx(win)); +} + + +void +cmd_getpary(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getpary(win)); +} + + +void +cmd_getparx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getparx(win)); +} + + +void +cmd_getparyx(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(2); + getparyx(win, y, x); + report_int(y); + report_int(x); +} + + +void +cmd_gettmode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(gettmode()); +} + + +void +cmd_getwin(int nargs, char **args) +{ + FILE *fp; + + if (check_arg_count(nargs, 1) == 1) + return; + + if ((fp = fopen(args[0], "r")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + report_count(1); + report_ptr(getwin(fp)); + fclose(fp); +} + + +void +cmd_halfdelay(int nargs, char **args) +{ + int ms; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &ms) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(halfdelay(ms)); +} + + +void +cmd_has_colors(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(has_colors()); +} + + +void +cmd_has_ic(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(has_ic()); +} + + +void +cmd_has_il(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(has_il()); +} + + +void +cmd_hline(int nargs, char **args) +{ + int count; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + ch = (chtype *) args[0]; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(hline(ch[0], count)); +} + + +void +cmd_idcok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(idcok(win, flag)); +} + + +void +cmd_idlok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(idlok(win, flag)); +} + + +void +cmd_init_color(int nargs, char **args) +{ + short colour, red, green, blue; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &red) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%hd", &green) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%hd", &blue) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(init_color(colour, red, green, blue)); +} + + +void +cmd_init_pair(int nargs, char **args) +{ + short pair, fore, back; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &fore) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%hd", &back) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(init_pair(pair, fore, back)); +} + + +void +cmd_initscr(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_ptr(initscr()); +} + + +void +cmd_intrflush(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(intrflush(win, flag)); +} + + +void +cmd_isendwin(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(isendwin()); +} + + +void +cmd_is_linetouched(int nargs, char **args) +{ + int line; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &line) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(is_linetouched(win, line)); +} + + +void +cmd_is_wintouched(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(is_wintouched(win)); +} + + +void +cmd_keyok(int nargs, char **args) +{ + int keysym, flag; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &keysym) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(keyok(keysym, flag)); +} + + +void +cmd_keypad(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(keypad(win, flag)); +} + + +void +cmd_keyname(int nargs, char **args) +{ + unsigned int key; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &key) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_status(keyname(key)); +} + + +void +cmd_killchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(killchar()); +} + + +void +cmd_leaveok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(leaveok(win, flag)); +} + + +void +cmd_meta(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(meta(win, flag)); +} + + +void +cmd_mvcur(int nargs, char **args) +{ + int oldy, oldx, y, x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &oldy) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &oldx) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvcur(oldy, oldx, y, x)); +} + + +void +cmd_mvderwin(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvderwin(win, y, x)); +} + + +void +cmd_mvhline(int nargs, char **args) +{ + int y, x, n; + chtype *ch; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[2]; + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvhline(y, x, ch[0], n)); +} + + +void +cmd_mvprintw(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvprintw(y, x, args[2], args[3])); +} + + +void +cmd_mvscanw(int nargs, char **args) +{ + int y, x; + char string[256]; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(mvscanw(y, x, args[2], &string)); + report_status(string); +} + + +void +cmd_mvvline(int nargs, char **args) +{ + int y, x, n; + chtype *ch; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[2]; + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvvline(y, x, ch[0], n)); +} + + +void +cmd_mvwhline(int nargs, char **args) +{ + int y, x, ch, n; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwhline(win, y, x, ch, n)); +} + + +void +cmd_mvwvline(int nargs, char **args) +{ + int y, x, n; + WINDOW *win; + chtype *ch; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[3]; + + if (sscanf(args[4], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwvline(win, y, x, ch[0], n)); +} + + +void +cmd_mvwin(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwin(win, y, x)); +} + + +void +cmd_mvwinchnstr(int nargs, char **args) +{ + int y, x, count; + chtype *string; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc((count + 1) * sizeof(chtype))) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinchnstr(win, y, x, string, count)); + report_nstr(string); + free(string); +} + + +void +cmd_mvwinchstr(int nargs, char **args) +{ + int y, x; + chtype string[256]; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinchstr(win, y, x, string)); + report_nstr(string); +} + + +void +cmd_mvwinnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinnstr(win, y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvwinstr(int nargs, char **args) +{ + int y, x; + char string[256]; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinstr(win, y, x, string)); + report_status(string); +} + + +void +cmd_mvwprintw(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwprintw(win, y, x, args[3], args[4])); +} + + +void +cmd_mvwscanw(int nargs, char **args) +{ + int y, x; + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_int(mvwscanw(win, y, x, args[3], &string)); + report_status(string); +} + + +void +cmd_napms(int nargs, char **args) +{ + int naptime; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &naptime) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(napms(naptime)); +} + + +void +cmd_newpad(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(newpad(y, x)); +} + + +void +cmd_newterm(int nargs, char **args) +{ + FILE *in, *out; + + if (check_arg_count(nargs, 3) == 1) + return; + + if ((in = fopen(args[1], "rw")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + + if ((out = fopen(args[2], "rw")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + report_count(1); + report_ptr(newterm(args[0], out, in)); +} + + +void +cmd_newwin(int nargs, char **args) +{ + int lines, cols, begin_y, begin_x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &begin_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &begin_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(newwin(lines, cols, begin_y, begin_x)); +} + + +void +cmd_nl(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(nl()); +} + + +void +cmd_no_color_attributes(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(no_color_attributes()); +} + + +void +cmd_nocbreak(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(nocbreak()); +} + + +void +cmd_nodelay(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(nodelay(win, flag)); +} + + +void +cmd_noecho(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(noecho()); +} + + +void +cmd_nonl(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(nonl()); +} + + +void +cmd_noqiflush(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + noqiflush(); + report_count(1); + report_return(OK); /* fake a return, the call returns void */ +} + + +void +cmd_noraw(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(noraw()); +} + + +void +cmd_notimeout(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(notimeout(win, flag)); +} + + +void +cmd_overlay(int nargs, char **args) +{ + WINDOW *source, *dest; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &source) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &dest) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(overlay(source, dest)); +} + + +void +cmd_overwrite(int nargs, char **args) +{ + WINDOW *source, *dest; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &source) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &dest) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(overwrite(source, dest)); +} + + +void +cmd_pair_content(int nargs, char **args) +{ + short pair, fore, back; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call3 */ + report_count(3); + report_return(pair_content(pair, &fore, &back)); + report_int(fore); + report_int(back); +} + + +void +cmd_pechochar(int nargs, char **args) +{ + int ch; + WINDOW *pad; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(pechochar(pad, ch)); +} + + +void +cmd_pnoutrefresh(int nargs, char **args) +{ + int pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, smax_x; + WINDOW *pad; + + if (check_arg_count(nargs, 7) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &pbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &pbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &sbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &sbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &smax_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &smax_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(pnoutrefresh(pad, pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, + smax_x)); +} + + +void +cmd_prefresh(int nargs, char **args) +{ + int pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, smax_x; + WINDOW *pad; + + if (check_arg_count(nargs, 7) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &pbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &pbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &sbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &sbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &smax_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &smax_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX causes refresh */ + report_count(1); + report_return(prefresh(pad, pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, + smax_x)); + +} + + +void +cmd_printw(int nargs, char **args) +{ + if (check_arg_count(nargs, 2) == 1) + return; + + + report_count(1); + report_return(printw(args[0], args[1])); +} + + +void +cmd_putwin(int nargs, char **args) +{ + FILE *fp; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((fp = fopen(args[1], "rw")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + report_count(1); + report_return(putwin(win, fp)); +} + + +void +cmd_qiflush(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + qiflush(); + report_count(1); + report_return(OK); /* fake a return because call returns void */ +} + + +void +cmd_raw(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(raw()); +} + + +void +cmd_redrawwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(redrawwin(win)); +} + + +void +cmd_reset_prog_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(reset_prog_mode()); +} + + +void +cmd_reset_shell_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(reset_shell_mode()); +} + + +void +cmd_resetty(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(resetty()); +} + + +void +cmd_resizeterm(int nargs, char **args) +{ + int rows, cols; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &rows) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(resizeterm(rows, cols)); +} + + +void +cmd_savetty(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(savetty()); +} + + +void +cmd_scanw(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(scanw("%s", string)); + report_status(string); +} + + +void +cmd_scroll(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(scroll(win)); +} + + +void +cmd_scrollok(int nargs, char **args) +{ + WINDOW *win; + int flag; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(scrollok(win, flag)); +} + + +void +cmd_setterm(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(setterm(args[0])); +} + + +void +cmd_set_term(int nargs, char **args) +{ + SCREEN *scrn; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &scrn) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(set_term(scrn)); +} + + +void +cmd_start_color(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(start_color()); +} + + +void +cmd_subpad(int nargs, char **args) +{ + WINDOW *pad; + int lines, cols, begin_y, begin_x; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &begin_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &begin_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(subpad(pad, lines, cols, begin_y, begin_x)); +} + + +void +cmd_subwin(int nargs, char **args) +{ + WINDOW *win; + int lines, cols, begin_y, begin_x; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &begin_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &begin_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(subwin(win, lines, cols, begin_y, begin_x)); +} + + +void +cmd_termattrs(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(termattrs()); +} + + +void +cmd_term_attrs(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(term_attrs()); +} + + +void +cmd_touchline(int nargs, char **args) +{ + WINDOW *win; + int start, count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &start) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(touchline(win, start, count)); +} + + +void +cmd_touchoverlap(int nargs, char **args) +{ + WINDOW *win1, *win2; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win1) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &win2) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(touchoverlap(win1, win2)); +} + + +void +cmd_touchwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(touchwin(win)); +} + + +void +cmd_ungetch(int nargs, char **args) +{ + int ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(ungetch(ch)); +} + + +void +cmd_untouchwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(untouchwin(win)); +} + + +void +cmd_use_default_colors(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(use_default_colors()); +} + + +void +cmd_vline(int nargs, char **args) +{ + int count; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + ch = (chtype *) args[0]; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(vline(ch[0], count)); +} + + +static int +internal_vw_printw(WINDOW *win, char *arg1, ...) +{ + va_list va; + int rv; + + va_start(va, arg1); + rv = vw_printw(win, arg1, va); + va_end(va); + + return rv; +} + +void +cmd_vw_printw(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(internal_vw_printw(win, args[1], args[2])); +} + + +static int +internal_vw_scanw(WINDOW *win, char *arg1, ...) +{ + va_list va; + int rv; + + va_start(va, arg1); + rv = vw_scanw(win, arg1, va); + va_end(va); + + return rv; +} + +void +cmd_vw_scanw(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_int(internal_vw_scanw(win, args[1], string)); + report_status(string); +} + + +void +cmd_vwprintw(int nargs, char **args) +{ + cmd_vw_printw(nargs, args); +} + + +void +cmd_vwscanw(int nargs, char **args) +{ + cmd_vw_scanw(nargs, args); +} + + +void +cmd_waddch(int nargs, char **args) +{ + WINDOW *win; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[1]; + + report_count(1); + report_return(waddch(win, ch[0])); +} + + +void +cmd_waddchnstr(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddchnstr(win, (chtype *) args[1], count)); +} + + +void +cmd_waddchstr(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddchstr(win, (chtype *) args[1])); +} + + +void +cmd_waddnstr(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 1) == 3) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddnstr(win, args[1], count)); + +} + + +void +cmd_wattr_get(int nargs, char **args) +{ + WINDOW *win; + int attr; + short pair; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call3 */ + report_count(3); + report_return(wattr_get(win, &attr, &pair, NULL)); + report_int(attr); + report_int(pair); +} + + +void +cmd_wattr_off(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattr_off(win, attr, NULL)); +} + + +void +cmd_wattr_on(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattr_on(win, attr, NULL)); +} + + +void +cmd_wattr_set(int nargs, char **args) +{ + WINDOW *win; + int attr; + short pair; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattr_set(win, attr, pair, NULL)); +} + + +void +cmd_wattroff(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattroff(win, attr)); +} + + +void +cmd_wattron(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattron(win, attr)); +} + + +void +cmd_wattrset(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattrset(win, attr)); +} + + +void +cmd_wbkgd(int nargs, char **args) +{ + WINDOW *win; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[1]; + report_count(1); + report_return(wbkgd(win, ch[0])); +} + + +void +cmd_wbkgdset(int nargs, char **args) +{ + WINDOW *win; + int ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + wbkgdset(win, ch); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_wborder(int nargs, char **args) +{ + WINDOW *win; + int ls, rs, ts, bs, tl, tr, bl, br; + + if (check_arg_count(nargs, 9) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ls) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &rs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &ts) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &bs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &tl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &tr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[7], "%d", &bl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[8], "%d", &br) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wborder(win, ls, rs, ts, bs, tl, tr, bl, br)); +} + + +void +cmd_wclear(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wclear(win)); +} + + +void +cmd_wclrtobot(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wclrtobot(win)); +} + + +void +cmd_wclrtoeol(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wclrtoeol(win)); + +} + + +void +cmd_wcolor_set(int nargs, char **args) +{ + WINDOW *win; + short pair; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wcolor_set(win, pair, NULL)); +} + + +void +cmd_wdelch(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wdelch(win)); +} + + +void +cmd_wdeleteln(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wdeleteln(win)); + +} + + +void +cmd_wechochar(int nargs, char **args) +{ + WINDOW *win; + int ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wechochar(win, ch)); +} + + +void +cmd_werase(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(werase(win)); +} + + +void +cmd_wgetch(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(wgetch(win)); +} + + +void +cmd_wgetnstr(int nargs, char **args) +{ + WINDOW *win; + int count; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(wgetnstr(win, string, count)); + report_status(string); +} + + +void +cmd_wgetstr(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + string[0] = '\0'; + + report_count(2); + report_return(wgetstr(win, string)); + report_status(string); +} + + +void +cmd_whline(int nargs, char **args) +{ + WINDOW *win; + int ch, count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(whline(win, ch, count)); +} + + +void +cmd_winch(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(winch(win)); +} + + +void +cmd_winchnstr(int nargs, char **args) +{ + WINDOW *win; + chtype string[256]; + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winchnstr(win, string, count)); + report_nstr(string); +} + + +void +cmd_winchstr(int nargs, char **args) +{ + WINDOW *win; + chtype string[256]; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winchstr(win, string)); + report_nstr(string); +} + + +void +cmd_winnstr(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winnstr(win, string, count)); + report_status(string); +} + + +void +cmd_winsch(int nargs, char **args) +{ + WINDOW *win; + int ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsch(win, ch)); +} + + +void +cmd_winsdelln(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsdelln(win, count)); +} + + +void +cmd_winsertln(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsertln(win)); +} + + +void +cmd_winstr(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winstr(win, string)); + report_status(string); +} + + +void +cmd_wmove(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wmove(win, y, x)); +} + + +void +cmd_wnoutrefresh(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wnoutrefresh(win)); +} + + +void +cmd_wprintw(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wprintw(win, args[1], args[2])); +} + + +void +cmd_wredrawln(int nargs, char **args) +{ + WINDOW *win; + int beg_line, num_lines; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &beg_line) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &num_lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wredrawln(win, beg_line, num_lines)); +} + + +void +cmd_wrefresh(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - generates output */ + report_count(1); + report_return(wrefresh(win)); +} + + +void +cmd_wresize(int nargs, char **args) +{ + WINDOW *win; + int lines, cols; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wresize(win, lines, cols)); +} + + +void +cmd_wscanw(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wscanw(win, args[1], &string)); +} + + +void +cmd_wscrl(int nargs, char **args) +{ + WINDOW *win; + int n; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wscrl(win, n)); +} + + +void +cmd_wsetscrreg(int nargs, char **args) +{ + WINDOW *win; + int top, bottom; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &top) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &bottom) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wsetscrreg(win, top, bottom)); +} + + +void +cmd_wstandend(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wstandend(win)); +} + + +void +cmd_wstandout(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wstandout(win)); +} + + +void +cmd_wtimeout(int nargs, char **args) +{ + WINDOW *win; + int tval; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &tval) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + wtimeout(win, tval); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_wtouchln(int nargs, char **args) +{ + WINDOW *win; + int line, n, changed; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &line) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &changed) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wtouchln(win, line, n, changed)); +} + + +void +cmd_wunderend(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wunderend(win)); +} + + +void +cmd_wunderscore(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wunderscore(win)); +} + + +void +cmd_wvline(int nargs, char **args) +{ + WINDOW *win; + int n; + chtype *ch; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[1]; + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wvline(win, ch[0], n)); +} + + +void +cmd_insnstr(int nargs, char **args) +{ + int n; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(insnstr(args[0], n)); +} + + +void +cmd_insstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(insstr(args[0])); +} + + +void +cmd_mvinsnstr(int nargs, char **args) +{ + int y, x, n; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinsnstr(y, x, args[2], n)); +} + + +void +cmd_mvinsstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinsstr(y, x, args[2])); +} + + +void +cmd_mvwinsnstr(int nargs, char **args) +{ + WINDOW *win; + int y, x, n; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwinsnstr(win, y, x, args[3], n)); + +} + + +void +cmd_mvwinsstr(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwinsstr(win, y, x, args[3])); +} + + +void +cmd_winsnstr(int nargs, char **args) +{ + WINDOW *win; + int n; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsnstr(win, args[1], n)); +} + + +void +cmd_winsstr(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsstr(win, args[1])); +} + + + +void +cmd_chgat(int nargs, char **args) +{ + int n, attr, colour; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* Note: 4th argument unused in current curses implementation */ + report_count(1); + report_return(chgat(n, attr, colour, NULL)); +} + + +void +cmd_wchgat(int nargs, char **args) +{ + WINDOW *win; + int n, attr; + short colour; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wchgat(win, n, attr, colour, NULL)); +} + + +void +cmd_mvchgat(int nargs, char **args) +{ + int y, x, n, attr; + short colour; + + if (check_arg_count(nargs, 6) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvchgat(y, x, n, attr, colour, NULL)); +} + + +void +cmd_mvwchgat(int nargs, char **args) +{ + WINDOW *win; + int y, x, n, attr, colour; + + if (check_arg_count(nargs, 6) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwchgat(win, y, x, n, attr, colour, NULL)); +} + + +void +cmd_add_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wadd_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvadd_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwadd_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_add_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_add_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wadd_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wadd_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvadd_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvadd_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwadd_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwadd_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_addnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_addwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvaddnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvaddwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwaddnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwaddwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_waddnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_waddwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_echo_wchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wecho_wchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_pecho_wchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* insert */ +void +cmd_ins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_ins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_ins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* input */ +void +cmd_get_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_unget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_getn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_get_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvgetn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvget_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwgetn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwget_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wgetn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wget_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_in_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvin_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwin_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_win_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_in_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_in_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvin_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvin_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwin_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwin_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_win_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_win_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_innwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_inwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvinnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvinwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwinnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwinwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_winnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_winwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* cchar handlgin */ +void +cmd_setcchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_getcchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* misc */ +void +cmd_key_name(int nargs, char **args) +{ + int w; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &w) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_status(key_name(w)); +} + + +void +cmd_border_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wborder_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_box_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_erasewchar(int nargs, char **args) +{ + wchar_t ch; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX - call2 */ + report_count(2); + report_return(erasewchar(&ch)); + report_int(ch); +} + + +void +cmd_killwchar(int nargs, char **args) +{ + wchar_t ch; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX - call2 */ + report_count(2); + report_return(erasewchar(&ch)); + report_int(ch); +} + + +void +cmd_hline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvhline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvvline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwhline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwvline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_vline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_whline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wvline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_bkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_bkgrndset(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_getbkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wbkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wbkgrndset(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wgetbkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h new file mode 100644 index 0000000..d7f2ad7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h @@ -0,0 +1,422 @@ +/* $NetBSD: curses_commands.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#ifndef _CURSES_COMMANDS_H_ +#define _CURSES_COMMANDS_H_ + +struct command_def { + const char *name; + void (*func)(int, char **); +}; + +/* + * prototypes for test commands + */ +void cmd_DRAIN(int, char **); /* not a curses function */ + +void cmd_addbytes(int, char **); +void cmd_addch(int, char **); +void cmd_addchnstr(int, char **); +void cmd_addchstr(int, char **); +void cmd_addnstr(int, char **); +void cmd_addstr(int, char **); +void cmd_attr_get(int, char **); +void cmd_attr_off(int, char **); +void cmd_attr_on(int, char **); +void cmd_attr_set(int, char **); +void cmd_attroff(int, char **); +void cmd_attron(int, char **); +void cmd_attrset(int, char **); +void cmd_bkgd(int, char **); +void cmd_bkgdset(int, char **); +void cmd_border(int, char **); +void cmd_clear(int, char **); +void cmd_clrtobot(int, char **); +void cmd_clrtoeol(int, char **); +void cmd_color_set(int, char **); +void cmd_delch(int, char **); +void cmd_deleteln(int, char **); +void cmd_echochar(int, char **); +void cmd_erase(int, char **); +void cmd_getch(int, char **); +void cmd_getnstr(int, char **); +void cmd_getstr(int, char **); +void cmd_inch(int, char **); +void cmd_inchnstr(int, char **); +void cmd_inchstr(int, char **); +void cmd_innstr(int, char **); +void cmd_insch(int, char **); +void cmd_insdelln(int, char **); +void cmd_insertln(int, char **); +void cmd_instr(int, char **); +void cmd_move(int, char **); +void cmd_refresh(int, char **); +void cmd_scrl(int, char **); +void cmd_setscrreg(int, char **); +void cmd_standend(int, char **); +void cmd_standout(int, char **); +void cmd_timeout(int, char **); +void cmd_underscore(int, char **); +void cmd_underend(int, char **); +void cmd_waddbytes(int, char **); +void cmd_waddstr(int, char **); +void cmd_mvaddbytes(int, char **); +void cmd_mvaddch(int, char **); +void cmd_mvaddchnstr(int, char **); +void cmd_mvaddchstr(int, char **); +void cmd_mvaddnstr(int, char **); +void cmd_mvaddstr(int, char **); +void cmd_mvdelch(int, char **); +void cmd_mvgetch(int, char **); +void cmd_mvgetnstr(int, char **); +void cmd_mvgetstr(int, char **); +void cmd_mvinch(int, char **); +void cmd_mvinchnstr(int, char **); +void cmd_mvinchstr(int, char **); +void cmd_mvinnstr(int, char **); +void cmd_mvinsch(int, char **); +void cmd_mvinstr(int, char **); + +void cmd_mvwaddbytes(int, char **); +void cmd_mvwaddch(int, char **); +void cmd_mvwaddchnstr(int, char **); +void cmd_mvwaddchstr(int, char **); +void cmd_mvwaddnstr(int, char **); +void cmd_mvwaddstr(int, char **); +void cmd_mvwdelch(int, char **); +void cmd_mvwgetch(int, char **); +void cmd_mvwgetnstr(int, char **); +void cmd_mvwgetstr(int, char **); +void cmd_mvwinch(int, char **); +void cmd_mvwinsch(int, char **); +void cmd_assume_default_colors(int, char **); +void cmd_baudrate(int, char **); +void cmd_beep(int, char **); +void cmd_box(int, char **); +void cmd_can_change_color(int, char **); +void cmd_cbreak(int, char **); +void cmd_chgat(int, char **); +void cmd_clearok(int, char **); +void cmd_color_content(int, char **); +void cmd_copywin(int, char **); +void cmd_curs_set(int, char **); +void cmd_def_prog_mode(int, char **); +void cmd_def_shell_mode(int, char **); +void cmd_define_key(int, char **); +void cmd_delay_output(int, char **); +void cmd_delscreen(int, char **); +void cmd_delwin(int, char **); +void cmd_derwin(int, char **); +void cmd_dupwin(int, char **); +void cmd_doupdate(int, char **); +void cmd_echo(int, char **); +void cmd_endwin(int, char **); +void cmd_erasechar(int, char **); +void cmd_flash(int, char **); +void cmd_flushinp(int, char **); +void cmd_flushok(int, char **); +void cmd_fullname(int, char **); +void cmd_getattrs(int, char **); +void cmd_getbkgd(int, char **); +void cmd_getcury(int, char **); +void cmd_getcurx(int, char **); +void cmd_getyx(int, char **); +void cmd_getbegy(int, char **); +void cmd_getbegx(int, char **); +void cmd_getmaxy(int, char **); +void cmd_getmaxx(int, char **); +void cmd_getpary(int, char **); +void cmd_getparx(int, char **); +void cmd_getparyx(int, char **); +void cmd_gettmode(int, char **); +void cmd_getwin(int, char **); +void cmd_halfdelay(int, char **); +void cmd_has_colors(int, char **); +void cmd_has_ic(int, char **); +void cmd_has_il(int, char **); +void cmd_hline(int, char **); +void cmd_idcok(int, char **); +void cmd_idlok(int, char **); +void cmd_init_color(int, char **); +void cmd_init_pair(int, char **); +void cmd_initscr(int, char **); +void cmd_intrflush(int, char **); +void cmd_isendwin(int, char **); +void cmd_is_linetouched(int, char **); +void cmd_is_wintouched(int, char **); +void cmd_keyok(int, char **); +void cmd_keypad(int, char **); +void cmd_keyname(int, char **); +void cmd_killchar(int, char **); +void cmd_leaveok(int, char **); +void cmd_meta(int, char **); +void cmd_mvchgat(int, char **); +void cmd_mvcur(int, char **); +void cmd_mvderwin(int, char **); +void cmd_mvhline(int, char **); +void cmd_mvprintw(int, char **); +void cmd_mvscanw(int, char **); +void cmd_mvvline(int, char **); +void cmd_mvwchgat(int, char **); +void cmd_mvwhline(int, char **); +void cmd_mvwvline(int, char **); +void cmd_mvwin(int, char **); +void cmd_mvwinchnstr(int, char **); +void cmd_mvwinchstr(int, char **); +void cmd_mvwinnstr(int, char **); +void cmd_mvwinstr(int, char **); +void cmd_mvwprintw(int, char **); +void cmd_mvwscanw(int, char **); +void cmd_napms(int, char **); +void cmd_newpad(int, char **); +void cmd_newterm(int, char **); +void cmd_newwin(int, char **); +void cmd_nl(int, char **); +void cmd_no_color_attributes(int, char **); +void cmd_nocbreak(int, char **); +void cmd_nodelay(int, char **); +void cmd_noecho(int, char **); +void cmd_nonl(int, char **); +void cmd_noqiflush(int, char **); +void cmd_noraw(int, char **); +void cmd_notimeout(int, char **); +void cmd_overlay(int, char **); +void cmd_overwrite(int, char **); +void cmd_pair_content(int, char **); +void cmd_pechochar(int, char **); +void cmd_pnoutrefresh(int, char **); +void cmd_prefresh(int, char **); +void cmd_printw(int, char **); +void cmd_putwin(int, char **); +void cmd_qiflush(int, char **); +void cmd_raw(int, char **); +void cmd_redrawwin(int, char **); +void cmd_reset_prog_mode(int, char **); +void cmd_reset_shell_mode(int, char **); +void cmd_resetty(int, char **); +void cmd_resizeterm(int, char **); +void cmd_savetty(int, char **); +void cmd_scanw(int, char **); +void cmd_scroll(int, char **); +void cmd_scrollok(int, char **); +void cmd_setterm(int, char **); +void cmd_set_term(int, char **); +void cmd_start_color(int, char **); +void cmd_subpad(int, char **); +void cmd_subwin(int, char **); +void cmd_termattrs(int, char **); +void cmd_term_attrs(int, char **); +void cmd_touchline(int, char **); +void cmd_touchoverlap(int, char **); +void cmd_touchwin(int, char **); +void cmd_ungetch(int, char **); +void cmd_untouchwin(int, char **); +void cmd_use_default_colors(int, char **); +void cmd_vline(int, char **); +void cmd_vw_printw(int, char **); +void cmd_vw_scanw(int, char **); +void cmd_vwprintw(int, char **); +void cmd_vwscanw(int, char **); +void cmd_waddch(int, char **); +void cmd_waddchnstr(int, char **); +void cmd_waddchstr(int, char **); +void cmd_waddnstr(int, char **); +void cmd_wattr_get(int, char **); +void cmd_wattr_off(int, char **); +void cmd_wattr_on(int, char **); +void cmd_wattr_set(int, char **); +void cmd_wattroff(int, char **); +void cmd_wattron(int, char **); +void cmd_wattrset(int, char **); +void cmd_wbkgd(int, char **); +void cmd_wbkgdset(int, char **); +void cmd_wborder(int, char **); +void cmd_wchgat(int, char **); +void cmd_wclear(int, char **); +void cmd_wclrtobot(int, char **); +void cmd_wclrtoeol(int, char **); +void cmd_wcolor_set(int, char **); +void cmd_wdelch(int, char **); +void cmd_wdeleteln(int, char **); +void cmd_wechochar(int, char **); +void cmd_werase(int, char **); +void cmd_wgetch(int, char **); +void cmd_wgetnstr(int, char **); +void cmd_wgetstr(int, char **); +void cmd_whline(int, char **); +void cmd_winch(int, char **); +void cmd_winchnstr(int, char **); +void cmd_winchstr(int, char **); +void cmd_winnstr(int, char **); +void cmd_winsch(int, char **); +void cmd_winsdelln(int, char **); +void cmd_winsertln(int, char **); +void cmd_winstr(int, char **); +void cmd_wmove(int, char **); +void cmd_wnoutrefresh(int, char **); +void cmd_wprintw(int, char **); +void cmd_wredrawln(int, char **); +void cmd_wrefresh(int, char **); +void cmd_wresize(int, char **); +void cmd_wscanw(int, char **); +void cmd_wscrl(int, char **); +void cmd_wsetscrreg(int, char **); +void cmd_wstandend(int, char **); +void cmd_wstandout(int, char **); +void cmd_wtimeout(int, char **); +void cmd_wtouchln(int, char **); +void cmd_wunderend(int, char **); +void cmd_wunderscore(int, char **); +void cmd_wvline(int, char **); +void cmd_insnstr(int, char **); +void cmd_insstr(int, char **); +void cmd_mvinsnstr(int, char **); +void cmd_mvinsstr(int, char **); +void cmd_mvwinsnstr(int, char **); +void cmd_mvwinsstr(int, char **); +void cmd_winsnstr(int, char **); +void cmd_winsstr(int, char **); + +void cmd_chgat(int, char **); +void cmd_wchgat(int, char **); +void cmd_mvchgat(int, char **); +void cmd_mvwchgat(int, char **); +void cmd_add_wch(int, char **); +void cmd_wadd_wch(int, char **); +void cmd_mvadd_wch(int, char **); +void cmd_mvwadd_wch(int, char **); + +void cmd_add_wchnstr(int, char **); +void cmd_add_wchstr(int, char **); +void cmd_wadd_wchnstr(int, char **); +void cmd_wadd_wchstr(int, char **); +void cmd_mvadd_wchnstr(int, char **); +void cmd_mvadd_wchstr(int, char **); +void cmd_mvwadd_wchnstr(int, char **); +void cmd_mvwadd_wchstr(int, char **); + +void cmd_addnwstr(int, char **); +void cmd_addwstr(int, char **); +void cmd_mvaddnwstr(int, char **); +void cmd_mvaddwstr(int, char **); +void cmd_mvwaddnwstr(int, char **); +void cmd_mvwaddwstr(int, char **); +void cmd_waddnwstr(int, char **); +void cmd_waddwstr(int, char **); + +void cmd_echo_wchar(int, char **); +void cmd_wecho_wchar(int, char **); +void cmd_pecho_wchar(int, char **); + +/* insert */ +void cmd_ins_wch(int, char **); +void cmd_wins_wch(int, char **); +void cmd_mvins_wch(int, char **); +void cmd_mvwins_wch(int, char **); + +void cmd_ins_nwstr(int, char **); +void cmd_ins_wstr(int, char **); +void cmd_mvins_nwstr(int, char **); +void cmd_mvins_wstr(int, char **); +void cmd_mvwins_nwstr(int, char **); +void cmd_mvwins_wstr(int, char **); +void cmd_wins_nwstr(int, char **); +void cmd_wins_wstr(int, char **); + +/* input */ +void cmd_get_wch(int, char **); +void cmd_unget_wch(int, char **); +void cmd_mvget_wch(int, char **); +void cmd_mvwget_wch(int, char **); +void cmd_wget_wch(int, char **); + +void cmd_getn_wstr(int, char **); +void cmd_get_wstr(int, char **); +void cmd_mvgetn_wstr(int, char **); +void cmd_mvget_wstr(int, char **); +void cmd_mvwgetn_wstr(int, char **); +void cmd_mvwget_wstr(int, char **); +void cmd_wgetn_wstr(int, char **); +void cmd_wget_wstr(int, char **); + +void cmd_in_wch(int, char **); +void cmd_mvin_wch(int, char **); +void cmd_mvwin_wch(int, char **); +void cmd_win_wch(int, char **); + +void cmd_in_wchnstr(int, char **); +void cmd_in_wchstr(int, char **); +void cmd_mvin_wchnstr(int, char **); +void cmd_mvin_wchstr(int, char **); +void cmd_mvwin_wchnstr(int, char **); +void cmd_mvwin_wchstr(int, char **); +void cmd_win_wchnstr(int, char **); +void cmd_win_wchstr(int, char **); + +void cmd_innwstr(int, char **); +void cmd_inwstr(int, char **); +void cmd_mvinnwstr(int, char **); +void cmd_mvinwstr(int, char **); +void cmd_mvwinnwstr(int, char **); +void cmd_mvwinwstr(int, char **); +void cmd_winnwstr(int, char **); +void cmd_winwstr(int, char **); + +/* cchar handlgin */ +void cmd_setcchar(int, char **); +void cmd_getcchar(int, char **); + +/* misc */ +void cmd_key_name(int, char **); +void cmd_border_set(int, char **); +void cmd_wborder_set(int, char **); +void cmd_box_set(int, char **); +void cmd_erasewchar(int, char **); +void cmd_killwchar(int, char **); +void cmd_hline_set(int, char **); +void cmd_mvhline_set(int, char **); +void cmd_mvvline_set(int, char **); +void cmd_mvwhline_set(int, char **); +void cmd_mvwvline_set(int, char **); +void cmd_vline_set(int, char **); +void cmd_whline_set(int, char **); +void cmd_wvline_set(int, char **); +void cmd_bkgrnd(int, char **); +void cmd_bkgrndset(int, char **); +void cmd_getbkgrnd(int, char **); +void cmd_wbkgrnd(int, char **); +void cmd_wbkgrndset(int, char **); +void cmd_wgetbkgrnd(int, char **); + + + + +#endif /* !_CURSES_COMMAND_H_ */ diff --git a/contrib/netbsd-tests/lib/libcurses/slave/slave.c b/contrib/netbsd-tests/lib/libcurses/slave/slave.c new file mode 100644 index 0000000..b05a1da --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/slave.c @@ -0,0 +1,177 @@ +/* $NetBSD: slave.c,v 1.6 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ +#include <fcntl.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <curses.h> +#include "returns.h" +#include "slave.h" + +int cmdpipe[2]; +int slvpipe[2]; + +#if 0 +static const char *returns_enum_names[] = { + "unused", "numeric", "string", "byte", "ERR", "OK", "NULL", "not NULL", + "variable" +}; +#endif + +/* + * Read the command pipe for the function to execute, gather the args + * and then process the command. + */ +static void +process_commands(WINDOW *mainscr) +{ + int len, maxlen, argslen, i, ret, type; + char *cmdbuf, *tmpbuf, **args, **tmpargs; + + len = maxlen = 30; + if ((cmdbuf = malloc(maxlen)) == NULL) + err(1, "slave cmdbuf malloc failed"); + + while(1) { + if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0) + err(1, "slave command type read failed"); + + if (type != ret_string) + errx(1, "Unexpected type for command, got %d", type); + + if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "slave command len read failed"); + + if ((len + 1) > maxlen) { + maxlen = len + 1; + if ((tmpbuf = realloc(cmdbuf, maxlen)) == NULL) + err(1, "slave cmdbuf realloc to %d " + "bytes failed", maxlen); + cmdbuf = tmpbuf; + } + + if (read(cmdpipe[READ_PIPE], cmdbuf, len) < 0) + err(1, "slave command read failed"); + cmdbuf[len] = '\0'; + argslen = 0; + args = NULL; + + do { + if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0) + err(1, "slave arg type read failed"); + + if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "slave arg len read failed"); + + if (len >= 0) { + tmpargs = realloc(args, + (argslen + 1) * sizeof(char *)); + if (tmpargs == NULL) + err(1, "slave realloc of args array " + "failed"); + + args = tmpargs; + if (type != ret_null) { + args[argslen] = malloc(len + 1); + + if (args[argslen] == NULL) + err(1, "slave alloc of %d bytes" + " for args failed", len); + } + + if (len == 0) { + if (type == ret_null) + args[argslen] = NULL; + else + args[argslen][0] = '\0'; + } else { + read(cmdpipe[READ_PIPE], args[argslen], + len); + if (type != ret_byte) + args[argslen][len] = '\0'; + + if (len == 6) { + if (strcmp(args[argslen], + "STDSCR") == 0) { + ret = asprintf(&tmpbuf, + "%p", + stdscr); + if (ret < 0) + err(2, + "asprintf of stdscr failed"); + free(args[argslen]); + args[argslen] = tmpbuf; + } + } + } + + argslen++; + } + } + while(len >= 0); + + command_execute(cmdbuf, argslen, args); + + if (args != NULL) { + for (i = 0; i < argslen; i++) + free(args[i]); + + free(args); + } + } +} + +int +main(int argc, char *argv[]) +{ + WINDOW *mainscr; + + if (argc != 5) { + fprintf(stderr, "Usage: %s <cmdin> <cmdout> <slvin> slvout>\n", + getprogname()); + return 0; + } + sscanf(argv[1], "%d", &cmdpipe[0]); + sscanf(argv[2], "%d", &cmdpipe[1]); + sscanf(argv[3], "%d", &slvpipe[0]); + sscanf(argv[4], "%d", &slvpipe[1]); + + mainscr = initscr(); + if (mainscr == NULL) + err(1, "initscr failed"); + + process_commands(mainscr); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/slave.h b/contrib/netbsd-tests/lib/libcurses/slave/slave.h new file mode 100644 index 0000000..98e9971 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/slave.h @@ -0,0 +1,50 @@ +/* $NetBSD: slave.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn <blymn@NetBSD.org> + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ +#ifndef CURTEST_SLAVE_H +#define CURTEST_SLAVE_H + +#include <curses.h> + +#define READ_PIPE 0 +#define WRITE_PIPE 1 + +void command_execute(char *, int, char **); +void report_count(int); +void report_error(const char *); +void report_int(int); +void report_byte(chtype); +void report_return(int); +void report_nstr(chtype *); +void report_status(const char *); +void report_ptr(void *); +int check_arg_count(int, int); + +#endif diff --git a/contrib/netbsd-tests/lib/libcurses/t_curses.sh b/contrib/netbsd-tests/lib/libcurses/t_curses.sh new file mode 100755 index 0000000..5ff9474 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/t_curses.sh @@ -0,0 +1,294 @@ + +h_run() +{ + file="$(atf_get_srcdir)/tests/${1}" + + export COLUMNS=80 + export LINES=24 + $(atf_get_srcdir)/director \ + -T $(atf_get_srcdir) \ + -t atf \ + -I $(atf_get_srcdir)/tests \ + -C $(atf_get_srcdir)/check_files \ + -s $(atf_get_srcdir)/slave $file || atf_fail "test ${file} failed" +} + +atf_test_case startup +startup_head() +{ + atf_set "descr" "Checks curses initialisation sequence" +} +startup_body() +{ + h_run start +} + +atf_test_case addch +addch_head() +{ + atf_set "descr" "Tests adding a chtype to stdscr" +} +addch_body() +{ + h_run addch +} + +atf_test_case addchstr +addchstr_head() +{ + atf_set "descr" "Tests adding a chtype string to stdscr" +} +addchstr_body() +{ + h_run addchstr +} + +atf_test_case addchnstr +addchnstr_head() +{ + atf_set "descr" "Tests adding bytes from a chtype string to stdscr" +} +addchnstr_body() +{ + h_run addchnstr +} + +atf_test_case addstr +addstr_head() +{ + atf_set "descr" "Tests adding bytes from a string to stdscr" +} +addstr_body() +{ + h_run addstr +} + +atf_test_case addnstr +addnstr_head() +{ + atf_set "descr" "Tests adding bytes from a string to stdscr" +} +addnstr_body() +{ + h_run addnstr +} + +atf_test_case getch +getch_head() +{ + atf_set "descr" "Checks reading a character input" +} +getch_body() +{ + h_run getch +} + +atf_test_case timeout +timeout_head() +{ + atf_set "descr" "Checks timeout when reading a character" +} +timeout_body() +{ + h_run timeout +} + +atf_test_case window +window_head() +{ + atf_set "descr" "Checks window creation" +} +window_body() +{ + h_run window +} + +atf_test_case wborder +wborder_head() +{ + atf_set "descr" "Checks drawing a border around a window" +} +wborder_body() +{ + h_run wborder +} + +atf_test_case box +box_head() +{ + atf_set "descr" "Checks drawing a box around a window" +} +box_body() +{ + h_run box +} + +atf_test_case wprintw +wprintw_head() +{ + atf_set "descr" "Checks printing to a window" +} +wprintw_body() +{ + h_run wprintw +} + +atf_test_case wscrl +wscrl_head() +{ + atf_set "descr" "Check window scrolling" +} +wscrl_body() +{ + h_run wscrl +} + +atf_test_case mvwin +mvwin_head() +{ + atf_set "descr" "Check moving a window" +} +mvwin_body() +{ + h_run mvwin +} + +atf_test_case getstr +getstr_head() +{ + atf_set "descr" "Check getting a string from input" +} +getstr_body() +{ + h_run getstr +} + +atf_test_case termattrs +termattrs_head() +{ + atf_set "descr" "Check the terminal attributes" +} +termattrs_body() +{ + h_run termattrs +} + +atf_test_case assume_default_colors +assume_default_colors_head() +{ + atf_set "descr" "Check setting the default color pair" +} +assume_default_colors_body() +{ + h_run assume_default_colors +} + +atf_test_case attributes +attributes_head() +{ + atf_set "descr" "Check setting, clearing and getting of attributes" +} +attributes_body() +{ + h_run attributes +} + +atf_test_case beep +beep_head() +{ + atf_set "descr" "Check sending a beep" +} +beep_body() +{ + h_run beep +} + +atf_test_case background +background_head() +{ + atf_set "descr" "Check setting background character and attributes for both stdscr and a window." +} +background_body() +{ + h_run background +} + +atf_test_case can_change_color +can_change_color_head() +{ + atf_set "descr" "Check if the terminal can change colours" +} +can_change_color_body() +{ + h_run can_change_color +} + +atf_test_case cbreak +cbreak_head() +{ + atf_set "descr" "Check cbreak mode works" +} +cbreak_body() +{ + h_run cbreak +} + +atf_test_case clear +clear_head() +{ + atf_set "descr" "Check clear and erase work" +} +clear_body() +{ + h_run clear +} + +atf_test_case copywin +copywin_head() +{ + atf_set "descr" "Check all the modes of copying a window work" +} +copywin_body() +{ + h_run copywin +} + +atf_test_case curs_set +curs_set_head() +{ + atf_set "descr" "Check setting the cursor visibility works" +} +curs_set_body() +{ + h_run curs_set +} + +atf_init_test_cases() +{ + atf_add_test_case startup + atf_add_test_case addch + atf_add_test_case addchstr + atf_add_test_case addchnstr + atf_add_test_case addstr + atf_add_test_case addnstr + atf_add_test_case getch + atf_add_test_case timeout + atf_add_test_case window + atf_add_test_case wborder + atf_add_test_case box + atf_add_test_case wprintw + atf_add_test_case wscrl + atf_add_test_case mvwin + atf_add_test_case getstr + atf_add_test_case termattrs + atf_add_test_case can_change_color + atf_add_test_case assume_default_colors + atf_add_test_case attributes +# atf_add_test_case beep # comment out for now - return is wrong + atf_add_test_case background + atf_add_test_case cbreak + atf_add_test_case clear + atf_add_test_case copywin + atf_add_test_case curs_set +} + diff --git a/contrib/netbsd-tests/lib/libcurses/testframe.txt b/contrib/netbsd-tests/lib/libcurses/testframe.txt new file mode 100644 index 0000000..19884d7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/testframe.txt @@ -0,0 +1,241 @@ + +CURSES TESTFRAME +---------------- + +1. Introduction + +The curses library is a complex piece of software and, often, changes +made to the library may introduce subtle bugs that are hidden by other +actions so a visual check of the curses output may look correct in +some circumstances and the bug only show itself after a certain +sequence of actions. To assist with validating that changes made to +the curses library have no undesired effects an automated test is +needed to detect and highlight any changes in the curses application +output stream. The programmer can then analyse the output changes and +either correct a bug or update the automated test to accept the new +output as valid. + +2. Architecture + +The curses testframe consists of two separate programs connected by a +number of pipes and a pseudo-tty (pty). The programs are called the +director and the slave. The director reads a configuration file of +tests to perform, passes these commands to the slave over a pipe and +reads the pty for any output from the slave. Data from the slave is +compared against expected output held in a file and any differences +are highlighted to the tester. The slave is a curses application that +is forked by the director on start up. It reads commands from the +director over a pipe, these commands are calls to curses routines +along with the parameters required for the call. The slave takes the +parameters and uses them as arguments for the requested curses routine +call. The return value from the curses routine is passed back to the +director over another pipe, if the curses routine updates any passed +by reference arguments then these are also passed back to the director +for analysis. + +3. Director + +The director has the following optional command line options: + + -v enables verbose output to assist debugging + -s slave_path the director will execute slave_path as the slave + process. The default is ./slave + -t term Sets the TERM environment variable to term when + executing the slave. The default is atf + +There is one mandatory command line parameter, that is a file name +that contains the test command file. The test command file holds the +calls required to exercise a particular curses routine and validate +both the return codes from the routines and the output from the +slave. The test language has a small number of commands, they are: + +assign: + Assign a value to a variable. The syntax is: + + assign var_name value + + Where var_name is the name of the variable. Variable names are + an arbitrary sequence of alphanumeric characters, the variable + name must start with an alphabetic character. Value is the value + to be assigned. The value can either be a numeric or a string + type. Variables are created on first use and will be + overwritten on each subsequent use. + +call, call2, call3, call4: + All these are used to call curses routines, the only difference + between then is the number of expected return values. Call + expects one return value, call2 expects 2, call3 expects 3 and + call4 expects four. Any parameters that are passed by reference + and updated by the call are treated like returns. So, for + example, calling the function getyx() which has three + parameters, the window, a pointer to storage for y and a pointer + to storage for x would be called like this: + + call3 OK 4 5 getyx $win1 + + Which calls getyx, the first (and possibly only) return is the + return status of the function call, in this case we expect "OK" + indicating that the call succeeded. The next two returns are + the values of y and x respectively, the parameter $win1 is a + variable that was assigned by a previous call. Any return can + be assigned to a variable by including the variable name in a + call return list. Variables are referenced in a call parameter + list by prefixing the name with a $ character. All returns are + validated against the expected values and an error raised if + there is a mismatch. The only exception to this is when the + return is assigned to a variable. Valid values for the returns + list are: + + variable - assign the return to the given variable + name. + numeric - the value of the return must match the + number given. + string - an arbitrary sequence of characters + enclosed in double quotes. + ERR - expect an ERR return + OK - expect an OK return + NULL - expect a NULL pointer return + NON_NULL - expect a pointer that is not NULL valued + + There is one special parameter that can be passed to a call, + that is the label STDSCR. This parameter will be substituted by + the value of stdscr when the function call is made. + +check: + Validate the value of a variable. This allows a variable to be + checked for an expected return after it has been assigned in a + previous call. The syntax is: + + check var_name expected_result + + Where var_name is a variable previously assigned and + expected_result is one of the valid return values listed in the + above call section. + +compare: + Compares the output stream from the slave against the contents + of a file that contains the expected + output. The syntax is: + + compare filename + + Where filename is the name of the file containing the expected + output. The file can either be an absolute path or relative + path. In the latter case the value of the environment variable + CHECK_PATH will be prepended to the argument to provide the path + to the file. The contents of this file will be compared byte by + byte against the output from the slave, any differences in the + output will be flagged. If the director is not in verbose mode + then the first mismatch in the byte stream will cause the + director to exit. + +comparend: + Performs the same function as the above compare except that + excess output from the slave is not discarded if there is more + data from the slave than there is in the check file. This + allows chaining of multiple check files. + +delay: + Defines an inter-character delay to be inserted between + characters being fed into the input of the slave. The syntax + is: + + delay time + + Where time is the amount of time to delay in milliseconds. + +include: + Include the contents of another test file, the parser will + suspend reading the current file and read commands from the + include file until the end of file of the include file is + reached at which point it will continue reading the original + file. Include files may be nested. The syntax is: + + include filename + + Where filename is the name of the file to include. If the + filename is not an absolute path then the contents of the + environment variable INCLUDE_PATH are prepended to the file + name. + +input: + Defines a string of characters that will be fed to the slave + when a call requires input. Any unused input will be discarded + after the call that required the input is called. The syntax + is: + + input "string to pass" + +noinput: + Normally the director will error if an input function is called + without input being previously defined, this is to prevent input + functions causing the test to hang waiting for input that never + comes. If it is known that there is pending input for the slave + then the noinput keyword can be used to flag that the input + function has data available for it to read. The noinput command + only applies to the next function call then behaviour reverts to + the default. + +The testframe can define different types of strings, the type of string +depends on the type of enclosing quotes. A null terminated string is +indicated by enclosing double (") quotes. A byte string, one that is +not null terminated and may contain the nul character within it is +indicated by enclosing single (') quotes. A string of chtype +character which are a combined attribute and character value is +indicated by enclosing backticks (`), for this type of string pairs of +bytes between the backticks are converted to an array of chtype, the +first byte is the attribute and the second is the character. + +All strings defined will have a simple set of character substitutions +performed on them when they are parsed. This allows the tester to +embed some control characters into the string. Valid substitutions +are: + + \e escape + \n new line + \r carriage return + \t tab + \\ \ character + \nnn Where nnn is three octal digits, the character + represented by the octal number will be inserted into + the string. + +Any other invalid conversions will have the \ stripped and the +subsequent characters inserted into the string. + +Integers may be specified by either a plain numeric (e.g. 12345) or by +hexadecimal notation by prefixing the number with 0x (e.g. 0x3039). +Internally, no distinction is made between the two formats and they +can be freely intermixed. + +Integers and variables containing integers can have operations +performed on them. Currently only bitwise ORing numbers together is +supported. This can be done by separating a list of integers and +variables with the pipe (|) symbol and enclosing the entire list in +round brackets "()" like this: + + ( $var1 | 0x0100 | $var2 | 512 ) + +Variables and integer constants may be freely intermixed. The result +of the operation can either be used as an argument for a call or can +be used as an expected result for a call. + +In addition to all the curses calls being supported by the slave, +there is one more special call called "drain". This call repeatedly +called getch() until there are no more characters in stdin. The call +assumes that the curses input is either in no delay or timed input +mode otherwise the test will time out and fail. This call can be used +to clear any pending input when testing testing a timed read to +prevent the input being used in a later test. + +4. Slave + +The user has no direct interaction with the slave process. The slave +is forked off by the director communicates to the director over a set +of pipes and a pseudo-tty connected to its standard i/o file +descriptors. The slave executes the passed curses calls and passes +back return values to the director. The slave automatically calls +initscr() on start up. + + + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addch b/contrib/netbsd-tests/lib/libcurses/tests/addch new file mode 100644 index 0000000..a67e385 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addch @@ -0,0 +1,4 @@ +include start +call OK addch `\001t` +call OK refresh +compare addch.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addchnstr b/contrib/netbsd-tests/lib/libcurses/tests/addchnstr new file mode 100644 index 0000000..661bf74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addchnstr @@ -0,0 +1,5 @@ +include start +# note that there are more characters in the array, check we only get 5 out +call OK addchnstr `\004a\004b\004c\004d\004e\004f\004g` 5 +call OK refresh +compare addchstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addchstr b/contrib/netbsd-tests/lib/libcurses/tests/addchstr new file mode 100644 index 0000000..4ccf7b8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addchstr @@ -0,0 +1,4 @@ +include start +call OK addchstr `\004a\004b\004c\004d\004e` +call OK refresh +compare addchstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addnstr b/contrib/netbsd-tests/lib/libcurses/tests/addnstr new file mode 100644 index 0000000..9c40801 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addnstr @@ -0,0 +1,5 @@ +include start +call OK addnstr "abcdefg" 5 +call OK refresh +# should be the same as addstr +compare addstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addstr b/contrib/netbsd-tests/lib/libcurses/tests/addstr new file mode 100644 index 0000000..8c1d24f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addstr @@ -0,0 +1,4 @@ +include start +call OK addstr "abcde" +call OK refresh +compare addstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors b/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors new file mode 100644 index 0000000..b6ccb09 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors @@ -0,0 +1,19 @@ +include start +call OK start_color +call OK assume_default_colors -1 -1 +call OK refresh +compare color_start.chk +# This should be the same as the default +compare color_default.chk +# default foreground, blue background +call OK assume_default_colors -1 $COLOR_BLUE +call OK refresh +compare color_blue_back.chk +# red foreground, default background +call OK assume_default_colors $COLOR_RED -1 +call OK refresh +compare color_red_fore.chk +# back to default +call OK assume_default_colors -1 -1 +call OK refresh +compare color_default.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/attributes b/contrib/netbsd-tests/lib/libcurses/tests/attributes new file mode 100644 index 0000000..b75d7d1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/attributes @@ -0,0 +1,23 @@ +include start +# no attributes, no color +call3 OK 0 0 attr_get +# set reverse and bold +call OK attr_set ($BOLD | $REVERSE) 2 +# returned attributes includes color information +call3 OK ($ACS_IS_WACS | $BOLD | $REVERSE) 2 attr_get +# turn off reverse +call OK attr_off $REVERSE +call3 OK ($ACS_IS_WACS | $BOLD) 2 attr_get +# turn on standout +call OK attr_on $STANDOUT +call3 OK ($ACS_IS_WACS | $BOLD | $STANDOUT) 2 attr_get +# turn on blink +call OK attron $BLINK +call3 OK ($ACS_IS_WACS | $BOLD | $STANDOUT | $BLINK) 2 attr_get +# turn off bold +call OK attroff $BOLD +call3 OK ($ACS_IS_WACS | $STANDOUT | $BLINK) 2 attr_get +# print out something to check our attributes are there, standout and blink +call OK printw "%s" "hello" +call OK refresh +compare attributes.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/background b/contrib/netbsd-tests/lib/libcurses/tests/background new file mode 100644 index 0000000..2c4a575 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/background @@ -0,0 +1,23 @@ +include start +call OK bkgd `\002A` +call OK refresh +# looks like a bug - bottom right char not filled +compare background1.chk +call OK printw "%s" "a test string" +call OK refresh +compare background2.chk +call win1 newwin 6 6 2 5 +check win1 NON_NULL +call OK wprintw $win1 "%s" "window 1" +# call OK refresh +call OK wrefresh $win1 +compare background3.chk +call OK wbkgd $win1 `\004B` +call OK refresh +call OK wrefresh $win1 +compare background4.chk +call OK wprintw $win1 "%s" "hello world" +call OK refresh +call OK wrefresh $win1 +compare background5.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/beep b/contrib/netbsd-tests/lib/libcurses/tests/beep new file mode 100644 index 0000000..832e87f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/beep @@ -0,0 +1,5 @@ +include start +# SUSv2 says this should return OK but we return 1 +call 1 beep +call OK refresh +compare bell.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/box b/contrib/netbsd-tests/lib/libcurses/tests/box new file mode 100644 index 0000000..bfd2e12 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/box @@ -0,0 +1,8 @@ +include window +call OK box $win1 `\000` `\000` +call OK wrefresh $win1 +# default settings of box will output same as wborder +compare wborder.chk +call OK box $win1 `\001\000` `\004\000` +call OK wrefresh $win1 +compare box_standout.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/can_change_color b/contrib/netbsd-tests/lib/libcurses/tests/can_change_color new file mode 100644 index 0000000..aed622a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/can_change_color @@ -0,0 +1,3 @@ +include start +# our test terminal can change colors so expect true. +call 1 can_change_color diff --git a/contrib/netbsd-tests/lib/libcurses/tests/cbreak b/contrib/netbsd-tests/lib/libcurses/tests/cbreak new file mode 100644 index 0000000..b8bf60e --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/cbreak @@ -0,0 +1,18 @@ +include start +# setting noecho stops getch setting cbreak itself so we should need +# a newline before getch returns, check this works first. +call OK noecho +input "abcd\n" +call 0x61 getch +noinput +call 0x62 getch +noinput +call 0x63 getch +noinput +call 0x64 getch +noinput +call 0x0a getch +# set cbreak, getch should return without needing a newline +input "ef" +call OK cbreak +call 0x65 getch diff --git a/contrib/netbsd-tests/lib/libcurses/tests/chgat b/contrib/netbsd-tests/lib/libcurses/tests/chgat new file mode 100644 index 0000000..863ab11 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/chgat @@ -0,0 +1,15 @@ +include start_color +call OK init_pair 3 $COLOR_YELLOW $COLOR_CYAN +call OK addch `\000d` +call OK chgat 5 $REVERSE 3 0 +call OK refresh +compare chgat1.chk +call OK addch `\000e` +call OK refresh +compare chgat2.chk +call OK move 0 0 +# The following should apply the attribute and colour to the whole line +call OK chgat -1 $UNDERSCORE 3 0 +call OK refresh +compare chgat3.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/clear b/contrib/netbsd-tests/lib/libcurses/tests/clear new file mode 100644 index 0000000..5aad934 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/clear @@ -0,0 +1,57 @@ +include addstr +call OK clear +call OK refresh +compare clear1.chk +call OK move 5 5 +call OK addstr "abcde" +call OK move 20 5 +call OK addstr "fghij" +call OK move 10 5 +call OK refresh +compare clear2.chk +call OK clrtobot +call OK refresh +compare clear3.chk +call OK erase +call OK refresh +compare clear4.chk +include fill_screen +compare fill.chk +call OK erase +call OK refresh +compare clear5.chk +# create a window to play with, defines win1 var +include window_create +call OK waddstr $win1 "abc" +call OK mvwaddstr $win1 4 1 "efg" +call OK wmove $win1 1 0 +call OK wrefresh $win1 +compare clear6.chk +call OK wclrtobot $win1 +call OK wrefresh $win1 +compare clear7.chk +include fill_screen +comparend home.chk +compare fill.chk +call OK wrefresh $win1 +call OK wclear $win1 +call OK wrefresh $win1 +compare clear8.chk +call OK clear +call OK refresh +compare clear1.chk +include fill_screen +compare fill.chk +call OK werase $win1 +call OK wrefresh $win1 +compare clear9.chk +call OK waddstr $win1 "abc" +call OK mvwaddstr $win1 4 1 "efg" +call OK wmove $win1 1 0 +call OK wrefresh $win1 +compare clear6.chk +call OK wmove $win1 4 0 +call OK wclrtoeol $win1 +call OK wrefresh $win1 +compare clear10.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/color_content b/contrib/netbsd-tests/lib/libcurses/tests/color_content new file mode 100644 index 0000000..0db66e5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/color_content @@ -0,0 +1,12 @@ +include start +call OK start_color +call4 OK 0 0 0 color_content $COLOR_BLACK +call4 OK 1000 0 0 color_content $COLOR_RED +call4 OK 0 1000 0 color_content $COLOR_GREEN +call4 OK 1000 1000 0 color_content $COLOR_YELLOW +call4 OK 0 0 1000 color_content $COLOR_BLUE +call4 OK 1000 0 1000 color_content $COLOR_MAGENTA +call4 OK 0 1000 1000 color_content $COLOR_CYAN +call4 OK 1000 1000 1000 color_content $COLOR_WHITE + + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/color_set b/contrib/netbsd-tests/lib/libcurses/tests/color_set new file mode 100644 index 0000000..07cd1c5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/color_set @@ -0,0 +1,11 @@ +include start +call OK start_color +call OK refresh +comparend color_start.chk +compare color_blank_draw.chk +call OK init_pair 4 $COLOR_RED $COLOR_GREEN +call OK color_set 4 0 +call OK printw "%s" "testing" +call OK refresh +compare color_set.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/copywin b/contrib/netbsd-tests/lib/libcurses/tests/copywin new file mode 100644 index 0000000..2dbec40 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/copywin @@ -0,0 +1,81 @@ +include start +include window_create +call win2 newwin 7 9 10 14 +check win2 NON_NULL +call OK wrefresh $win2 +compare copywin1.chk +call OK mvwprintw $win1 0 0 "%s" "testin" +call OK mvwprintw $win1 1 0 "%s" "gtesti" +call OK mvwprintw $win1 2 0 "%s" "ngtest" +call OK mvwprintw $win1 3 0 "%s" "ingtes" +call OK mvwprintw $win1 4 0 "%s" "tingte" +call OK mvwprintw $win1 5 0 "%s" "stingt" +call OK wrefresh $win1 +compare copywin2.chk +call OK copywin $win1 $win2 0 0 1 1 7 7 0 +call OK wrefresh $win2 +compare copywin3.chk +call OK wclear $win1 +call OK wclear $win2 +call OK wrefresh $win1 +call OK wrefresh $win2 +compare copywin4.chk +call OK mvwprintw $win2 0 0 "%s" "testingte" +call OK mvwprintw $win2 1 0 "%s" "stingtest" +call OK mvwprintw $win2 2 0 "%s" "ingtestin" +call OK mvwprintw $win2 3 0 "%s" "gtestingt" +call OK mvwprintw $win2 4 0 "%s" "estingtes" +call OK mvwprintw $win2 5 0 "%s" "tingtesti" +call OK wrefresh $win2 +compare copywin5.chk +call OK copywin $win2 $win1 0 0 0 0 7 9 0 +call OK wrefresh $win1 +compare copywin6.chk +call OK wclear $win1 +call OK wclear $win2 +call OK wrefresh $win1 +call OK wrefresh $win2 +compare copywin7.chk +call OK mvwprintw $win1 0 0 "%s" "t s i " +call OK mvwprintw $win1 1 0 "%s" "g e t " +call OK mvwprintw $win1 2 0 "%s" "n t s " +call OK mvwprintw $win1 3 0 "%s" " n t s" +call OK mvwprintw $win1 4 0 "%s" "t n t " +call OK mvwprintw $win1 5 0 "%s" " t n t" +call OK wrefresh $win1 +compare copywin8.chk +call OK mvwprintw $win2 0 0 "%s" " e t n" +call OK mvwprintw $win2 1 0 "%s" " t s i" +call OK mvwprintw $win2 2 0 "%s" " g e t" +call OK mvwprintw $win2 3 0 "%s" "i g e " +call OK mvwprintw $win2 4 0 "%s" " i g e" +call OK mvwprintw $win2 5 0 "%s" "s i g " +call OK wrefresh $win2 +compare copywin9.chk +call OK copywin $win1 $win2 0 0 0 0 6 6 0 +call OK wrefresh $win2 +compare copywin10.chk +call OK wclear $win1 +call OK wclear $win2 +call OK wrefresh $win1 +call OK wrefresh $win2 +compare copywin11.chk +call OK mvwprintw $win1 0 0 "%s" "t s i " +call OK mvwprintw $win1 1 0 "%s" "g e t " +call OK mvwprintw $win1 2 0 "%s" "n t s " +call OK mvwprintw $win1 3 0 "%s" " n t s" +call OK mvwprintw $win1 4 0 "%s" "t n t " +call OK mvwprintw $win1 5 0 "%s" " t n t" +call OK wrefresh $win1 +compare copywin12.chk +call OK mvwprintw $win2 0 0 "%s" " e t n" +call OK mvwprintw $win2 1 0 "%s" " t s i" +call OK mvwprintw $win2 2 0 "%s" " g e t" +call OK mvwprintw $win2 3 0 "%s" "i g e " +call OK mvwprintw $win2 4 0 "%s" " i g e" +call OK mvwprintw $win2 5 0 "%s" "s i g " +call OK wrefresh $win2 +compare copywin13.chk +call OK copywin $win1 $win2 0 0 0 0 6 6 1 +call OK wrefresh $win2 +compare copywin14.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/curs_set b/contrib/netbsd-tests/lib/libcurses/tests/curs_set new file mode 100644 index 0000000..5d7cb54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/curs_set @@ -0,0 +1,7 @@ +include start +call 2 curs_set 0 +compare curs_set1.chk +call 0 curs_set 1 +compare curs_set2.chk +call 1 curs_set 2 +compare curs_set3.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/fill_screen b/contrib/netbsd-tests/lib/libcurses/tests/fill_screen new file mode 100644 index 0000000..b9e2942 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/fill_screen @@ -0,0 +1,29 @@ +# +# Fill the screen with characters. We don't do a compare in here because +# this is meant to be included from other tests which could result in random +# cursor motions before the fill is done. +# +call OK mvaddstr 0 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 1 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 2 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 3 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 4 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 5 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 6 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 7 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 8 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 9 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 10 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 11 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 12 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 13 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 14 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 15 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 16 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 17 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 18 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 19 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 20 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 21 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 22 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK refresh diff --git a/contrib/netbsd-tests/lib/libcurses/tests/getch b/contrib/netbsd-tests/lib/libcurses/tests/getch new file mode 100644 index 0000000..9f437f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/getch @@ -0,0 +1,3 @@ +include start +input "i" +call 105 getch diff --git a/contrib/netbsd-tests/lib/libcurses/tests/getstr b/contrib/netbsd-tests/lib/libcurses/tests/getstr new file mode 100644 index 0000000..320325f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/getstr @@ -0,0 +1,6 @@ +include window +input "input\n" +call2 OK "input" wgetstr $win1 +compare wgetstr.chk +call OK wrefresh $win1 +compare wgetstr_refresh.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/mvwin b/contrib/netbsd-tests/lib/libcurses/tests/mvwin new file mode 100644 index 0000000..86d9bd6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/mvwin @@ -0,0 +1,12 @@ +include window +call OK wmove $win1 1 1 +call OK wprintw $win1 "%s" "xxxx" +call OK wrefresh $win1 +compare /dev/zero +call OK refresh +compare /dev/zero +call OK mvwin $win1 4 7 +call OK wrefresh $win1 +compare /dev/zero +call OK refresh +compare /dev/zero diff --git a/contrib/netbsd-tests/lib/libcurses/tests/start b/contrib/netbsd-tests/lib/libcurses/tests/start new file mode 100644 index 0000000..963f2f4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/start @@ -0,0 +1,3 @@ +include std_defines +call OK refresh +compare curses_start.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/start_color b/contrib/netbsd-tests/lib/libcurses/tests/start_color new file mode 100644 index 0000000..6d3f133 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/start_color @@ -0,0 +1,5 @@ +include start +call OK start_color +call OK refresh +comparend color_start.chk +compare color_blank_draw.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/std_defines b/contrib/netbsd-tests/lib/libcurses/tests/std_defines new file mode 100644 index 0000000..9c986df --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/std_defines @@ -0,0 +1,138 @@ +# +# Define some standard symbols for curses so tests can reference things +# symbolically instead of using magic numbers. +# +# +# boolean +# +assign TRUE 0x01 +assign FALSE 0x00 +# +# colours +# +assign COLOR_BLACK 0x00 +assign COLOR_RED 0x01 +assign COLOR_GREEN 0x02 +assign COLOR_YELLOW 0x03 +assign COLOR_BLUE 0x04 +assign COLOR_MAGENTA 0x05 +assign COLOR_CYAN 0x06 +assign COLOR_WHITE 0x07 +# +# Attributes +# +assign NORMAL 0x00000000 +assign STANDOUT 0x00000100 +assign UNDERSCORE 0x00000200 +assign REVERSE 0x00000400 +assign BLINK 0x00000800 +assign DIM 0x00001000 +assign BOLD 0x00002000 +assign BLANK 0x00004000 +assign PROTECT 0x00008000 +assign ALTCHARSET 0x00010000 +assign ACS_IS_WACS 0x00040000 +# +# Keys +# +assign KEY_BREAK 0x101 +assign KEY_DOWN 0x102 +assign KEY_UP 0x103 +assign KEY_LEFT 0x104 +assign KEY_RIGHT 0x105 +assign KEY_HOME 0x106 +assign KEY_BACKSPACE 0x107 +assign KEY_F0 0x108 +assign KEY_F1 0x109 +assign KEY_F2 0x10a +assign KEY_F3 0x10b +assign KEY_F4 0x10c +assign KEY_F5 0x10d +assign KEY_F6 0x10e +assign KEY_F7 0x10f +assign KEY_F8 0x110 +assign KEY_F9 0x111 +assign KEY_DL 0x148 +assign KEY_IL 0x149 +assign KEY_DC 0x14A +assign KEY_IC 0x14B +assign KEY_EIC 0x14C +assign KEY_CLEAR 0x14D +assign KEY_EOS 0x14E +assign KEY_EOL 0x14F +assign KEY_SF 0x150 +assign KEY_SR 0x151 +assign KEY_NPAGE 0x152 +assign KEY_PPAGE 0x153 +assign KEY_STAB 0x154 +assign KEY_CTAB 0x155 +assign KEY_CATAB 0x156 +assign KEY_ENTER 0x157 +assign KEY_SRESET 0x158 +assign KEY_RESET 0x159 +assign KEY_PRINT 0x15A +assign KEY_LL 0x15B +assign KEY_A1 0x15C +assign KEY_A3 0x15D +assign KEY_B2 0x15E +assign KEY_C1 0x15F +assign KEY_C3 0x160 +assign KEY_BTAB 0x161 +assign KEY_BEG 0x162 +assign KEY_CANCEL 0x163 +assign KEY_CLOSE 0x164 +assign KEY_COMMAND 0x165 +assign KEY_COPY 0x166 +assign KEY_CREATE 0x167 +assign KEY_END 0x168 +assign KEY_EXIT 0x169 +assign KEY_FIND 0x16A +assign KEY_HELP 0x16B +assign KEY_MARK 0x16C +assign KEY_MESSAGE 0x16D +assign KEY_MOVE 0x16E +assign KEY_NEXT 0x16F +assign KEY_OPEN 0x170 +assign KEY_OPTIONS 0x171 +assign KEY_PREVIOUS 0x172 +assign KEY_REDO 0x173 +assign KEY_REFERENCE 0x174 +assign KEY_REFRESH 0x175 +assign KEY_REPLACE 0x176 +assign KEY_RESTART 0x177 +assign KEY_RESUME 0x178 +assign KEY_SAVE 0x179 +assign KEY_SBEG 0x17A +assign KEY_SCANCEL 0x17B +assign KEY_SCOMMAND 0x17C +assign KEY_SCOPY 0x17D +assign KEY_SCREATE 0x17E +assign KEY_SDC 0x17F +assign KEY_SDL 0x180 +assign KEY_SELECT 0x181 +assign KEY_SEND 0x182 +assign KEY_SEOL 0x183 +assign KEY_SEXIT 0x184 +assign KEY_SFIND 0x185 +assign KEY_SHELP 0x186 +assign KEY_SHOME 0x187 +assign KEY_SIC 0x188 +assign KEY_SLEFT 0x189 +assign KEY_SMESSAGE 0x18A +assign KEY_SMOVE 0x18B +assign KEY_SNEXT 0x18C +assign KEY_SOPTIONS 0x18D +assign KEY_SPREVIOUS 0x18E +assign KEY_SPRINT 0x18F +assign KEY_SREDO 0x190 +assign KEY_SREPLACE 0x191 +assign KEY_SRIGHT 0x192 +assign KEY_SRSUME 0x193 +assign KEY_SSAVE 0x194 +assign KEY_SSUSPEND 0x195 +assign KEY_SUNDO 0x196 +assign KEY_SUSPEND 0x197 +assign KEY_UNDO 0x198 +assign KEY_MOUSE 0x199 +assign KEY_RESIZE 0x200 + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/termattrs b/contrib/netbsd-tests/lib/libcurses/tests/termattrs new file mode 100644 index 0000000..1025301 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/termattrs @@ -0,0 +1,3 @@ +include start +# the atf terminal can do all attributes except PROTECT +call 0x17f00 termattrs diff --git a/contrib/netbsd-tests/lib/libcurses/tests/timeout b/contrib/netbsd-tests/lib/libcurses/tests/timeout new file mode 100644 index 0000000..1adf057 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/timeout @@ -0,0 +1,21 @@ +# +# Validate the timeout works. +# +include start +delay 2000 +input "a" +call 97 getch +call OK timeout 100 +input "b" +# since delay is in effect and we set timeout the following getch should +# return ERR not the character b. +call -1 getch +# drain input.... +call OK drain +call OK timeout -1 +call OK keypad STDSCR 1 +delay 0 +input "\eOA" +call $KEY_UP getch +call OK refresh +compare timeout.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wborder b/contrib/netbsd-tests/lib/libcurses/tests/wborder new file mode 100644 index 0000000..7a8e78f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/wborder @@ -0,0 +1,6 @@ +include window +call OK wborder $win1 0 0 0 0 0 0 0 0 +call OK wrefresh $win1 +compare wborder.chk +call OK refresh +compare wborder_refresh.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/window b/contrib/netbsd-tests/lib/libcurses/tests/window new file mode 100644 index 0000000..52b2d0a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/window @@ -0,0 +1,2 @@ +include start +include window_create diff --git a/contrib/netbsd-tests/lib/libcurses/tests/window_create b/contrib/netbsd-tests/lib/libcurses/tests/window_create new file mode 100644 index 0000000..8c96134 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/window_create @@ -0,0 +1,4 @@ +call win1 newwin 6 6 2 5 +check win1 NON_NULL +call OK wrefresh $win1 +compare window.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wprintw b/contrib/netbsd-tests/lib/libcurses/tests/wprintw new file mode 100644 index 0000000..a30fcc0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/wprintw @@ -0,0 +1,6 @@ +include start +call win1 newwin 2 5 2 5 +check win1 NON_NULL +call OK wprintw $win1 "%s" "hello" +call OK wrefresh $win1 +compare wprintw_refresh.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wscrl b/contrib/netbsd-tests/lib/libcurses/tests/wscrl new file mode 100644 index 0000000..51be531 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/wscrl @@ -0,0 +1,11 @@ +include window +call OK wmove $win1 1 1 +call OK wprintw $win1 "%s" "xxxx" +call OK wrefresh $win1 +call OK refresh +compare wscrl1.chk +call OK scrollok $win1 1 +call OK wscrl $win1 -2 +call OK wrefresh $win1 +call OK refresh +compare wscrl2.chk diff --git a/contrib/netbsd-tests/lib/libdes/t_des.c b/contrib/netbsd-tests/lib/libdes/t_des.c new file mode 100644 index 0000000..abf2e54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libdes/t_des.c @@ -0,0 +1,989 @@ +/* $NetBSD: t_des.c,v 1.1 2010/08/25 16:46:36 jmmv Exp $ */ + +/* + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights + * reserved. + * + * This package is an SSL implementation written by Eric Young + * (eay@cryptsoft.com). The implementation was written so as to conform with + * Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as the + * following conditions are aheared to. The following conditions apply to + * all code found in this distribution, be it the RC4, RSA, lhash, DES, etc., + * code; not just the SSL code. The SSL documentation included with this + * distribution is covered by the same copyright terms except that the holder + * is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in the code + * are not to be removed. If this package is used in a product, Eric Young + * should be given attribution as the author of the parts of the library + * used. This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. All advertising materials + * mentioning features or use of this software must display the following + * acknowledgement: "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" The word 'cryptographic' can be left out + * if the rouines from the library being used are not cryptographic related + * :-). 4. If you include any Windows specific code (or a derivative thereof) + * from the apps directory (application code) you must include an + * acknowledgement: "This product includes software written by Tim Hudson + * (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply + * be copied and put under another distribution licence [including the GNU + * Public Licence.] + */ + +#include <atf-c.h> +#include <des.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define crypt(c,s) (des_crypt((c),(s))) + +/* tisk tisk - the test keys don't all have odd parity :-( */ +/* test data */ +#define NUM_TESTS 34 +static unsigned char key_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, + {0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57}, + {0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E}, + {0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86}, + {0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E}, + {0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6}, + {0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE}, + {0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6}, + {0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE}, + {0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16}, + {0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F}, + {0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46}, + {0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E}, + {0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76}, + {0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07}, + {0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F}, + {0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7}, + {0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF}, + {0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6}, + {0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF}, + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, + {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10} +}; + +static unsigned char plain_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42}, + {0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA}, + {0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72}, + {0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A}, + {0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2}, + {0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A}, + {0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2}, + {0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A}, + {0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02}, + {0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A}, + {0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32}, + {0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA}, + {0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62}, + {0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2}, + {0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA}, + {0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92}, + {0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A}, + {0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2}, + {0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; + +static unsigned char cipher_data[NUM_TESTS][8] = { + {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7}, + {0x73, 0x59, 0xB2, 0x16, 0x3E, 0x4E, 0xDC, 0x58}, + {0x95, 0x8E, 0x6E, 0x62, 0x7A, 0x05, 0x55, 0x7B}, + {0xF4, 0x03, 0x79, 0xAB, 0x9E, 0x0E, 0xC5, 0x33}, + {0x17, 0x66, 0x8D, 0xFC, 0x72, 0x92, 0x53, 0x2D}, + {0x8A, 0x5A, 0xE1, 0xF8, 0x1A, 0xB8, 0xF2, 0xDD}, + {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7}, + {0xED, 0x39, 0xD9, 0x50, 0xFA, 0x74, 0xBC, 0xC4}, + {0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B}, + {0x7A, 0x38, 0x9D, 0x10, 0x35, 0x4B, 0xD2, 0x71}, + {0x86, 0x8E, 0xBB, 0x51, 0xCA, 0xB4, 0x59, 0x9A}, + {0x71, 0x78, 0x87, 0x6E, 0x01, 0xF1, 0x9B, 0x2A}, + {0xAF, 0x37, 0xFB, 0x42, 0x1F, 0x8C, 0x40, 0x95}, + {0x86, 0xA5, 0x60, 0xF1, 0x0E, 0xC6, 0xD8, 0x5B}, + {0x0C, 0xD3, 0xDA, 0x02, 0x00, 0x21, 0xDC, 0x09}, + {0xEA, 0x67, 0x6B, 0x2C, 0xB7, 0xDB, 0x2B, 0x7A}, + {0xDF, 0xD6, 0x4A, 0x81, 0x5C, 0xAF, 0x1A, 0x0F}, + {0x5C, 0x51, 0x3C, 0x9C, 0x48, 0x86, 0xC0, 0x88}, + {0x0A, 0x2A, 0xEE, 0xAE, 0x3F, 0xF4, 0xAB, 0x77}, + {0xEF, 0x1B, 0xF0, 0x3E, 0x5D, 0xFA, 0x57, 0x5A}, + {0x88, 0xBF, 0x0D, 0xB6, 0xD7, 0x0D, 0xEE, 0x56}, + {0xA1, 0xF9, 0x91, 0x55, 0x41, 0x02, 0x0B, 0x56}, + {0x6F, 0xBF, 0x1C, 0xAF, 0xCF, 0xFD, 0x05, 0x56}, + {0x2F, 0x22, 0xE4, 0x9B, 0xAB, 0x7C, 0xA1, 0xAC}, + {0x5A, 0x6B, 0x61, 0x2C, 0xC2, 0x6C, 0xCE, 0x4A}, + {0x5F, 0x4C, 0x03, 0x8E, 0xD1, 0x2B, 0x2E, 0x41}, + {0x63, 0xFA, 0xC0, 0xD0, 0x34, 0xD9, 0xF7, 0x93}, + {0x61, 0x7B, 0x3A, 0x0C, 0xE8, 0xF0, 0x71, 0x00}, + {0xDB, 0x95, 0x86, 0x05, 0xF8, 0xC8, 0xC6, 0x06}, + {0xED, 0xBF, 0xD1, 0xC6, 0x6C, 0x29, 0xCC, 0xC7}, + {0x35, 0x55, 0x50, 0xB2, 0x15, 0x0E, 0x24, 0x51}, + {0xCA, 0xAA, 0xAF, 0x4D, 0xEA, 0xF1, 0xDB, 0xAE}, + {0xD5, 0xD4, 0x4F, 0xF7, 0x20, 0x68, 0x3D, 0x0D}, + {0x2A, 0x2B, 0xB0, 0x08, 0xDF, 0x97, 0xC2, 0xF2} +}; + +static unsigned char cipher_ecb2[NUM_TESTS - 1][8] = { + {0x92, 0x95, 0xB5, 0x9B, 0xB3, 0x84, 0x73, 0x6E}, + {0x19, 0x9E, 0x9D, 0x6D, 0xF3, 0x9A, 0xA8, 0x16}, + {0x2A, 0x4B, 0x4D, 0x24, 0x52, 0x43, 0x84, 0x27}, + {0x35, 0x84, 0x3C, 0x01, 0x9D, 0x18, 0xC5, 0xB6}, + {0x4A, 0x5B, 0x2F, 0x42, 0xAA, 0x77, 0x19, 0x25}, + {0xA0, 0x6B, 0xA9, 0xB8, 0xCA, 0x5B, 0x17, 0x8A}, + {0xAB, 0x9D, 0xB7, 0xFB, 0xED, 0x95, 0xF2, 0x74}, + {0x3D, 0x25, 0x6C, 0x23, 0xA7, 0x25, 0x2F, 0xD6}, + {0xB7, 0x6F, 0xAB, 0x4F, 0xBD, 0xBD, 0xB7, 0x67}, + {0x8F, 0x68, 0x27, 0xD6, 0x9C, 0xF4, 0x1A, 0x10}, + {0x82, 0x57, 0xA1, 0xD6, 0x50, 0x5E, 0x81, 0x85}, + {0xA2, 0x0F, 0x0A, 0xCD, 0x80, 0x89, 0x7D, 0xFA}, + {0xCD, 0x2A, 0x53, 0x3A, 0xDB, 0x0D, 0x7E, 0xF3}, + {0xD2, 0xC2, 0xBE, 0x27, 0xE8, 0x1B, 0x68, 0xE3}, + {0xE9, 0x24, 0xCF, 0x4F, 0x89, 0x3C, 0x5B, 0x0A}, + {0xA7, 0x18, 0xC3, 0x9F, 0xFA, 0x9F, 0xD7, 0x69}, + {0x77, 0x2C, 0x79, 0xB1, 0xD2, 0x31, 0x7E, 0xB1}, + {0x49, 0xAB, 0x92, 0x7F, 0xD0, 0x22, 0x00, 0xB7}, + {0xCE, 0x1C, 0x6C, 0x7D, 0x85, 0xE3, 0x4A, 0x6F}, + {0xBE, 0x91, 0xD6, 0xE1, 0x27, 0xB2, 0xE9, 0x87}, + {0x70, 0x28, 0xAE, 0x8F, 0xD1, 0xF5, 0x74, 0x1A}, + {0xAA, 0x37, 0x80, 0xBB, 0xF3, 0x22, 0x1D, 0xDE}, + {0xA6, 0xC4, 0xD2, 0x5E, 0x28, 0x93, 0xAC, 0xB3}, + {0x22, 0x07, 0x81, 0x5A, 0xE4, 0xB7, 0x1A, 0xAD}, + {0xDC, 0xCE, 0x05, 0xE7, 0x07, 0xBD, 0xF5, 0x84}, + {0x26, 0x1D, 0x39, 0x2C, 0xB3, 0xBA, 0xA5, 0x85}, + {0xB4, 0xF7, 0x0F, 0x72, 0xFB, 0x04, 0xF0, 0xDC}, + {0x95, 0xBA, 0xA9, 0x4E, 0x87, 0x36, 0xF2, 0x89}, + {0xD4, 0x07, 0x3A, 0xF1, 0x5A, 0x17, 0x82, 0x0E}, + {0xEF, 0x6F, 0xAF, 0xA7, 0x66, 0x1A, 0x7E, 0x89}, + {0xC1, 0x97, 0xF5, 0x58, 0x74, 0x8A, 0x20, 0xE7}, + {0x43, 0x34, 0xCF, 0xDA, 0x22, 0xC4, 0x86, 0xC8}, + {0x08, 0xD7, 0xB4, 0xFB, 0x62, 0x9D, 0x08, 0x85} +}; + +static unsigned char cbc_key[8] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +}; +static unsigned char cbc2_key[8] = { + 0xf1, 0xe0, 0xd3, 0xc2, 0xb5, 0xa4, 0x97, 0x86, +}; +static unsigned char cbc3_key[8] = { + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, +}; +static unsigned char cbc_iv[8] = { + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, +}; +/* + * Changed the following text constant to binary so it will work on ebcdic + * machines :-) + */ +/* static char cbc_data[40]="7654321 Now is the time for \0001"; */ +static unsigned char cbc_data[40] = { + 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char cbc_ok[32] = { + 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, + 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, + 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4, +}; + +#ifdef SCREW_THE_PARITY +#error "SCREW_THE_PARITY is not ment to be defined." +#error "Original vectors are preserved for reference only." +static unsigned char cbc2_key[8] = { + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, +}; +static unsigned char xcbc_ok[32] = { + 0x86, 0x74, 0x81, 0x0D, 0x61, 0xA4, 0xA5, 0x48, + 0xB9, 0x93, 0x03, 0xE1, 0xB8, 0xBB, 0xBD, 0xBD, + 0x64, 0x30, 0x0B, 0xB9, 0x06, 0x65, 0x81, 0x76, + 0x04, 0x1D, 0x77, 0x62, 0x17, 0xCA, 0x2B, 0xD2, +}; +#else +static unsigned char xcbc_ok[32] = { + 0x84, 0x6B, 0x29, 0x14, 0x85, 0x1E, 0x9A, 0x29, + 0x54, 0x73, 0x2F, 0x8A, 0xA0, 0xA6, 0x11, 0xC1, + 0x15, 0xCD, 0xC2, 0xD7, 0x95, 0x1B, 0x10, 0x53, + 0xA6, 0x3C, 0x5E, 0x03, 0xB2, 0x1A, 0xA3, 0xC4, +}; +#endif + +static unsigned char cbc3_ok[32] = { + 0x3F, 0xE3, 0x01, 0xC9, 0x62, 0xAC, 0x01, 0xD0, + 0x22, 0x13, 0x76, 0x3C, 0x1C, 0xBD, 0x4C, 0xDC, + 0x79, 0x96, 0x57, 0xC0, 0x64, 0xEC, 0xF5, 0xD4, + 0x1C, 0x67, 0x38, 0x12, 0xCF, 0xDE, 0x96, 0x75 +}; + +static unsigned char pcbc_ok[32] = { + 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0x6d, 0xec, 0xb4, 0x70, 0xa0, 0xe5, 0x6b, 0x15, + 0xae, 0xa6, 0xbf, 0x61, 0xed, 0x7d, 0x9c, 0x9f, + 0xf7, 0x17, 0x46, 0x3b, 0x8a, 0xb3, 0xcc, 0x88 +}; + +static unsigned char cfb_key[8] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +}; +static unsigned char cfb_iv[8] = { + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, +}; +static unsigned char cfb_buf1[40], cfb_buf2[40], cfb_tmp[8]; +static unsigned char plain[24] = +{ + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, +}; +static unsigned char cfb_cipher8[24] = { + 0xf3, 0x1f, 0xda, 0x07, 0x01, 0x14, + 0x62, 0xee, 0x18, 0x7f, 0x43, 0xd8, + 0x0a, 0x7c, 0xd9, 0xb5, 0xb0, 0xd2, + 0x90, 0xda, 0x6e, 0x5b, 0x9a, 0x87, +}; +static unsigned char cfb_cipher16[24] = { + 0xF3, 0x09, 0x87, 0x87, 0x7F, 0x57, + 0xF7, 0x3C, 0x36, 0xB6, 0xDB, 0x70, + 0xD8, 0xD5, 0x34, 0x19, 0xD3, 0x86, + 0xB2, 0x23, 0xB7, 0xB2, 0xAD, 0x1B, +}; +static unsigned char cfb_cipher32[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xA4, 0xDF, + 0xA4, 0x9F, 0x33, 0xDC, 0x7B, 0xAD, + 0x4C, 0xC8, 0x9F, 0x64, 0xE4, 0x53, + 0xE5, 0xEC, 0x67, 0x20, 0xDA, 0xB6, +}; +static unsigned char cfb_cipher48[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, + 0x30, 0xB5, 0x15, 0xEC, 0xBB, 0x85, + 0x97, 0x5A, 0x13, 0x8C, 0x68, 0x60, + 0xE2, 0x38, 0x34, 0x3C, 0xDC, 0x1F, +}; +static unsigned char cfb_cipher64[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, + 0x6E, 0x51, 0xA6, 0x9E, 0x83, 0x9B, + 0x1A, 0x92, 0xF7, 0x84, 0x03, 0x46, + 0x71, 0x33, 0x89, 0x8E, 0xA6, 0x22, +}; + +static unsigned char ofb_key[8] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +}; +static unsigned char ofb_iv[8] = { + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, +}; +static unsigned char ofb_buf1[24], ofb_buf2[24], ofb_tmp[8]; +static unsigned char ofb_cipher[24] = +{ + 0xf3, 0x09, 0x62, 0x49, 0xc7, 0xf4, 0x6e, 0x51, + 0x35, 0xf2, 0x4a, 0x24, 0x2e, 0xeb, 0x3d, 0x3f, + 0x3d, 0x6d, 0x5b, 0xe3, 0x25, 0x5a, 0xf8, 0xc3 +}; + +static DES_LONG cbc_cksum_ret = 0xB462FEF7L; +static unsigned char cbc_cksum_data[8] = { + 0x1D, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4, +}; + +static char * +pt(unsigned char *p) +{ + static char bufs[10][20]; + static int bnum = 0; + char *ret; + int i; + static const char *f = "0123456789ABCDEF"; + + ret = &(bufs[bnum++][0]); + bnum %= 10; + for (i = 0; i < 8; i++) { + ret[i * 2] = f[(p[i] >> 4) & 0xf]; + ret[i * 2 + 1] = f[p[i] & 0xf]; + } + ret[16] = '\0'; + return (ret); +} + +static void +fail_cfb_buf(const char *msg, unsigned char *ptr) +{ + char buf[1024]; + int i; + + *buf = '\0'; + for (i = 0; i < 24; i += 8) { + char buf2[128]; + snprintf(buf2, sizeof(buf2), "%s /", pt(&(cfb_buf1[i]))); + strlcat(buf, buf2, sizeof(buf)); + } + + atf_tc_fail_nonfatal("%s: %s", msg, buf); +} + +#if !defined(LIBDES_LIT) +static void +cfb_test(int bits, unsigned char *cfb_cipher) +{ + des_key_schedule ks; + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + des_cfb_encrypt(plain, cfb_buf1, bits, sizeof(plain), ks, &cfb_tmp, + DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt encrypt error", cfb_buf1); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + des_cfb_encrypt(cfb_buf1, cfb_buf2, bits, sizeof(plain), ks, &cfb_tmp, + DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt decrypt error", cfb_buf2); +} +#endif /* !defined(LIBDES_LIT) */ + +#if !defined(LIBDES_LIT) +static void +cfb64_test(unsigned char *cfb_cipher) +{ + int n; + des_key_schedule ks; + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_cfb64_encrypt(plain, cfb_buf1, 12, ks, &cfb_tmp, &n, DES_ENCRYPT); + des_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), sizeof(plain) - 12, ks, + &cfb_tmp, &n, DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt encrypt error", cfb_buf1); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_cfb64_encrypt(cfb_buf1, cfb_buf2, 17, ks, &cfb_tmp, &n, DES_DECRYPT); + des_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + sizeof(plain) - 17, ks, &cfb_tmp, &n, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt decrypt error", cfb_buf2); +} +#endif /* !defined(LIBDES_LIT) */ + +#if !defined(LIBDES_LIT) +static void +ede_cfb64_test(unsigned char *cfb_cipher) +{ + int n; + des_key_schedule ks; + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_ede3_cfb64_encrypt(plain, cfb_buf1, 12, ks, ks, ks, &cfb_tmp, &n, + DES_ENCRYPT); + des_ede3_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), + sizeof(plain) - 12, ks, ks, ks, + &cfb_tmp, &n, DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) + fail_cfb_buf("ede_cfb_encrypt encrypt error", cfb_buf1); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_ede3_cfb64_encrypt(cfb_buf1, cfb_buf2, (long) 17, ks, ks, ks, + &cfb_tmp, &n, DES_DECRYPT); + des_ede3_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + sizeof(plain) - 17, ks, ks, ks, + &cfb_tmp, &n, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + fail_cfb_buf("ede_cfb_encrypt decrypt error", cfb_buf2); +} +#endif /* !defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cbcm); +#if defined(NO_DESCBCM) +ATF_TC_BODY(cbcm, tc) +{ + atf_tc_skip("Test program built with NO_DESCBCM"); +} +#else /* defined(NO_DESCBM) */ +ATF_TC_BODY(cbcm, tc) +{ + int i, j; + des_cblock iv3, iv2; + unsigned char cbc_in[40], cbc_out[40]; + des_key_schedule ks, ks2, ks3; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + if ((j = des_set_key_checked(&cbc2_key, ks2)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + if ((j = des_set_key_checked(&cbc3_key, ks3)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + i = strlen((char *) cbc_data) + 1; + /* i=((i+7)/8)*8; */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + memset(iv2, '\0', sizeof iv2); + + des_ede3_cbcm_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3, &iv2, + DES_ENCRYPT); + des_ede3_cbcm_encrypt(&cbc_data[16], &cbc_out[16], i - 16, ks, ks2, ks3, + &iv3, &iv2, DES_ENCRYPT); + /* + * if (memcmp(cbc_out,cbc3_ok, (unsigned int)(strlen((char + * *)cbc_data)+1+7)/8*8) != 0) { printf("des_ede3_cbc_encrypt encrypt + * error\n"); err=1; } + */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + memset(iv2, '\0', sizeof iv2); + des_ede3_cbcm_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3, &iv2, + DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) { + char buf[1024]; + int n; + + *buf = '\0'; + for (n = 0; n < i; ++n) { + char buf2[16]; + snprintf(buf2, sizeof(buf2), " %02x", cbc_data[n]); + strlcat(buf, buf2, sizeof(buf)); + } + strlcat(buf, ", ", sizeof(buf)); + for (n = 0; n < i; ++n) { + char buf2[16]; + snprintf(buf2, sizeof(buf2), " %02x", cbc_in[n]); + strlcat(buf, buf2, sizeof(buf)); + } + + atf_tc_fail_nonfatal("des_ede3_cbcm_encrypt decrypt error: %s", + buf); + } +} +#endif /* defined(NO_DESCBM) */ + +ATF_TC_WITHOUT_HEAD(ecb); +ATF_TC_BODY(ecb, tc) +{ + int i; + des_cblock in, out, outin; + des_key_schedule ks; + + for (i = 0; i < NUM_TESTS; i++) { + des_set_key_unchecked(&key_data[i], ks); + memcpy(in, plain_data[i], 8); + memset(out, 0, 8); + memset(outin, 0, 8); + des_ecb_encrypt(&in, &out, ks, DES_ENCRYPT); + des_ecb_encrypt(&out, &outin, ks, DES_DECRYPT); + + if (memcmp(out, cipher_data[i], 8) != 0) { + atf_tc_fail_nonfatal("Encryption error %2d\nk=%s p=%s " + "o=%s act=%s\n", i + 1, + pt(key_data[i]), pt(in), + pt(cipher_data[i]), pt(out)); + } + if (memcmp(in, outin, 8) != 0) { + atf_tc_fail_nonfatal("Decryption error %2d\nk=%s p=%s " + "o=%s act=%s\n", i + 1, + pt(key_data[i]), pt(out), pt(in), + pt(outin)); + } + } +} + +ATF_TC_WITHOUT_HEAD(ede_ecb); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ede_ecb, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ede_ecb, tc) +{ + int i; + des_cblock in, out, outin; + des_key_schedule ks, ks2, ks3; + + for (i = 0; i < (NUM_TESTS - 1); i++) { + des_set_key_unchecked(&key_data[i], ks); + des_set_key_unchecked(&key_data[i + 1], ks2); + des_set_key_unchecked(&key_data[i + 2], ks3); + memcpy(in, plain_data[i], 8); + memset(out, 0, 8); + memset(outin, 0, 8); + des_ecb2_encrypt(&in, &out, ks, ks2, DES_ENCRYPT); + des_ecb2_encrypt(&out, &outin, ks, ks2, DES_DECRYPT); + + if (memcmp(out, cipher_ecb2[i], 8) != 0) { + atf_tc_fail_nonfatal("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(in), pt(cipher_ecb2[i]), + pt(out)); + } + if (memcmp(in, outin, 8) != 0) { + atf_tc_fail_nonfatal("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(out), pt(in), pt(outin)); + } + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cbc); +ATF_TC_BODY(cbc, tc) +{ + int j; + des_cblock iv3; + des_key_schedule ks; + unsigned char cbc_in[40], cbc_out[40]; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ncbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks, + &iv3, DES_ENCRYPT); + if (memcmp(cbc_out, cbc_ok, 32) != 0) + atf_tc_fail_nonfatal("cbc_encrypt encrypt error\n"); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ncbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks, + &iv3, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data)) != 0) + atf_tc_fail_nonfatal("cbc_encrypt decrypt error\n"); +} + +ATF_TC_WITHOUT_HEAD(desx_cbc); +#if defined(LIBDES_LIT) +ATF_TC_BODY(desx_cbc, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(desx_cbc, tc) +{ + int j; + des_cblock iv3; + des_key_schedule ks; + unsigned char cbc_in[40], cbc_out[40]; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_xcbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks, + &iv3, &cbc2_key, &cbc3_key, DES_ENCRYPT); + if (memcmp(cbc_out, xcbc_ok, 32) != 0) { + atf_tc_fail_nonfatal("des_xcbc_encrypt encrypt error\n"); + } + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_xcbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks, + &iv3, &cbc2_key, &cbc3_key, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) { + atf_tc_fail_nonfatal("des_xcbc_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ede_cbc); +ATF_TC_BODY(ede_cbc, tc) +{ + int i, j; + des_cblock iv3; + des_key_schedule ks, ks2, ks3; + unsigned char cbc_in[40], cbc_out[40]; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + if ((j = des_set_key_checked(&cbc2_key, ks2)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + if ((j = des_set_key_checked(&cbc3_key, ks3)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + i = strlen((char *) cbc_data) + 1; + /* i=((i+7)/8)*8; */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + + des_ede3_cbc_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3, + DES_ENCRYPT); + des_ede3_cbc_encrypt(&(cbc_data[16]), &(cbc_out[16]), i - 16, ks, ks2, + ks3, &iv3, DES_ENCRYPT); + if (memcmp(cbc_out, cbc3_ok, (unsigned int) + (strlen((char *) cbc_data) + 1 + 7) / 8 * 8) != 0) + atf_tc_fail_nonfatal("des_ede3_cbc_encrypt encrypt error\n"); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ede3_cbc_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3, + DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) + atf_tc_fail_nonfatal("des_ede3_cbc_encrypt decrypt error\n"); +} + +ATF_TC_WITHOUT_HEAD(pcbc); +#if defined(LIBDES_LIT) +ATF_TC_BODY(pcbc, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(pcbc, tc) +{ + int j; + unsigned char cbc_in[40], cbc_out[40]; + des_key_schedule ks; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + des_pcbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + if (memcmp(cbc_out, pcbc_ok, 32) != 0) { + atf_tc_fail_nonfatal("pcbc_encrypt encrypt error\n"); + } + des_pcbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks, &cbc_iv, + DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) { + atf_tc_fail_nonfatal("pcbc_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cfb); +#if defined(LIBDES_LIT) +ATF_TC_BODY(cfb, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(cfb, tc) +{ + size_t i; + des_key_schedule ks; + + printf("cfb8\n"); + cfb_test(8, cfb_cipher8); + printf("cfb16\n"); + cfb_test(16, cfb_cipher16); + printf("cfb32\n"); + cfb_test(32, cfb_cipher32); + printf("cfb48\n"); + cfb_test(48, cfb_cipher48); + printf("cfb64\n"); + cfb_test(64, cfb_cipher64); + + printf("cfb64()\n"); + cfb64_test(cfb_cipher64); + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + for (i = 0; i < sizeof(plain); i++) + des_cfb_encrypt(&(plain[i]), &(cfb_buf1[i]), + 8, 1, ks, &cfb_tmp, DES_ENCRYPT); + if (memcmp(cfb_cipher8, cfb_buf1, sizeof(plain)) != 0) + atf_tc_fail_nonfatal("cfb_encrypt small encrypt error\n"); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + for (i = 0; i < sizeof(plain); i++) + des_cfb_encrypt(&(cfb_buf1[i]), &(cfb_buf2[i]), + 8, 1, ks, &cfb_tmp, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + atf_tc_fail_nonfatal("cfb_encrypt small decrypt error\n"); + printf("ede_cfb64()\n"); + ede_cfb64_test(cfb_cipher64); +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ofb); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ofb, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ofb, tc) +{ + des_key_schedule ks; + + des_set_key_checked(&ofb_key, ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + des_ofb_encrypt(plain, ofb_buf1, 64, sizeof(plain) / 8, ks, &ofb_tmp); + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + atf_tc_fail_nonfatal("ofb_encrypt encrypt error: " + "%02X %02X %02X %02X %02X %02X %02X %02X, " + "%02X %02X %02X %02X %02X %02X %02X %02X", + ofb_buf1[8 + 0], ofb_buf1[8 + 1], + ofb_buf1[8 + 2], ofb_buf1[8 + 3], + ofb_buf1[8 + 4], ofb_buf1[8 + 5], + ofb_buf1[8 + 6], ofb_buf1[8 + 7], + ofb_buf1[8 + 0], ofb_cipher[8 + 1], + ofb_cipher[8 + 2], ofb_cipher[8 + 3], + ofb_buf1[8 + 4], ofb_cipher[8 + 5], + ofb_cipher[8 + 6], ofb_cipher[8 + 7]); + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + des_ofb_encrypt(ofb_buf1, ofb_buf2, 64, sizeof(ofb_buf1) / 8, ks, + &ofb_tmp); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + atf_tc_fail_nonfatal("ofb_encrypt decrypt error: " + "%02X %02X %02X %02X %02X %02X %02X %02X, " + "%02X %02X %02X %02X %02X %02X %02X %02X", + ofb_buf2[8 + 0], ofb_buf2[8 + 1], + ofb_buf2[8 + 2], ofb_buf2[8 + 3], + ofb_buf2[8 + 4], ofb_buf2[8 + 5], + ofb_buf2[8 + 6], ofb_buf2[8 + 7], + plain[8 + 0], plain[8 + 1], + plain[8 + 2], plain[8 + 3], + plain[8 + 4], plain[8 + 5], + plain[8 + 6], plain[8 + 7]); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ofb64); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ofb64, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ofb64, tc) +{ + int num; + size_t i; + des_key_schedule ks; + + des_set_key_checked(&ofb_key, ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + memset(ofb_buf1, 0, sizeof(ofb_buf1)); + memset(ofb_buf2, 0, sizeof(ofb_buf1)); + num = 0; + for (i = 0; i < sizeof(plain); i++) { + des_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, &ofb_tmp, + &num); + } + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + atf_tc_fail_nonfatal("ofb64_encrypt encrypt error\n"); + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + num = 0; + des_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks, &ofb_tmp, &num); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + atf_tc_fail_nonfatal("ofb64_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ede_ofb64); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ede_ofb64, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ede_ofb64, tc) +{ + int num; + size_t i; + des_key_schedule ks; + + des_set_key_checked(&ofb_key, ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + memset(ofb_buf1, 0, sizeof(ofb_buf1)); + memset(ofb_buf2, 0, sizeof(ofb_buf1)); + num = 0; + for (i = 0; i < sizeof(plain); i++) { + des_ede3_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, ks, ks, + &ofb_tmp, &num); + } + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + atf_tc_fail_nonfatal("ede_ofb64_encrypt encrypt error\n"); + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + num = 0; + des_ede3_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks, + ks, ks, &ofb_tmp, &num); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + atf_tc_fail_nonfatal("ede_ofb64_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cbc_cksum); +#if defined(LIBDES_LIT) +ATF_TC_BODY(cbc_cksum, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(cbc_cksum, tc) +{ + unsigned char cret[8]; + des_key_schedule ks; + DES_LONG cs; + + des_set_key_checked(&cbc_key, ks); + cs = des_cbc_cksum(cbc_data, &cret, strlen((char *) cbc_data), ks, &cbc_iv); + if (cs != cbc_cksum_ret) { + atf_tc_fail_nonfatal("bad return value (%08lX), should be %08lX\n", + (unsigned long) cs, (unsigned long) cbc_cksum_ret); + } + if (memcmp(cret, cbc_cksum_data, 8) != 0) { + atf_tc_fail_nonfatal("bad cbc_cksum block returned\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(quad_cksum); +#if defined(LIBDES_LIT) +ATF_TC_BODY(quad_cksum, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(quad_cksum, tc) +{ + DES_LONG cs, lqret[4]; + + cs = quad_cksum(cbc_data, (des_cblock *) lqret, + (long) strlen((char *) cbc_data), 2, (des_cblock *) cbc_iv); + if (cs != 0x70d7a63aL) { + atf_tc_fail_nonfatal("quad_cksum error, ret %08lx should be 70d7a63a\n", + (unsigned long) cs); + } + if (lqret[0] != 0x327eba8dL) { + atf_tc_fail_nonfatal("quad_cksum error, out[0] %08lx is not %08lx\n", + (unsigned long) lqret[0], 0x327eba8dUL); + } + if (lqret[1] != 0x201a49ccL) { + atf_tc_fail_nonfatal("quad_cksum error, out[1] %08lx is not %08lx\n", + (unsigned long) lqret[1], 0x201a49ccUL); + } + if (lqret[2] != 0x70d7a63aL) { + atf_tc_fail_nonfatal("quad_cksum error, out[2] %08lx is not %08lx\n", + (unsigned long) lqret[2], 0x70d7a63aUL); + } + if (lqret[3] != 0x501c2c26L) { + atf_tc_fail_nonfatal("quad_cksum error, out[3] %08lx is not %08lx\n", + (unsigned long) lqret[3], 0x501c2c26UL); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(align); +ATF_TC_BODY(align, tc) +{ + int i; + unsigned char cbc_in[40], cbc_out[40]; + des_key_schedule ks; + + printf("input word alignment test"); + for (i = 0; i < 4; i++) { + printf(" %d", i); + des_ncbc_encrypt(&(cbc_out[i]), cbc_in, + strlen((char *) cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + } + + printf("\noutput word alignment test"); + for (i = 0; i < 4; i++) { + printf(" %d", i); + des_ncbc_encrypt(cbc_out, &(cbc_in[i]), + strlen((char *) cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + } +} + +ATF_TC_WITHOUT_HEAD(fast_crypt); +ATF_TC_BODY(fast_crypt, tc) +{ + char *str; + + str = crypt("testing", "ef"); + if (strcmp("efGnQx2725bI2", str) != 0) + atf_tc_fail_nonfatal("fast crypt error, %s should be efGnQx2725bI2\n", str); + str = crypt("bca76;23", "yA"); + if (strcmp("yA1Rp/1hZXIJk", str) != 0) + atf_tc_fail_nonfatal("fast crypt error, %s should be yA1Rp/1hZXIJk\n", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cbcm); + ATF_TP_ADD_TC(tp, ecb); + ATF_TP_ADD_TC(tp, ede_ecb); + ATF_TP_ADD_TC(tp, cbc); + ATF_TP_ADD_TC(tp, desx_cbc); + ATF_TP_ADD_TC(tp, ede_cbc); + ATF_TP_ADD_TC(tp, pcbc); + ATF_TP_ADD_TC(tp, cfb); + ATF_TP_ADD_TC(tp, ofb); + ATF_TP_ADD_TC(tp, ofb64); + ATF_TP_ADD_TC(tp, ede_ofb64); + ATF_TP_ADD_TC(tp, cbc_cksum); + ATF_TP_ADD_TC(tp, quad_cksum); + ATF_TP_ADD_TC(tp, align); + ATF_TP_ADD_TC(tp, fast_crypt); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libevent/t_event.sh b/contrib/netbsd-tests/lib/libevent/t_event.sh new file mode 100755 index 0000000..1e4c9bc --- /dev/null +++ b/contrib/netbsd-tests/lib/libevent/t_event.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_event.sh,v 1.3 2010/11/29 18:21:15 pgoyette Exp $ +# +# Copyright (c) 2009 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# +# This is not great but rather than reimplementing the libevent +# provided regression tests, we use an ATF wrapper around the test +# program which carries out all the tests and prints an extensive +# report. +# + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Test libevent with kqueue backend" +} +kqueue_body() { + EVENT_NOPOLL=1 EVENT_NOSELECT=1 \ + $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report" +} + +atf_test_case poll +poll_head() { + atf_set "descr" "Test libevent with poll backend" +} +poll_body() { + EVENT_NOKQUEUE=1 EVENT_NOSELECT=1 \ + $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report" +} + +atf_test_case select +select_head() { + atf_set "descr" "Test libevent with select backend" +} +select_body() { + EVENT_NOKQUEUE=1 EVENT_NOPOLL=1 \ + $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report" +} + +atf_init_test_cases() +{ + atf_add_test_case kqueue + atf_add_test_case poll + atf_add_test_case select +} diff --git a/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c b/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c new file mode 100644 index 0000000..b5b5739 --- /dev/null +++ b/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c @@ -0,0 +1,168 @@ +/* $NetBSD: t_backtrace.c,v 1.15 2014/05/01 03:46:11 joerg Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_backtrace.c,v 1.15 2014/05/01 03:46:11 joerg Exp $"); + +#include <atf-c.h> +#include <atf-c/config.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <execinfo.h> +#include <unistd.h> + +#ifndef __arraycount +#define __arraycount(a) (sizeof(a) / sizeof(a[0])) +#endif + +void myfunc3(size_t ncalls); +void myfunc2(size_t ncalls); +void myfunc1(size_t origcalls, volatile size_t ncalls); +void myfunc(size_t ncalls); + +volatile int prevent_inline; + +void +myfunc3(size_t ncalls) +{ + static const struct { + const char *name; + bool is_optional; + } frames[] = { + { "myfunc", false }, + { "atfu_backtrace_fmt_basic_body", false }, + { "atf_tc_run", false }, + { "atf_tp_run", true }, + { "run_tc", true }, + { "controlled_main", true }, + { "atf_tp_main", false }, + { "main", true }, + { "___start", true }, + }; + size_t j, nptrs, min_frames, max_frames; + void *buffer[ncalls + 10]; + char **strings; + + min_frames = 0; + max_frames = 0; + for (j = 0; j < __arraycount(frames); ++j) { + if (!frames[j].is_optional) + ++min_frames; + ++max_frames; + } + nptrs = backtrace(buffer, __arraycount(buffer)); + ATF_REQUIRE(nptrs != (size_t)-1); + strings = backtrace_symbols_fmt(buffer, nptrs, "%n"); + + ATF_CHECK(strings != NULL); + + printf("got nptrs=%zu ncalls=%zu (min_frames: %zu, max_frames: %zu)\n", + nptrs, ncalls, min_frames, max_frames); + printf("backtrace is:\n"); + for (j = 0; j < nptrs; j++) { + printf("#%zu: %s\n", j, strings[j]); + } + + ATF_REQUIRE(nptrs >= ncalls + 2 + min_frames); + ATF_REQUIRE(nptrs <= ncalls + 2 + max_frames); + ATF_CHECK_STREQ(strings[0], "myfunc3"); + ATF_CHECK_STREQ(strings[1], "myfunc2"); + + for (j = 2; j < ncalls + 2; j++) + ATF_CHECK_STREQ(strings[j], "myfunc1"); + + for (size_t i = 0; j < nptrs; i++, j++) { + if (frames[i].is_optional && + strcmp(strings[j], frames[i].name)) { + --i; + continue; + } + ATF_CHECK_STREQ(strings[j], frames[i].name); + } + + free(strings); + + if (prevent_inline) + vfork(); +} + +void +myfunc2(size_t ncalls) +{ + myfunc3(ncalls); + + if (prevent_inline) + vfork(); +} + +void +myfunc1(size_t origcalls, volatile size_t ncalls) +{ + if (ncalls > 1) + myfunc1(origcalls, ncalls - 1); + else + myfunc2(origcalls); + + if (prevent_inline) + vfork(); +} + +void +myfunc(size_t ncalls) +{ + myfunc1(ncalls, ncalls); + + if (prevent_inline) + vfork(); +} + +ATF_TC(backtrace_fmt_basic); +ATF_TC_HEAD(backtrace_fmt_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test backtrace_fmt(3)"); + atf_tc_set_md_var(tc, "require.files", "/proc/self"); +} + +ATF_TC_BODY(backtrace_fmt_basic, tc) +{ + myfunc(12); + + if (prevent_inline) + vfork(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, backtrace_fmt_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_acos.c b/contrib/netbsd-tests/lib/libm/t_acos.c new file mode 100644 index 0000000..f051fb6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_acos.c @@ -0,0 +1,105 @@ +/* $NetBSD: t_acos.c,v 1.10 2014/03/05 20:14:46 dsl Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> +#include "t_libm.h" + +/* + * acos(3) and acosf(3) + */ + +ATF_LIBM_TEST(acos_is_nan, "Test acos/acosf(x) == NaN, x = NaN, +/-Inf, ![-1..1]") +{ + static const double x[] = { + -1.000000001, 1.000000001, + -1.0000001, 1.0000001, + -1.1, 1.1, +#ifndef __vax__ + T_LIBM_NAN, + T_LIBM_MINUS_INF, T_LIBM_PLUS_INF, +#endif + }; + unsigned int i; + + for (i = 0; i < __arraycount(x); i++) { + T_LIBM_CHECK_NAN(i, acos, x[i]); + if (i < 2) + /* Values are too small for float */ + continue; + T_LIBM_CHECK_NAN(i, acosf, x[i]); + } +} + +ATF_LIBM_TEST(acos_inrange, "Test acos/acosf(x) for some valid values") +{ + static const struct { + double x; + double y; + } values[] = { + { -1, M_PI, }, + { -0.99, 3.000053180265366, }, + { -0.5, 2.094395102393195, }, + { -0.1, 1.670963747956456, }, + { 0, M_PI / 2, }, + { 0.1, 1.470628905633337, }, + { 0.5, 1.047197551196598, }, + { 0.99, 0.141539473324427, }, + }; + unsigned int i; + + /* + * Note that acos(x) might be calculated as atan2(sqrt(1-x*x),x). + * This means that acos(-1) is atan2(+0,-1), if the sign is wrong + * the value will be -M_PI (atan2(-0,-1)) not M_PI. + */ + + for (i = 0; i < __arraycount(values); i++) { + T_LIBM_CHECK(i, acos, values[i].x, values[i].y, 1.0e-15); + T_LIBM_CHECK(i, acosf, values[i].x, values[i].y, 1.0e-5); + } +} + +ATF_LIBM_TEST(acos_is_plus_zero, "Test acosf(1.0) == +0.0") +{ + T_LIBM_CHECK_PLUS_ZERO(0, acos, 1.0); + T_LIBM_CHECK_PLUS_ZERO(0, acosf, 1.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, acos_inrange); + ATF_TP_ADD_TC(tp, acos_is_nan); + ATF_TP_ADD_TC(tp, acos_is_plus_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_asin.c b/contrib/netbsd-tests/lib/libm/t_asin.c new file mode 100644 index 0000000..06de852 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_asin.c @@ -0,0 +1,296 @@ +/* $NetBSD: t_asin.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> + +static const struct { + double x; + double y; +} values[] = { + { -1.0, -M_PI / 2, }, + { -0.9, -1.119769514998634, }, + { -0.5, -M_PI / 6, }, + { -0.1, -0.1001674211615598, }, + { 0.1, 0.1001674211615598, }, + { 0.5, M_PI / 6, }, + { 0.9, 1.119769514998634, }, + { 1.0, M_PI / 2, }, +}; + +/* + * asin(3) + */ +ATF_TC(asin_nan); +ATF_TC_HEAD(asin_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(NaN) == NaN"); +} + +ATF_TC_BODY(asin_nan, tc) +{ + const double x = 0.0L / 0.0L; + + if (isnan(asin(x)) == 0) + atf_tc_fail_nonfatal("asin(NaN) != NaN"); +} + +ATF_TC(asin_inf_neg); +ATF_TC_HEAD(asin_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(-Inf) == NaN"); +} + +ATF_TC_BODY(asin_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (isnan(asin(x)) == 0) + atf_tc_fail_nonfatal("asin(-Inf) != NaN"); +} + +ATF_TC(asin_inf_pos); +ATF_TC_HEAD(asin_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(+Inf) == NaN"); +} + +ATF_TC_BODY(asin_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + if (isnan(asin(x)) == 0) + atf_tc_fail_nonfatal("asin(+Inf) != NaN"); +} + +ATF_TC(asin_range); +ATF_TC_HEAD(asin_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(x) == NaN, x < -1, x > 1"); +} + +ATF_TC_BODY(asin_range, tc) +{ + const double x[] = { -1.1, -1.000000001, 1.1, 1.000000001 }; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + if (isnan(asin(x[i])) == 0) + atf_tc_fail_nonfatal("asin(%f) != NaN", x[i]); + } +} + +ATF_TC(asin_inrange); +ATF_TC_HEAD(asin_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(x) for some values"); +} + +ATF_TC_BODY(asin_inrange, tc) +{ + const double eps = 1.0e-15; + double y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + y = asin(values[i].x); + if (fabs(y - values[i].y) > eps) + atf_tc_fail_nonfatal("asin(%g) != %g", + values[i].x, values[i].y); + } +} + +ATF_TC(asin_zero_neg); +ATF_TC_HEAD(asin_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(-0.0) == -0.0"); +} + +ATF_TC_BODY(asin_zero_neg, tc) +{ + const double x = -0.0L; + double y = asin(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("asin(-0.0) != -0.0"); +} + +ATF_TC(asin_zero_pos); +ATF_TC_HEAD(asin_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(+0.0) == +0.0"); +} + +ATF_TC_BODY(asin_zero_pos, tc) +{ + const double x = 0.0L; + double y = asin(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("asin(+0.0) != +0.0"); +} + +/* + * asinf(3) + */ +ATF_TC(asinf_nan); +ATF_TC_HEAD(asinf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(NaN) == NaN"); +} + +ATF_TC_BODY(asinf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + if (isnan(asinf(x)) == 0) + atf_tc_fail_nonfatal("asinf(NaN) != NaN"); +} + +ATF_TC(asinf_inf_neg); +ATF_TC_HEAD(asinf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(-Inf) == NaN"); +} + +ATF_TC_BODY(asinf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(asinf(x)) == 0) + atf_tc_fail_nonfatal("asinf(-Inf) != NaN"); +} + +ATF_TC(asinf_inf_pos); +ATF_TC_HEAD(asinf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(+Inf) == NaN"); +} + +ATF_TC_BODY(asinf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(asinf(x)) == 0) + atf_tc_fail_nonfatal("asinf(+Inf) != NaN"); +} + +ATF_TC(asinf_range); +ATF_TC_HEAD(asinf_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(x) == NaN, x < -1, x > 1"); +} + +ATF_TC_BODY(asinf_range, tc) +{ + const float x[] = { -1.1, -1.0000001, 1.1, 1.0000001 }; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + if (isnan(asinf(x[i])) == 0) + atf_tc_fail_nonfatal("asinf(%f) != NaN", x[i]); + } +} + +ATF_TC(asinf_inrange); +ATF_TC_HEAD(asinf_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(x) for some values"); +} + +ATF_TC_BODY(asinf_inrange, tc) +{ + const float eps = 1.0e-6; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + if (fabs(asinf(x) - y) > eps) + atf_tc_fail_nonfatal("asinf(%g) != %g", x, y); + } +} + +ATF_TC(asinf_zero_neg); +ATF_TC_HEAD(asinf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(-0.0) == -0.0"); +} + +ATF_TC_BODY(asinf_zero_neg, tc) +{ + const float x = -0.0L; + float y = asinf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("asinf(-0.0) != -0.0"); +} + +ATF_TC(asinf_zero_pos); +ATF_TC_HEAD(asinf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(+0.0) == +0.0"); +} + +ATF_TC_BODY(asinf_zero_pos, tc) +{ + const float x = 0.0L; + float y = asinf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("asinf(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, asin_nan); + ATF_TP_ADD_TC(tp, asin_inf_neg); + ATF_TP_ADD_TC(tp, asin_inf_pos); + ATF_TP_ADD_TC(tp, asin_range); + ATF_TP_ADD_TC(tp, asin_inrange); + ATF_TP_ADD_TC(tp, asin_zero_neg); + ATF_TP_ADD_TC(tp, asin_zero_pos); + + ATF_TP_ADD_TC(tp, asinf_nan); + ATF_TP_ADD_TC(tp, asinf_inf_neg); + ATF_TP_ADD_TC(tp, asinf_inf_pos); + ATF_TP_ADD_TC(tp, asinf_range); + ATF_TP_ADD_TC(tp, asinf_inrange); + ATF_TP_ADD_TC(tp, asinf_zero_neg); + ATF_TP_ADD_TC(tp, asinf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_atan.c b/contrib/netbsd-tests/lib/libm/t_atan.c new file mode 100644 index 0000000..c3aa15f --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_atan.c @@ -0,0 +1,101 @@ +/* $NetBSD: t_atan.c,v 1.15 2014/03/17 11:08:11 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> +#include "t_libm.h" + +static const struct { + double x; + double y; +} values[] = { +#ifndef __vax__ + /* vax has no +/- INF */ + { T_LIBM_MINUS_INF, -M_PI / 2 }, + { T_LIBM_PLUS_INF, M_PI / 2 }, +#endif + { -100, -1.560796660108231, }, + { -10, -1.471127674303735, }, + { -1, -M_PI / 4, }, + { -0.1, -0.09966865249116204, }, + { 0.1, 0.09966865249116204, }, + { 1, M_PI / 4, }, + { 10, 1.471127674303735, }, + { 100, 1.560796660108231, }, +}; + +/* + * atan(3) + */ +ATF_LIBM_TEST(atan_nan, "Test atan/atanf(NaN) == NaN") +{ +#ifdef T_LIBM_NAN + T_LIBM_CHECK_NAN(0, atan, T_LIBM_NAN); + T_LIBM_CHECK_NAN(0, atanf, T_LIBM_NAN); +#else + atf_tc_skip("no NaN on this machine"); +#endif +} + +ATF_LIBM_TEST(atan_inrange, "Test atan/atanf(x) for some values") +{ + unsigned int i; + + for (i = 0; i < __arraycount(values); i++) { + T_LIBM_CHECK(i, atan, values[i].x, values[i].y, 1.0e-15); + T_LIBM_CHECK(i, atanf, values[i].x, values[i].y, 1.0e-7); + } +} + +ATF_LIBM_TEST(atan_zero_neg, "Test atan/atanf(-0.0) == -0.0") +{ + + T_LIBM_CHECK_MINUS_ZERO(0, atan, -0.0); + T_LIBM_CHECK_MINUS_ZERO(0, atanf, -0.0); +} + +ATF_LIBM_TEST(atan_zero_pos, "Test atan/atanf(+0.0) == +0.0") +{ + + T_LIBM_CHECK_PLUS_ZERO(0, atan, +0.0); + T_LIBM_CHECK_PLUS_ZERO(0, atanf, +0.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, atan_nan); + ATF_TP_ADD_TC(tp, atan_inrange); + ATF_TP_ADD_TC(tp, atan_zero_neg); + ATF_TP_ADD_TC(tp, atan_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_cbrt.c b/contrib/netbsd-tests/lib/libm/t_cbrt.c new file mode 100644 index 0000000..a7de9f6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_cbrt.c @@ -0,0 +1,366 @@ +/* $NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <math.h> +#include <stdio.h> + +/* + * cbrt(3) + */ +ATF_TC(cbrt_nan); +ATF_TC_HEAD(cbrt_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(NaN) == NaN"); +} + +ATF_TC_BODY(cbrt_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cbrt(x)) != 0); +} + +ATF_TC(cbrt_pow); +ATF_TC_HEAD(cbrt_pow, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(3) vs. pow(3)"); +} + +ATF_TC_BODY(cbrt_pow, tc) +{ + const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; + const double eps = 1.0e-14; + double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = cbrt(x[i]); + z = pow(x[i], 1.0 / 3.0); + + if (fabs(y - z) > eps) + atf_tc_fail_nonfatal("cbrt(%0.03f) != " + "pow(%0.03f, 1/3)\n", x[i], x[i]); + } +} + +ATF_TC(cbrt_inf_neg); +ATF_TC_HEAD(cbrt_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(-Inf) == -Inf"); +} + +ATF_TC_BODY(cbrt_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = cbrt(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(cbrt_inf_pos); +ATF_TC_HEAD(cbrt_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(+Inf) == +Inf"); +} + +ATF_TC_BODY(cbrt_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = cbrt(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cbrt_zero_neg); +ATF_TC_HEAD(cbrt_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(-0.0) == -0.0"); +} + +ATF_TC_BODY(cbrt_zero_neg, tc) +{ + const double x = -0.0L; + double y = cbrt(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("cbrt(-0.0) != -0.0"); +} + +ATF_TC(cbrt_zero_pos); +ATF_TC_HEAD(cbrt_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(+0.0) == +0.0"); +} + +ATF_TC_BODY(cbrt_zero_pos, tc) +{ + const double x = 0.0L; + double y = cbrt(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("cbrt(+0.0) != +0.0"); +} + +/* + * cbrtf(3) + */ +ATF_TC(cbrtf_nan); +ATF_TC_HEAD(cbrtf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(NaN) == NaN"); +} + +ATF_TC_BODY(cbrtf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cbrtf(x)) != 0); +} + +ATF_TC(cbrtf_powf); +ATF_TC_HEAD(cbrtf_powf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(3) vs. powf(3)"); +} + +ATF_TC_BODY(cbrtf_powf, tc) +{ + const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; + const float eps = 1.0e-5; + float y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = cbrtf(x[i]); + z = powf(x[i], 1.0 / 3.0); + + if (fabsf(y - z) > eps) + atf_tc_fail_nonfatal("cbrtf(%0.03f) != " + "powf(%0.03f, 1/3)\n", x[i], x[i]); + } +} + +ATF_TC(cbrtf_inf_neg); +ATF_TC_HEAD(cbrtf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(-Inf) == -Inf"); +} + +ATF_TC_BODY(cbrtf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = cbrtf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(cbrtf_inf_pos); +ATF_TC_HEAD(cbrtf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(+Inf) == +Inf"); +} + +ATF_TC_BODY(cbrtf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = cbrtf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cbrtf_zero_neg); +ATF_TC_HEAD(cbrtf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(-0.0) == -0.0"); +} + +ATF_TC_BODY(cbrtf_zero_neg, tc) +{ + const float x = -0.0L; + float y = cbrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("cbrtf(-0.0) != -0.0"); +} + +ATF_TC(cbrtf_zero_pos); +ATF_TC_HEAD(cbrtf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(+0.0) == +0.0"); +} + +ATF_TC_BODY(cbrtf_zero_pos, tc) +{ + const float x = 0.0L; + float y = cbrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("cbrtf(+0.0) != +0.0"); +} + +/* + * cbrtl(3) + */ +ATF_TC(cbrtl_nan); +ATF_TC_HEAD(cbrtl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(NaN) == NaN"); +} + +ATF_TC_BODY(cbrtl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cbrtl(x)) != 0); +} + +ATF_TC(cbrtl_powl); +ATF_TC_HEAD(cbrtl_powl, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(3) vs. powl(3)"); +} + +ATF_TC_BODY(cbrtl_powl, tc) +{ + const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; + const long double eps = 1.0e-15; + long double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = cbrtl(x[i]); + z = powl(x[i], 1.0 / 3.0); + + if (fabsl(y - z) > eps * fabsl(1 + x[i])) + atf_tc_fail_nonfatal("cbrtl(%0.03Lf) != " + "powl(%0.03Lf, 1/3)\n", x[i], x[i]); + } +} + +ATF_TC(cbrtl_inf_neg); +ATF_TC_HEAD(cbrtl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(-Inf) == -Inf"); +} + +ATF_TC_BODY(cbrtl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = cbrtl(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(cbrtl_inf_pos); +ATF_TC_HEAD(cbrtl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(+Inf) == +Inf"); +} + +ATF_TC_BODY(cbrtl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = cbrtl(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cbrtl_zero_neg); +ATF_TC_HEAD(cbrtl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(-0.0) == -0.0"); +} + +ATF_TC_BODY(cbrtl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = cbrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("cbrtl(-0.0) != -0.0"); +} + +ATF_TC(cbrtl_zero_pos); +ATF_TC_HEAD(cbrtl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(+0.0) == +0.0"); +} + +ATF_TC_BODY(cbrtl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = cbrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("cbrtl(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cbrt_nan); + ATF_TP_ADD_TC(tp, cbrt_pow); + ATF_TP_ADD_TC(tp, cbrt_inf_neg); + ATF_TP_ADD_TC(tp, cbrt_inf_pos); + ATF_TP_ADD_TC(tp, cbrt_zero_neg); + ATF_TP_ADD_TC(tp, cbrt_zero_pos); + + ATF_TP_ADD_TC(tp, cbrtf_nan); + ATF_TP_ADD_TC(tp, cbrtf_powf); + ATF_TP_ADD_TC(tp, cbrtf_inf_neg); + ATF_TP_ADD_TC(tp, cbrtf_inf_pos); + ATF_TP_ADD_TC(tp, cbrtf_zero_neg); + ATF_TP_ADD_TC(tp, cbrtf_zero_pos); + + ATF_TP_ADD_TC(tp, cbrtl_nan); + ATF_TP_ADD_TC(tp, cbrtl_powl); + ATF_TP_ADD_TC(tp, cbrtl_inf_neg); + ATF_TP_ADD_TC(tp, cbrtl_inf_pos); + ATF_TP_ADD_TC(tp, cbrtl_zero_neg); + ATF_TP_ADD_TC(tp, cbrtl_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_ceil.c b/contrib/netbsd-tests/lib/libm/t_ceil.c new file mode 100644 index 0000000..b57f30e --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_ceil.c @@ -0,0 +1,931 @@ +/* $NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <math.h> +#include <limits.h> +#include <stdio.h> + +#ifdef __vax__ +#define SMALL_NUM 1.0e-38 +#else +#define SMALL_NUM 1.0e-40 +#endif + +/* + * ceil(3) + */ +ATF_TC(ceil_basic); +ATF_TC_HEAD(ceil_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ceil(3)"); +} + +ATF_TC_BODY(ceil_basic, tc) +{ + const double x = 0.999999999999999; + const double y = 0.000000000000001; + + ATF_CHECK(fabs(ceil(x) - 1) < SMALL_NUM); + ATF_CHECK(fabs(ceil(y) - 1) < SMALL_NUM); +} + +ATF_TC(ceil_nan); +ATF_TC_HEAD(ceil_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(NaN) == NaN"); +} + +ATF_TC_BODY(ceil_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(ceil(x)) != 0); +} + +ATF_TC(ceil_inf_neg); +ATF_TC_HEAD(ceil_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(-Inf) == -Inf"); +} + +ATF_TC_BODY(ceil_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = ceil(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceil(-Inf) != -Inf"); +} + +ATF_TC(ceil_inf_pos); +ATF_TC_HEAD(ceil_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(+Inf) == +Inf"); +} + +ATF_TC_BODY(ceil_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = ceil(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceil(+Inf) != +Inf"); +} + +ATF_TC(ceil_zero_neg); +ATF_TC_HEAD(ceil_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(-0.0) == -0.0"); +} + +ATF_TC_BODY(ceil_zero_neg, tc) +{ + const double x = -0.0L; + double y = ceil(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceil(-0.0) != -0.0"); +} + +ATF_TC(ceil_zero_pos); +ATF_TC_HEAD(ceil_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(+0.0) == +0.0"); +} + +ATF_TC_BODY(ceil_zero_pos, tc) +{ + const double x = 0.0L; + double y = ceil(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceil(+0.0) != +0.0"); +} + +/* + * ceilf(3) + */ +ATF_TC(ceilf_basic); +ATF_TC_HEAD(ceilf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ceilf(3)"); +} + +ATF_TC_BODY(ceilf_basic, tc) +{ + const float x = 0.9999999; + const float y = 0.0000001; + + ATF_CHECK(fabsf(ceilf(x) - 1) < SMALL_NUM); + ATF_CHECK(fabsf(ceilf(y) - 1) < SMALL_NUM); +} + +ATF_TC(ceilf_nan); +ATF_TC_HEAD(ceilf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(NaN) == NaN"); +} + +ATF_TC_BODY(ceilf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(ceilf(x)) != 0); +} + +ATF_TC(ceilf_inf_neg); +ATF_TC_HEAD(ceilf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(-Inf) == -Inf"); +} + +ATF_TC_BODY(ceilf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = ceilf(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceilf(-Inf) != -Inf"); +} + +ATF_TC(ceilf_inf_pos); +ATF_TC_HEAD(ceilf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(+Inf) == +Inf"); +} + +ATF_TC_BODY(ceilf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = ceilf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceilf(+Inf) != +Inf"); +} + +ATF_TC(ceilf_zero_neg); +ATF_TC_HEAD(ceilf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(-0.0) == -0.0"); +} + +ATF_TC_BODY(ceilf_zero_neg, tc) +{ + const float x = -0.0L; + float y = ceilf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceilf(-0.0) != -0.0"); +} + +ATF_TC(ceilf_zero_pos); +ATF_TC_HEAD(ceilf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(+0.0) == +0.0"); +} + +ATF_TC_BODY(ceilf_zero_pos, tc) +{ + const float x = 0.0L; + float y = ceilf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceilf(+0.0) != +0.0"); +} + +/* + * ceill(3) + */ +ATF_TC(ceill_basic); +ATF_TC_HEAD(ceill_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ceill(3)"); +} + +ATF_TC_BODY(ceill_basic, tc) +{ + const long double x = 0.9999999; + const long double y = 0.0000001; + + ATF_CHECK(fabsl(ceill(x) - 1) < SMALL_NUM); + ATF_CHECK(fabsl(ceill(y) - 1) < SMALL_NUM); +} + +ATF_TC(ceill_nan); +ATF_TC_HEAD(ceill_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(NaN) == NaN"); +} + +ATF_TC_BODY(ceill_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(ceill(x)) != 0); +} + +ATF_TC(ceill_inf_neg); +ATF_TC_HEAD(ceill_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(-Inf) == -Inf"); +} + +ATF_TC_BODY(ceill_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = ceill(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceill(-Inf) != -Inf"); +} + +ATF_TC(ceill_inf_pos); +ATF_TC_HEAD(ceill_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(+Inf) == +Inf"); +} + +ATF_TC_BODY(ceill_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = ceill(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceill(+Inf) != +Inf"); +} + +ATF_TC(ceill_zero_neg); +ATF_TC_HEAD(ceill_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(-0.0) == -0.0"); +} + +ATF_TC_BODY(ceill_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = ceill(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceill(-0.0) != -0.0"); +} + +ATF_TC(ceill_zero_pos); +ATF_TC_HEAD(ceill_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(+0.0) == +0.0"); +} + +ATF_TC_BODY(ceill_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = ceill(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceill(+0.0) != +0.0"); +} + +/* + * floor(3) + */ +ATF_TC(floor_basic); +ATF_TC_HEAD(floor_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of floor(3)"); +} + +ATF_TC_BODY(floor_basic, tc) +{ + const double x = 0.999999999999999; + const double y = 0.000000000000001; + + ATF_CHECK(floor(x) < SMALL_NUM); + ATF_CHECK(floor(y) < SMALL_NUM); +} + +ATF_TC(floor_nan); +ATF_TC_HEAD(floor_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(NaN) == NaN"); +} + +ATF_TC_BODY(floor_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(floor(x)) != 0); +} + +ATF_TC(floor_inf_neg); +ATF_TC_HEAD(floor_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(-Inf) == -Inf"); +} + +ATF_TC_BODY(floor_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = floor(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floor(-Inf) != -Inf"); +} + +ATF_TC(floor_inf_pos); +ATF_TC_HEAD(floor_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(+Inf) == +Inf"); +} + +ATF_TC_BODY(floor_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = floor(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floor(+Inf) != +Inf"); +} + +ATF_TC(floor_zero_neg); +ATF_TC_HEAD(floor_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(-0.0) == -0.0"); +} + +ATF_TC_BODY(floor_zero_neg, tc) +{ + const double x = -0.0L; + double y = floor(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floor(-0.0) != -0.0"); +} + +ATF_TC(floor_zero_pos); +ATF_TC_HEAD(floor_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(+0.0) == +0.0"); +} + +ATF_TC_BODY(floor_zero_pos, tc) +{ + const double x = 0.0L; + double y = floor(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floor(+0.0) != +0.0"); +} + +/* + * floorf(3) + */ +ATF_TC(floorf_basic); +ATF_TC_HEAD(floorf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of floorf(3)"); +} + +ATF_TC_BODY(floorf_basic, tc) +{ + const float x = 0.9999999; + const float y = 0.0000001; + + ATF_CHECK(floorf(x) < SMALL_NUM); + ATF_CHECK(floorf(y) < SMALL_NUM); +} + +ATF_TC(floorf_nan); +ATF_TC_HEAD(floorf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(NaN) == NaN"); +} + +ATF_TC_BODY(floorf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(floorf(x)) != 0); +} + +ATF_TC(floorf_inf_neg); +ATF_TC_HEAD(floorf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(-Inf) == -Inf"); +} + +ATF_TC_BODY(floorf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = floorf(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorf(-Inf) != -Inf"); +} + +ATF_TC(floorf_inf_pos); +ATF_TC_HEAD(floorf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(+Inf) == +Inf"); +} + +ATF_TC_BODY(floorf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = floorf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorf(+Inf) != +Inf"); +} + +ATF_TC(floorf_zero_neg); +ATF_TC_HEAD(floorf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(-0.0) == -0.0"); +} + +ATF_TC_BODY(floorf_zero_neg, tc) +{ + const float x = -0.0L; + float y = floorf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorf(-0.0) != -0.0"); +} + +ATF_TC(floorf_zero_pos); +ATF_TC_HEAD(floorf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(+0.0) == +0.0"); +} + +ATF_TC_BODY(floorf_zero_pos, tc) +{ + const float x = 0.0L; + float y = floorf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorf(+0.0) != +0.0"); +} + +/* + * floorl(3) + */ +ATF_TC(floorl_basic); +ATF_TC_HEAD(floorl_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of floorl(3)"); +} + +ATF_TC_BODY(floorl_basic, tc) +{ + const long double x = 0.9999999; + const long double y = 0.0000001; + + ATF_CHECK(floorl(x) < SMALL_NUM); + ATF_CHECK(floorl(y) < SMALL_NUM); +} + +ATF_TC(floorl_nan); +ATF_TC_HEAD(floorl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(NaN) == NaN"); +} + +ATF_TC_BODY(floorl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(floorl(x)) != 0); +} + +ATF_TC(floorl_inf_neg); +ATF_TC_HEAD(floorl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(-Inf) == -Inf"); +} + +ATF_TC_BODY(floorl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = floorl(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorl(-Inf) != -Inf"); +} + +ATF_TC(floorl_inf_pos); +ATF_TC_HEAD(floorl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(+Inf) == +Inf"); +} + +ATF_TC_BODY(floorl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = floorl(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorl(+Inf) != +Inf"); +} + +ATF_TC(floorl_zero_neg); +ATF_TC_HEAD(floorl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(-0.0) == -0.0"); +} + +ATF_TC_BODY(floorl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = floorl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorl(-0.0) != -0.0"); +} + +ATF_TC(floorl_zero_pos); +ATF_TC_HEAD(floorl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(+0.0) == +0.0"); +} + +ATF_TC_BODY(floorl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = floorl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorl(+0.0) != +0.0"); +} + +/* + * trunc(3) + */ +ATF_TC(trunc_basic); +ATF_TC_HEAD(trunc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of trunc(3)"); +} + +ATF_TC_BODY(trunc_basic, tc) +{ + const double x = 0.999999999999999; + const double y = 0.000000000000001; + + ATF_CHECK(trunc(x) < SMALL_NUM); + ATF_CHECK(trunc(y) < SMALL_NUM); +} + +ATF_TC(trunc_nan); +ATF_TC_HEAD(trunc_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(NaN) == NaN"); +} + +ATF_TC_BODY(trunc_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(trunc(x)) != 0); +} + +ATF_TC(trunc_inf_neg); +ATF_TC_HEAD(trunc_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(-Inf) == -Inf"); +} + +ATF_TC_BODY(trunc_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = trunc(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("trunc(-Inf) != -Inf"); +} + +ATF_TC(trunc_inf_pos); +ATF_TC_HEAD(trunc_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(+Inf) == +Inf"); +} + +ATF_TC_BODY(trunc_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = trunc(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("trunc(+Inf) != +Inf"); +} + +ATF_TC(trunc_zero_neg); +ATF_TC_HEAD(trunc_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(-0.0) == -0.0"); +} + +ATF_TC_BODY(trunc_zero_neg, tc) +{ + const double x = -0.0L; + double y = trunc(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("trunc(-0.0) != -0.0"); +} + +ATF_TC(trunc_zero_pos); +ATF_TC_HEAD(trunc_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(+0.0) == +0.0"); +} + +ATF_TC_BODY(trunc_zero_pos, tc) +{ + const double x = 0.0L; + double y = trunc(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("trunc(+0.0) != +0.0"); +} + +/* + * truncf(3) + */ +ATF_TC(truncf_basic); +ATF_TC_HEAD(truncf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of truncf(3)"); +} + +ATF_TC_BODY(truncf_basic, tc) +{ + const float x = 0.9999999; + const float y = 0.0000001; + + ATF_CHECK(truncf(x) < SMALL_NUM); + ATF_CHECK(truncf(y) < SMALL_NUM); +} + +ATF_TC(truncf_nan); +ATF_TC_HEAD(truncf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(NaN) == NaN"); +} + +ATF_TC_BODY(truncf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(truncf(x)) != 0); +} + +ATF_TC(truncf_inf_neg); +ATF_TC_HEAD(truncf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(-Inf) == -Inf"); +} + +ATF_TC_BODY(truncf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = truncf(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncf(-Inf) != -Inf"); +} + +ATF_TC(truncf_inf_pos); +ATF_TC_HEAD(truncf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(+Inf) == +Inf"); +} + +ATF_TC_BODY(truncf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = truncf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncf(+Inf) != +Inf"); +} + +ATF_TC(truncf_zero_neg); +ATF_TC_HEAD(truncf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(-0.0) == -0.0"); +} + +ATF_TC_BODY(truncf_zero_neg, tc) +{ + const float x = -0.0L; + float y = truncf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncf(-0.0) != -0.0"); +} + +ATF_TC(truncf_zero_pos); +ATF_TC_HEAD(truncf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(+0.0) == +0.0"); +} + +ATF_TC_BODY(truncf_zero_pos, tc) +{ + const float x = 0.0L; + float y = truncf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncf(+0.0) != +0.0"); +} + +/* + * truncl(3) + */ +ATF_TC(truncl_basic); +ATF_TC_HEAD(truncl_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of truncl(3)"); +} + +ATF_TC_BODY(truncl_basic, tc) +{ + const long double x = 0.9999999; + const long double y = 0.0000001; + + ATF_CHECK(truncl(x) < SMALL_NUM); + ATF_CHECK(truncl(y) < SMALL_NUM); +} + +ATF_TC(truncl_nan); +ATF_TC_HEAD(truncl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(NaN) == NaN"); +} + +ATF_TC_BODY(truncl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(truncl(x)) != 0); +} + +ATF_TC(truncl_inf_neg); +ATF_TC_HEAD(truncl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(-Inf) == -Inf"); +} + +ATF_TC_BODY(truncl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = truncl(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncl(-Inf) != -Inf"); +} + +ATF_TC(truncl_inf_pos); +ATF_TC_HEAD(truncl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(+Inf) == +Inf"); +} + +ATF_TC_BODY(truncl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = truncl(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncl(+Inf) != +Inf"); +} + +ATF_TC(truncl_zero_neg); +ATF_TC_HEAD(truncl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(-0.0) == -0.0"); +} + +ATF_TC_BODY(truncl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = truncl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncl(-0.0) != -0.0"); +} + +ATF_TC(truncl_zero_pos); +ATF_TC_HEAD(truncl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(+0.0) == +0.0"); +} + +ATF_TC_BODY(truncl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = truncl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncl(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ceil_basic); + ATF_TP_ADD_TC(tp, ceil_nan); + ATF_TP_ADD_TC(tp, ceil_inf_neg); + ATF_TP_ADD_TC(tp, ceil_inf_pos); + ATF_TP_ADD_TC(tp, ceil_zero_neg); + ATF_TP_ADD_TC(tp, ceil_zero_pos); + + ATF_TP_ADD_TC(tp, ceilf_basic); + ATF_TP_ADD_TC(tp, ceilf_nan); + ATF_TP_ADD_TC(tp, ceilf_inf_neg); + ATF_TP_ADD_TC(tp, ceilf_inf_pos); + ATF_TP_ADD_TC(tp, ceilf_zero_neg); + ATF_TP_ADD_TC(tp, ceilf_zero_pos); + + ATF_TP_ADD_TC(tp, ceill_basic); + ATF_TP_ADD_TC(tp, ceill_nan); + ATF_TP_ADD_TC(tp, ceill_inf_neg); + ATF_TP_ADD_TC(tp, ceill_inf_pos); + ATF_TP_ADD_TC(tp, ceill_zero_neg); + ATF_TP_ADD_TC(tp, ceill_zero_pos); + + ATF_TP_ADD_TC(tp, floor_basic); + ATF_TP_ADD_TC(tp, floor_nan); + ATF_TP_ADD_TC(tp, floor_inf_neg); + ATF_TP_ADD_TC(tp, floor_inf_pos); + ATF_TP_ADD_TC(tp, floor_zero_neg); + ATF_TP_ADD_TC(tp, floor_zero_pos); + + ATF_TP_ADD_TC(tp, floorf_basic); + ATF_TP_ADD_TC(tp, floorf_nan); + ATF_TP_ADD_TC(tp, floorf_inf_neg); + ATF_TP_ADD_TC(tp, floorf_inf_pos); + ATF_TP_ADD_TC(tp, floorf_zero_neg); + ATF_TP_ADD_TC(tp, floorf_zero_pos); + + ATF_TP_ADD_TC(tp, floorl_basic); + ATF_TP_ADD_TC(tp, floorl_nan); + ATF_TP_ADD_TC(tp, floorl_inf_neg); + ATF_TP_ADD_TC(tp, floorl_inf_pos); + ATF_TP_ADD_TC(tp, floorl_zero_neg); + ATF_TP_ADD_TC(tp, floorl_zero_pos); + + ATF_TP_ADD_TC(tp, trunc_basic); + ATF_TP_ADD_TC(tp, trunc_nan); + ATF_TP_ADD_TC(tp, trunc_inf_neg); + ATF_TP_ADD_TC(tp, trunc_inf_pos); + ATF_TP_ADD_TC(tp, trunc_zero_neg); + ATF_TP_ADD_TC(tp, trunc_zero_pos); + + ATF_TP_ADD_TC(tp, truncf_basic); + ATF_TP_ADD_TC(tp, truncf_nan); + ATF_TP_ADD_TC(tp, truncf_inf_neg); + ATF_TP_ADD_TC(tp, truncf_inf_pos); + ATF_TP_ADD_TC(tp, truncf_zero_neg); + ATF_TP_ADD_TC(tp, truncf_zero_pos); + + ATF_TP_ADD_TC(tp, truncl_basic); + ATF_TP_ADD_TC(tp, truncl_nan); + ATF_TP_ADD_TC(tp, truncl_inf_neg); + ATF_TP_ADD_TC(tp, truncl_inf_pos); + ATF_TP_ADD_TC(tp, truncl_zero_neg); + ATF_TP_ADD_TC(tp, truncl_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_cos.c b/contrib/netbsd-tests/lib/libm/t_cos.c new file mode 100644 index 0000000..d99d608 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_cos.c @@ -0,0 +1,263 @@ +/* $NetBSD: t_cos.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> + +static const struct { + int angle; + double x; + double y; +} angles[] = { + { -180, -3.141592653589793, -1.0000000000000000 }, + { -135, -2.356194490192345, -0.7071067811865476 }, + { -90, -1.570796326794897, 0.0000000000000000 }, + { -45, -0.785398163397448, 0.7071067811865476 }, + { 0, 0.000000000000000, 1.0000000000000000 }, + { 30, 0.523598775598299, 0.8660254037844386 }, + { 45, 0.785398163397448, 0.7071067811865476 }, + { 60, 1.047197551196598, 0.5000000000000000 }, + { 90, 1.570796326794897, 0.0000000000000000 }, + { 120, 2.094395102393195, -0.5000000000000000 }, + { 135, 2.356194490192345, -0.7071067811865476 }, + { 150, 2.617993877991494, -0.8660254037844386 }, + { 180, 3.141592653589793, -1.0000000000000000 }, + { 270, 4.712388980384690, 0.0000000000000000 }, + { 360, 6.283185307179586, 1.0000000000000000 } +}; + +/* + * cos(3) + */ +ATF_TC(cos_angles); +ATF_TC_HEAD(cos_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(cos_angles, tc) +{ + const double eps = 1.0e-15; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + if (fabs(cos(angles[i].x) - angles[i].y) > eps) + atf_tc_fail_nonfatal("cos(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(cos_nan); +ATF_TC_HEAD(cos_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(NaN) == NaN"); +} + +ATF_TC_BODY(cos_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cos(x)) != 0); +} + +ATF_TC(cos_inf_neg); +ATF_TC_HEAD(cos_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(-Inf) == NaN"); +} + +ATF_TC_BODY(cos_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(isnan(cos(x)) != 0); +} + +ATF_TC(cos_inf_pos); +ATF_TC_HEAD(cos_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(+Inf) == NaN"); +} + +ATF_TC_BODY(cos_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(isnan(cos(x)) != 0); +} + + +ATF_TC(cos_zero_neg); +ATF_TC_HEAD(cos_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(-0.0) == 1.0"); +} + +ATF_TC_BODY(cos_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(cos(x) == 1.0); +} + +ATF_TC(cos_zero_pos); +ATF_TC_HEAD(cos_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(+0.0) == 1.0"); +} + +ATF_TC_BODY(cos_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(cos(x) == 1.0); +} + +/* + * cosf(3) + */ +ATF_TC(cosf_angles); +ATF_TC_HEAD(cosf_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(cosf_angles, tc) +{ + const float eps = 1.0e-7; + float x, y; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + x = angles[i].x; + y = angles[i].y; + + if (fabsf(cosf(x) - y) > eps) + atf_tc_fail_nonfatal("cosf(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(cosf_nan); +ATF_TC_HEAD(cosf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(NaN) == NaN"); +} + +ATF_TC_BODY(cosf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cosf(x)) != 0); +} + +ATF_TC(cosf_inf_neg); +ATF_TC_HEAD(cosf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(-Inf) == NaN"); +} + +ATF_TC_BODY(cosf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(cosf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("cosf(-Inf) != NaN"); + } +} + +ATF_TC(cosf_inf_pos); +ATF_TC_HEAD(cosf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(+Inf) == NaN"); +} + +ATF_TC_BODY(cosf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(cosf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("cosf(+Inf) != NaN"); + } +} + + +ATF_TC(cosf_zero_neg); +ATF_TC_HEAD(cosf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(-0.0) == 1.0"); +} + +ATF_TC_BODY(cosf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(cosf(x) == 1.0); +} + +ATF_TC(cosf_zero_pos); +ATF_TC_HEAD(cosf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(+0.0) == 1.0"); +} + +ATF_TC_BODY(cosf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(cosf(x) == 1.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cos_angles); + ATF_TP_ADD_TC(tp, cos_nan); + ATF_TP_ADD_TC(tp, cos_inf_neg); + ATF_TP_ADD_TC(tp, cos_inf_pos); + ATF_TP_ADD_TC(tp, cos_zero_neg); + ATF_TP_ADD_TC(tp, cos_zero_pos); + + ATF_TP_ADD_TC(tp, cosf_angles); + ATF_TP_ADD_TC(tp, cosf_nan); + ATF_TP_ADD_TC(tp, cosf_inf_neg); + ATF_TP_ADD_TC(tp, cosf_inf_pos); + ATF_TP_ADD_TC(tp, cosf_zero_neg); + ATF_TP_ADD_TC(tp, cosf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_cosh.c b/contrib/netbsd-tests/lib/libm/t_cosh.c new file mode 100644 index 0000000..3f998de --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_cosh.c @@ -0,0 +1,270 @@ +/* $NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <math.h> +#include <stdio.h> + +static const struct { + double x; + double y; + double e; +} values[] = { + { -10, 11013.23292010332, 1e4, }, + { -2, 3.762195691083631, 1, }, + { -1, 1.543080634815244, 1, }, + { -0.05, 1.001250260438369, 1, }, + { -0.001, 1.000000500000042, 1, }, + { 0, 1, 1, }, + { 0.001, 1.000000500000042, 1, }, + { 0.05, 1.001250260438369, 1, }, + { 1, 1.543080634815244, 1, }, + { 2, 3.762195691083631, 1, }, + { 10, 11013.23292010332, 1e4, }, +}; + +/* + * cosh(3) + */ +ATF_TC(cosh_inrange); +ATF_TC_HEAD(cosh_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "cosh(x) for some values"); +} + +ATF_TC_BODY(cosh_inrange, tc) +{ + double eps; + double x; + double y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-15 * values[i].e; + + if (fabs(cosh(x) - y) > eps) + atf_tc_fail_nonfatal("cosh(%g) != %g\n", x, y); + } +} + +ATF_TC(cosh_nan); +ATF_TC_HEAD(cosh_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(NaN) == NaN"); +} + +ATF_TC_BODY(cosh_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cosh(x)) != 0); +} + +ATF_TC(cosh_inf_neg); +ATF_TC_HEAD(cosh_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(-Inf) == +Inf"); +} + +ATF_TC_BODY(cosh_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = cosh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cosh_inf_pos); +ATF_TC_HEAD(cosh_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(+Inf) == +Inf"); +} + +ATF_TC_BODY(cosh_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = cosh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cosh_zero_neg); +ATF_TC_HEAD(cosh_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(-0.0) == 1.0"); +} + +ATF_TC_BODY(cosh_zero_neg, tc) +{ + const double x = -0.0L; + + if (cosh(x) != 1.0) + atf_tc_fail_nonfatal("cosh(-0.0) != 1.0"); +} + +ATF_TC(cosh_zero_pos); +ATF_TC_HEAD(cosh_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(+0.0) == 1.0"); +} + +ATF_TC_BODY(cosh_zero_pos, tc) +{ + const double x = 0.0L; + + if (cosh(x) != 1.0) + atf_tc_fail_nonfatal("cosh(+0.0) != 1.0"); +} + +/* + * coshf(3) + */ +ATF_TC(coshf_inrange); +ATF_TC_HEAD(coshf_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "coshf(x) for some values"); +} + +ATF_TC_BODY(coshf_inrange, tc) +{ + float eps; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-6 * values[i].e; + + if (fabsf(coshf(x) - y) > eps) + atf_tc_fail_nonfatal("coshf(%g) != %g\n", x, y); + } +} + +ATF_TC(coshf_nan); +ATF_TC_HEAD(coshf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(NaN) == NaN"); +} + +ATF_TC_BODY(coshf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(coshf(x)) != 0); +} + +ATF_TC(coshf_inf_neg); +ATF_TC_HEAD(coshf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(-Inf) == +Inf"); +} + +ATF_TC_BODY(coshf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = coshf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(coshf_inf_pos); +ATF_TC_HEAD(coshf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(+Inf) == +Inf"); +} + +ATF_TC_BODY(coshf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = coshf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(coshf_zero_neg); +ATF_TC_HEAD(coshf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(-0.0) == 1.0"); +} + +ATF_TC_BODY(coshf_zero_neg, tc) +{ + const float x = -0.0L; + + if (coshf(x) != 1.0) + atf_tc_fail_nonfatal("coshf(-0.0) != 1.0"); +} + +ATF_TC(coshf_zero_pos); +ATF_TC_HEAD(coshf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(+0.0) == 1.0"); +} + +ATF_TC_BODY(coshf_zero_pos, tc) +{ + const float x = 0.0L; + + if (coshf(x) != 1.0) + atf_tc_fail_nonfatal("coshf(+0.0) != 1.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cosh_inrange); + ATF_TP_ADD_TC(tp, cosh_nan); + ATF_TP_ADD_TC(tp, cosh_inf_neg); + ATF_TP_ADD_TC(tp, cosh_inf_pos); + ATF_TP_ADD_TC(tp, cosh_zero_neg); + ATF_TP_ADD_TC(tp, cosh_zero_pos); + + ATF_TP_ADD_TC(tp, coshf_inrange); + ATF_TP_ADD_TC(tp, coshf_nan); + ATF_TP_ADD_TC(tp, coshf_inf_neg); + ATF_TP_ADD_TC(tp, coshf_inf_pos); + ATF_TP_ADD_TC(tp, coshf_zero_neg); + ATF_TP_ADD_TC(tp, coshf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_erf.c b/contrib/netbsd-tests/lib/libm/t_erf.c new file mode 100644 index 0000000..25bbae7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_erf.c @@ -0,0 +1,299 @@ +/* $NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <math.h> + +/* + * erf(3) + */ +ATF_TC(erf_nan); +ATF_TC_HEAD(erf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(NaN) == NaN"); +} + +ATF_TC_BODY(erf_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erf(x)) != 0); +} + +ATF_TC(erf_inf_neg); +ATF_TC_HEAD(erf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(-Inf) == -1.0"); +} + +ATF_TC_BODY(erf_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (erf(x) != -1.0) + atf_tc_fail_nonfatal("erf(-Inf) != -1.0"); +} + +ATF_TC(erf_inf_pos); +ATF_TC_HEAD(erf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(+Inf) == 1.0"); +} + +ATF_TC_BODY(erf_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + if (erf(x) != 1.0) + atf_tc_fail_nonfatal("erf(+Inf) != 1.0"); +} + +ATF_TC(erf_zero_neg); +ATF_TC_HEAD(erf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(-0.0) == -0.0"); +} + +ATF_TC_BODY(erf_zero_neg, tc) +{ + const double x = -0.0L; + double y = erf(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("erf(-0.0) != -0.0"); +} + +ATF_TC(erf_zero_pos); +ATF_TC_HEAD(erf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(+0.0) == +0.0"); +} + +ATF_TC_BODY(erf_zero_pos, tc) +{ + const double x = 0.0L; + double y = erf(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erf(+0.0) != +0.0"); +} + +/* + * erff(3) + */ +ATF_TC(erff_nan); +ATF_TC_HEAD(erff_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(NaN) == NaN"); +} + +ATF_TC_BODY(erff_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erff(x)) != 0); +} + +ATF_TC(erff_inf_neg); +ATF_TC_HEAD(erff_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(-Inf) == -1.0"); +} + +ATF_TC_BODY(erff_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (erff(x) != -1.0) + atf_tc_fail_nonfatal("erff(-Inf) != -1.0"); +} + +ATF_TC(erff_inf_pos); +ATF_TC_HEAD(erff_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(+Inf) == 1.0"); +} + +ATF_TC_BODY(erff_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (erff(x) != 1.0) + atf_tc_fail_nonfatal("erff(+Inf) != 1.0"); +} + +ATF_TC(erff_zero_neg); +ATF_TC_HEAD(erff_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(-0.0) == -0.0"); +} + +ATF_TC_BODY(erff_zero_neg, tc) +{ + const float x = -0.0L; + float y = erff(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("erff(-0.0) != -0.0"); +} + +ATF_TC(erff_zero_pos); +ATF_TC_HEAD(erff_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(+0.0) == +0.0"); +} + +ATF_TC_BODY(erff_zero_pos, tc) +{ + const float x = 0.0L; + float y = erff(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erff(+0.0) != +0.0"); +} + +/* + * erfc(3) + */ +ATF_TC(erfc_nan); +ATF_TC_HEAD(erfc_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfc(NaN) == NaN"); +} + +ATF_TC_BODY(erfc_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erfc(x)) != 0); +} + +ATF_TC(erfc_inf_neg); +ATF_TC_HEAD(erfc_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfc(-Inf) == 2.0"); +} + +ATF_TC_BODY(erfc_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (erfc(x) != 2.0) + atf_tc_fail_nonfatal("erfc(-Inf) != 2.0"); +} + +ATF_TC(erfc_inf_pos); +ATF_TC_HEAD(erfc_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfc(+Inf) == +0.0"); +} + +ATF_TC_BODY(erfc_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = erfc(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erfc(+Inf) != +0.0"); +} + +/* + * erfcf(3) + */ +ATF_TC(erfcf_nan); +ATF_TC_HEAD(erfcf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfcf(NaN) == NaN"); +} + +ATF_TC_BODY(erfcf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erfcf(x)) != 0); +} + +ATF_TC(erfcf_inf_neg); +ATF_TC_HEAD(erfcf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfcf(-Inf) == 2.0"); +} + +ATF_TC_BODY(erfcf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (erfcf(x) != 2.0) + atf_tc_fail_nonfatal("erfcf(-Inf) != 2.0"); +} + +ATF_TC(erfcf_inf_pos); +ATF_TC_HEAD(erfcf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfcf(+Inf) == +0.0"); +} + +ATF_TC_BODY(erfcf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = erfcf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erfcf(+Inf) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, erf_nan); + ATF_TP_ADD_TC(tp, erf_inf_neg); + ATF_TP_ADD_TC(tp, erf_inf_pos); + ATF_TP_ADD_TC(tp, erf_zero_neg); + ATF_TP_ADD_TC(tp, erf_zero_pos); + + ATF_TP_ADD_TC(tp, erff_nan); + ATF_TP_ADD_TC(tp, erff_inf_neg); + ATF_TP_ADD_TC(tp, erff_inf_pos); + ATF_TP_ADD_TC(tp, erff_zero_neg); + ATF_TP_ADD_TC(tp, erff_zero_pos); + + ATF_TP_ADD_TC(tp, erfc_nan); + ATF_TP_ADD_TC(tp, erfc_inf_neg); + ATF_TP_ADD_TC(tp, erfc_inf_pos); + + ATF_TP_ADD_TC(tp, erfcf_nan); + ATF_TP_ADD_TC(tp, erfcf_inf_neg); + ATF_TP_ADD_TC(tp, erfcf_inf_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_exp.c b/contrib/netbsd-tests/lib/libm/t_exp.c new file mode 100644 index 0000000..6d41097 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_exp.c @@ -0,0 +1,567 @@ +/* $NetBSD: t_exp.c,v 1.7 2014/03/17 11:08:11 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> +#include "t_libm.h" + +/* y = exp(x) */ +static const struct { + double x; + double y; + double e; +} exp_values[] = { + { -10, 0.4539992976248485e-4, 1e-4, }, + { -5, 0.6737946999085467e-2, 1e-2, }, + { -1, 0.3678794411714423, 1e-1, }, + { -0.1, 0.9048374180359595, 1e-1, }, + { 0, 1.0000000000000000, 1, }, + { 0.1, 1.1051709180756477, 1, }, + { 1, 2.7182818284590452, 1, }, + { 5, 148.41315910257660, 1e2, }, + { 10, 22026.465794806718, 1e4, }, +}; + +/* + * exp2/exp2f(3) + */ +ATF_LIBM_TEST(exp2_is_nan, "Test exp2(x) == NaN") +{ +#ifdef T_LIBM_NAN + T_LIBM_CHECK_NAN(0, exp2, T_LIBM_NAN); + T_LIBM_CHECK_NAN(0, exp2f, T_LIBM_NAN); +#else + atf_tc_skip("no NaN on this machine"); +#endif +} + +ATF_LIBM_TEST(exp2_is_plus_zero, "Test exp2(x) == +0.0") +{ +#ifdef T_LIBM_MINUS_INF + T_LIBM_CHECK_PLUS_ZERO(0, exp2, T_LIBM_MINUS_INF); + T_LIBM_CHECK_PLUS_ZERO(0, exp2f, T_LIBM_MINUS_INF); +#else + atf_tc_skip("no +/-Inf on this machine"); +#endif +} + +ATF_LIBM_TEST(exp2_powers, "Test exp2(x) is correct for some integer x") +{ + static const struct { + double x; + double d_y; + double f_y; + } v[] = { + { +0.0, 1.0, 1.0 }, + { -0.0, 1.0, 1.0 }, + { 1, 0x1p1, 0x1p1 }, + { 2, 0x1p2, 0x1p2 }, + { 100, 0x1p100, 0x1p100 }, + { 125, 0x1p125, 0x1p125 }, + { 126, 0x1p126, 0x1p126 }, +#if __DBL_MAX_EXP__ > 129 + { 127, 0x1p127, 0x1p127 }, +#endif +#ifdef T_LIBM_PLUS_INF + { 128, 0x1p128, T_LIBM_PLUS_INF }, + { 129, 0x1p129, T_LIBM_PLUS_INF }, + { 1000, 0x1p1000, T_LIBM_PLUS_INF }, + { 1020, 0x1p1020, T_LIBM_PLUS_INF }, + { 1023, 0x1p1023, T_LIBM_PLUS_INF }, + { 1024, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 1030, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 1050, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 2000, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 16383, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 16384, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 16385, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, +#endif + { -1, 0x1p-1, 0x1p-1 }, + { -2, 0x1p-2, 0x1p-2 }, + { -100, 0x1p-100, 0x1p-100 }, + { -127, 0x1p-127, 0x1p-127 }, + { -128, 0x1p-128, 0x1p-128 }, +#if __LDBL_MIN_EXP__ < -129 + { -300, 0x1p-300, 0.0}, + { -400, 0x1p-400, 0.0}, + {-1000, 0x1p-1000, 0.0}, + {-1022, 0x1p-1022, 0.0}, + /* These should be denormal numbers */ + {-1023, 0x1p-1023, 0.0}, + {-1024, 0x1p-1024, 0.0}, + {-1040, 0x1p-1040, 0.0}, + {-1060, 0x1p-1060, 0.0}, + /* This is the smallest result gcc will allow */ + {-1074, 0x1p-1074, 0.0}, +#endif + {-1075, 0x0, 0.0}, + {-1080, 0x0, 0.0}, + {-2000, 0x0, 0.0}, + {-16382, 0x0, 0.0}, + {-16383, 0x0, 0.0}, + {-16384, 0x0, 0.0}, + }; + unsigned int i; + + for (i = 0; i < __arraycount(v); i++) { + T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0); + T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0); + } +} + +ATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x") +{ + static const struct { + double x; + double y; + double d_eps; + double f_eps; + } v[] = { +#if __DBL_MAX_EXP__ > 128 + /* The largest double constant */ + { 0x1.fffffffffffffp9, 0x1.ffffffffffd3ap1023, + 0x1p969, 0.0 }, + /* The largest float constant */ + { 0x1.fffffep6, 0x1.ffff4ep+127, 6e30, 0.0 }, +#endif +#ifdef T_LIBM_PLUS_INF + { T_LIBM_PLUS_INF, T_LIBM_PLUS_INF, 0.0, 0.0 }, +#endif + + /* The few values from the old tests */ + /* Results from i386/amd64, d_eps needed on i386 */ + { 1.1, 0x1.125fbee250664p+1, 0x1p-52, 0x1.8p-22 }, + { 2.2, 0x1.2611186bae675p+2, 0x1p-51, 0x1.8p-21 }, + { 3.3, 0x1.3b2c47bff8328p+3, 0x1p-50, 0x1.8p-20 }, + { 4.4, 0x1.51cb453b9536ep+4, 0x1p-49, 0x1.8p-19 }, + { 5.5, 0x1.6a09e667f3bcdp+5, 0x1p-48, 0x1.8p-18 }, + { 6.6, 0x1.8406003b2ae5bp+6, 0x1p-47, 0x1.8p-17 }, + /* + * These two currently fail for 'float'. + * 8.8 is definitely out by more than it should be. + */ + { 7.7, 0x1.9fdf8bcce533ep+7, 0x1p-46, 0x1.8p-16 }, + { 8.8, 0x1.bdb8cdadbe124p+8, 0x1p-45, 0x1.8p-15 }, + }; + unsigned int i; + + for (i = 0; i < __arraycount(v); i++) { + T_LIBM_CHECK(i, exp2, v[i].x, v[i].y, v[i].d_eps); + if (i > 1) + T_LIBM_CHECK(i, exp2f, v[i].x, v[i].y, v[i].f_eps); + } +} + + +/* + * exp(3) + */ +ATF_TC(exp_nan); +ATF_TC_HEAD(exp_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(NaN) == NaN"); +} + +ATF_TC_BODY(exp_nan, tc) +{ + const double x = 0.0L / 0.0L; + + if (isnan(exp(x)) == 0) + atf_tc_fail_nonfatal("exp(NaN) != NaN"); +} + +ATF_TC(exp_inf_neg); +ATF_TC_HEAD(exp_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(-Inf) == +0.0"); +} + +ATF_TC_BODY(exp_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = exp(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("exp(-Inf) != +0.0"); +} + +ATF_TC(exp_inf_pos); +ATF_TC_HEAD(exp_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(+Inf) == +Inf"); +} + +ATF_TC_BODY(exp_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = exp(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("exp(+Inf) != +Inf"); +} + +ATF_TC(exp_product); +ATF_TC_HEAD(exp_product, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected exp(x)"); +} + +ATF_TC_BODY(exp_product, tc) +{ + double eps; + double x; + double y; + size_t i; + + for (i = 0; i < __arraycount(exp_values); i++) { + x = exp_values[i].x; + y = exp_values[i].y; + eps = 1e-15 * exp_values[i].e; + + if (fabs(exp(x) - y) > eps) + atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y); + } +} + +ATF_TC(exp_zero_neg); +ATF_TC_HEAD(exp_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(-0.0) == 1.0"); +} + +ATF_TC_BODY(exp_zero_neg, tc) +{ + const double x = -0.0L; + + if (fabs(exp(x) - 1.0) > 0.0) + atf_tc_fail_nonfatal("exp(-0.0) != 1.0"); +} + +ATF_TC(exp_zero_pos); +ATF_TC_HEAD(exp_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(+0.0) == 1.0"); +} + +ATF_TC_BODY(exp_zero_pos, tc) +{ + const double x = 0.0L; + + if (fabs(exp(x) - 1.0) > 0.0) + atf_tc_fail_nonfatal("exp(+0.0) != 1.0"); +} + +/* + * expf(3) + */ +ATF_TC(expf_nan); +ATF_TC_HEAD(expf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(NaN) == NaN"); +} + +ATF_TC_BODY(expf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + if (isnan(expf(x)) == 0) + atf_tc_fail_nonfatal("expf(NaN) != NaN"); +} + +ATF_TC(expf_inf_neg); +ATF_TC_HEAD(expf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(-Inf) == +0.0"); +} + +ATF_TC_BODY(expf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = expf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expf(-Inf) != +0.0"); +} + +ATF_TC(expf_inf_pos); +ATF_TC_HEAD(expf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(+Inf) == +Inf"); +} + +ATF_TC_BODY(expf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = expf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expf(+Inf) != +Inf"); +} + +ATF_TC(expf_product); +ATF_TC_HEAD(expf_product, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected expf(x)"); +} + +ATF_TC_BODY(expf_product, tc) +{ + float eps; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(exp_values); i++) { + x = exp_values[i].x; + y = exp_values[i].y; + eps = 1e-6 * exp_values[i].e; + + if (fabsf(expf(x) - y) > eps) + atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y); + } +} + +ATF_TC(expf_zero_neg); +ATF_TC_HEAD(expf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(-0.0) == 1.0"); +} + +ATF_TC_BODY(expf_zero_neg, tc) +{ + const float x = -0.0L; + + if (fabsf(expf(x) - 1.0f) > 0.0) + atf_tc_fail_nonfatal("expf(-0.0) != 1.0"); +} + +ATF_TC(expf_zero_pos); +ATF_TC_HEAD(expf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(+0.0) == 1.0"); +} + +ATF_TC_BODY(expf_zero_pos, tc) +{ + const float x = 0.0L; + + if (fabsf(expf(x) - 1.0f) > 0.0) + atf_tc_fail_nonfatal("expf(+0.0) != 1.0"); +} + +/* + * expm1(3) + */ +ATF_TC(expm1_nan); +ATF_TC_HEAD(expm1_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(NaN) == NaN"); +} + +ATF_TC_BODY(expm1_nan, tc) +{ + const double x = 0.0L / 0.0L; + + if (isnan(expm1(x)) == 0) + atf_tc_fail_nonfatal("expm1(NaN) != NaN"); +} + +ATF_TC(expm1_inf_neg); +ATF_TC_HEAD(expm1_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(-Inf) == -1"); +} + +ATF_TC_BODY(expm1_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (expm1(x) != -1.0) + atf_tc_fail_nonfatal("expm1(-Inf) != -1.0"); +} + +ATF_TC(expm1_inf_pos); +ATF_TC_HEAD(expm1_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(+Inf) == +Inf"); +} + +ATF_TC_BODY(expm1_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = expm1(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1(+Inf) != +Inf"); +} + +ATF_TC(expm1_zero_neg); +ATF_TC_HEAD(expm1_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(-0.0) == -0.0"); +} + +ATF_TC_BODY(expm1_zero_neg, tc) +{ + const double x = -0.0L; + double y = expm1(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("expm1(-0.0) != -0.0"); +} + +ATF_TC(expm1_zero_pos); +ATF_TC_HEAD(expm1_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(+0.0) == 1.0"); +} + +ATF_TC_BODY(expm1_zero_pos, tc) +{ + const double x = 0.0L; + double y = expm1(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1(+0.0) != +0.0"); +} + +/* + * expm1f(3) + */ +ATF_TC(expm1f_nan); +ATF_TC_HEAD(expm1f_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(NaN) == NaN"); +} + +ATF_TC_BODY(expm1f_nan, tc) +{ + const float x = 0.0L / 0.0L; + + if (isnan(expm1f(x)) == 0) + atf_tc_fail_nonfatal("expm1f(NaN) != NaN"); +} + +ATF_TC(expm1f_inf_neg); +ATF_TC_HEAD(expm1f_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(-Inf) == -1"); +} + +ATF_TC_BODY(expm1f_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (expm1f(x) != -1.0) + atf_tc_fail_nonfatal("expm1f(-Inf) != -1.0"); +} + +ATF_TC(expm1f_inf_pos); +ATF_TC_HEAD(expm1f_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(+Inf) == +Inf"); +} + +ATF_TC_BODY(expm1f_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = expm1f(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1f(+Inf) != +Inf"); +} + +ATF_TC(expm1f_zero_neg); +ATF_TC_HEAD(expm1f_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(-0.0) == -0.0"); +} + +ATF_TC_BODY(expm1f_zero_neg, tc) +{ + const float x = -0.0L; + float y = expm1f(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("expm1f(-0.0) != -0.0"); +} + +ATF_TC(expm1f_zero_pos); +ATF_TC_HEAD(expm1f_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(+0.0) == 1.0"); +} + +ATF_TC_BODY(expm1f_zero_pos, tc) +{ + const float x = 0.0L; + float y = expm1f(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1f(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, exp2_is_nan); + ATF_TP_ADD_TC(tp, exp2_is_plus_zero); + ATF_TP_ADD_TC(tp, exp2_values); + ATF_TP_ADD_TC(tp, exp2_powers); + + ATF_TP_ADD_TC(tp, exp_nan); + ATF_TP_ADD_TC(tp, exp_inf_neg); + ATF_TP_ADD_TC(tp, exp_inf_pos); + ATF_TP_ADD_TC(tp, exp_product); + ATF_TP_ADD_TC(tp, exp_zero_neg); + ATF_TP_ADD_TC(tp, exp_zero_pos); + + ATF_TP_ADD_TC(tp, expf_nan); + ATF_TP_ADD_TC(tp, expf_inf_neg); + ATF_TP_ADD_TC(tp, expf_inf_pos); + ATF_TP_ADD_TC(tp, expf_product); + ATF_TP_ADD_TC(tp, expf_zero_neg); + ATF_TP_ADD_TC(tp, expf_zero_pos); + + ATF_TP_ADD_TC(tp, expm1_nan); + ATF_TP_ADD_TC(tp, expm1_inf_neg); + ATF_TP_ADD_TC(tp, expm1_inf_pos); + ATF_TP_ADD_TC(tp, expm1_zero_neg); + ATF_TP_ADD_TC(tp, expm1_zero_pos); + + ATF_TP_ADD_TC(tp, expm1f_nan); + ATF_TP_ADD_TC(tp, expm1f_inf_neg); + ATF_TP_ADD_TC(tp, expm1f_inf_pos); + ATF_TP_ADD_TC(tp, expm1f_zero_neg); + ATF_TP_ADD_TC(tp, expm1f_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_fmod.c b/contrib/netbsd-tests/lib/libm/t_fmod.c new file mode 100644 index 0000000..7dac93d --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_fmod.c @@ -0,0 +1,63 @@ +/* $NetBSD: t_fmod.c,v 1.2 2014/02/27 17:26:02 joerg Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <float.h> +#include <math.h> + +ATF_TC(fmod); +ATF_TC_HEAD(fmod, tc) +{ + atf_tc_set_md_var(tc, "descr","Check fmod family"); +} + +ATF_TC_BODY(fmod, tc) +{ + ATF_CHECK(fmodf(2.0, 1.0) == 0); + ATF_CHECK(fmod(2.0, 1.0) == 0); + ATF_CHECK(fmodl(2.0, 1.0) == 0); + + ATF_CHECK(fmodf(2.0, 0.5) == 0); + ATF_CHECK(fmod(2.0, 0.5) == 0); + ATF_CHECK(fmodl(2.0, 0.5) == 0); + + ATF_CHECK(fabsf(fmodf(1.0, 0.1) - 0.1f) <= 55 * FLT_EPSILON); + ATF_CHECK(fabs(fmod(1.0, 0.1) - 0.1) <= 55 * DBL_EPSILON); + ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fmod); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_infinity.c b/contrib/netbsd-tests/lib/libm/t_infinity.c new file mode 100644 index 0000000..7ac1737 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_infinity.c @@ -0,0 +1,119 @@ +/* $NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $"); + +#include <atf-c.h> +#include <math.h> +#include <float.h> +#include <stdlib.h> + +ATF_TC(infinity_float); +ATF_TC_HEAD(infinity_float, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check FPU generated infinite float values"); +} + +ATF_TC_BODY(infinity_float, tc) +{ + float v; + + v = FLT_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); + + v = -FLT_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); +} + +ATF_TC(infinity_double); +ATF_TC_HEAD(infinity_double, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check FPU generated infinite double values"); +} + +ATF_TC_BODY(infinity_double, tc) +{ + double v; + + v = DBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); + + v = -DBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); +} + +ATF_TC(infinity_long_double); +ATF_TC_HEAD(infinity_long_double, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check FPU generated infinite long double values"); +} + +ATF_TC_BODY(infinity_long_double, tc) +{ + +#ifndef LDBL_MAX + atf_tc_skip("no long double support on this architecture"); + return; +#else + long double v; + + v = LDBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); + + v = -LDBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, infinity_float); + ATF_TP_ADD_TC(tp, infinity_double); + ATF_TP_ADD_TC(tp, infinity_long_double); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_ldexp.c b/contrib/netbsd-tests/lib/libm/t_ldexp.c new file mode 100644 index 0000000..9dd001d --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_ldexp.c @@ -0,0 +1,481 @@ +/* $NetBSD: t_ldexp.c,v 1.13 2014/03/12 21:40:07 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ldexp.c,v 1.13 2014/03/12 21:40:07 martin Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <math.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> + +#define SKIP 9999 +#define FORMAT "%23.23lg" + +static const int exps[] = { 0, 1, -1, 100, -100 }; + +struct ldexp_test { + double x; + int exp1; + int exp2; + const char *result; +}; + +struct ldexp_test ldexp_basic[] = { + { 1.0, 5, SKIP, " 32" }, + { 1.0, 1022, SKIP, "4.4942328371557897693233e+307" }, + { 1.0, 1023, -1, "4.4942328371557897693233e+307" }, + { 1.0, 1023, SKIP, "8.9884656743115795386465e+307" }, + { 1.0, 1022, 1, "8.9884656743115795386465e+307" }, + { 1.0, -1022, 2045, "8.9884656743115795386465e+307" }, + { 1.0, -5, SKIP, " 0.03125" }, + { 1.0, -1021, SKIP, "4.4501477170144027661805e-308" }, + { 1.0, -1022, 1, "4.4501477170144027661805e-308" }, + { 1.0, -1022, SKIP, "2.2250738585072013830902e-308" }, + { 1.0, -1021, -1, "2.2250738585072013830902e-308" }, + { 1.0, 1023, -2045, "2.2250738585072013830902e-308" }, + { 1.0, 1023, -1023, " 1" }, + { 1.0, -1022, 1022, " 1" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_zero[] = { + { 0.0, -1, SKIP, " 0" }, + { 0.0, 0, SKIP, " 0" }, + { 0.0, 1, SKIP, " 0" }, + { 0.0, 1024, SKIP, " 0" }, + { 0.0, 1025, SKIP, " 0" }, + { 0.0, -1023, SKIP, " 0" }, + { 0.0, -1024, SKIP, " 0" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_infinity[] = { + { 1.0, 1024, -1, " inf" }, + { 1.0, 1024, 0, " inf" }, + { 1.0, 1024, 1, " inf" }, + { -1.0, 1024, -1, " -inf" }, + { -1.0, 1024, 0, " -inf" }, + { -1.0, 1024, 1, " -inf" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_overflow[] = { + { 1.0, 1024, SKIP, " inf" }, + { 1.0, 1023, 1, " inf" }, + { 1.0, -1022, 2046, " inf" }, + { 1.0, 1025, SKIP, " inf" }, + { -1.0, 1024, SKIP, " -inf" }, + { -1.0, 1023, 1, " -inf" }, + { -1.0, -1022, 2046, " -inf" }, + { -1.0, 1025, SKIP, " -inf" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_denormal[] = { + { 1.0, -1023, SKIP, "1.1125369292536006915451e-308" }, + { 1.0, -1022, -1, "1.1125369292536006915451e-308" }, + { 1.0, 1023, -2046, "1.1125369292536006915451e-308" }, + { 1.0, -1024, SKIP, "5.5626846462680034577256e-309" }, + { 1.0, -1074, SKIP, "4.9406564584124654417657e-324" }, + { -1.0, -1023, SKIP, "-1.1125369292536006915451e-308" }, + { -1.0, -1022, -1, "-1.1125369292536006915451e-308" }, + { -1.0, 1023, -2046, "-1.1125369292536006915451e-308" }, + { -1.0, -1024, SKIP, "-5.5626846462680034577256e-309" }, + { -1.0, -1074, SKIP, "-4.9406564584124654417657e-324" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_underflow[] = { + { 1.0, -1075, SKIP, " 0" }, + { 1.0, -1074, -1, " 0" }, + { 1.0, 1023, -2098, " 0" }, + { 1.0, -1076, SKIP, " 0" }, + { -1.0, -1075, SKIP, " -0" }, + { -1.0, -1074, -1, " -0" }, + { -1.0, 1023, -2098, " -0" }, + { -1.0, -1076, SKIP, " -0" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_denormal_large[] = { + { 1.0, -1028, 1024, " 0.0625" }, + { 1.0, -1028, 1025, " 0.125" }, + { 1.0, -1028, 1026, " 0.25" }, + { 1.0, -1028, 1027, " 0.5" }, + { 1.0, -1028, 1028, " 1" }, + { 1.0, -1028, 1029, " 2" }, + { 1.0, -1028, 1030, " 4" }, + { 1.0, -1028, 1040, " 4096" }, + { 1.0, -1028, 1050, " 4194304" }, + { 1.0, -1028, 1060, " 4294967296" }, + { 1.0, -1028, 1100, " 4722366482869645213696" }, + { 1.0, -1028, 1200, "5.9863107065073783529623e+51" }, + { 1.0, -1028, 1300, "7.5885503602567541832791e+81" }, + { 1.0, -1028, 1400, "9.6196304190416209014353e+111" }, + { 1.0, -1028, 1500, "1.2194330274671844653834e+142" }, + { 1.0, -1028, 1600, "1.5458150092069033378781e+172" }, + { 1.0, -1028, 1700, "1.9595533242629369747791e+202" }, + { 1.0, -1028, 1800, "2.4840289476811342962384e+232" }, + { 1.0, -1028, 1900, "3.1488807865122869393369e+262" }, + { 1.0, -1028, 2000, "3.9916806190694396233127e+292" }, + { 1.0, -1028, 2046, "2.808895523222368605827e+306" }, + { 1.0, -1028, 2047, "5.6177910464447372116541e+306" }, + { 1.0, -1028, 2048, "1.1235582092889474423308e+307" }, + { 1.0, -1028, 2049, "2.2471164185778948846616e+307" }, + { 1.0, -1028, 2050, "4.4942328371557897693233e+307" }, + { 1.0, -1028, 2051, "8.9884656743115795386465e+307" }, + { 0, 0, 0, NULL } +}; + +static void +run_test(struct ldexp_test *table) +{ + char outbuf[64]; + size_t i; + double v; + + for (i = 0; table->result != NULL; table++, i++) { + + v = ldexp(table->x, table->exp1); + + if (table->exp2 == SKIP) + continue; + + v = ldexp(v, table->exp2); + + (void)snprintf(outbuf, sizeof(outbuf), FORMAT, v); + + ATF_CHECK_STREQ_MSG(table->result, outbuf, + "Entry %zu:\n\tExp: \"%s\"\n\tAct: \"%s\"", + i, table->result, outbuf); + } +} + +/* + * ldexp(3) + */ +ATF_TC(ldexp_exp2); +ATF_TC_HEAD(ldexp_exp2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(x, n) == x * exp2(n)"); +} + +ATF_TC_BODY(ldexp_exp2, tc) +{ + const double n[] = { 1, 2, 3, 10, 50, 100 }; +#if __DBL_MIN_10_EXP__ <= -40 + const double eps = 1.0e-40; +#else + const double eps = __DBL_MIN__*4.0; +#endif + const double x = 12.0; + double y; + size_t i; + + for (i = 0; i < __arraycount(n); i++) { + + y = ldexp(x, n[i]); + + if (fabs(y - (x * exp2(n[i]))) > eps) { + atf_tc_fail_nonfatal("ldexp(%0.01f, %0.01f) " + "!= %0.01f * exp2(%0.01f)", x, n[i], x, n[i]); + } + } +} + +ATF_TC(ldexp_nan); +ATF_TC_HEAD(ldexp_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(NaN) == NaN"); +} + +ATF_TC_BODY(ldexp_nan, tc) +{ + const double x = 0.0L / 0.0L; + double y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexp(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(ldexp_inf_neg); +ATF_TC_HEAD(ldexp_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(-Inf) == -Inf"); +} + +ATF_TC_BODY(ldexp_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexp(x, exps[i]) == x); +} + +ATF_TC(ldexp_inf_pos); +ATF_TC_HEAD(ldexp_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(+Inf) == +Inf"); +} + +ATF_TC_BODY(ldexp_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexp(x, exps[i]) == x); +} + +ATF_TC(ldexp_zero_neg); +ATF_TC_HEAD(ldexp_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(-0.0) == -0.0"); +} + +ATF_TC_BODY(ldexp_zero_neg, tc) +{ + const double x = -0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexp(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(ldexp_zero_pos); +ATF_TC_HEAD(ldexp_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(+0.0) == +0.0"); +} + +ATF_TC_BODY(ldexp_zero_pos, tc) +{ + const double x = 0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexp(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +/* + * ldexpf(3) + */ + +ATF_TC(ldexpf_exp2f); +ATF_TC_HEAD(ldexpf_exp2f, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(x, n) == x * exp2f(n)"); +} + +ATF_TC_BODY(ldexpf_exp2f, tc) +{ + const float n[] = { 1, 2, 3, 10, 50, 100 }; + const float eps = 1.0e-9; + const float x = 12.0; + float y; + size_t i; + + for (i = 0; i < __arraycount(n); i++) { + + y = ldexpf(x, n[i]); + + if (fabsf(y - (x * exp2f(n[i]))) > eps) { + atf_tc_fail_nonfatal("ldexpf(%0.01f, %0.01f) " + "!= %0.01f * exp2f(%0.01f)", x, n[i], x, n[i]); + } + } +} + +ATF_TC(ldexpf_nan); +ATF_TC_HEAD(ldexpf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(NaN) == NaN"); +} + +ATF_TC_BODY(ldexpf_nan, tc) +{ + const float x = 0.0L / 0.0L; + float y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexpf(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(ldexpf_inf_neg); +ATF_TC_HEAD(ldexpf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(-Inf) == -Inf"); +} + +ATF_TC_BODY(ldexpf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexpf(x, exps[i]) == x); +} + +ATF_TC(ldexpf_inf_pos); +ATF_TC_HEAD(ldexpf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(+Inf) == +Inf"); +} + +ATF_TC_BODY(ldexpf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexpf(x, exps[i]) == x); +} + +ATF_TC(ldexpf_zero_neg); +ATF_TC_HEAD(ldexpf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(-0.0) == -0.0"); +} + +ATF_TC_BODY(ldexpf_zero_neg, tc) +{ + const float x = -0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexpf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(ldexpf_zero_pos); +ATF_TC_HEAD(ldexpf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(+0.0) == +0.0"); +} + +ATF_TC_BODY(ldexpf_zero_pos, tc) +{ + const float x = 0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexpf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +#define TEST(name, desc) \ + ATF_TC(name); \ + ATF_TC_HEAD(name, tc) \ + { \ + \ + atf_tc_set_md_var(tc, "descr", \ + "Test ldexp(3) for " ___STRING(desc)); \ + } \ + ATF_TC_BODY(name, tc) \ + { \ + if (strcmp("vax", MACHINE_ARCH) == 0) \ + atf_tc_skip("Test not valid for " MACHINE_ARCH); \ + run_test(name); \ + } + +TEST(ldexp_basic, basics) +TEST(ldexp_zero, zero) +TEST(ldexp_infinity, infinity) +TEST(ldexp_overflow, overflow) +TEST(ldexp_denormal, denormal) +TEST(ldexp_denormal_large, large) +TEST(ldexp_underflow, underflow) + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ldexp_basic); + ATF_TP_ADD_TC(tp, ldexp_zero); + ATF_TP_ADD_TC(tp, ldexp_infinity); + ATF_TP_ADD_TC(tp, ldexp_overflow); + ATF_TP_ADD_TC(tp, ldexp_denormal); + ATF_TP_ADD_TC(tp, ldexp_underflow); + ATF_TP_ADD_TC(tp, ldexp_denormal_large); + + ATF_TP_ADD_TC(tp, ldexp_exp2); + ATF_TP_ADD_TC(tp, ldexp_nan); + ATF_TP_ADD_TC(tp, ldexp_inf_neg); + ATF_TP_ADD_TC(tp, ldexp_inf_pos); + ATF_TP_ADD_TC(tp, ldexp_zero_neg); + ATF_TP_ADD_TC(tp, ldexp_zero_pos); + + ATF_TP_ADD_TC(tp, ldexpf_exp2f); + ATF_TP_ADD_TC(tp, ldexpf_nan); + ATF_TP_ADD_TC(tp, ldexpf_inf_neg); + ATF_TP_ADD_TC(tp, ldexpf_inf_pos); + ATF_TP_ADD_TC(tp, ldexpf_zero_neg); + ATF_TP_ADD_TC(tp, ldexpf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_libm.h b/contrib/netbsd-tests/lib/libm/t_libm.h new file mode 100644 index 0000000..34e3cb2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_libm.h @@ -0,0 +1,62 @@ +/* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */ + +/* + * Check result of fn(arg) is correct within the bounds. + * Should be ok to do the checks using 'double' for 'float' functions. + * On i386 float and double values are returned on the x87 stack and might + * be out of range for the function - so save and print as 'long double'. + * (otherwise you can get 'inf != inf' reported!) + */ +#define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \ + long double epsilon = epsilon_; \ + long double expect = expect_; \ + long double r = fn(arg); \ + long double e = fabsl(r - expect); \ + if (r != expect && e > epsilon) \ + atf_tc_fail_nonfatal( \ + "subtest %u: " #fn "(%g) is %Lg (%.14La) " \ + "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \ + subtest, arg, r, r, expect, expect, e, e, epsilon); \ + } while (0) + +/* Check that the result of fn(arg) is NaN */ +#ifndef __vax__ +#define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \ + double r = fn(arg); \ + if (!isnan(r)) \ + atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \ + subtest, arg, r); \ + } while (0) +#else +/* vax doesn't support NaN */ +#define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg) +#endif + +/* Check that the result of fn(arg) is +0.0 */ +#define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \ + double r = fn(arg); \ + if (fabs(r) > 0.0 || signbit(r) != 0) \ + atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \ + subtest, arg, r); \ + } while (0) + +/* Check that the result of fn(arg) is -0.0 */ +#define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \ + double r = fn(arg); \ + if (fabs(r) > 0.0 || signbit(r) == 0) \ + atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \ + subtest, arg, r); \ + } while (0) + +/* Some useful constants (for test vectors) */ +#ifndef __vax__ /* no NAN nor +/- INF on vax */ +#define T_LIBM_NAN (0.0 / 0.0) +#define T_LIBM_PLUS_INF (+1.0 / 0.0) +#define T_LIBM_MINUS_INF (-1.0 / 0.0) +#endif + +/* One line definition of a simple test */ +#define ATF_LIBM_TEST(name, description) \ +ATF_TC(name); \ +ATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \ +ATF_TC_BODY(name, tc) diff --git a/contrib/netbsd-tests/lib/libm/t_log.c b/contrib/netbsd-tests/lib/libm/t_log.c new file mode 100644 index 0000000..de5a1c6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_log.c @@ -0,0 +1,885 @@ +/* $NetBSD: t_log.c,v 1.11 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_log.c,v 1.11 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* + * log10(3) + */ +ATF_TC(log10_base); +ATF_TC_HEAD(log10_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(10) == 1"); +} + +ATF_TC_BODY(log10_base, tc) +{ + ATF_CHECK(log10(10.0) == 1.0); +} + +ATF_TC(log10_nan); +ATF_TC_HEAD(log10_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(NaN) == NaN"); +} + +ATF_TC_BODY(log10_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log10(x)) != 0); +} + +ATF_TC(log10_inf_neg); +ATF_TC_HEAD(log10_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(-Inf) == NaN"); +} + +ATF_TC_BODY(log10_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log10(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log10_inf_pos); +ATF_TC_HEAD(log10_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(+Inf) == +Inf"); +} + +ATF_TC_BODY(log10_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log10(x) == x); +} + +ATF_TC(log10_one_pos); +ATF_TC_HEAD(log10_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(1.0) == +0.0"); +} + +ATF_TC_BODY(log10_one_pos, tc) +{ + const double x = log10(1.0); + const double y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log10_zero_neg); +ATF_TC_HEAD(log10_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(-0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log10_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log10(x) == -HUGE_VAL); +} + +ATF_TC(log10_zero_pos); +ATF_TC_HEAD(log10_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(+0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log10_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log10(x) == -HUGE_VAL); +} + +/* + * log10f(3) + */ +ATF_TC(log10f_base); +ATF_TC_HEAD(log10f_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(10) == 1"); +} + +ATF_TC_BODY(log10f_base, tc) +{ + ATF_CHECK(log10f(10.0) == 1.0); +} + +ATF_TC(log10f_nan); +ATF_TC_HEAD(log10f_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(NaN) == NaN"); +} + +ATF_TC_BODY(log10f_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log10f(x)) != 0); +} + +ATF_TC(log10f_inf_neg); +ATF_TC_HEAD(log10f_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(-Inf) == NaN"); +} + +ATF_TC_BODY(log10f_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = log10f(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log10f_inf_pos); +ATF_TC_HEAD(log10f_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(+Inf) == +Inf"); +} + +ATF_TC_BODY(log10f_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + +#if defined(__alpha__) + atf_tc_expect_fail("PR port-alpha/46301"); +#endif + + ATF_CHECK(log10f(x) == x); +} + +ATF_TC(log10f_one_pos); +ATF_TC_HEAD(log10f_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(1.0) == +0.0"); +} + +ATF_TC_BODY(log10f_one_pos, tc) +{ + const float x = log10f(1.0); + const float y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log10f_zero_neg); +ATF_TC_HEAD(log10f_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(-0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log10f_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(log10f(x) == -HUGE_VALF); +} + +ATF_TC(log10f_zero_pos); +ATF_TC_HEAD(log10f_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(+0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log10f_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(log10f(x) == -HUGE_VALF); +} + +/* + * log1p(3) + */ +ATF_TC(log1p_nan); +ATF_TC_HEAD(log1p_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(NaN) == NaN"); +} + +ATF_TC_BODY(log1p_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log1p(x)) != 0); +} + +ATF_TC(log1p_inf_neg); +ATF_TC_HEAD(log1p_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(-Inf) == NaN"); +} + +ATF_TC_BODY(log1p_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log1p(x); + + if (isnan(y) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1p(-Inf) != NaN"); + } +} + +ATF_TC(log1p_inf_pos); +ATF_TC_HEAD(log1p_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(+Inf) == +Inf"); +} + +ATF_TC_BODY(log1p_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log1p(x) == x); +} + +ATF_TC(log1p_one_neg); +ATF_TC_HEAD(log1p_one_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(-1.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log1p_one_neg, tc) +{ + const double x = log1p(-1.0); + + if (x != -HUGE_VAL) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1p(-1.0) != -HUGE_VAL"); + } +} + +ATF_TC(log1p_zero_neg); +ATF_TC_HEAD(log1p_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(-0.0) == -0.0"); +} + +ATF_TC_BODY(log1p_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log1p(x) == x); +} + +ATF_TC(log1p_zero_pos); +ATF_TC_HEAD(log1p_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(+0.0) == +0.0"); +} + +ATF_TC_BODY(log1p_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log1p(x) == x); +} + +/* + * log1pf(3) + */ +ATF_TC(log1pf_nan); +ATF_TC_HEAD(log1pf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(NaN) == NaN"); +} + +ATF_TC_BODY(log1pf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log1pf(x)) != 0); +} + +ATF_TC(log1pf_inf_neg); +ATF_TC_HEAD(log1pf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(-Inf) == NaN"); +} + +ATF_TC_BODY(log1pf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = log1pf(x); + + if (isnan(y) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1pf(-Inf) != NaN"); + } +} + +ATF_TC(log1pf_inf_pos); +ATF_TC_HEAD(log1pf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(+Inf) == +Inf"); +} + +ATF_TC_BODY(log1pf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + ATF_CHECK(log1pf(x) == x); +} + +ATF_TC(log1pf_one_neg); +ATF_TC_HEAD(log1pf_one_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(-1.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log1pf_one_neg, tc) +{ + const float x = log1pf(-1.0); + + if (x != -HUGE_VALF) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1pf(-1.0) != -HUGE_VALF"); + } +} + +ATF_TC(log1pf_zero_neg); +ATF_TC_HEAD(log1pf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(-0.0) == -0.0"); +} + +ATF_TC_BODY(log1pf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(log1pf(x) == x); +} + +ATF_TC(log1pf_zero_pos); +ATF_TC_HEAD(log1pf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(+0.0) == +0.0"); +} + +ATF_TC_BODY(log1pf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(log1pf(x) == x); +} + +/* + * log2(3) + */ +ATF_TC(log2_base); +ATF_TC_HEAD(log2_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(2) == 1"); +} + +ATF_TC_BODY(log2_base, tc) +{ + ATF_CHECK(log2(2.0) == 1.0); +} + +ATF_TC(log2_nan); +ATF_TC_HEAD(log2_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(NaN) == NaN"); +} + +ATF_TC_BODY(log2_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log2(x)) != 0); +} + +ATF_TC(log2_inf_neg); +ATF_TC_HEAD(log2_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(-Inf) == NaN"); +} + +ATF_TC_BODY(log2_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log2(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log2_inf_pos); +ATF_TC_HEAD(log2_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(+Inf) == +Inf"); +} + +ATF_TC_BODY(log2_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log2(x) == x); +} + +ATF_TC(log2_one_pos); +ATF_TC_HEAD(log2_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(1.0) == +0.0"); +} + +ATF_TC_BODY(log2_one_pos, tc) +{ + const double x = log2(1.0); + const double y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log2_zero_neg); +ATF_TC_HEAD(log2_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(-0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log2_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log2(x) == -HUGE_VAL); +} + +ATF_TC(log2_zero_pos); +ATF_TC_HEAD(log2_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(+0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log2_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log2(x) == -HUGE_VAL); +} + +/* + * log2f(3) + */ +ATF_TC(log2f_base); +ATF_TC_HEAD(log2f_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(2) == 1"); +} + +ATF_TC_BODY(log2f_base, tc) +{ + ATF_CHECK(log2f(2.0) == 1.0); +} + +ATF_TC(log2f_nan); +ATF_TC_HEAD(log2f_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(NaN) == NaN"); +} + +ATF_TC_BODY(log2f_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log2f(x)) != 0); +} + +ATF_TC(log2f_inf_neg); +ATF_TC_HEAD(log2f_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(-Inf) == NaN"); +} + +ATF_TC_BODY(log2f_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = log2f(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log2f_inf_pos); +ATF_TC_HEAD(log2f_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(+Inf) == +Inf"); +} + +ATF_TC_BODY(log2f_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + +#if defined(__alpha__) + atf_tc_expect_fail("PR port-alpha/46301"); +#endif + + ATF_CHECK(log2f(x) == x); +} + +ATF_TC(log2f_one_pos); +ATF_TC_HEAD(log2f_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(1.0) == +0.0"); +} + +ATF_TC_BODY(log2f_one_pos, tc) +{ + const float x = log2f(1.0); + const float y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log2f_zero_neg); +ATF_TC_HEAD(log2f_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(-0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log2f_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(log2f(x) == -HUGE_VALF); +} + +ATF_TC(log2f_zero_pos); +ATF_TC_HEAD(log2f_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(+0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log2f_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(log2f(x) == -HUGE_VALF); +} + +/* + * log(3) + */ +ATF_TC(log_base); +ATF_TC_HEAD(log_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(e) == 1"); +} + +ATF_TC_BODY(log_base, tc) +{ + const double eps = 1.0e-38; + + if (fabs(log(M_E) - 1.0) > eps) + atf_tc_fail_nonfatal("log(e) != 1"); +} + +ATF_TC(log_nan); +ATF_TC_HEAD(log_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(NaN) == NaN"); +} + +ATF_TC_BODY(log_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log(x)) != 0); +} + +ATF_TC(log_inf_neg); +ATF_TC_HEAD(log_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(-Inf) == NaN"); +} + +ATF_TC_BODY(log_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log_inf_pos); +ATF_TC_HEAD(log_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(+Inf) == +Inf"); +} + +ATF_TC_BODY(log_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log(x) == x); +} + +ATF_TC(log_one_pos); +ATF_TC_HEAD(log_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(1.0) == +0.0"); +} + +ATF_TC_BODY(log_one_pos, tc) +{ + const double x = log(1.0); + const double y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log_zero_neg); +ATF_TC_HEAD(log_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(-0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log(x) == -HUGE_VAL); +} + +ATF_TC(log_zero_pos); +ATF_TC_HEAD(log_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(+0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log(x) == -HUGE_VAL); +} + +/* + * logf(3) + */ +ATF_TC(logf_base); +ATF_TC_HEAD(logf_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(e) == 1"); +} + +ATF_TC_BODY(logf_base, tc) +{ + const float eps = 1.0e-7; + + if (fabsf(logf(M_E) - 1.0f) > eps) + atf_tc_fail_nonfatal("logf(e) != 1"); +} + +ATF_TC(logf_nan); +ATF_TC_HEAD(logf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(NaN) == NaN"); +} + +ATF_TC_BODY(logf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(logf(x)) != 0); +} + +ATF_TC(logf_inf_neg); +ATF_TC_HEAD(logf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(-Inf) == NaN"); +} + +ATF_TC_BODY(logf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = logf(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(logf_inf_pos); +ATF_TC_HEAD(logf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(+Inf) == +Inf"); +} + +ATF_TC_BODY(logf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + +#if defined(__alpha__) + atf_tc_expect_fail("PR port-alpha/46301"); +#endif + + ATF_CHECK(logf(x) == x); +} + +ATF_TC(logf_one_pos); +ATF_TC_HEAD(logf_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(1.0) == +0.0"); +} + +ATF_TC_BODY(logf_one_pos, tc) +{ + const float x = logf(1.0); + const float y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(logf_zero_neg); +ATF_TC_HEAD(logf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(-0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(logf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(logf(x) == -HUGE_VALF); +} + +ATF_TC(logf_zero_pos); +ATF_TC_HEAD(logf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(+0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(logf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(logf(x) == -HUGE_VALF); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, log10_base); + ATF_TP_ADD_TC(tp, log10_nan); + ATF_TP_ADD_TC(tp, log10_inf_neg); + ATF_TP_ADD_TC(tp, log10_inf_pos); + ATF_TP_ADD_TC(tp, log10_one_pos); + ATF_TP_ADD_TC(tp, log10_zero_neg); + ATF_TP_ADD_TC(tp, log10_zero_pos); + + ATF_TP_ADD_TC(tp, log10f_base); + ATF_TP_ADD_TC(tp, log10f_nan); + ATF_TP_ADD_TC(tp, log10f_inf_neg); + ATF_TP_ADD_TC(tp, log10f_inf_pos); + ATF_TP_ADD_TC(tp, log10f_one_pos); + ATF_TP_ADD_TC(tp, log10f_zero_neg); + ATF_TP_ADD_TC(tp, log10f_zero_pos); + + ATF_TP_ADD_TC(tp, log1p_nan); + ATF_TP_ADD_TC(tp, log1p_inf_neg); + ATF_TP_ADD_TC(tp, log1p_inf_pos); + ATF_TP_ADD_TC(tp, log1p_one_neg); + ATF_TP_ADD_TC(tp, log1p_zero_neg); + ATF_TP_ADD_TC(tp, log1p_zero_pos); + + ATF_TP_ADD_TC(tp, log1pf_nan); + ATF_TP_ADD_TC(tp, log1pf_inf_neg); + ATF_TP_ADD_TC(tp, log1pf_inf_pos); + ATF_TP_ADD_TC(tp, log1pf_one_neg); + ATF_TP_ADD_TC(tp, log1pf_zero_neg); + ATF_TP_ADD_TC(tp, log1pf_zero_pos); + + ATF_TP_ADD_TC(tp, log2_base); + ATF_TP_ADD_TC(tp, log2_nan); + ATF_TP_ADD_TC(tp, log2_inf_neg); + ATF_TP_ADD_TC(tp, log2_inf_pos); + ATF_TP_ADD_TC(tp, log2_one_pos); + ATF_TP_ADD_TC(tp, log2_zero_neg); + ATF_TP_ADD_TC(tp, log2_zero_pos); + + ATF_TP_ADD_TC(tp, log2f_base); + ATF_TP_ADD_TC(tp, log2f_nan); + ATF_TP_ADD_TC(tp, log2f_inf_neg); + ATF_TP_ADD_TC(tp, log2f_inf_pos); + ATF_TP_ADD_TC(tp, log2f_one_pos); + ATF_TP_ADD_TC(tp, log2f_zero_neg); + ATF_TP_ADD_TC(tp, log2f_zero_pos); + + ATF_TP_ADD_TC(tp, log_base); + ATF_TP_ADD_TC(tp, log_nan); + ATF_TP_ADD_TC(tp, log_inf_neg); + ATF_TP_ADD_TC(tp, log_inf_pos); + ATF_TP_ADD_TC(tp, log_one_pos); + ATF_TP_ADD_TC(tp, log_zero_neg); + ATF_TP_ADD_TC(tp, log_zero_pos); + + ATF_TP_ADD_TC(tp, logf_base); + ATF_TP_ADD_TC(tp, logf_nan); + ATF_TP_ADD_TC(tp, logf_inf_neg); + ATF_TP_ADD_TC(tp, logf_inf_pos); + ATF_TP_ADD_TC(tp, logf_one_pos); + ATF_TP_ADD_TC(tp, logf_zero_neg); + ATF_TP_ADD_TC(tp, logf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_modf.c b/contrib/netbsd-tests/lib/libm/t_modf.c new file mode 100644 index 0000000..a856b15 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_modf.c @@ -0,0 +1,68 @@ +/* $NetBSD: t_modf.c,v 1.1 2014/06/16 12:54:43 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <float.h> +#include <math.h> + +ATF_TC(modf); +ATF_TC_HEAD(modf, tc) +{ + atf_tc_set_md_var(tc, "descr","Check modf family"); +} + +ATF_TC_BODY(modf, tc) +{ + float basef; + double base; + long double basel; + ATF_CHECK(modff(1.0, &basef) == 0.0); + ATF_CHECK(basef == 1.0); + ATF_CHECK(modf(1.0, &base) == 0.0); + ATF_CHECK(base == 1.0); + ATF_CHECK(modfl(1.0, &basel) == 0.0); + ATF_CHECK(basel == 1.0); + + ATF_CHECK(modff(-1 - FLT_EPSILON, &basef) == -FLT_EPSILON); + ATF_CHECK(basef == -1.0); + ATF_CHECK(modf(-1 - DBL_EPSILON, &base) == -DBL_EPSILON); + ATF_CHECK(base == -1.0); + ATF_CHECK(modfl(-1 - LDBL_EPSILON, &basel) == -LDBL_EPSILON); + ATF_CHECK(basel == -1.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, modf); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_pow.c b/contrib/netbsd-tests/lib/libm/t_pow.c new file mode 100644 index 0000000..62b7235 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_pow.c @@ -0,0 +1,669 @@ +/* $NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <math.h> + +/* + * pow(3) + */ +ATF_TC(pow_nan_x); +ATF_TC_HEAD(pow_nan_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN"); +} + +ATF_TC_BODY(pow_nan_x, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(pow(x, 2.0)) != 0); +} + +ATF_TC(pow_nan_y); +ATF_TC_HEAD(pow_nan_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN"); +} + +ATF_TC_BODY(pow_nan_y, tc) +{ + const double y = 0.0L / 0.0L; + + ATF_CHECK(isnan(pow(2.0, y)) != 0); +} + +ATF_TC(pow_inf_neg_x); +ATF_TC_HEAD(pow_inf_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0"); +} + +ATF_TC_BODY(pow_inf_neg_x, tc) +{ + const double x = -1.0L / 0.0L; + double z; + + /* + * If y is odd, y > 0, and x is -Inf, -Inf is returned. + * If y is even, y > 0, and x is -Inf, +Inf is returned. + */ + z = pow(x, 3.0); + + if (isinf(z) == 0 || signbit(z) == 0) + atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf"); + + z = pow(x, 4.0); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf"); + + /* + * If y is odd, y < 0, and x is -Inf, -0.0 is returned. + * If y is even, y < 0, and x is -Inf, +0.0 is returned. + */ + z = pow(x, -3.0); + + if (fabs(z) > 0.0 || signbit(z) == 0) + atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0"); + + z = pow(x, -4.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0"); +} + +ATF_TC(pow_inf_neg_y); +ATF_TC_HEAD(pow_inf_neg_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(pow_inf_neg_y, tc) +{ + const double y = -1.0L / 0.0L; + double z; + + /* + * If |x| < 1 and y is -Inf, +Inf is returned. + * If |x| > 1 and y is -Inf, +0.0 is returned. + */ + z = pow(0.1, y); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf"); + + z = pow(1.1, y); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0"); +} + +ATF_TC(pow_inf_pos_x); +ATF_TC_HEAD(pow_inf_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0"); +} + +ATF_TC_BODY(pow_inf_pos_x, tc) +{ + const double x = 1.0L / 0.0L; + double z; + + /* + * For y < 0, if x is +Inf, +0.0 is returned. + * For y > 0, if x is +Inf, +Inf is returned. + */ + z = pow(x, -2.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0"); + + z = pow(x, 2.0); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf"); +} + +ATF_TC(pow_inf_pos_y); +ATF_TC_HEAD(pow_inf_pos_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(pow_inf_pos_y, tc) +{ + const double y = 1.0L / 0.0L; + double z; + + /* + * If |x| < 1 and y is +Inf, +0.0 is returned. + * If |x| > 1 and y is +Inf, +Inf is returned. + */ + z = pow(0.1, y); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0"); + + z = pow(1.1, y); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf"); +} + +ATF_TC(pow_one_neg_x); +ATF_TC_HEAD(pow_one_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0"); +} + +ATF_TC_BODY(pow_one_neg_x, tc) +{ + const double infp = 1.0L / 0.0L; + const double infn = -1.0L / 0.0L; + + /* + * If x is -1.0, and y is +-Inf, 1.0 shall be returned. + */ + ATF_REQUIRE(isinf(infp) != 0); + ATF_REQUIRE(isinf(infn) != 0); + + if (pow(-1.0, infp) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0"); + } + + if (pow(-1.0, infn) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0"); + } +} + +ATF_TC(pow_one_pos_x); +ATF_TC_HEAD(pow_one_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0"); +} + +ATF_TC_BODY(pow_one_pos_x, tc) +{ + const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 }; + const double z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of y (including NaN), + * if x is 1.0, 1.0 shall be returned. + */ + if (pow(1.0, z) != 1.0) + atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0"); + + for (i = 0; i < __arraycount(y); i++) { + + if (pow(1.0, y[i]) != 1.0) + atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]); + } +} + +ATF_TC(pow_zero_x); +ATF_TC_HEAD(pow_zero_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE"); +} + +ATF_TC_BODY(pow_zero_x, tc) +{ + double z; + + /* + * If x is +0.0 or -0.0, y > 0, and y + * is an odd integer, x is returned. + */ + z = pow(+0.0, 3.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0"); + + z = pow(-0.0, 3.0); + + if (fabs(z) > 0.0 || signbit(z) == 0) + atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0"); + + /* + * If y > 0 and not an odd integer, + * if x is +0.0 or -0.0, +0.0 is returned. + */ + z = pow(+0.0, 4.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0"); + + z = pow(-0.0, 4.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0"); + + /* + * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL, + * +-HUGE_VALF, or +-HUGE_VALL shall be returned. + */ + z = pow(+0.0, -4.0); + + if (z != HUGE_VAL) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL"); + } + + z = pow(-0.0, -4.0); + + if (z != HUGE_VAL) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL"); + } + + z = pow(+0.0, -5.0); + + if (z != HUGE_VAL) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL"); + } + + z = pow(-0.0, -5.0); + + if (z != -HUGE_VAL) + atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL"); +} + +ATF_TC(pow_zero_y); +ATF_TC_HEAD(pow_zero_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0"); +} + +ATF_TC_BODY(pow_zero_y, tc) +{ + const double x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 }; + const double z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of x (including NaN), + * if y is +0.0 or -0.0, 1.0 is returned. + */ + if (pow(z, +0.0) != 1.0) + atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0"); + + if (pow(z, -0.0) != 1.0) + atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0"); + + for (i = 0; i < __arraycount(x); i++) { + + if (pow(x[i], +0.0) != 1.0) + atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]); + + if (pow(x[i], -0.0) != 1.0) + atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]); + } +} + +/* + * powf(3) + */ +ATF_TC(powf_nan_x); +ATF_TC_HEAD(powf_nan_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN"); +} + +ATF_TC_BODY(powf_nan_x, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnanf(powf(x, 2.0)) != 0); +} + +ATF_TC(powf_nan_y); +ATF_TC_HEAD(powf_nan_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN"); +} + +ATF_TC_BODY(powf_nan_y, tc) +{ + const float y = 0.0L / 0.0L; + + ATF_CHECK(isnanf(powf(2.0, y)) != 0); +} + +ATF_TC(powf_inf_neg_x); +ATF_TC_HEAD(powf_inf_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0"); +} + +ATF_TC_BODY(powf_inf_neg_x, tc) +{ + const float x = -1.0L / 0.0L; + float z; + + /* + * If y is odd, y > 0, and x is -Inf, -Inf is returned. + * If y is even, y > 0, and x is -Inf, +Inf is returned. + */ + z = powf(x, 3.0); + + if (isinff(z) == 0 || signbit(z) == 0) + atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf"); + + z = powf(x, 4.0); + + if (isinff(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf"); + + /* + * If y is odd, y < 0, and x is -Inf, -0.0 is returned. + * If y is even, y < 0, and x is -Inf, +0.0 is returned. + */ + z = powf(x, -3.0); + + if (fabsf(z) > 0.0 || signbit(z) == 0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0"); + } + + z = powf(x, -4.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0"); +} + +ATF_TC(powf_inf_neg_y); +ATF_TC_HEAD(powf_inf_neg_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(powf_inf_neg_y, tc) +{ + const float y = -1.0L / 0.0L; + float z; + + /* + * If |x| < 1 and y is -Inf, +Inf is returned. + * If |x| > 1 and y is -Inf, +0.0 is returned. + */ + z = powf(0.1, y); + + if (isinff(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf"); + + z = powf(1.1, y); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0"); +} + +ATF_TC(powf_inf_pos_x); +ATF_TC_HEAD(powf_inf_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0"); +} + +ATF_TC_BODY(powf_inf_pos_x, tc) +{ + const float x = 1.0L / 0.0L; + float z; + + /* + * For y < 0, if x is +Inf, +0.0 is returned. + * For y > 0, if x is +Inf, +Inf is returned. + */ + z = powf(x, -2.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0"); + + z = powf(x, 2.0); + + if (isinff(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf"); +} + +ATF_TC(powf_inf_pos_y); +ATF_TC_HEAD(powf_inf_pos_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(powf_inf_pos_y, tc) +{ + const float y = 1.0L / 0.0L; + float z; + + /* + * If |x| < 1 and y is +Inf, +0.0 is returned. + * If |x| > 1 and y is +Inf, +Inf is returned. + */ + z = powf(0.1, y); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0"); + + z = powf(1.1, y); + + if (isinff(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf"); +} + +ATF_TC(powf_one_neg_x); +ATF_TC_HEAD(powf_one_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0"); +} + +ATF_TC_BODY(powf_one_neg_x, tc) +{ + const float infp = 1.0L / 0.0L; + const float infn = -1.0L / 0.0L; + + /* + * If x is -1.0, and y is +-Inf, 1.0 shall be returned. + */ + ATF_REQUIRE(isinff(infp) != 0); + ATF_REQUIRE(isinff(infn) != 0); + + if (powf(-1.0, infp) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0"); + } + + if (powf(-1.0, infn) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0"); + } +} + +ATF_TC(powf_one_pos_x); +ATF_TC_HEAD(powf_one_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0"); +} + +ATF_TC_BODY(powf_one_pos_x, tc) +{ + const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 }; + const float z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of y (including NaN), + * if x is 1.0, 1.0 shall be returned. + */ + if (powf(1.0, z) != 1.0) + atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0"); + + for (i = 0; i < __arraycount(y); i++) { + + if (powf(1.0, y[i]) != 1.0) + atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]); + } +} + +ATF_TC(powf_zero_x); +ATF_TC_HEAD(powf_zero_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE"); +} + +ATF_TC_BODY(powf_zero_x, tc) +{ + float z; + + /* + * If x is +0.0 or -0.0, y > 0, and y + * is an odd integer, x is returned. + */ + z = powf(+0.0, 3.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0"); + + z = powf(-0.0, 3.0); + + if (fabsf(z) > 0.0 || signbit(z) == 0) + atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0"); + + /* + * If y > 0 and not an odd integer, + * if x is +0.0 or -0.0, +0.0 is returned. + */ + z = powf(+0.0, 4.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0"); + + z = powf(-0.0, 4.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0"); + + /* + * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL, + * +-HUGE_VALF, or +-HUGE_VALL shall be returned. + */ + z = powf(+0.0, -4.0); + + if (z != HUGE_VALF) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF"); + } + + z = powf(-0.0, -4.0); + + if (z != HUGE_VALF) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF"); + } + + z = powf(+0.0, -5.0); + + if (z != HUGE_VALF) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF"); + } + + z = powf(-0.0, -5.0); + + if (z != -HUGE_VALF) + atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF"); +} + +ATF_TC(powf_zero_y); +ATF_TC_HEAD(powf_zero_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0"); +} + +ATF_TC_BODY(powf_zero_y, tc) +{ + const float x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 }; + const float z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of x (including NaN), + * if y is +0.0 or -0.0, 1.0 is returned. + */ + if (powf(z, +0.0) != 1.0) + atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0"); + + if (powf(z, -0.0) != 1.0) + atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0"); + + for (i = 0; i < __arraycount(x); i++) { + + if (powf(x[i], +0.0) != 1.0) + atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]); + + if (powf(x[i], -0.0) != 1.0) + atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pow_nan_x); + ATF_TP_ADD_TC(tp, pow_nan_y); + ATF_TP_ADD_TC(tp, pow_inf_neg_x); + ATF_TP_ADD_TC(tp, pow_inf_neg_y); + ATF_TP_ADD_TC(tp, pow_inf_pos_x); + ATF_TP_ADD_TC(tp, pow_inf_pos_y); + ATF_TP_ADD_TC(tp, pow_one_neg_x); + ATF_TP_ADD_TC(tp, pow_one_pos_x); + ATF_TP_ADD_TC(tp, pow_zero_x); + ATF_TP_ADD_TC(tp, pow_zero_y); + + ATF_TP_ADD_TC(tp, powf_nan_x); + ATF_TP_ADD_TC(tp, powf_nan_y); + ATF_TP_ADD_TC(tp, powf_inf_neg_x); + ATF_TP_ADD_TC(tp, powf_inf_neg_y); + ATF_TP_ADD_TC(tp, powf_inf_pos_x); + ATF_TP_ADD_TC(tp, powf_inf_pos_y); + ATF_TP_ADD_TC(tp, powf_one_neg_x); + ATF_TP_ADD_TC(tp, powf_one_pos_x); + ATF_TP_ADD_TC(tp, powf_zero_x); + ATF_TP_ADD_TC(tp, powf_zero_y); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_precision.c b/contrib/netbsd-tests/lib/libm/t_precision.c new file mode 100644 index 0000000..390be9d --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_precision.c @@ -0,0 +1,76 @@ +/* $NetBSD: t_precision.c,v 1.1 2013/11/11 11:10:45 joerg Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_precision.c,v 1.1 2013/11/11 11:10:45 joerg Exp $"); + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <float.h> +#include <stdlib.h> + +ATF_TC(t_precision); + +ATF_TC_HEAD(t_precision, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Basic precision test for double and long double"); +} + +volatile double x = 1; +volatile long double y = 1; + +ATF_TC_BODY(t_precision, tc) +{ + x += DBL_EPSILON; + ATF_CHECK(x != 1.0); + x -= 1; + ATF_CHECK(x == DBL_EPSILON); + + x = 2; + x += DBL_EPSILON; + ATF_CHECK(x == 2.0); + + y += LDBL_EPSILON; + ATF_CHECK(y != 1.0L); + y -= 1; + ATF_CHECK(y == LDBL_EPSILON); + y = 2; + y += LDBL_EPSILON; + ATF_CHECK(y == 2.0L); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_precision); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_round.c b/contrib/netbsd-tests/lib/libm/t_round.c new file mode 100644 index 0000000..f47e1a0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_round.c @@ -0,0 +1,85 @@ +/* $NetBSD: t_round.c,v 1.4 2013/11/11 23:57:34 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <float.h> +#include <math.h> + +/* + * This tests for a bug in the initial implementation where + * precision was lost in an internal substraction, leading to + * rounding into the wrong direction. + */ + +/* 0.5 - EPSILON */ +#define VAL 0x0.7ffffffffffffcp0 +#define VALF 0x0.7fffff8p0 +#define VALL (0.5 - LDBL_EPSILON) + +#ifdef __vax__ +#define SMALL_NUM 1.0e-38 +#else +#define SMALL_NUM 1.0e-40 +#endif + +ATF_TC(round_dir); +ATF_TC_HEAD(round_dir, tc) +{ + atf_tc_set_md_var(tc, "descr","Check for rounding in wrong direction"); +} + +ATF_TC_BODY(round_dir, tc) +{ + double a = VAL, b, c; + float af = VALF, bf, cf; + long double al = VALL, bl, cl; + + b = round(a); + bf = roundf(af); + bl = roundl(al); + + ATF_CHECK(fabs(b) < SMALL_NUM); + ATF_CHECK(fabsf(bf) < SMALL_NUM); + ATF_CHECK(fabsl(bl) < SMALL_NUM); + + c = round(-a); + cf = roundf(-af); + cl = roundl(-al); + + ATF_CHECK(fabs(c) < SMALL_NUM); + ATF_CHECK(fabsf(cf) < SMALL_NUM); + ATF_CHECK(fabsl(cl) < SMALL_NUM); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, round_dir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_scalbn.c b/contrib/netbsd-tests/lib/libm/t_scalbn.c new file mode 100644 index 0000000..586c2c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_scalbn.c @@ -0,0 +1,523 @@ +/* $NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $"); + +#include <math.h> +#include <limits.h> +#include <float.h> +#include <errno.h> + +#include <atf-c.h> + +static const int exps[] = { 0, 1, -1, 100, -100 }; + +/* tests here do not require specific precision, so we just use double */ +struct testcase { + int exp; + double inval; + double result; + int error; +}; +struct testcase test_vals[] = { + { 0, 1.00085, 1.00085, 0 }, + { 0, 0.99755, 0.99755, 0 }, + { 0, -1.00085, -1.00085, 0 }, + { 0, -0.99755, -0.99755, 0 }, + { 1, 1.00085, 2.0* 1.00085, 0 }, + { 1, 0.99755, 2.0* 0.99755, 0 }, + { 1, -1.00085, 2.0* -1.00085, 0 }, + { 1, -0.99755, 2.0* -0.99755, 0 }, + + /* + * We could add more corner test cases here, but we would have to + * add some ifdefs for the exact format and use a reliable + * generator program - bail for now and only do trivial stuff above. + */ +}; + +/* + * scalbn(3) + */ +ATF_TC(scalbn_val); +ATF_TC_HEAD(scalbn_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn() for a few values"); +} + +ATF_TC_BODY(scalbn_val, tc) +{ + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + double rv; + + for (i = 0; i < tcnt; i++) { + rv = scalbn(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*DBL_EPSILON, + "test %zu: return value %g instead of %g (difference %g)", + i, rv, tests[i].result, tests[i].result-rv); + } +} + +ATF_TC(scalbn_nan); +ATF_TC_HEAD(scalbn_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN"); +} + +ATF_TC_BODY(scalbn_nan, tc) +{ + const double x = 0.0L / 0.0L; + double y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(scalbn_inf_neg); +ATF_TC_HEAD(scalbn_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(-Inf, n) == -Inf"); +} + +ATF_TC_BODY(scalbn_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbn(x, exps[i]) == x); +} + +ATF_TC(scalbn_inf_pos); +ATF_TC_HEAD(scalbn_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(+Inf, n) == +Inf"); +} + +ATF_TC_BODY(scalbn_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbn(x, exps[i]) == x); +} + +ATF_TC(scalbn_ldexp); +ATF_TC_HEAD(scalbn_ldexp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)"); +} + +ATF_TC_BODY(scalbn_ldexp, tc) +{ +#if FLT_RADIX == 2 + const double x = 2.91288191221812821; + double y; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK_MSG(y == ldexp(x, exps[i]), "test %zu: exponent=%d, " + "y=%g, expected %g (diff: %g)", i, exps[i], y, + ldexp(x, exps[i]), y - ldexp(x, exps[i])); + } +#endif +} + +ATF_TC(scalbn_zero_neg); +ATF_TC_HEAD(scalbn_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0"); +} + +ATF_TC_BODY(scalbn_zero_neg, tc) +{ + const double x = -0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(scalbn_zero_pos); +ATF_TC_HEAD(scalbn_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(+0.0, n) == +0.0"); +} + +ATF_TC_BODY(scalbn_zero_pos, tc) +{ + const double x = 0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +/* + * scalbnf(3) + */ +ATF_TC(scalbnf_val); +ATF_TC_HEAD(scalbnf_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf() for a few values"); +} + +ATF_TC_BODY(scalbnf_val, tc) +{ + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + double rv; + + for (i = 0; i < tcnt; i++) { + rv = scalbnf(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*FLT_EPSILON, + "test %zu: return value %g instead of %g (difference %g)", + i, rv, tests[i].result, tests[i].result-rv); + } +} + +ATF_TC(scalbnf_nan); +ATF_TC_HEAD(scalbnf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN"); +} + +ATF_TC_BODY(scalbnf_nan, tc) +{ + const float x = 0.0L / 0.0L; + float y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(scalbnf_inf_neg); +ATF_TC_HEAD(scalbnf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(-Inf, n) == -Inf"); +} + +ATF_TC_BODY(scalbnf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnf(x, exps[i]) == x); +} + +ATF_TC(scalbnf_inf_pos); +ATF_TC_HEAD(scalbnf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(+Inf, n) == +Inf"); +} + +ATF_TC_BODY(scalbnf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnf(x, exps[i]) == x); +} + +ATF_TC(scalbnf_ldexpf); +ATF_TC_HEAD(scalbnf_ldexpf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)"); +} + +ATF_TC_BODY(scalbnf_ldexpf, tc) +{ +#if FLT_RADIX == 2 + const float x = 2.91288191221812821; + float y; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK_MSG(y == ldexpf(x, exps[i]), + "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)", + i, exps[i], y, ldexpf(x, exps[i]), y-ldexpf(x, exps[i])); + } +#endif +} + +ATF_TC(scalbnf_zero_neg); +ATF_TC_HEAD(scalbnf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0"); +} + +ATF_TC_BODY(scalbnf_zero_neg, tc) +{ + const float x = -0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(scalbnf_zero_pos); +ATF_TC_HEAD(scalbnf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(+0.0, n) == +0.0"); +} + +ATF_TC_BODY(scalbnf_zero_pos, tc) +{ + const float x = 0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +/* + * scalbnl(3) + */ +ATF_TC(scalbnl_val); +ATF_TC_HEAD(scalbnl_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl() for a few values"); +} + +ATF_TC_BODY(scalbnl_val, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + long double rv; + + for (i = 0; i < tcnt; i++) { + rv = scalbnl(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabsl(rv-(long double)tests[i].result)<2.0*LDBL_EPSILON, + "test %zu: return value %Lg instead of %Lg (difference %Lg)", + i, rv, (long double)tests[i].result, (long double)tests[i].result-rv); + } +#endif +} + +ATF_TC(scalbnl_nan); +ATF_TC_HEAD(scalbnl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN"); +} + +ATF_TC_BODY(scalbnl_nan, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = 0.0L / 0.0L; + long double y; + size_t i; + + if (isnan(x) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("(0.0L / 0.0L) != NaN"); + } + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnl(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +#endif +} + +ATF_TC(scalbnl_inf_neg); +ATF_TC_HEAD(scalbnl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(-Inf, n) == -Inf"); +} + +ATF_TC_BODY(scalbnl_inf_neg, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnl(x, exps[i]) == x); +#endif +} + +ATF_TC(scalbnl_inf_pos); +ATF_TC_HEAD(scalbnl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(+Inf, n) == +Inf"); +} + +ATF_TC_BODY(scalbnl_inf_pos, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnl(x, exps[i]) == x); +#endif +} + +ATF_TC(scalbnl_zero_neg); +ATF_TC_HEAD(scalbnl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(-0.0, n) == -0.0"); +} + +ATF_TC_BODY(scalbnl_zero_neg, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = -0.0L; + long double y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnl(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +#endif +} + +ATF_TC(scalbnl_zero_pos); +ATF_TC_HEAD(scalbnl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(+0.0, n) == +0.0"); +} + +ATF_TC_BODY(scalbnl_zero_pos, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = 0.0L; + long double y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnl(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, scalbn_val); + ATF_TP_ADD_TC(tp, scalbn_nan); + ATF_TP_ADD_TC(tp, scalbn_inf_neg); + ATF_TP_ADD_TC(tp, scalbn_inf_pos); + ATF_TP_ADD_TC(tp, scalbn_ldexp); + ATF_TP_ADD_TC(tp, scalbn_zero_neg); + ATF_TP_ADD_TC(tp, scalbn_zero_pos); + + ATF_TP_ADD_TC(tp, scalbnf_val); + ATF_TP_ADD_TC(tp, scalbnf_nan); + ATF_TP_ADD_TC(tp, scalbnf_inf_neg); + ATF_TP_ADD_TC(tp, scalbnf_inf_pos); + ATF_TP_ADD_TC(tp, scalbnf_ldexpf); + ATF_TP_ADD_TC(tp, scalbnf_zero_neg); + ATF_TP_ADD_TC(tp, scalbnf_zero_pos); + + ATF_TP_ADD_TC(tp, scalbnl_val); + ATF_TP_ADD_TC(tp, scalbnl_nan); + ATF_TP_ADD_TC(tp, scalbnl_inf_neg); + ATF_TP_ADD_TC(tp, scalbnl_inf_pos); +/* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */ + ATF_TP_ADD_TC(tp, scalbnl_zero_neg); + ATF_TP_ADD_TC(tp, scalbnl_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_sin.c b/contrib/netbsd-tests/lib/libm/t_sin.c new file mode 100644 index 0000000..a82f49d --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_sin.c @@ -0,0 +1,263 @@ +/* $NetBSD: t_sin.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> + +static const struct { + int angle; + double x; + double y; +} angles[] = { + { -180, -3.141592653589793, 0.0000000000000000 }, + { -135, -2.356194490192345, -0.7071067811865476 }, + { -90, -1.570796326794897, -1.0000000000000000 }, + { -45, -0.785398163397448, -0.7071067811865476 }, + { 0, 0.000000000000000, 0.0000000000000000 }, + { 30, 0.523598775598299, 0.5000000000000000 }, + { 45, 0.785398163397448, 0.7071067811865476 }, + { 60, 1.047197551196598, 0.8660254037844386 }, + { 90, 1.570796326794897, 1.0000000000000000 }, + { 120, 2.094395102393195, 0.8660254037844386 }, + { 135, 2.356194490192345, 0.7071067811865476 }, + { 150, 2.617993877991494, 0.5000000000000000 }, + { 180, 3.141592653589793, 0.0000000000000000 }, + { 270, 4.712388980384690, -1.0000000000000000 }, + { 360, 6.283185307179586, 0.0000000000000000 } +}; + +/* + * sin(3) + */ +ATF_TC(sin_angles); +ATF_TC_HEAD(sin_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(sin_angles, tc) +{ + const double eps = 1.0e-15; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + if (fabs(sin(angles[i].x) - angles[i].y) > eps) + atf_tc_fail_nonfatal("sin(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(sin_nan); +ATF_TC_HEAD(sin_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(NaN) == NaN"); +} + +ATF_TC_BODY(sin_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sin(x)) != 0); +} + +ATF_TC(sin_inf_neg); +ATF_TC_HEAD(sin_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(-Inf) == NaN"); +} + +ATF_TC_BODY(sin_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(isnan(sin(x)) != 0); +} + +ATF_TC(sin_inf_pos); +ATF_TC_HEAD(sin_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(+Inf) == NaN"); +} + +ATF_TC_BODY(sin_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(isnan(sin(x)) != 0); +} + + +ATF_TC(sin_zero_neg); +ATF_TC_HEAD(sin_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(-0.0) == -0.0"); +} + +ATF_TC_BODY(sin_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(sin(x) == x); +} + +ATF_TC(sin_zero_pos); +ATF_TC_HEAD(sin_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(+0.0) == +0.0"); +} + +ATF_TC_BODY(sin_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(sin(x) == x); +} + +/* + * sinf(3) + */ +ATF_TC(sinf_angles); +ATF_TC_HEAD(sinf_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(sinf_angles, tc) +{ + const float eps = 1.0e-6; + float x, y; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + x = angles[i].x; + y = angles[i].y; + + if (fabsf(sinf(x) - y) > eps) + atf_tc_fail_nonfatal("sinf(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(sinf_nan); +ATF_TC_HEAD(sinf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(NaN) == NaN"); +} + +ATF_TC_BODY(sinf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sinf(x)) != 0); +} + +ATF_TC(sinf_inf_neg); +ATF_TC_HEAD(sinf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(-Inf) == NaN"); +} + +ATF_TC_BODY(sinf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(sinf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("sinf(-Inf) != NaN"); + } +} + +ATF_TC(sinf_inf_pos); +ATF_TC_HEAD(sinf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(+Inf) == NaN"); +} + +ATF_TC_BODY(sinf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(sinf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("sinf(+Inf) != NaN"); + } +} + + +ATF_TC(sinf_zero_neg); +ATF_TC_HEAD(sinf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(-0.0) == -0.0"); +} + +ATF_TC_BODY(sinf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(sinf(x) == x); +} + +ATF_TC(sinf_zero_pos); +ATF_TC_HEAD(sinf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(+0.0) == +0.0"); +} + +ATF_TC_BODY(sinf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(sinf(x) == x); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sin_angles); + ATF_TP_ADD_TC(tp, sin_nan); + ATF_TP_ADD_TC(tp, sin_inf_neg); + ATF_TP_ADD_TC(tp, sin_inf_pos); + ATF_TP_ADD_TC(tp, sin_zero_neg); + ATF_TP_ADD_TC(tp, sin_zero_pos); + + ATF_TP_ADD_TC(tp, sinf_angles); + ATF_TP_ADD_TC(tp, sinf_nan); + ATF_TP_ADD_TC(tp, sinf_inf_neg); + ATF_TP_ADD_TC(tp, sinf_inf_pos); + ATF_TP_ADD_TC(tp, sinf_zero_neg); + ATF_TP_ADD_TC(tp, sinf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_sinh.c b/contrib/netbsd-tests/lib/libm/t_sinh.c new file mode 100644 index 0000000..d935f0e --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_sinh.c @@ -0,0 +1,273 @@ +/* $NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <math.h> +#include <stdio.h> + +static const struct { + double x; + double y; + double e; +} values[] = { + { -10, -11013.23287470339, 1e4, }, + { -2, -3.626860407847019, 1, }, + { -1, -1.175201193643801, 1, }, + { -0.05, -0.050020835937655, 1, }, + { -0.001,-0.001000000166667, 1, }, + { 0.001, 0.001000000166667, 1, }, + { 0.05, 0.050020835937655, 1, }, + { 1, 1.175201193643801, 1, }, + { 2, 3.626860407847019, 1, }, + { 10, 11013.23287470339, 1e4, }, +}; + +/* + * sinh(3) + */ +ATF_TC(sinh_inrange); +ATF_TC_HEAD(sinh_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "sinh(x) for some values"); +} + +ATF_TC_BODY(sinh_inrange, tc) +{ + double eps; + double x; + double y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-15 * values[i].e; + + if (fabs(sinh(x) - y) > eps) + atf_tc_fail_nonfatal("sinh(%g) != %g\n", x, y); + } +} + +ATF_TC(sinh_nan); +ATF_TC_HEAD(sinh_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(NaN) == NaN"); +} + +ATF_TC_BODY(sinh_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sinh(x)) != 0); +} + +ATF_TC(sinh_inf_neg); +ATF_TC_HEAD(sinh_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(-Inf) == -Inf"); +} + +ATF_TC_BODY(sinh_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = sinh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(sinh_inf_pos); +ATF_TC_HEAD(sinh_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(+Inf) == +Inf"); +} + +ATF_TC_BODY(sinh_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = sinh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sinh_zero_neg); +ATF_TC_HEAD(sinh_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(-0.0) == -0.0"); +} + +ATF_TC_BODY(sinh_zero_neg, tc) +{ + const double x = -0.0L; + double y = sinh(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sinh(-0.0) != -0.0"); +} + +ATF_TC(sinh_zero_pos); +ATF_TC_HEAD(sinh_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(+0.0) == +0.0"); +} + +ATF_TC_BODY(sinh_zero_pos, tc) +{ + const double x = 0.0L; + double y = sinh(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sinh(+0.0) != +0.0"); +} + +/* + * sinhf(3) + */ +ATF_TC(sinhf_inrange); +ATF_TC_HEAD(sinhf_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "sinhf(x) for some values"); +} + +ATF_TC_BODY(sinhf_inrange, tc) +{ + float eps; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-6 * values[i].e; + + if (fabsf(sinhf(x) - y) > eps) + atf_tc_fail_nonfatal("sinhf(%g) != %g\n", x, y); + } +} + +ATF_TC(sinhf_nan); +ATF_TC_HEAD(sinhf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(NaN) == NaN"); +} + +ATF_TC_BODY(sinhf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sinhf(x)) != 0); +} + +ATF_TC(sinhf_inf_neg); +ATF_TC_HEAD(sinhf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(-Inf) == -Inf"); +} + +ATF_TC_BODY(sinhf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = sinhf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(sinhf_inf_pos); +ATF_TC_HEAD(sinhf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(+Inf) == +Inf"); +} + +ATF_TC_BODY(sinhf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = sinhf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sinhf_zero_neg); +ATF_TC_HEAD(sinhf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(-0.0) == -0.0"); +} + +ATF_TC_BODY(sinhf_zero_neg, tc) +{ + const float x = -0.0L; + float y = sinhf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sinhf(-0.0) != -0.0"); +} + +ATF_TC(sinhf_zero_pos); +ATF_TC_HEAD(sinhf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(+0.0) == +0.0"); +} + +ATF_TC_BODY(sinhf_zero_pos, tc) +{ + const float x = 0.0L; + float y = sinhf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sinhf(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sinh_inrange); + ATF_TP_ADD_TC(tp, sinh_nan); + ATF_TP_ADD_TC(tp, sinh_inf_neg); + ATF_TP_ADD_TC(tp, sinh_inf_pos); + ATF_TP_ADD_TC(tp, sinh_zero_neg); + ATF_TP_ADD_TC(tp, sinh_zero_pos); + + ATF_TP_ADD_TC(tp, sinhf_inrange); + ATF_TP_ADD_TC(tp, sinhf_nan); + ATF_TP_ADD_TC(tp, sinhf_inf_neg); + ATF_TP_ADD_TC(tp, sinhf_inf_pos); + ATF_TP_ADD_TC(tp, sinhf_zero_neg); + ATF_TP_ADD_TC(tp, sinhf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_sqrt.c b/contrib/netbsd-tests/lib/libm/t_sqrt.c new file mode 100644 index 0000000..1d551ec --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_sqrt.c @@ -0,0 +1,368 @@ +/* $NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $"); + +#include <atf-c.h> +#include <math.h> +#include <float.h> +#include <stdio.h> + +/* + * sqrt(3) + */ +ATF_TC(sqrt_nan); +ATF_TC_HEAD(sqrt_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(NaN) == NaN"); +} + +ATF_TC_BODY(sqrt_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sqrt(x)) != 0); +} + +ATF_TC(sqrt_pow); +ATF_TC_HEAD(sqrt_pow, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(3) vs. pow(3)"); +} + +ATF_TC_BODY(sqrt_pow, tc) +{ + const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; +#if __DBL_MIN_10_EXP__ <= -40 + const double eps = 1.0e-40; +#else + const double eps = __DBL_MIN__*4.0; +#endif + double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = sqrt(x[i]); + z = pow(x[i], 1.0 / 2.0); + + if (fabs(y - z) > eps) + atf_tc_fail_nonfatal("sqrt(%0.03f) != " + "pow(%0.03f, 1/2)\n", x[i], x[i]); + } +} + +ATF_TC(sqrt_inf_neg); +ATF_TC_HEAD(sqrt_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(-Inf) == NaN"); +} + +ATF_TC_BODY(sqrt_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = sqrt(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(sqrt_inf_pos); +ATF_TC_HEAD(sqrt_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(+Inf) == +Inf"); +} + +ATF_TC_BODY(sqrt_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = sqrt(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sqrt_zero_neg); +ATF_TC_HEAD(sqrt_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(-0.0) == -0.0"); +} + +ATF_TC_BODY(sqrt_zero_neg, tc) +{ + const double x = -0.0L; + double y = sqrt(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sqrt(-0.0) != -0.0"); +} + +ATF_TC(sqrt_zero_pos); +ATF_TC_HEAD(sqrt_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(+0.0) == +0.0"); +} + +ATF_TC_BODY(sqrt_zero_pos, tc) +{ + const double x = 0.0L; + double y = sqrt(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sqrt(+0.0) != +0.0"); +} + +/* + * sqrtf(3) + */ +ATF_TC(sqrtf_nan); +ATF_TC_HEAD(sqrtf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(NaN) == NaN"); +} + +ATF_TC_BODY(sqrtf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sqrtf(x)) != 0); +} + +ATF_TC(sqrtf_powf); +ATF_TC_HEAD(sqrtf_powf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(3) vs. powf(3)"); +} + +ATF_TC_BODY(sqrtf_powf, tc) +{ + const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; + const float eps = 1.0e-30; + volatile float y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = sqrtf(x[i]); + z = powf(x[i], 1.0 / 2.0); + + if (fabsf(y - z) > eps) + atf_tc_fail_nonfatal("sqrtf(%0.03f) != " + "powf(%0.03f, 1/2)\n", x[i], x[i]); + } +} + +ATF_TC(sqrtf_inf_neg); +ATF_TC_HEAD(sqrtf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(-Inf) == NaN"); +} + +ATF_TC_BODY(sqrtf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = sqrtf(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(sqrtf_inf_pos); +ATF_TC_HEAD(sqrtf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(+Inf) == +Inf"); +} + +ATF_TC_BODY(sqrtf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = sqrtf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sqrtf_zero_neg); +ATF_TC_HEAD(sqrtf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(-0.0) == -0.0"); +} + +ATF_TC_BODY(sqrtf_zero_neg, tc) +{ + const float x = -0.0L; + float y = sqrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sqrtf(-0.0) != -0.0"); +} + +ATF_TC(sqrtf_zero_pos); +ATF_TC_HEAD(sqrtf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(+0.0) == +0.0"); +} + +ATF_TC_BODY(sqrtf_zero_pos, tc) +{ + const float x = 0.0L; + float y = sqrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sqrtf(+0.0) != +0.0"); +} + +/* + * sqrtl(3) + */ +ATF_TC(sqrtl_nan); +ATF_TC_HEAD(sqrtl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(NaN) == NaN"); +} + +ATF_TC_BODY(sqrtl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sqrtl(x)) != 0); +} + +ATF_TC(sqrtl_powl); +ATF_TC_HEAD(sqrtl_powl, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(3) vs. powl(3)"); +} + +ATF_TC_BODY(sqrtl_powl, tc) +{ + const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; + const long double eps = 5.0*DBL_EPSILON; /* XXX powl == pow for now */ + volatile long double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = sqrtl(x[i]); + z = powl(x[i], 1.0 / 2.0); + + if (fabsl(y - z) > eps) + atf_tc_fail_nonfatal("sqrtl(%0.03Lf) != " + "powl(%0.03Lf, 1/2)\n", x[i], x[i]); + } +} + +ATF_TC(sqrtl_inf_neg); +ATF_TC_HEAD(sqrtl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(-Inf) == NaN"); +} + +ATF_TC_BODY(sqrtl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = sqrtl(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(sqrtl_inf_pos); +ATF_TC_HEAD(sqrtl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(+Inf) == +Inf"); +} + +ATF_TC_BODY(sqrtl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = sqrtl(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sqrtl_zero_neg); +ATF_TC_HEAD(sqrtl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(-0.0) == -0.0"); +} + +ATF_TC_BODY(sqrtl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = sqrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sqrtl(-0.0) != -0.0"); +} + +ATF_TC(sqrtl_zero_pos); +ATF_TC_HEAD(sqrtl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(+0.0) == +0.0"); +} + +ATF_TC_BODY(sqrtl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = sqrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sqrtl(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sqrt_nan); + ATF_TP_ADD_TC(tp, sqrt_pow); + ATF_TP_ADD_TC(tp, sqrt_inf_neg); + ATF_TP_ADD_TC(tp, sqrt_inf_pos); + ATF_TP_ADD_TC(tp, sqrt_zero_neg); + ATF_TP_ADD_TC(tp, sqrt_zero_pos); + + ATF_TP_ADD_TC(tp, sqrtf_nan); + ATF_TP_ADD_TC(tp, sqrtf_powf); + ATF_TP_ADD_TC(tp, sqrtf_inf_neg); + ATF_TP_ADD_TC(tp, sqrtf_inf_pos); + ATF_TP_ADD_TC(tp, sqrtf_zero_neg); + ATF_TP_ADD_TC(tp, sqrtf_zero_pos); + + ATF_TP_ADD_TC(tp, sqrtl_nan); + ATF_TP_ADD_TC(tp, sqrtl_powl); + ATF_TP_ADD_TC(tp, sqrtl_inf_neg); + ATF_TP_ADD_TC(tp, sqrtl_inf_pos); + ATF_TP_ADD_TC(tp, sqrtl_zero_neg); + ATF_TP_ADD_TC(tp, sqrtl_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_tan.c b/contrib/netbsd-tests/lib/libm/t_tan.c new file mode 100644 index 0000000..807e3d1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_tan.c @@ -0,0 +1,260 @@ +/* $NetBSD: t_tan.c,v 1.5 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> + +static const struct { + int angle; + double x; + double y; +} angles[] = { + { -180, -3.141592653589793, 0.0000000000000000 }, + { -135, -2.356194490192345, 1.0000000000000000 }, + { -45, -0.785398163397448, -1.0000000000000000 }, + { 0, 0.000000000000000, 0.0000000000000000 }, + { 30, 0.523598775598299, 0.5773502691896258 }, + { 45, 0.785398163397448, 1.0000000000000000 }, + { 60, 1.047197551196598, 1.7320508075688773 }, + { 120, 2.094395102393195, -1.7320508075688773 }, + { 135, 2.356194490192345, -1.0000000000000000 }, + { 150, 2.617993877991494, -0.5773502691896258 }, + { 180, 3.141592653589793, 0.0000000000000000 }, + { 360, 6.283185307179586, 0.0000000000000000 } +}; + +/* + * tan(3) + */ +ATF_TC(tan_angles); +ATF_TC_HEAD(tan_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(tan_angles, tc) +{ + const double eps = 1.0e-14; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + if (fabs(tan(angles[i].x) - angles[i].y) > eps) + atf_tc_fail_nonfatal("tan(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(tan_nan); +ATF_TC_HEAD(tan_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(NaN) == NaN"); +} + +ATF_TC_BODY(tan_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tan(x)) != 0); +} + +ATF_TC(tan_inf_neg); +ATF_TC_HEAD(tan_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(-Inf) == NaN"); +} + +ATF_TC_BODY(tan_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(isnan(tan(x)) != 0); +} + +ATF_TC(tan_inf_pos); +ATF_TC_HEAD(tan_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(+Inf) == NaN"); +} + +ATF_TC_BODY(tan_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(isnan(tan(x)) != 0); +} + + +ATF_TC(tan_zero_neg); +ATF_TC_HEAD(tan_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(-0.0) == -0.0"); +} + +ATF_TC_BODY(tan_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(tan(x) == x); +} + +ATF_TC(tan_zero_pos); +ATF_TC_HEAD(tan_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(+0.0) == +0.0"); +} + +ATF_TC_BODY(tan_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(tan(x) == x); +} + +/* + * tanf(3) + */ +ATF_TC(tanf_angles); +ATF_TC_HEAD(tanf_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(tanf_angles, tc) +{ + const float eps = 1.0e-6; + float x, y; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + x = angles[i].x; + y = angles[i].y; + + if (fabsf(tanf(x) - y) > eps) + atf_tc_fail_nonfatal("tanf(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(tanf_nan); +ATF_TC_HEAD(tanf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(NaN) == NaN"); +} + +ATF_TC_BODY(tanf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tanf(x)) != 0); +} + +ATF_TC(tanf_inf_neg); +ATF_TC_HEAD(tanf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(-Inf) == NaN"); +} + +ATF_TC_BODY(tanf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(tanf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("tanf(-Inf) != NaN"); + } +} + +ATF_TC(tanf_inf_pos); +ATF_TC_HEAD(tanf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(+Inf) == NaN"); +} + +ATF_TC_BODY(tanf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(tanf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("tanf(+Inf) != NaN"); + } +} + + +ATF_TC(tanf_zero_neg); +ATF_TC_HEAD(tanf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(-0.0) == -0.0"); +} + +ATF_TC_BODY(tanf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(tanf(x) == x); +} + +ATF_TC(tanf_zero_pos); +ATF_TC_HEAD(tanf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(+0.0) == +0.0"); +} + +ATF_TC_BODY(tanf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(tanf(x) == x); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tan_angles); + ATF_TP_ADD_TC(tp, tan_nan); + ATF_TP_ADD_TC(tp, tan_inf_neg); + ATF_TP_ADD_TC(tp, tan_inf_pos); + ATF_TP_ADD_TC(tp, tan_zero_neg); + ATF_TP_ADD_TC(tp, tan_zero_pos); + + ATF_TP_ADD_TC(tp, tanf_angles); + ATF_TP_ADD_TC(tp, tanf_nan); + ATF_TP_ADD_TC(tp, tanf_inf_neg); + ATF_TP_ADD_TC(tp, tanf_inf_pos); + ATF_TP_ADD_TC(tp, tanf_zero_neg); + ATF_TP_ADD_TC(tp, tanf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_tanh.c b/contrib/netbsd-tests/lib/libm/t_tanh.c new file mode 100644 index 0000000..4cc4551 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_tanh.c @@ -0,0 +1,207 @@ +/* $NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $"); + +#include <atf-c.h> +#include <math.h> + +/* + * tanh(3) + */ +ATF_TC(tanh_nan); +ATF_TC_HEAD(tanh_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(NaN) == NaN"); +} + +ATF_TC_BODY(tanh_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tanh(x)) != 0); +} + +ATF_TC(tanh_inf_neg); +ATF_TC_HEAD(tanh_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(-Inf) == -1.0"); +} + +ATF_TC_BODY(tanh_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(tanh(x) == -1.0); +} + +ATF_TC(tanh_inf_pos); +ATF_TC_HEAD(tanh_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(+Inf) == +1.0"); +} + +ATF_TC_BODY(tanh_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(tanh(x) == 1.0); +} + +ATF_TC(tanh_zero_neg); +ATF_TC_HEAD(tanh_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(-0.0) == -0.0"); +} + +ATF_TC_BODY(tanh_zero_neg, tc) +{ + const double x = -0.0L; + double y = tanh(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) != 0); + + ATF_REQUIRE_MSG(signbit(y) != 0, + "compiler bug, waiting for newer gcc import, see PR lib/44057"); +} + +ATF_TC(tanh_zero_pos); +ATF_TC_HEAD(tanh_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(+0.0) == +0.0"); +} + +ATF_TC_BODY(tanh_zero_pos, tc) +{ + const double x = 0.0L; + double y = tanh(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +/* + * tanhf(3) + */ +ATF_TC(tanhf_nan); +ATF_TC_HEAD(tanhf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(NaN) == NaN"); +} + +ATF_TC_BODY(tanhf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tanhf(x)) != 0); +} + +ATF_TC(tanhf_inf_neg); +ATF_TC_HEAD(tanhf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(-Inf) == -1.0"); +} + +ATF_TC_BODY(tanhf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + ATF_CHECK(tanhf(x) == -1.0); +} + +ATF_TC(tanhf_inf_pos); +ATF_TC_HEAD(tanhf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(+Inf) == +1.0"); +} + +ATF_TC_BODY(tanhf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + ATF_CHECK(tanhf(x) == 1.0); +} + +ATF_TC(tanhf_zero_neg); +ATF_TC_HEAD(tanhf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(-0.0) == -0.0"); +} + +ATF_TC_BODY(tanhf_zero_neg, tc) +{ + const float x = -0.0L; + float y = tanh(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) != 0); + + ATF_REQUIRE_MSG(signbit(y) != 0, + "compiler bug, waiting for newer gcc import, see PR lib/44057"); +} + +ATF_TC(tanhf_zero_pos); +ATF_TC_HEAD(tanhf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(+0.0) == +0.0"); +} + +ATF_TC_BODY(tanhf_zero_pos, tc) +{ + const float x = 0.0L; + float y = tanhf(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tanh_nan); + ATF_TP_ADD_TC(tp, tanh_inf_neg); + ATF_TP_ADD_TC(tp, tanh_inf_pos); + ATF_TP_ADD_TC(tp, tanh_zero_neg); + ATF_TP_ADD_TC(tp, tanh_zero_pos); + + ATF_TP_ADD_TC(tp, tanhf_nan); + ATF_TP_ADD_TC(tp, tanhf_inf_neg); + ATF_TP_ADD_TC(tp, tanhf_inf_pos); + ATF_TP_ADD_TC(tp, tanhf_zero_neg); + ATF_TP_ADD_TC(tp, tanhf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libobjc/t_threads.m b/contrib/netbsd-tests/lib/libobjc/t_threads.m new file mode 100644 index 0000000..a6bd720 --- /dev/null +++ b/contrib/netbsd-tests/lib/libobjc/t_threads.m @@ -0,0 +1,136 @@ +/* $NetBSD: t_threads.m,v 1.2 2013/10/31 21:02:11 christos Exp $ */ + +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Originally written by David Wetzel */ + +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <atf-c.h> + +#include <objc/objc.h> +#include <objc/thr.h> +#include <objc/Object.h> +#if __GNUC_PREREQ__(4,8) +#include <objc/runtime.h> +#endif + +static int IsMultithreaded = 0; +static objc_mutex_t Mutex; +static objc_condition_t Condition; + +@interface MyClass : Object +{ +} +-(void)start; +#if __GNUC_PREREQ__(4,8) +-init; ++new; ++alloc; +-free; +#endif +@end + +@implementation MyClass +-(void)start +{ + printf("detached thread started!\n"); + + objc_condition_signal(Condition); +} +#if __GNUC_PREREQ__(4,8) +-init +{ + return self; +} + ++new +{ + return [[self alloc] init]; +} + ++alloc +{ + return class_createInstance(self, 0); +} + +-free +{ + return object_dispose(self); +} +#endif +@end + +static void +becomeMultiThreaded(void) +{ + printf("becoming multithreaded!\n"); + IsMultithreaded++; +} + +ATF_TC(thread_callback); +ATF_TC_HEAD(thread_callback, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that the thread callback is only" + "called once"); +} +ATF_TC_BODY(thread_callback, tc) +{ + id o = [MyClass new]; + objc_thread_callback cb; + objc_thread_t rv; + + cb = objc_set_thread_callback(becomeMultiThreaded); + printf("Old Callback: %p\n", cb); + ATF_CHECK(cb == 0); + + Mutex = objc_mutex_allocate(); + Condition = objc_condition_allocate(); + + ATF_CHECK_EQ(0, IsMultithreaded); + + rv = objc_thread_detach(@selector(start), o, nil); + printf("detach value: %p\n", rv); + assert(rv != NULL); + + objc_mutex_lock(Mutex); + objc_condition_wait(Condition, Mutex); + objc_mutex_unlock(Mutex); + + ATF_CHECK_EQ(1, IsMultithreaded); + printf("Shutting down\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, thread_callback); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libposix/t_rename.c b/contrib/netbsd-tests/lib/libposix/t_rename.c new file mode 100644 index 0000000..85b2b95 --- /dev/null +++ b/contrib/netbsd-tests/lib/libposix/t_rename.c @@ -0,0 +1,89 @@ +/* $NetBSD: t_rename.c,v 1.2 2011/05/16 00:03:36 christos Exp $ */ + +/* + * Copyright (c) 2001, 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#define _NETBSD_SOURCE /* strlcat/random */ +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_rename.c,v 1.2 2011/05/16 00:03:36 christos Exp $"); + +#include <sys/types.h> +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../h_macros.h" + +ATF_TC(rename); +ATF_TC_HEAD(rename, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks rename(2)"); +} +ATF_TC_BODY(rename, tc) +{ + struct stat sb; + + REQUIRE_LIBC(open("t1", O_CREAT | O_TRUNC | O_WRONLY, 0600), -1); + REQUIRE_LIBC(link("t1", "t2"), -1); + + /* Check if rename to same name works as expected */ + REQUIRE_LIBC(rename("t1", "t1"), -1); + + /* Rename removed file? */ + REQUIRE_LIBC(stat("t1", &sb), -1); + + REQUIRE_LIBC(rename("t1", "t2"), -1); + +#if BSD_RENAME + /* check if rename of hardlinked file works the BSD way */ + ATF_REQUIRE_MSG(stat("t1", &sb) != 0, "BSD rename should remove file t1"); + ATF_REQUIRE_EQ(errno, ENOENT); +#else + /* check if rename of hardlinked file works as the standard says */ + REQUIRE_LIBC(stat("t1", &sb), -1); +#endif + /* check if we get the expected error */ + /* this also exercises icky shared libraries goo */ + ATF_REQUIRE_MSG(rename("no/such/file/or/dir", "no/such/file/or/dir") != 0, + "No error renaming nonexistent file"); + ATF_REQUIRE_EQ(errno, ENOENT); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, rename); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libppath/personnel.plist b/contrib/netbsd-tests/lib/libppath/personnel.plist new file mode 100644 index 0000000..daec88c --- /dev/null +++ b/contrib/netbsd-tests/lib/libppath/personnel.plist @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>John Doe</key> + <dict> + <key>children</key> + <array> + <string>Jane Doe</string> + <string>John Doe, Jr.</string> + </array> + + <key>pets</key> + <array> + <string>Fido</string> + <string>Spot</string> + </array> + + <key>job title</key> + <string>computer programmer</string> + + <key>u.s. citizen</key> + <true/> + </dict> +</dict> +</plist> diff --git a/contrib/netbsd-tests/lib/libppath/plist_to_c b/contrib/netbsd-tests/lib/libppath/plist_to_c new file mode 100755 index 0000000..f471b4e --- /dev/null +++ b/contrib/netbsd-tests/lib/libppath/plist_to_c @@ -0,0 +1,20 @@ +#!/bin/sh + +prog=$(basename $0) +usage() +{ + echo "usage: ${prog} symbol" 1>&2 + exit 1 +} + +if [ $# -ne 1 ]; then + usage +fi + +sed 's/\(["\]\)/\\\1/g' | \ +${AWK:-awk} -v sym=$1 ' +BEGIN { printf "const char " sym "[] = \""; } + { printf $0 "\\n"; } +END { print "\";"; }' + +exit 0 diff --git a/contrib/netbsd-tests/lib/libppath/t_ppath.c b/contrib/netbsd-tests/lib/libppath/t_ppath.c new file mode 100644 index 0000000..7330763 --- /dev/null +++ b/contrib/netbsd-tests/lib/libppath/t_ppath.c @@ -0,0 +1,1548 @@ +/* $Id: t_ppath.c,v 1.1 2011/08/25 19:09:46 dyoung Exp $ */ + +/* Copyright (c) 2010 David Young. All rights reserved. */ + +#include <sys/cdefs.h> +__RCSID("$Id: t_ppath.c,v 1.1 2011/08/25 19:09:46 dyoung Exp $"); + +#include <assert.h> +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <ppath/ppath.h> +#include "personnel.h" + +void test_ppath_extant_inc(void); +void test_ppath_extant_dec(void); +void test_ppath_component_extant_inc(void); +void test_ppath_component_extant_dec(void); + +__strong_alias(ppath_extant_inc, test_ppath_extant_inc); +__strong_alias(ppath_extant_dec, test_ppath_extant_dec); +__strong_alias(ppath_component_extant_inc, test_ppath_component_extant_inc); +__strong_alias(ppath_component_extant_dec, test_ppath_component_extant_dec); + +static uint64_t nppath = 0, nppath_component = 0; + +static bool +dictionary_equals(prop_dictionary_t ld, prop_dictionary_t rd) +{ + bool eq; + char *lt, *rt; + + lt = prop_dictionary_externalize(ld); + rt = prop_dictionary_externalize(rd); + + assert(lt != NULL && rt != NULL); + + eq = (strcmp(lt, rt) == 0); + + free(lt); + free(rt); + + return eq; +} + +static void +assert_no_ppath_extant(void) +{ + ATF_CHECK_EQ(nppath, 0); +} + +static void +assert_no_ppath_component_extant(void) +{ + ATF_CHECK_EQ(nppath_component, 0); +} + +void +test_ppath_extant_inc(void) +{ + if (++nppath == 0) + atf_tc_fail("count of extant paths overflowed"); +} + +void +test_ppath_extant_dec(void) +{ + if (nppath-- == 0) + atf_tc_fail("count of extant path underflowed"); +} + +void +test_ppath_component_extant_inc(void) +{ + if (++nppath_component == 0) + atf_tc_fail("count of extant path components overflowed"); +} + +void +test_ppath_component_extant_dec(void) +{ + if (nppath_component-- == 0) + atf_tc_fail("count of extant path components underflowed"); +} + +ATF_TC(push_until_full); + +ATF_TC_HEAD(push_until_full, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_push() returns error " + "after ppath_t reaches maximum length"); +} + +ATF_TC_BODY(push_until_full, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc; + int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if ((pc = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, p); + } + + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, NULL); + + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, NULL); + + ppath_component_release(pc); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(pop_until_empty); +ATF_TC_HEAD(pop_until_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_pop() returns error " + "after ppath_t is empty"); +} + +ATF_TC_BODY(pop_until_empty, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc, *rpc; + int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if ((pc = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, p); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + rp = ppath_pop(p, &rpc); + ATF_CHECK_EQ(rp, p); + ATF_CHECK_EQ(rpc, pc); + ppath_component_release(rpc); + } + + rp = ppath_pop(p, &rpc); + ATF_CHECK_EQ(rp, NULL); + rp = ppath_pop(p, &rpc); + ATF_CHECK_EQ(rp, NULL); + + ppath_component_release(pc); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(length); + +ATF_TC_HEAD(length, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_push() " + "and ppath_pop() affect ppath_length() correctly"); +} + +ATF_TC_BODY(length, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc; + unsigned int i, len; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if ((pc = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + len = ppath_length(p); + ATF_CHECK_EQ(len, i); + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, p); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + len = ppath_length(p); + ATF_CHECK_EQ(len, PPATH_MAX_COMPONENTS - i); + rp = ppath_pop(p, NULL); + ATF_CHECK_EQ(rp, p); + } + ppath_component_release(pc); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(component_at); + +ATF_TC_HEAD(component_at, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_component_at() " + "returns the expected component"); +} + +ATF_TC_BODY(component_at, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc; + unsigned int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + if ((pc = ppath_idx(i)) == NULL) + atf_tc_fail("ppath_idx failed"); + rp = ppath_push(p, pc); + ppath_component_release(pc); + ATF_CHECK_EQ(rp, p); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + pc = ppath_component_at(p, i); + ATF_CHECK_EQ(ppath_component_idx(pc), (int)i); + ppath_component_release(pc); + } + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_idx_key); + +ATF_TC_HEAD(get_idx_key, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_component_idx() " + "and ppath_component_key() return -1 and NULL, respectively, if " + "the component is a key or an index, respectively."); +} + +ATF_TC_BODY(get_idx_key, tc) +{ + ppath_component_t *idx, *key; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((idx = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + if ((key = ppath_key("key")) == NULL) + atf_tc_fail("ppath_idx failed"); + + ATF_CHECK_EQ(ppath_component_key(idx), NULL); + ATF_CHECK_EQ(ppath_component_idx(key), -1); + + ppath_component_release(idx); + ppath_component_release(key); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(ppath_copy); + +ATF_TC_HEAD(ppath_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_copy() " + "creates an exact replica of a path, and that no " + "resources are leaked."); +} + +ATF_TC_BODY(ppath_copy, tc) +{ + ppath_component_t *pc, *cpc; + ppath_t *p, *cp, *rp; + unsigned int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + if ((pc = ppath_idx(i)) == NULL) + atf_tc_fail("ppath_idx failed"); + rp = ppath_push(p, pc); + ppath_component_release(pc); + ATF_CHECK_EQ(rp, p); + } + + if ((cp = ppath_copy(p)) == NULL) + atf_tc_fail("ppath_copy failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + pc = ppath_component_at(p, i); + cpc = ppath_component_at(cp, i); + ATF_CHECK_EQ(pc, cpc); + ppath_component_release(pc); + ppath_component_release(cpc); + } + + ppath_release(cp); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(replace); + +ATF_TC_HEAD(replace, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_replace_idx() " + "and ppath_replace_key() produce the paths we expect without " + "leaking resources."); +} + +ATF_TC_BODY(replace, tc) +{ + ppath_component_t *pc; + ppath_t *p, *cp, *rp; + unsigned int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + /* index replacement fails on an empty path */ + rp = ppath_replace_idx(p, 0); + ATF_CHECK_EQ(rp, NULL); + + /* key replacement fails on an empty path */ + rp = ppath_replace_key(p, "key"); + ATF_CHECK_EQ(rp, NULL); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + if ((pc = ppath_idx(i)) == NULL) + atf_tc_fail("ppath_idx failed"); + rp = ppath_push(p, pc); + ppath_component_release(pc); + ATF_CHECK_EQ(rp, p); + } + + if ((cp = ppath_copy(p)) == NULL) + atf_tc_fail("ppath_copy failed"); + + rp = ppath_pop(cp, NULL); + ATF_CHECK_EQ(rp, cp); + rp = ppath_push_key(cp, "key"); + ATF_CHECK_EQ(rp, cp); + + ppath_replace_idx(p, 0); + + if ((pc = ppath_component_at(p, PPATH_MAX_COMPONENTS - 1)) == NULL) + atf_tc_fail("ppath_idx failed"); + ATF_CHECK_EQ(ppath_component_idx(pc), 0); + ppath_component_release(pc); + + for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) { + if ((pc = ppath_component_at(p, i)) == NULL) + atf_tc_fail("ppath_idx failed"); + ATF_CHECK_EQ(ppath_component_idx(pc), (int)i); + ppath_component_release(pc); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) { + if ((pc = ppath_component_at(cp, i)) == NULL) + atf_tc_fail("ppath_idx failed"); + ATF_CHECK_EQ(ppath_component_idx(pc), (int)i); + ppath_component_release(pc); + } + + if ((pc = ppath_component_at(cp, PPATH_MAX_COMPONENTS - 1)) == NULL) + atf_tc_fail("ppath_idx failed"); + if (ppath_component_key(pc) == NULL || + strcmp(ppath_component_key(pc), "key") != 0) + atf_tc_fail("last path component expected to be \"key\""); + ppath_component_release(pc); + ppath_release(p); + ppath_release(cp); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copyset_object_twice_success); + +ATF_TC_HEAD(copyset_object_twice_success, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check that after back-to-back ppath_copyset_object() calls, " + "changing the \"u.s. citizen\" property and the first property " + "in \"children\" in the \"John Doe\" record in the " + "\"personnel\" property list, the properties are changed " + "in the new dictionary and unchanged in the old dictionary"); +} + +ATF_TC_BODY(copyset_object_twice_success, tc) +{ + const char *s; + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL, ond; + prop_object_t r, or; + ppath_t *p, *p2, *p3; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL || + (p3 = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + if (ppath_push_key(p2, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p2, "children") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_idx(p2, 0) == NULL) + atf_tc_fail("ppath_push_idx failed"); + + if (ppath_push_key(p3, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + s = ""; + rc = ppath_get_string(d, p2, &s); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(s, "Jane Doe"); + + rc = ppath_copyset_bool(d, &nd, p, false); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_get_object(nd, p3, &r); + ATF_CHECK_EQ(rc, 0); + + ond = nd; + + rc = ppath_copyset_string(d, &nd, p2, "Martha Doe"); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(nd, ond); + + rc = ppath_get_object(nd, p3, &or); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(r, or); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, false); + + s = ""; + rc = ppath_get_string(nd, p2, &s); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(s, "Martha Doe"); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copydel modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_set_bool(od, p, false); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_set_string(od, p2, "Martha Doe"); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + ppath_release(p2); + ppath_release(p3); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copydel_object_twice_success); + +ATF_TC_HEAD(copydel_object_twice_success, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check that after back-to-back ppath_copydel_object() calls, " + "removing the \"u.s. citizen\" property and the first property " + "in \"children\" from the \"John Doe\" record in the " + "\"personnel\" property list, the properties are missing " + "from the new dictionary and unchanged in the old dictionary"); +} + +ATF_TC_BODY(copydel_object_twice_success, tc) +{ + const char *s; + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL, ond; + prop_object_t r, or; + ppath_t *p, *p2, *p3; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL || + (p3 = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + if (ppath_push_key(p2, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p2, "children") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_idx(p2, 0) == NULL) + atf_tc_fail("ppath_push_idx failed"); + + if (ppath_push_key(p3, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + s = ""; + rc = ppath_get_string(d, p2, &s); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(s, "Jane Doe"); + + rc = ppath_copydel_bool(d, &nd, p); + ATF_CHECK_EQ(rc, 0); + + ond = nd; + + rc = ppath_get_object(nd, p3, &r); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_copydel_string(d, &nd, p2); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(nd, ond); + + rc = ppath_get_object(nd, p3, &or); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(r, or); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copydel modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_delete_bool(od, p); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_delete_string(od, p2); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + ppath_release(p2); + ppath_release(p3); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copydel_bool_success); + +ATF_TC_HEAD(copydel_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_copydel_bool() deletes " + "the \"u.s. citizen\" property in the \"John Doe\" record in the " + "\"personnel\" property list and verifies the value is missing " + "from the new dictionary and unchanged in the old dictionary"); +} + +ATF_TC_BODY(copydel_bool_success, tc) +{ + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_copydel_bool(d, &nd, p); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copydel modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_delete_bool(od, p); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copyset_bool_success); + +ATF_TC_HEAD(copyset_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_copyset_bool() sets " + "the \"u.s. citizen\" property in the \"John Doe\" record in the " + "\"personnel\" property list to false and verifies the new value " + "in the new dictionary and that the old dictionary is unchanged"); +} + +ATF_TC_BODY(copyset_bool_success, tc) +{ + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_copyset_bool(d, &nd, p, false); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, false); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copyset modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copyset made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_set_bool(nd, p, true); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copyset made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(set_bool_eftype); + +ATF_TC_HEAD(set_bool_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not " + "overwrite with a bool " + "the \"job title\" property in the \"John Doe\" record in " + "the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(set_bool_eftype, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, false); + + rc = ppath_set_bool(d, p, false); + ATF_CHECK_EQ(rc, EFTYPE); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(set_bool_enoent); + +ATF_TC_HEAD(set_bool_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not create " + "the \"russian citizen\" property in the \"John Doe\" record in " + "the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(set_bool_enoent, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "russian citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, false); + + rc = ppath_set_bool(d, p, false); + ATF_CHECK_EQ(rc, ENOENT); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(create_bool_eexist); + +ATF_TC_HEAD(create_bool_eexist, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() returns " + "EEXIST because the \"u.s. citizen\" property in the " + "\"John Doe\" record in the \"personnel\" property list " + "already exists"); +} + +ATF_TC_BODY(create_bool_eexist, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_create_bool(d, p, false); + ATF_CHECK_EQ(rc, EEXIST); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(create_bool_success); + +ATF_TC_HEAD(create_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() creates " + "the \"russian citizen\" property in the \"John Doe\" record in " + "the \"personnel\" property list and sets it to false"); +} + +ATF_TC_BODY(create_bool_success, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "russian citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, false); + + rc = ppath_create_bool(d, p, false); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, false); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(set_bool_success); + +ATF_TC_HEAD(set_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() sets " + "the \"u.s. citizen\" property in the \"John Doe\" record in the " + "\"personnel\" property list to false and verifies the new value"); +} + +ATF_TC_BODY(set_bool_success, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_set_bool(d, p, v); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_bool_success); + +ATF_TC_HEAD(get_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() fetches " + "the \"u.s. citizen\" property from the \"John Doe\" record in the " + "\"personnel\" property list, and compares it with the expected " + "value, true"); +} + +ATF_TC_BODY(get_bool_success, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(delete_bool_success); + +ATF_TC_HEAD(delete_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() succeeds " + "for the path (\"John Doe\", \"u.s. citizen\") in the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(delete_bool_success, tc) +{ + int rc; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_delete_bool(d, p); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_get_bool(d, p, NULL); + ATF_CHECK_EQ(rc, ENOENT); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(delete_bool_eftype); + +ATF_TC_HEAD(delete_bool_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns " + "EFTYPE for the path (\"John Doe\", \"job title\") in the " + "\"personnel\" property list and does not delete the path"); +} + +ATF_TC_BODY(delete_bool_eftype, tc) +{ + int rc; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_delete_bool(d, p); + ATF_CHECK_EQ(rc, EFTYPE); + + rc = ppath_get_object(d, p, NULL); + ATF_CHECK_EQ(rc, 0); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(delete_bool_enoent); + +ATF_TC_HEAD(delete_bool_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns " + "ENOENT for the path (\"John Doe\", \"citizen\") in the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(delete_bool_enoent, tc) +{ + int rc; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_delete_bool(d, p); + ATF_CHECK_EQ(rc, ENOENT); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_bool_enoent); + +ATF_TC_HEAD(get_bool_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns " + "ENOENT for the path (\"John Doe\", \"citizen\") in the " + "\"personnel\" property list, and the bool * argument is " + "unchanged"); +} + +ATF_TC_BODY(get_bool_enoent, tc) +{ + int rc; + bool v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, false); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_bool_eftype); + +ATF_TC_HEAD(get_bool_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns " + "EFTYPE for the path (\"John Doe\", \"job title\") in the " + "\"personnel\" property list, and the bool * argument is " + "unchanged"); +} + +ATF_TC_BODY(get_bool_eftype, tc) +{ + int rc; + bool v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, true); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, false); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_string_eftype); + +ATF_TC_HEAD(get_string_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns " + "EFTYPE for the path (\"John Doe\", \"u.s. citizen\") in the " + "\"personnel\" property list, and the const char ** argument is " + "unchanged"); +} + +ATF_TC_BODY(get_string_eftype, tc) +{ + int rc; + const char *v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = NULL; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, NULL); + + v = "xyz"; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_STREQ(v, "xyz"); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_string_enoent); + +ATF_TC_HEAD(get_string_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns " + "ENOENT for the path (\"John Doe\", \"title\") in the " + "\"personnel\" property list, and the const char ** argument is " + "unchanged"); +} + +ATF_TC_BODY(get_string_enoent, tc) +{ + int rc; + const char *v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = NULL; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, NULL); + + v = "xyz"; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_STREQ(v, "xyz"); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_string_success); + +ATF_TC_HEAD(get_string_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_string() fetches " + "the \"job title\" property from the \"John Doe\" record in the " + "\"personnel\" property list and compares it with the expected " + "value, \"computer programmer\""); +} + +ATF_TC_BODY(get_string_success, tc) +{ + int rc; + const char *v = NULL;; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(v, "computer programmer"); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, push_until_full); + ATF_TP_ADD_TC(tp, pop_until_empty); + ATF_TP_ADD_TC(tp, length); + ATF_TP_ADD_TC(tp, component_at); + ATF_TP_ADD_TC(tp, get_idx_key); + ATF_TP_ADD_TC(tp, ppath_copy); + ATF_TP_ADD_TC(tp, replace); + + ATF_TP_ADD_TC(tp, delete_bool_eftype); + ATF_TP_ADD_TC(tp, delete_bool_enoent); + ATF_TP_ADD_TC(tp, delete_bool_success); + + ATF_TP_ADD_TC(tp, get_bool_eftype); + ATF_TP_ADD_TC(tp, get_bool_enoent); + ATF_TP_ADD_TC(tp, get_bool_success); + + ATF_TP_ADD_TC(tp, copydel_bool_success); + ATF_TP_ADD_TC(tp, copydel_object_twice_success); + ATF_TP_ADD_TC(tp, copyset_object_twice_success); + ATF_TP_ADD_TC(tp, copyset_bool_success); + ATF_TP_ADD_TC(tp, create_bool_eexist); + ATF_TP_ADD_TC(tp, create_bool_success); + ATF_TP_ADD_TC(tp, set_bool_enoent); + ATF_TP_ADD_TC(tp, set_bool_eftype); + ATF_TP_ADD_TC(tp, set_bool_success); + + ATF_TP_ADD_TC(tp, get_string_eftype); + ATF_TP_ADD_TC(tp, get_string_enoent); + ATF_TP_ADD_TC(tp, get_string_success); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libprop/t_basic.c b/contrib/netbsd-tests/lib/libprop/t_basic.c new file mode 100644 index 0000000..febf29d --- /dev/null +++ b/contrib/netbsd-tests/lib/libprop/t_basic.c @@ -0,0 +1,203 @@ +/* $NetBSD: t_basic.c,v 1.4 2011/04/20 20:02:58 martin Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Written by Jason Thorpe 5/26/2006. + * Public domain. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_basic.c,v 1.4 2011/04/20 20:02:58 martin Exp $"); + +#include <stdlib.h> +#include <string.h> +#include <prop/proplib.h> + +#include <atf-c.h> + +static const char compare1[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" +"<plist version=\"1.0\">\n" +"<dict>\n" +" <key>false-val</key>\n" +" <false/>\n" +" <key>one</key>\n" +" <integer>1</integer>\n" +" <key>three</key>\n" +" <array>\n" +" <dict>\n" +" <key>one</key>\n" +" <integer>1</integer>\n" +" <key>two</key>\n" +" <string>number-two</string>\n" +" </dict>\n" +" <dict>\n" +" <key>one</key>\n" +" <integer>1</integer>\n" +" <key>two</key>\n" +" <string>number-two</string>\n" +" </dict>\n" +" <dict>\n" +" <key>one</key>\n" +" <integer>1</integer>\n" +" <key>two</key>\n" +" <string>number-two</string>\n" +" </dict>\n" +" </array>\n" +" <key>true-val</key>\n" +" <true/>\n" +" <key>two</key>\n" +" <string>number-two</string>\n" +"</dict>\n" +"</plist>\n"; + +ATF_TC(prop_basic); +ATF_TC_HEAD(prop_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of proplib(3)"); +} + +ATF_TC_BODY(prop_basic, tc) +{ + prop_dictionary_t dict; + char *ext1; + + dict = prop_dictionary_create(); + ATF_REQUIRE(dict != NULL); + + { + prop_number_t num = prop_number_create_integer(1); + ATF_REQUIRE(num != NULL); + + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "one", num), true); + prop_object_release(num); + } + + { + prop_string_t str = prop_string_create_cstring("number-two"); + ATF_REQUIRE(str != NULL); + + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "two", str), true); + prop_object_release(str); + } + + { + prop_array_t arr; + prop_dictionary_t dict_copy; + int i; + + arr = prop_array_create(); + ATF_REQUIRE(arr != NULL); + + for (i = 0; i < 3; ++i) { + dict_copy = prop_dictionary_copy(dict); + ATF_REQUIRE(dict_copy != NULL); + ATF_REQUIRE_EQ(prop_array_add(arr, dict_copy), true); + prop_object_release(dict_copy); + } + + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "three", arr), true); + prop_object_release(arr); + } + + { + prop_bool_t val = prop_bool_create(true); + ATF_REQUIRE(val != NULL); + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "true-val", val), true); + prop_object_release(val); + + val = prop_bool_create(false); + ATF_REQUIRE(val != NULL); + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "false-val", val), true); + prop_object_release(val); + } + + ext1 = prop_dictionary_externalize(dict); + ATF_REQUIRE(ext1 != NULL); + ATF_REQUIRE_STREQ(compare1, ext1); + + { + prop_dictionary_t dict2; + char *ext2; + + dict2 = prop_dictionary_internalize(ext1); + ATF_REQUIRE(dict2 != NULL); + ext2 = prop_dictionary_externalize(dict2); + ATF_REQUIRE(ext2 != NULL); + ATF_REQUIRE_STREQ(ext1, ext2); + prop_object_release(dict2); + free(ext2); + } + + prop_object_release(dict); + free(ext1); +} + +ATF_TC(prop_dictionary_equals); +ATF_TC_HEAD(prop_dictionary_equals, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test prop_dictionary_equals(3)"); +} + +ATF_TC_BODY(prop_dictionary_equals, tc) +{ + prop_dictionary_t c, d; + + /* + * Fixed, should not fail any more... + * + atf_tc_expect_death("PR lib/43964"); + * + */ + + d = prop_dictionary_internalize(compare1); + + ATF_REQUIRE(d != NULL); + + c = prop_dictionary_copy(d); + + ATF_REQUIRE(c != NULL); + + if (prop_dictionary_equals(c, d) != true) + atf_tc_fail("dictionaries are not equal"); + + prop_object_release(c); + prop_object_release(d); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, prop_basic); + ATF_TP_ADD_TC(tp, prop_dictionary_equals); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/d_mach b/contrib/netbsd-tests/lib/libpthread/d_mach new file mode 100644 index 0000000..f3c3981 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/d_mach @@ -0,0 +1,92 @@ +above.warped.net +anoncvs.cirr.com +anoncvs.isc.netbsd.org +anoncvs.leo.org +anoncvs.netbsd.lt +anoncvs.netbsd.ro +anoncvs.netbsd.se +antioche.antioche.eu.org +boulder.tele.dk +centaurus.4web.cz +chur.math.ntnu.no +cnftp.bjpu.edu.cn +console.netbsd.org +cvs.fi.netbsd.org +cvs.mikrolahti.fi +cvs.netbsd.org +cvsup-netbsd.leo.org +cvsup.netbsd.se +cvsup.pasta.cs.uit.no +ftp.bitcon.no +ftp.chg.ru +ftp.duth.gr +ftp.estpak.ee +ftp.fsn.hu +ftp.funet.fi +ftp.grondar.za +ftp.leo.org +ftp.netbsd.lt +ftp.netbsd.org +ftp.nluug.nl +ftp.plig.org +ftp.uni-erlangen.de +ftp.xgate.co.kr +gd.tuwien.ac.at +gort.ludd.luth.se +grappa.unix-ag.uni-kl.de +info.wins.uva.nl +irc.warped.net +knug.youn.co.kr +lala.iri.co.jp +mail.jp.netbsd.org +mail.kr.netbsd.org +mail.netbsd.org +melanoma.cs.rmit.edu.au +mirror.aarnet.edu.au +mirror.netbsd.com.br +mirror03.inet.tele.dk +moon.vub.ac.be +nbwww.sergei.cc +net.bsd.cz +netbsd.3miasto.net +netbsd.4ka.mipt.ru +netbsd.apk.od.ua +netbsd.csie.nctu.edu.tw +netbsd.enderunix.org +netbsd.ftp.fu-berlin.de +netbsd.netlead.com.au +netbsd.nsysu.edu.tw +netbsd.pair.com +netbsd.stevens-tech.edu +netbsd.triada.bg +netbsd.unix.net.nz +netbsd.unixtech.be +netbsd.vejas.lt +netbsd.wagener-consulting.lu +netbsd.zarco.org +netbsdiso.interoute.net.uk +netbsdwww.bitcon.no +netbsdwww.cordef.com.pl +netbsdwww.cs.rmit.edu.au +netbsdwww.interoute.net.uk +news.gw.com +ns.netbsd.org +pigu.iri.co.jp +pluto.cdpa.nsysu.edu.tw +projects.slowass.net +server6.pasta.cs.uit.no +skeleton.phys.spbu.ru +snoopy.allbsd.org +spike.allbsd.org +sundry.netbsd.org +tanya.sergei.cc +web-a.fi.gw.com +web-a.us.gw.com +web.netbsd.mirror.arhea.net +www.en.netbsd.de +www.netbsd.cl +www.netbsd.nl +www.netbsd.org +www.netbsd.ro +zathras.netbsd.org +zeppo.rediris.es diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c b/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c new file mode 100644 index 0000000..63bf6a3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c @@ -0,0 +1,86 @@ +/* $NetBSD: h_pthread_dlopen.c,v 1.1 2013/03/21 16:50:22 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_pthread_dlopen.c,v 1.1 2013/03/21 16:50:22 christos Exp $"); + +#if 0 +#include <atf-c.h> +#else +#include <assert.h> +#define ATF_REQUIRE(a) assert(a) +#endif +#include <unistd.h> +#include <pthread.h> + +int testf_dso_null(void); +int testf_dso_mutex_lock(pthread_mutex_t *); +int testf_dso_mutex_unlock(pthread_mutex_t *); +int testf_dso_pthread_create(pthread_t *, const pthread_attr_t *, + void *(*)(void *), void *); + +int +testf_dso_null(void) +{ + return 0xcafe; +} + +int +testf_dso_mutex_lock(pthread_mutex_t *mtx) +{ + ATF_REQUIRE(mtx != NULL); + ATF_REQUIRE(pthread_mutex_lock(mtx) == 0); + + return 0xcafe; +} + +int +testf_dso_mutex_unlock(pthread_mutex_t *mtx) +{ + ATF_REQUIRE(mtx != NULL); + ATF_REQUIRE(pthread_mutex_unlock(mtx) == 0); + + return 0xcafe; +} + +int +testf_dso_pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*routine)(void *), void *arg) +{ + int ret; + + ret = pthread_create(thread, attr, routine, arg); + ATF_REQUIRE(ret == 0); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c new file mode 100644 index 0000000..68e9835 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c @@ -0,0 +1,171 @@ +/* $NetBSD: t_dlopen.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_dlopen.c,v 1.1 2013/03/21 16:50:21 christos Exp $"); + +#include <atf-c.h> +#include <dlfcn.h> +#include <pthread.h> +#include <unistd.h> + +ATF_TC(dlopen); + +ATF_TC_HEAD(dlopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO"); +} + +#define DSO TESTDIR "/h_pthread_dlopen.so" + +ATF_TC_BODY(dlopen, tc) +{ + void *handle; + int (*testf_dso_null)(void); + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_null = dlsym(handle, "testf_dso_null"); + ATF_REQUIRE_MSG(testf_dso_null != NULL, "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_null() == 0xcafe); + + ATF_REQUIRE(dlclose(handle) == 0); +} + +ATF_TC(dlopen_mutex); + +ATF_TC_HEAD(dlopen_mutex, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO without breaking mutex"); +} + +ATF_TC_BODY(dlopen_mutex, tc) +{ + pthread_mutex_t mtx; + void *handle; + int (*testf_dso_null)(void); + + ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0); + ATF_REQUIRE(pthread_mutex_lock(&mtx) == 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_null = dlsym(handle, "testf_dso_null"); + ATF_REQUIRE_MSG(testf_dso_null != NULL, "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_null() == 0xcafe); + + ATF_REQUIRE(pthread_mutex_unlock(&mtx) == 0); + + ATF_REQUIRE(dlclose(handle) == 0); + + pthread_mutex_destroy(&mtx); +} + +ATF_TC(dlopen_mutex_libc); + +ATF_TC_HEAD(dlopen_mutex_libc, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO and use libc locked mutex"); +} + +ATF_TC_BODY(dlopen_mutex_libc, tc) +{ + pthread_mutex_t mtx; + void *handle; + int (*testf_dso_mutex_unlock)(pthread_mutex_t *); + + ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0); + ATF_REQUIRE(pthread_mutex_lock(&mtx) == 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_mutex_unlock = dlsym(handle, "testf_dso_mutex_unlock"); + ATF_REQUIRE_MSG(testf_dso_mutex_unlock != NULL, + "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_mutex_unlock(&mtx) == 0xcafe); + + dlclose(handle); + + pthread_mutex_destroy(&mtx); +} + +ATF_TC(dlopen_mutex_libpthread); + +ATF_TC_HEAD(dlopen_mutex_libpthread, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO and use " + "libpthread locked mutex"); +} + +ATF_TC_BODY(dlopen_mutex_libpthread, tc) +{ + pthread_mutex_t mtx; + void *handle; + int (*testf_dso_mutex_lock)(pthread_mutex_t *); + + ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_mutex_lock = dlsym(handle, "testf_dso_mutex_lock"); + ATF_REQUIRE_MSG(testf_dso_mutex_lock != NULL, + "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_mutex_lock(&mtx) == 0xcafe); + + ATF_REQUIRE(pthread_mutex_unlock(&mtx) == 0); + + dlclose(handle); + + pthread_mutex_destroy(&mtx); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dlopen); + ATF_TP_ADD_TC(tp, dlopen_mutex); + ATF_TP_ADD_TC(tp, dlopen_mutex_libc); + ATF_TP_ADD_TC(tp, dlopen_mutex_libpthread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c new file mode 100644 index 0000000..ab8bec3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c @@ -0,0 +1,96 @@ +/* $NetBSD: t_dso_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_dso_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $"); + +#include <sys/resource.h> +#include <atf-c.h> +#include <dlfcn.h> +#include <pthread.h> +#include <unistd.h> + +#define DSO TESTDIR "/h_pthread_dlopen.so" + +void * +routine(void *arg) +{ + ATF_REQUIRE((intptr_t)arg == 0xcafe); + return NULL; +} + +ATF_TC(dso_pthread_create_dso); + +ATF_TC_HEAD(dso_pthread_create_dso, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if non -lpthread main can call pthread_create() " + "in -lpthread DSO"); +} + +ATF_TC_BODY(dso_pthread_create_dso, tc) +{ + int ret; + pthread_t thread; + void *arg = (void *)0xcafe; + void *handle; + int (*testf_dso_pthread_create)(pthread_t *, pthread_attr_t *, + void *(*)(void *), void *); + struct rlimit rl; + + atf_tc_expect_signal(6, + "calling pthread_create() requires -lpthread main"); + + rl.rlim_max = rl.rlim_cur = 0; + ATF_REQUIRE_EQ(setrlimit(RLIMIT_CORE, &rl), 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_pthread_create = dlsym(handle, "testf_dso_pthread_create"); + ATF_REQUIRE_MSG(testf_dso_pthread_create != NULL, + "dlsym fails: %s", dlerror()); + + ret = testf_dso_pthread_create(&thread, NULL, routine, arg); + ATF_REQUIRE(ret == 0); + + ATF_REQUIRE(dlclose(handle) == 0); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dso_pthread_create_dso); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c new file mode 100644 index 0000000..7ba89b3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c @@ -0,0 +1,106 @@ +/* $NetBSD: t_main_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_main_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $"); + +#include <atf-c.h> +#include <dlfcn.h> +#include <pthread.h> +#include <unistd.h> + +#define DSO TESTDIR "/h_pthread_dlopen.so" + +void * +routine(void *arg) +{ + ATF_REQUIRE((intptr_t)arg == 0xcafe); + return NULL; +} + +ATF_TC(main_pthread_create_main); + +ATF_TC_HEAD(main_pthread_create_main, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if -lpthread main can call pthread_create() in main()"); +} + +ATF_TC_BODY(main_pthread_create_main, tc) +{ + int ret; + pthread_t thread; + void *arg = (void *)0xcafe; + + ret = pthread_create(&thread, NULL, routine, arg); + ATF_REQUIRE(ret == 0); +} + +ATF_TC(main_pthread_create_dso); + +ATF_TC_HEAD(main_pthread_create_dso, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if -lpthread main can call pthread_create() in DSO"); +} + +ATF_TC_BODY(main_pthread_create_dso, tc) +{ + int ret; + pthread_t thread; + void *arg = (void *)0xcafe; + void *handle; + int (*testf_dso_pthread_create)(pthread_t *, pthread_attr_t *, + void *(*)(void *), void *); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_pthread_create = dlsym(handle, "testf_dso_pthread_create"); + ATF_REQUIRE_MSG(testf_dso_pthread_create != NULL, + "dlsym fails: %s", dlerror()); + + ret = testf_dso_pthread_create(&thread, NULL, routine, arg); + ATF_REQUIRE(ret == 0); + + ATF_REQUIRE(dlclose(handle) == 0); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, main_pthread_create_main); + ATF_TP_ADD_TC(tp, main_pthread_create_dso); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_atexit.c b/contrib/netbsd-tests/lib/libpthread/h_atexit.c new file mode 100644 index 0000000..2d4c91c --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_atexit.c @@ -0,0 +1,183 @@ +/* $NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Program to test atexit(3) and __cxa_atexit()/__cxa_finalize(). + * + * Written by Jason R. Thorpe, February 2003. + * Public domain. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +extern int __cxa_atexit(void (*func)(void *), void *, void *); +extern void __cxa_finalize(void *); + +static int dso_handle_1; +static int dso_handle_2; +static int dso_handle_3; + +static int arg_1; +static int arg_2; +static int arg_3; + +static int exiting_state; + +#define ASSERT(expr) \ +do { \ + if ((expr) == 0) { \ + write(STDERR_FILENO, __func__, strlen(__func__)); \ + write(STDERR_FILENO, ": ", 2); \ + write(STDERR_FILENO, __STRING(expr), \ + strlen(__STRING(expr))); \ + write(STDERR_FILENO, "\n", 1); \ + my_abort(); \ + } \ +} while (/*CONSTCOND*/0) + +#define SUCCESS() \ +do { \ + write(STDOUT_FILENO, __func__, strlen(__func__)); \ + write(STDOUT_FILENO, "\n", 1); \ +} while (/*CONSTCOND*/0) + +static void +my_abort(void) +{ + + kill(getpid(), SIGABRT); + /* NOTREACHED */ +} + +static void +cxa_handler_5(void *arg) +{ + static int cxa_handler_5_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_5_called == 0); + ASSERT(exiting_state == 5); + + exiting_state--; + cxa_handler_5_called = 1; + SUCCESS(); +} + +static void +cxa_handler_4(void *arg) +{ + static int cxa_handler_4_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_4_called == 0); + ASSERT(exiting_state == 4); + + exiting_state--; + cxa_handler_4_called = 1; + SUCCESS(); +} + +static void +cxa_handler_3(void *arg) +{ + static int cxa_handler_3_called; + + ASSERT(arg == (void *)&arg_2); + ASSERT(cxa_handler_3_called == 0); + ASSERT(exiting_state == 3); + + exiting_state--; + cxa_handler_3_called = 1; + SUCCESS(); +} + +static void +cxa_handler_2(void *arg) +{ + static int cxa_handler_2_called; + + ASSERT(arg == (void *)&arg_3); + ASSERT(cxa_handler_2_called == 0); + ASSERT(exiting_state == 2); + + exiting_state--; + cxa_handler_2_called = 1; + SUCCESS(); +} + +static void +normal_handler_1(void) +{ + static int normal_handler_1_called; + + ASSERT(normal_handler_1_called == 0); + ASSERT(exiting_state == 1); + + exiting_state--; + normal_handler_1_called = 1; + SUCCESS(); +} + +static void +normal_handler_0(void) +{ + static int normal_handler_0_called; + + ASSERT(normal_handler_0_called == 0); + ASSERT(exiting_state == 0); + + normal_handler_0_called = 1; + SUCCESS(); +} + +int +main(int argc, char *argv[]) +{ + + exiting_state = 5; + + ASSERT(0 == atexit(normal_handler_0)); + ASSERT(0 == atexit(normal_handler_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3)); + + __cxa_finalize(&dso_handle_1); + __cxa_finalize(&dso_handle_2); + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_cancel.c b/contrib/netbsd-tests/lib/libpthread/h_cancel.c new file mode 100644 index 0000000..1077806 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_cancel.c @@ -0,0 +1,58 @@ +/* $NetBSD: h_cancel.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_cancel.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <unistd.h> + +int +main(void) +{ + char str1[] = "You should see this.\n"; + char str2[] = "You should not see this.\n"; + + printf("Cancellation test: Self-cancellation and disabling.\n"); + + pthread_cancel(pthread_self()); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + + write(STDOUT_FILENO, str1, sizeof(str1)-1); + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + write(STDOUT_FILENO, str2, sizeof(str2)-1); + + exit(1); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_common.h b/contrib/netbsd-tests/lib/libpthread/h_common.h new file mode 100644 index 0000000..f4d03bc --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_common.h @@ -0,0 +1,12 @@ +#ifndef H_COMMON_H +#define H_COMMON_H + +#include <string.h> + +#define PTHREAD_REQUIRE(x) \ + do { \ + int ret = (x); \ + ATF_REQUIRE_MSG(ret == 0, "%s: %s", #x, strerror(ret)); \ + } while (0) + +#endif // H_COMMON_H diff --git a/contrib/netbsd-tests/lib/libpthread/h_exit.c b/contrib/netbsd-tests/lib/libpthread/h_exit.c new file mode 100644 index 0000000..a37f88f --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_exit.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_exit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_exit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> + +int +main(void) +{ + printf("Test of pthread_exit() in main thread only.\n"); + + pthread_exit(NULL); + + printf("You shouldn't see this."); + exit(1); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_resolv.c b/contrib/netbsd-tests/lib/libpthread/h_resolv.c new file mode 100644 index 0000000..9c5fedc --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_resolv.c @@ -0,0 +1,208 @@ +/* $NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */ + +/*- + * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $"); + +#include <pthread.h> +#include <stdio.h> +#include <netdb.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> +#include <string.h> +#include <stringlist.h> + +#define NTHREADS 10 +#define NHOSTS 100 +#define WS " \t\n\r" + +static StringList *hosts = NULL; +static int debug = 0; +static int *ask = NULL; +static int *got = NULL; + +static void usage(void) __attribute__((__noreturn__)); +static void load(const char *); +static void resolvone(int); +static void *resolvloop(void *); +static void run(int *); + +static pthread_mutex_t stats = PTHREAD_MUTEX_INITIALIZER; + +static void +usage(void) +{ + (void)fprintf(stderr, + "Usage: %s [-d] [-h <nhosts>] [-n <nthreads>] <file> ...\n", + getprogname()); + exit(1); +} + +static void +load(const char *fname) +{ + FILE *fp; + size_t len; + char *line; + + if ((fp = fopen(fname, "r")) == NULL) + err(1, "Cannot open `%s'", fname); + while ((line = fgetln(fp, &len)) != NULL) { + char c = line[len]; + char *ptr; + line[len] = '\0'; + for (ptr = strtok(line, WS); ptr; ptr = strtok(NULL, WS)) + sl_add(hosts, strdup(ptr)); + line[len] = c; + } + + (void)fclose(fp); +} + +static void +resolvone(int n) +{ + char buf[1024]; + pthread_t self = pthread_self(); + size_t i = (random() & 0x0fffffff) % hosts->sl_cur; + char *host = hosts->sl_str[i]; + struct addrinfo *res; + int error, len; + if (debug) { + len = snprintf(buf, sizeof(buf), "%p: %d resolving %s %d\n", + self, n, host, (int)i); + (void)write(STDOUT_FILENO, buf, len); + } + error = getaddrinfo(host, NULL, NULL, &res); + if (debug) { + len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", + self, host, error ? "not found" : "ok"); + (void)write(STDOUT_FILENO, buf, len); + } + pthread_mutex_lock(&stats); + ask[i]++; + got[i] += error == 0; + pthread_mutex_unlock(&stats); + if (error == 0) + freeaddrinfo(res); +} + +static void * +resolvloop(void *p) +{ + int *nhosts = (int *)p; + if (*nhosts == 0) + return NULL; + do + resolvone(*nhosts); + while (--(*nhosts)); + return NULL; +} + +static void +run(int *nhosts) +{ + pthread_t self = pthread_self(); + if (pthread_create(&self, NULL, resolvloop, nhosts) != 0) + err(1, "pthread_create"); +} + +int +main(int argc, char *argv[]) +{ + int nthreads = NTHREADS; + int nhosts = NHOSTS; + int i, c, done, *nleft; + hosts = sl_init(); + + srandom(1234); + + while ((c = getopt(argc, argv, "dh:n:")) != -1) + switch (c) { + case 'd': + debug++; + break; + case 'h': + nhosts = atoi(optarg); + break; + case 'n': + nthreads = atoi(optarg); + break; + default: + usage(); + } + + for (i = optind; i < argc; i++) + load(argv[i]); + + if (hosts->sl_cur == 0) + usage(); + + if ((nleft = malloc(nthreads * sizeof(int))) == NULL) + err(1, "malloc"); + if ((ask = calloc(hosts->sl_cur, sizeof(int))) == NULL) + err(1, "calloc"); + if ((got = calloc(hosts->sl_cur, sizeof(int))) == NULL) + err(1, "calloc"); + + + for (i = 0; i < nthreads; i++) { + nleft[i] = nhosts; + run(&nleft[i]); + } + + for (done = 0; !done;) { + done = 1; + for (i = 0; i < nthreads; i++) { + if (nleft[i] != 0) { + done = 0; + break; + } + } + sleep(1); + } + c = 0; + for (i = 0; i < (int)hosts->sl_cur; i++) { + if (ask[i] != got[i] && got[i] != 0) { + warnx("Error: host %s ask %d got %d\n", + hosts->sl_str[i], ask[i], got[i]); + c++; + } + } + free(nleft); + free(ask); + free(got); + sl_free(hosts, 1); + return c; +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_atexit.sh b/contrib/netbsd-tests/lib/libpthread/t_atexit.sh new file mode 100755 index 0000000..7b99618 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_atexit.sh @@ -0,0 +1,49 @@ +# $NetBSD: t_atexit.sh,v 1.2 2010/11/07 17:51:20 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case atexit +atexit_head() +{ + atf_set "descr" "Checks atexit functionality" +} +atexit_body() +{ + cat >expout <<EOF +cxa_handler_5 +cxa_handler_4 +cxa_handler_3 +cxa_handler_2 +normal_handler_1 +normal_handler_0 +EOF + atf_check -o file:expout "$(atf_get_srcdir)/h_atexit" +} + +atf_init_test_cases() +{ + atf_add_test_case atexit +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_barrier.c b/contrib/netbsd-tests/lib/libpthread/t_barrier.c new file mode 100644 index 0000000..a06cfd9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_barrier.c @@ -0,0 +1,110 @@ +/* $NetBSD: t_barrier.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_barrier.c,v 1.2 2010/11/03 16:10:22 christos Exp $"); + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +#define COUNT 5 + +pthread_barrier_t barrier; +pthread_mutex_t mutex; +int serial_count; +int after_barrier_count; + +static void * +threadfunc(void *arg) +{ + int which = (int)(long)arg; + int rv; + + printf("thread %d entering barrier\n", which); + rv = pthread_barrier_wait(&barrier); + printf("thread %d leaving barrier -> %d\n", which, rv); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + after_barrier_count++; + if (rv == PTHREAD_BARRIER_SERIAL_THREAD) + serial_count++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return NULL; +} + +ATF_TC(barrier); +ATF_TC_HEAD(barrier, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks barriers"); +} +ATF_TC_BODY(barrier, tc) +{ + int i; + pthread_t new[COUNT]; + void *joinval; + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_barrier_init(&barrier, NULL, COUNT)); + + for (i = 0; i < COUNT; i++) { + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + ATF_REQUIRE_EQ(after_barrier_count, 0); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&new[i], NULL, threadfunc, + (void *)(long)i)); + sleep(2); + } + + for (i = 0; i < COUNT; i++) { + PTHREAD_REQUIRE(pthread_join(new[i], &joinval)); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + ATF_REQUIRE(after_barrier_count > i); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("main joined with thread %d\n", i); + } + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + ATF_REQUIRE_EQ(after_barrier_count, COUNT); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + ATF_REQUIRE_EQ(serial_count, 1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, barrier); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_cancel.sh b/contrib/netbsd-tests/lib/libpthread/t_cancel.sh new file mode 100755 index 0000000..4a0701e --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_cancel.sh @@ -0,0 +1,44 @@ +# $NetBSD: t_cancel.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case register_while_disabled +register_while_disabled_head() +{ + atf_set "descr" "Checks that a cancellation registered while" \ + "cancellation is enabled is not honored while cancellation is" \ + "disabled" +} +register_while_disabled_body() +{ + atf_check -o inline:"You should see this.\n" \ + "$(atf_get_srcdir)/h_cancel" +} + +atf_init_test_cases() +{ + atf_add_test_case register_while_disabled +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_cond.c b/contrib/netbsd-tests/lib/libpthread/t_cond.c new file mode 100644 index 0000000..9f33c9e --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_cond.c @@ -0,0 +1,563 @@ +/* $NetBSD: t_cond.c,v 1.6 2014/09/03 16:23:24 gson Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_cond.c,v 1.6 2014/09/03 16:23:24 gson Exp $"); + +#include <sys/time.h> + +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +static pthread_mutex_t mutex; +static pthread_cond_t cond; +static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t static_cond = PTHREAD_COND_INITIALIZER; +static int count, share, toggle, total; + +static void * +signal_delay_wait_threadfunc(void *arg) +{ + int *shared = (int *) arg; + + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("2: Got mutex.\n"); + printf("Shared value: %d. Changing to 0.\n", *shared); + *shared = 0; + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&cond)); + + return NULL; +} + +ATF_TC(signal_delay_wait); +ATF_TC_HEAD(signal_delay_wait, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks condition variables"); +} +ATF_TC_BODY(signal_delay_wait, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 1\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + sharedval = 1; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, signal_delay_wait_threadfunc, + &sharedval)); + + printf("1: Before waiting.\n"); + do { + sleep(2); + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + printf("1: After waiting, in loop.\n"); + } while (sharedval != 0); + + printf("1: After the loop.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +static void * +signal_before_unlock_threadfunc(void *arg) +{ + int *shared = (int *) arg; + + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("2: Got mutex.\n"); + printf("Shared value: %d. Changing to 0.\n", *shared); + *shared = 0; + + /* Signal first, then unlock, for a different test than #1. */ + PTHREAD_REQUIRE(pthread_cond_signal(&cond)); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return NULL; +} + +ATF_TC(signal_before_unlock); +ATF_TC_HEAD(signal_before_unlock, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: signal before unlocking mutex"); +} +ATF_TC_BODY(signal_before_unlock, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 2\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + sharedval = 1; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, + signal_before_unlock_threadfunc, &sharedval)); + + printf("1: Before waiting.\n"); + do { + sleep(2); + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + printf("1: After waiting, in loop.\n"); + } while (sharedval != 0); + + printf("1: After the loop.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +static void * +signal_before_unlock_static_init_threadfunc(void *arg) +{ + int *shared = (int *) arg; + + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + printf("2: Got mutex.\n"); + printf("Shared value: %d. Changing to 0.\n", *shared); + *shared = 0; + + /* Signal first, then unlock, for a different test than #1. */ + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + return NULL; +} + +ATF_TC(signal_before_unlock_static_init); +ATF_TC_HEAD(signal_before_unlock_static_init, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: signal before unlocking " + "mutex, use static initializers"); +} +ATF_TC_BODY(signal_before_unlock_static_init, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 3\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + sharedval = 1; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, + signal_before_unlock_static_init_threadfunc, &sharedval)); + + printf("1: Before waiting.\n"); + do { + sleep(2); + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, &static_mutex)); + printf("1: After waiting, in loop.\n"); + } while (sharedval != 0); + + printf("1: After the loop.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +static void * +signal_wait_race_threadfunc(void *arg) +{ + printf("2: Second thread.\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + printf("2: Before the loop.\n"); + while (count>0) { + count--; + total++; + toggle = 0; + /* printf("2: Before signal %d.\n", count); */ + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 1); + } + printf("2: After the loop.\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + return NULL; +} + +ATF_TC(signal_wait_race); +ATF_TC_HEAD(signal_wait_race, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks condition variables"); +} +ATF_TC_BODY(signal_wait_race, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 4\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + count = 50000; + toggle = 0; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, signal_wait_race_threadfunc, + &sharedval)); + + printf("1: Before waiting.\n"); + while (count>0) { + count--; + total++; + toggle = 1; + /* printf("1: Before signal %d.\n", count); */ + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 0); + } + printf("1: After the loop.\n"); + + toggle = 1; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined. Final count = %d, total = %d\n", + count, total); + + ATF_REQUIRE_EQ(count, 0); + ATF_REQUIRE_EQ(total, 50000); +} + +static void * +pthread_cond_timedwait_func(void *arg) +{ + struct timespec ts; + size_t i = 0; + int rv; + + for (;;) { + + if (i++ >= 10000) + pthread_exit(NULL); + + (void)memset(&ts, 0, sizeof(struct timespec)); + + ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &ts) == 0); + + /* + * Set to one second in the past: + * pthread_cond_timedwait(3) should + * return ETIMEDOUT immediately. + */ + ts.tv_sec = ts.tv_sec - 1; + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + rv = pthread_cond_timedwait(&static_cond, &static_mutex, &ts); + + /* + * Sometimes we catch ESRCH. + * This should never happen. + */ + ATF_REQUIRE(rv == ETIMEDOUT); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + } +} + +ATF_TC(cond_timedwait_race); +ATF_TC_HEAD(cond_timedwait_race, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pthread_cond_timedwait(3)"); + +} +ATF_TC_BODY(cond_timedwait_race, tc) +{ + pthread_t tid[64]; + size_t i; + + for (i = 0; i < __arraycount(tid); i++) { + + PTHREAD_REQUIRE(pthread_create(&tid[i], NULL, + pthread_cond_timedwait_func, NULL)); + } + + for (i = 0; i < __arraycount(tid); i++) { + + PTHREAD_REQUIRE(pthread_join(tid[i], NULL)); + } +} + +static void * +broadcast_threadfunc(void *arg) +{ + printf("2: Second thread.\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + while (count>0) { + count--; + total++; + toggle = 0; + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 1); + } + printf("2: After the loop.\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + return NULL; +} + + +ATF_TC(broadcast); +ATF_TC_HEAD(broadcast, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: use pthread_cond_broadcast()"); +} +ATF_TC_BODY(broadcast, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 5\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + count = 50000; + toggle = 0; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, broadcast_threadfunc, + &sharedval)); + + printf("1: Before waiting.\n"); + while (count>0) { + count--; + total++; + toggle = 1; + PTHREAD_REQUIRE(pthread_cond_broadcast(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 0); + } + printf("1: After the loop.\n"); + + toggle = 1; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined. Final count = %d, total = %d\n", count, + total); + + ATF_REQUIRE_EQ(count, 0); + ATF_REQUIRE_EQ(total, 50000); +} + +static void * +bogus_timedwaits_threadfunc(void *arg) +{ + return NULL; +} + +ATF_TC(bogus_timedwaits); +ATF_TC_HEAD(bogus_timedwaits, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: bogus timedwaits"); +} +ATF_TC_BODY(bogus_timedwaits, tc) +{ + pthread_t new; + struct timespec ts; + struct timeval tv; + + printf("condition variable test 6: bogus timedwaits\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + printf("unthreaded test (past)\n"); + gettimeofday(&tv, NULL); + tv.tv_sec -= 2; /* Place the time in the past */ + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (unthreaded) in the " + "past"); + + printf("unthreaded test (zero time)\n"); + tv.tv_sec = 0; + tv.tv_usec = 0; + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (unthreaded) with zero " + "time"); + + PTHREAD_REQUIRE(pthread_create(&new, NULL, bogus_timedwaits_threadfunc, + NULL)); + PTHREAD_REQUIRE(pthread_join(new, NULL)); + + printf("threaded test\n"); + gettimeofday(&tv, NULL); + tv.tv_sec -= 2; /* Place the time in the past */ + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (threaded) in the past"); + + printf("threaded test (zero time)\n"); + tv.tv_sec = 0; + tv.tv_usec = 0; + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (threaded) with zero " + "time"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); +} + +static void +unlock(void *arg) +{ + pthread_mutex_unlock((pthread_mutex_t *)arg); +} + +static void * +destroy_after_cancel_threadfunc(void *arg) +{ + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + pthread_cleanup_push(unlock, &mutex); + + while (1) { + share = 1; + PTHREAD_REQUIRE(pthread_cond_broadcast(&cond)); + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + } + + pthread_cleanup_pop(0); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return NULL; +} + +ATF_TC(destroy_after_cancel); +ATF_TC_HEAD(destroy_after_cancel, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks destroying a condition variable " + "after cancelling a wait"); +} +ATF_TC_BODY(destroy_after_cancel, tc) +{ + pthread_t thread; + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&thread, NULL, + destroy_after_cancel_threadfunc, NULL)); + + while (share == 0) { + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + } + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_cancel(thread)); + + PTHREAD_REQUIRE(pthread_join(thread, NULL)); + PTHREAD_REQUIRE(pthread_cond_destroy(&cond)); + + PTHREAD_REQUIRE(pthread_mutex_destroy(&mutex)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, signal_delay_wait); + ATF_TP_ADD_TC(tp, signal_before_unlock); + ATF_TP_ADD_TC(tp, signal_before_unlock_static_init); + ATF_TP_ADD_TC(tp, signal_wait_race); + ATF_TP_ADD_TC(tp, cond_timedwait_race); + ATF_TP_ADD_TC(tp, broadcast); + ATF_TP_ADD_TC(tp, bogus_timedwaits); + ATF_TP_ADD_TC(tp, destroy_after_cancel); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_condwait.c b/contrib/netbsd-tests/lib/libpthread/t_condwait.c new file mode 100644 index 0000000..9b79587 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_condwait.c @@ -0,0 +1,142 @@ +/* $NetBSD: t_condwait.c,v 1.4 2013/04/12 17:18:11 christos Exp $ */ + +/* + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_condwait.c,v 1.4 2013/04/12 17:18:11 christos Exp $"); + +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "isqemu.h" + +#define WAITTIME 2 /* Timeout wait secound */ + +static const int debug = 1; + +static void * +run(void *param) +{ + struct timespec ts, to, te; + clockid_t clck; + pthread_condattr_t attr; + pthread_cond_t cond; + pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; + int ret = 0; + + + clck = *(clockid_t *)param; + pthread_condattr_init(&attr); + pthread_condattr_setclock(&attr, clck); /* MONOTONIC or MONOTONIC */ + pthread_cond_init(&cond, &attr); + + ATF_REQUIRE_EQ((ret = pthread_mutex_lock(&m)), 0); + + ATF_REQUIRE_EQ(clock_gettime(clck, &ts), 0); + to = ts; + + if (debug) + printf("started: %lld.%09ld sec\n", (long long)to.tv_sec, + to.tv_nsec); + + ts.tv_sec += WAITTIME; /* Timeout wait */ + + switch (ret = pthread_cond_timedwait(&cond, &m, &ts)) { + case ETIMEDOUT: + /* Timeout */ + ATF_REQUIRE_EQ(clock_gettime(clck, &te), 0); + timespecsub(&te, &to, &to); + if (debug) { + printf("timeout: %lld.%09ld sec\n", + (long long)te.tv_sec, te.tv_nsec); + printf("elapsed: %lld.%09ld sec\n", + (long long)to.tv_sec, to.tv_nsec); + } + if (isQEMU()) { + double to_seconds = to.tv_sec + 1e-9 * to.tv_nsec; + ATF_REQUIRE(to_seconds >= WAITTIME * 0.9); + /* Loose upper limit because of qemu timing bugs */ + ATF_REQUIRE(to_seconds < WAITTIME * 2.5); + } else { + ATF_REQUIRE_EQ(to.tv_sec, WAITTIME); + } + break; + default: + ATF_REQUIRE_MSG(0, "pthread_cond_timedwait: %s", strerror(ret)); + } + + ATF_REQUIRE_MSG(!(ret = pthread_mutex_unlock(&m)), + "pthread_mutex_unlock: %s", strerror(ret)); + pthread_exit(&ret); +} + +static void +cond_wait(clockid_t clck, const char *msg) { + pthread_t child; + + if (debug) + printf( "**** %s clock wait starting\n", msg); + ATF_REQUIRE_EQ(pthread_create(&child, NULL, run, &clck), 0); + ATF_REQUIRE_EQ(pthread_join(child, NULL), 0); /* wait for terminate */ + if (debug) + printf( "**** %s clock wait ended\n", msg); +} + +ATF_TC(cond_wait_real); +ATF_TC_HEAD(cond_wait_real, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_cond_timedwait " + "with CLOCK_REALTIME"); +} + +ATF_TC_BODY(cond_wait_real, tc) { + cond_wait(CLOCK_REALTIME, "CLOCK_REALTIME"); +} + +ATF_TC(cond_wait_mono); +ATF_TC_HEAD(cond_wait_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_cond_timedwait " + "with CLOCK_MONOTONIC"); +} + +ATF_TC_BODY(cond_wait_mono, tc) { + cond_wait(CLOCK_MONOTONIC, "CLOCK_MONOTONIC"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, cond_wait_real); + ATF_TP_ADD_TC(tp, cond_wait_mono); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_detach.c b/contrib/netbsd-tests/lib/libpthread/t_detach.c new file mode 100644 index 0000000..21db871 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_detach.c @@ -0,0 +1,91 @@ +/* $NetBSD: t_detach.c,v 1.1 2011/03/24 13:52:04 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_detach.c,v 1.1 2011/03/24 13:52:04 jruoho Exp $"); + +#include <pthread.h> +#include <errno.h> + +#include <atf-c.h> + +#include "h_common.h" + +static void *func(void *); + +static void * +func(void *arg) +{ + return NULL; +} + +ATF_TC(pthread_detach); +ATF_TC_HEAD(pthread_detach, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of pthread_detach(3)"); +} + +ATF_TC_BODY(pthread_detach, tc) +{ + const int state = PTHREAD_CREATE_JOINABLE; + pthread_attr_t attr; + pthread_t t; + int rv; + + /* + * Create a joinable thread. + */ + PTHREAD_REQUIRE(pthread_attr_init(&attr)); + PTHREAD_REQUIRE(pthread_attr_setdetachstate(&attr, state)); + PTHREAD_REQUIRE(pthread_create(&t, &attr, func, NULL)); + + /* + * Detach the thread and try to + * join it; EINVAL should follow. + */ + PTHREAD_REQUIRE(pthread_detach(t)); + + rv = pthread_join(t, NULL); + ATF_REQUIRE(rv == EINVAL); + + /* + * As usual, ESRCH should follow if + * we try to detach an invalid thread. + */ + rv = pthread_cancel(NULL); + ATF_REQUIRE(rv == ESRCH); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pthread_detach); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_equal.c b/contrib/netbsd-tests/lib/libpthread/t_equal.c new file mode 100644 index 0000000..bcda996 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_equal.c @@ -0,0 +1,74 @@ +/* $NetBSD: t_equal.c,v 1.1 2011/03/24 12:40:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_equal.c,v 1.1 2011/03/24 12:40:59 jruoho Exp $"); + +#include <pthread.h> + +#include <atf-c.h> + +#include "h_common.h" + +static void *func(void *); + +static void * +func(void *arg) +{ + return NULL; +} + +ATF_TC(pthread_equal); +ATF_TC_HEAD(pthread_equal, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of pthread_equal(3)"); +} + +ATF_TC_BODY(pthread_equal, tc) +{ + pthread_t t1, t2; + + ATF_REQUIRE(pthread_create(&t1, NULL, func, NULL) == 0); + ATF_REQUIRE(pthread_create(&t2, NULL, func, NULL) == 0); + + ATF_REQUIRE(pthread_equal(t1, t1) != 0); + ATF_REQUIRE(pthread_equal(t2, t2) != 0); + ATF_REQUIRE(pthread_equal(t1, t2) == 0); + + ATF_REQUIRE(pthread_join(t1, NULL) == 0); + ATF_REQUIRE(pthread_join(t2, NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pthread_equal); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_exit.sh b/contrib/netbsd-tests/lib/libpthread/t_exit.sh new file mode 100755 index 0000000..7fbd689 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_exit.sh @@ -0,0 +1,41 @@ +# $NetBSD: t_exit.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case main_thread +main_thread_head() +{ + atf_set "descr" "Checks calling pthread_exit() in the main thread" +} +main_thread_body() +{ + atf_check -o ignore "$(atf_get_srcdir)/h_exit" +} + +atf_init_test_cases() +{ + atf_add_test_case main_thread +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_fork.c b/contrib/netbsd-tests/lib/libpthread/t_fork.c new file mode 100644 index 0000000..ab8806d --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_fork.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_fork.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fork.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +/* + * Written by Love Hörnquist Åstrand <lha@NetBSD.org>, March 2003. + * Public domain. + */ + +#include <sys/types.h> +#include <sys/wait.h> + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +static pid_t parent; +static int thread_survived = 0; + +static void * +print_pid(void *arg) +{ + sleep(3); + + thread_survived = 1; + if (parent != getpid()) { + exit(1); + } + return NULL; +} + +ATF_TC(fork); +ATF_TC_HEAD(fork, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that child process doesn't get threads"); +} +ATF_TC_BODY(fork, tc) +{ + pthread_t p; + pid_t fork_pid; + + parent = getpid(); + + PTHREAD_REQUIRE(pthread_create(&p, NULL, print_pid, NULL)); + + fork_pid = fork(); + ATF_REQUIRE(fork_pid != -1); + + if (fork_pid) { + int status; + + PTHREAD_REQUIRE(pthread_join(p, NULL)); + ATF_REQUIRE_MSG(thread_survived, "thread did not survive in parent"); + + waitpid(fork_pid, &status, 0); + ATF_REQUIRE_MSG(WIFEXITED(status), "child died wrongly"); + ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), 0, "thread survived in child"); + } else { + sleep(5); + exit(thread_survived ? 1 : 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fork); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_fpu.c b/contrib/netbsd-tests/lib/libpthread/t_fpu.c new file mode 100644 index 0000000..4047b1f --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_fpu.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_fpu.c,v 1.2 2013/01/27 14:47:37 mbalmer Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fpu.c,v 1.2 2013/01/27 14:47:37 mbalmer Exp $"); + +/* + * This is adapted from part of csw/cstest of the MPD implementation by + * the University of Arizona CS department (http://www.cs.arizona.edu/sr/) + * which is in the public domain: + * + * "The MPD system is in the public domain and you may use and distribute it + * as you wish. We ask that you retain credits referencing the University + * of Arizona and that you identify any changes you make. + * + * We can't provide a warranty with MPD; it's up to you to determine its + * suitability and reliability for your needs. We would like to hear of + * any problems you encounter but we cannot promise a timely correction." + * + * It was changed to use pthread_create() and sched_yield() instead of + * the internal MPD context switching primitives by Ignatios Souvatzis + * <is@netbsd.org>. + */ + +#include <math.h> +#include <pthread.h> +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +#define N_RECURSE 10 + +static void recurse(void); + +int recursion_depth = 0; +pthread_mutex_t recursion_depth_lock; + +static void * +stir(void *p) +{ + double *q = (double *)p; + double x = *q++; + double y = *q++; + double z = *q++; + + for (;;) { + x = sin ((y = cos (x + y + .4)) - (z = cos (x + z + .6))); + PTHREAD_REQUIRE(sched_yield()); + } +} + +static double +mul3(double x, double y, double z) +{ + PTHREAD_REQUIRE(sched_yield()); + + return x * y * z; +} + +static void * +bar(void *p) +{ + double d; + int rc; + + d = mul3(mul3(2., 3., 5.), mul3(7., 11., 13.), mul3(17., 19., 23.)); + ATF_REQUIRE_EQ(d, 223092870.); + + PTHREAD_REQUIRE(pthread_mutex_lock(&recursion_depth_lock)); + rc = recursion_depth++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&recursion_depth_lock)); + + if (rc < N_RECURSE) + recurse(); + else + atf_tc_pass(); + + /* NOTREACHED */ + return NULL; +} + +static void +recurse(void) { + pthread_t s2; + pthread_create(&s2, 0, bar, 0); + sleep(20); /* XXX must be long enough for our slowest machine */ +} + +ATF_TC(fpu); +ATF_TC_HEAD(fpu, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that thread context switches will leave the " + "floating point computations unharmed"); +} +ATF_TC_BODY(fpu, tc) +{ + double stirseed[] = { 1.7, 3.2, 2.4 }; + pthread_t s5; + + printf("Testing threaded floating point computations...\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&recursion_depth_lock, 0)); + + pthread_create(&s5, 0, stir, stirseed); + recurse(); + + atf_tc_fail("exiting from main"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fpu); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_join.c b/contrib/netbsd-tests/lib/libpthread/t_join.c new file mode 100644 index 0000000..7f6f834 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_join.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $"); + +#include <errno.h> +#include <pthread.h> +#include <stdint.h> + +#include <atf-c.h> + +#include "h_common.h" + +#ifdef CHECK_STACK_ALIGNMENT +extern int check_stack_alignment(void); +#endif + +#define STACKSIZE 65536 + +static bool error; + +static void *threadfunc1(void *); +static void *threadfunc2(void *); + +ATF_TC(pthread_join); +ATF_TC_HEAD(pthread_join, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks basic error conditions in pthread_join(3)"); +} + +ATF_TC_BODY(pthread_join, tc) +{ + pthread_t thread; + + PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc1, NULL)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +static void * +threadfunc1(void *arg) +{ + pthread_t thread[25]; + pthread_t caller; + void *val = NULL; + uintptr_t i; + int rv; + pthread_attr_t attr; + + caller = pthread_self(); + +#ifdef CHECK_STACK_ALIGNMENT + /* + * Check alignment of thread stack, if supported. + */ + ATF_REQUIRE(check_stack_alignment()); +#endif + + /* + * The behavior is undefined, but should error + * out, if we try to join the calling thread. + */ + rv = pthread_join(caller, NULL); + + /* + * The specification recommends EDEADLK. + */ + ATF_REQUIRE(rv != 0); + ATF_REQUIRE_EQ(rv, EDEADLK); + + ATF_REQUIRE(pthread_attr_init(&attr) == 0); + + for (i = 0; i < __arraycount(thread); i++) { + + error = true; + + ATF_REQUIRE(pthread_attr_setstacksize(&attr, STACKSIZE * (i + 1)) == 0); + + rv = pthread_create(&thread[i], &attr, threadfunc2, (void *)i); + + ATF_REQUIRE_EQ(rv, 0); + + /* + * Check join and exit condition. + */ + PTHREAD_REQUIRE(pthread_join(thread[i], &val)); + + ATF_REQUIRE_EQ(error, false); + + ATF_REQUIRE(val != NULL); + ATF_REQUIRE(val == (void *)(i + 1)); + + /* + * Once the thread has returned, ESRCH should + * again follow if we try to join it again. + */ + rv = pthread_join(thread[i], NULL); + + ATF_REQUIRE_EQ(rv, ESRCH); + + /* + * Try to detach the exited thread. + */ + rv = pthread_detach(thread[i]); + + ATF_REQUIRE(rv != 0); + } + + ATF_REQUIRE(pthread_attr_destroy(&attr) == 0); + + pthread_exit(NULL); + + return NULL; +} + +static void * +threadfunc2(void *arg) +{ + static uintptr_t i = 0; + uintptr_t j; + pthread_attr_t attr; + size_t stacksize; + + j = (uintptr_t)arg; + + ATF_REQUIRE(pthread_attr_get_np(pthread_self(), &attr) == 0); + ATF_REQUIRE(pthread_attr_getstacksize(&attr, &stacksize) == 0); + ATF_REQUIRE(stacksize == STACKSIZE * (j + 1)); + ATF_REQUIRE(pthread_attr_destroy(&attr) == 0); + + if (i++ == j) + error = false; + + pthread_exit((void *)i); + + return NULL; +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pthread_join); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_kill.c b/contrib/netbsd-tests/lib/libpthread/t_kill.c new file mode 100644 index 0000000..2fcdd99 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_kill.c @@ -0,0 +1,147 @@ +/* $NetBSD: t_kill.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_kill.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <pthread.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <atf-c.h> + +#include "h_common.h" + +#define NTHREAD 2 + +struct threadinfo { + pthread_t id; + sig_atomic_t gotsignal; +} th[NTHREAD]; + +pthread_t mainthread; + +static void +sighandler(int signo) +{ + pthread_t self; + int i; + + self = pthread_self(); + ATF_REQUIRE_MSG((self != mainthread) && (signo == SIGUSR1), + "unexpected signal"); + + for (i = 0; i < NTHREAD; i++) + if (self == th[i].id) + break; + + ATF_REQUIRE_MSG(i != NTHREAD, "unknown thread"); + + th[i].gotsignal++; +} + +static void * +f(void *arg) +{ + struct threadinfo volatile *t = arg; + + while (t->gotsignal < 1) { + /* busy loop */ + } + + return NULL; +} + +ATF_TC(simple); +ATF_TC_HEAD(simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_kill()"); +} +ATF_TC_BODY(simple, tc) +{ + int i; + pthread_t self; + + mainthread = pthread_self(); + + ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR); + + for (i = 0; i < NTHREAD; i++) { + PTHREAD_REQUIRE(pthread_create(&th[i].id, NULL, f, &th[i])); + } + + sched_yield(); + + self = pthread_self(); + ATF_REQUIRE_EQ_MSG(self, mainthread, "thread id changed"); + + for (i = 0; i < NTHREAD; i++) { + PTHREAD_REQUIRE(pthread_kill(th[i].id, SIGUSR1)); + } + + for (i = 0; i < NTHREAD; i++) { + PTHREAD_REQUIRE(pthread_join(th[i].id, NULL)); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_mutex.c b/contrib/netbsd-tests/lib/libpthread/t_mutex.c new file mode 100644 index 0000000..1b435c2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_mutex.c @@ -0,0 +1,316 @@ +/* $NetBSD: t_mutex.c,v 1.6 2014/02/09 21:26:07 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mutex.c,v 1.6 2014/02/09 21:26:07 jmmv Exp $"); + +#include <pthread.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include "h_common.h" + +static pthread_mutex_t mutex; +static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER; +static int global_x; + +static void * +mutex1_threadfunc(void *arg) +{ + int *param; + + printf("2: Second thread.\n"); + + param = arg; + printf("2: Locking mutex\n"); + pthread_mutex_lock(&mutex); + printf("2: Got mutex. *param = %d\n", *param); + ATF_REQUIRE_EQ(*param, 20); + (*param)++; + + pthread_mutex_unlock(&mutex); + + return param; +} + +ATF_TC(mutex1); +ATF_TC_HEAD(mutex1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes"); +} +ATF_TC_BODY(mutex1, tc) +{ + int x; + pthread_t new; + void *joinval; + + printf("1: Mutex-test 1\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + x = 1; + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex1_threadfunc, &x)); + printf("1: Before changing the value.\n"); + sleep(2); + x = 20; + printf("1: Before releasing the mutex.\n"); + sleep(2); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("1: Thread joined. X was %d. Return value (int) was %d\n", + x, *(int *)joinval); + ATF_REQUIRE_EQ(x, 21); + ATF_REQUIRE_EQ(*(int *)joinval, 21); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +static void * +mutex2_threadfunc(void *arg) +{ + long count = *(int *)arg; + + printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count); + + while (count--) { + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + } + + return (void *)count; +} + +ATF_TC(mutex2); +ATF_TC_HEAD(mutex2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes"); +#if defined(__powerpc__) + atf_tc_set_md_var(tc, "timeout", "40"); +#endif +} +ATF_TC_BODY(mutex2, tc) +{ + int count, count2; + pthread_t new; + void *joinval; + + printf("1: Mutex-test 2\n"); + +#if defined(__powerpc__) + atf_tc_expect_timeout("PR port-powerpc/44387"); +#endif + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + global_x = 0; + count = count2 = 10000000; + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex2_threadfunc, &count2)); + + printf("1: Thread %p\n", pthread_self()); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + while (count--) { + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + } + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("1: Thread joined. X was %d. Return value (long) was %ld\n", + global_x, (long)joinval); + ATF_REQUIRE_EQ(global_x, 20000000); + +#if defined(__powerpc__) + /* XXX force a timeout in ppc case since an un-triggered race + otherwise looks like a "failure" */ + /* We sleep for longer than the timeout to make ATF not + complain about unexpected success */ + sleep(41); +#endif +} + +static void * +mutex3_threadfunc(void *arg) +{ + long count = *(int *)arg; + + printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count); + + while (count--) { + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + } + + return (void *)count; +} + +ATF_TC(mutex3); +ATF_TC_HEAD(mutex3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes using a static " + "initializer"); +#if defined(__powerpc__) + atf_tc_set_md_var(tc, "timeout", "40"); +#endif +} +ATF_TC_BODY(mutex3, tc) +{ + int count, count2; + pthread_t new; + void *joinval; + + printf("1: Mutex-test 3\n"); + +#if defined(__powerpc__) + atf_tc_expect_timeout("PR port-powerpc/44387"); +#endif + + global_x = 0; + count = count2 = 10000000; + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex3_threadfunc, &count2)); + + printf("1: Thread %p\n", pthread_self()); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + while (count--) { + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + } + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + printf("1: Thread joined. X was %d. Return value (long) was %ld\n", + global_x, (long)joinval); + ATF_REQUIRE_EQ(global_x, 20000000); + +#if defined(__powerpc__) + /* XXX force a timeout in ppc case since an un-triggered race + otherwise looks like a "failure" */ + /* We sleep for longer than the timeout to make ATF not + complain about unexpected success */ + sleep(41); +#endif +} + +static void * +mutex4_threadfunc(void *arg) +{ + int *param; + + printf("2: Second thread.\n"); + + param = arg; + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("2: Got mutex. *param = %d\n", *param); + (*param)++; + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return param; +} + +ATF_TC(mutex4); +ATF_TC_HEAD(mutex4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes"); +} +ATF_TC_BODY(mutex4, tc) +{ + int x; + pthread_t new; + pthread_mutexattr_t mattr; + void *joinval; + + printf("1: Mutex-test 4\n"); + + PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr)); + PTHREAD_REQUIRE(pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE)); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, &mattr)); + + PTHREAD_REQUIRE(pthread_mutexattr_destroy(&mattr)); + + x = 1; + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex4_threadfunc, &x)); + + printf("1: Before recursively acquiring the mutex.\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + printf("1: Before releasing the mutex once.\n"); + sleep(2); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex once.\n"); + + x = 20; + + printf("1: Before releasing the mutex twice.\n"); + sleep(2); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex twice.\n"); + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("1: Thread joined. X was %d. Return value (int) was %d\n", + x, *(int *)joinval); + ATF_REQUIRE_EQ(x, 21); + ATF_REQUIRE_EQ(*(int *)joinval, 21); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mutex1); + ATF_TP_ADD_TC(tp, mutex2); + ATF_TP_ADD_TC(tp, mutex3); + ATF_TP_ADD_TC(tp, mutex4); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_name.c b/contrib/netbsd-tests/lib/libpthread/t_name.c new file mode 100644 index 0000000..d17895e --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_name.c @@ -0,0 +1,103 @@ +/* $NetBSD: t_name.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_name.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +#define NAME_TOO_LONG "12345678901234567890123456789012" /* 32 chars */ +#define NAME_JUST_RIGHT "1234567890123456789012345678901" /* 31 chars */ + +#define CONST_NAME "xyzzy" +char non_const_name[] = CONST_NAME; + +static void * +threadfunc(void *arg) +{ + pthread_t self = pthread_self(); + char retname[32]; + + PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname))); + ATF_REQUIRE_STREQ(retname, NAME_JUST_RIGHT); + + PTHREAD_REQUIRE(pthread_setname_np(self, non_const_name, NULL)); + (void) memset(non_const_name, 0, sizeof(non_const_name)); + PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname))); + ATF_REQUIRE_STREQ(retname, CONST_NAME); + + return NULL; +} + +ATF_TC(name); +ATF_TC_HEAD(name, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_{,attr}_{get,set}name_np() API"); +} +ATF_TC_BODY(name, tc) +{ + pthread_t thr, self = pthread_self(); + pthread_attr_t attr; + char retname[32]; + + PTHREAD_REQUIRE(pthread_attr_init(&attr)); + PTHREAD_REQUIRE(pthread_attr_getname_np(&attr, retname, + sizeof(retname), NULL)); + ATF_REQUIRE_EQ(retname[0], '\0'); + ATF_REQUIRE_EQ(pthread_attr_setname_np(&attr, NAME_TOO_LONG, NULL), EINVAL); + PTHREAD_REQUIRE(pthread_attr_setname_np(&attr, "%s", + __UNCONST(NAME_JUST_RIGHT))); + + (void) strcpy(retname, "foo"); + PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname))); + ATF_REQUIRE_EQ(retname[0], '\0'); + + PTHREAD_REQUIRE(pthread_create(&thr, &attr, threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_join(thr, NULL)); + + ATF_REQUIRE_EQ(pthread_getname_np(thr, retname, sizeof(retname)), ESRCH); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, name); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_once.c b/contrib/netbsd-tests/lib/libpthread/t_once.c new file mode 100644 index 0000000..575d5d7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_once.c @@ -0,0 +1,196 @@ +/* $NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> + +#include <atf-c.h> + +#include "h_common.h" + +static pthread_once_t once = PTHREAD_ONCE_INIT; +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static int x; + +#define NTHREADS 25 + +static void +ofunc(void) +{ + printf("Variable x has value %d\n", x); + x++; +} + +ATF_TC(once1); +ATF_TC_HEAD(once1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_once()"); +} +ATF_TC_BODY(once1, tc) +{ + + printf("1: Test 1 of pthread_once()\n"); + + PTHREAD_REQUIRE(pthread_once(&once, ofunc)); + PTHREAD_REQUIRE(pthread_once(&once, ofunc)); + + printf("1: X has value %d\n",x ); + ATF_REQUIRE_EQ(x, 1); +} + +static void +once2_ofunc(void) +{ + x++; + printf("ofunc: Variable x has value %d\n", x); + x++; +} + +static void * +once2_threadfunc(void *arg) +{ + int num; + + PTHREAD_REQUIRE(pthread_once(&once, once2_ofunc)); + + num = *(int *)arg; + printf("Thread %d sees x with value %d\n", num, x); + ATF_REQUIRE_EQ(x, 2); + + return NULL; +} + +ATF_TC(once2); +ATF_TC_HEAD(once2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_once()"); +} +ATF_TC_BODY(once2, tc) +{ + pthread_t threads[NTHREADS]; + int id[NTHREADS]; + int i; + + printf("1: Test 2 of pthread_once()\n"); + + for (i=0; i < NTHREADS; i++) { + id[i] = i; + PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, once2_threadfunc, &id[i])); + } + + for (i=0; i < NTHREADS; i++) + PTHREAD_REQUIRE(pthread_join(threads[i], NULL)); + + printf("1: X has value %d\n",x ); + ATF_REQUIRE_EQ(x, 2); +} + +static void +once3_cleanup(void *m) +{ + pthread_mutex_t *mu = m; + + PTHREAD_REQUIRE(pthread_mutex_unlock(mu)); +} + +static void +once3_ofunc(void) +{ + pthread_testcancel(); +} + +static void * +once3_threadfunc(void *arg) +{ + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + pthread_cleanup_push(once3_cleanup, &mutex); + PTHREAD_REQUIRE(pthread_once(&once, once3_ofunc)); + pthread_cleanup_pop(1); + + return NULL; +} + +static void +handler(int sig, siginfo_t *info, void *ctx) +{ + atf_tc_fail("Signal handler was called; " + "main thread deadlocked in pthread_once()"); +} + +ATF_TC(once3); +ATF_TC_HEAD(once3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_once()"); +} +ATF_TC_BODY(once3, tc) +{ + pthread_t thread; + struct sigaction act; + struct itimerval it; + printf("Test 3 of pthread_once() (test versus cancellation)\n"); + + act.sa_sigaction = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + sigaction(SIGALRM, &act, NULL); + + timerclear(&it.it_value); + it.it_value.tv_usec = 500000; + timerclear(&it.it_interval); + setitimer(ITIMER_REAL, &it, NULL); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&thread, NULL, once3_threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_cancel(thread)); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); + + PTHREAD_REQUIRE(pthread_once(&once, ofunc)); + + /* Cancel timer */ + timerclear(&it.it_value); + setitimer(ITIMER_REAL, &it, NULL); + + printf("Test succeeded\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, once1); + ATF_TP_ADD_TC(tp, once2); + ATF_TP_ADD_TC(tp, once3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_preempt.c b/contrib/netbsd-tests/lib/libpthread/t_preempt.c new file mode 100644 index 0000000..7ec43b6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_preempt.c @@ -0,0 +1,128 @@ +/* $NetBSD: t_preempt.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_preempt.c,v 1.2 2010/11/03 16:10:22 christos Exp $"); + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +pthread_mutex_t mutex; +pthread_cond_t cond; +int started; + +#define HUGE_BUFFER 1<<20 +#define NTHREADS 1 + +static void * +threadfunc(void *arg) +{ + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("2: Got mutex.\n"); + started++; + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&cond)); + sleep(1); + + return NULL; +} + +ATF_TC(preempt1); +ATF_TC_HEAD(preempt1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks kernel preemption during a large uiomove"); +} +ATF_TC_BODY(preempt1, tc) +{ + int i; + ssize_t rv; + pthread_t new; + void *joinval; + + char *mem; + int fd; + + mem = malloc(HUGE_BUFFER); + ATF_REQUIRE_MSG(mem != NULL, "%s", strerror(errno)); + + fd = open("/dev/urandom", O_RDONLY, 0); + ATF_REQUIRE_MSG(fd != -1, "%s", strerror(errno)); + + printf("1: preempt test\n"); + + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + started = 0; + + for (i = 0; i < NTHREADS; i++) { + PTHREAD_REQUIRE(pthread_create(&new, NULL, threadfunc, NULL)); + } + + while (started < NTHREADS) { + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + } + + printf("1: Thread has started.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex.\n"); + + rv = read(fd, mem, HUGE_BUFFER); + close(fd); + ATF_REQUIRE_EQ(rv, HUGE_BUFFER); + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, preempt1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_resolv.sh b/contrib/netbsd-tests/lib/libpthread/t_resolv.sh new file mode 100755 index 0000000..847eadc --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_resolv.sh @@ -0,0 +1,42 @@ +# $NetBSD: t_resolv.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case resolv +resolv_head() +{ + atf_set "descr" "Checks parallel name resolution" +} +resolv_body() +{ + "$(atf_get_srcdir)"/h_resolv -d -n 5 -h 5 \ + "$(atf_get_srcdir)"/d_mach || atf_fail "test failed" +} + +atf_init_test_cases() +{ + atf_add_test_case resolv +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_rwlock.c b/contrib/netbsd-tests/lib/libpthread/t_rwlock.c new file mode 100644 index 0000000..b2a3d6f --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_rwlock.c @@ -0,0 +1,125 @@ +/* $NetBSD: t_rwlock.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_rwlock.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <errno.h> +#include <pthread.h> +#include <stdlib.h> +#include <string.h> + +#include <atf-c.h> + +#include "h_common.h" + +pthread_rwlock_t lk; + +struct timespec to; + +/* ARGSUSED */ +static void * +do_nothing(void *dummy) +{ + return NULL; +} + +ATF_TC(rwlock1); +ATF_TC_HEAD(rwlock1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks read/write locks"); +} +ATF_TC_BODY(rwlock1, tc) +{ + int error; + pthread_t t; + + PTHREAD_REQUIRE(pthread_create(&t, NULL, do_nothing, NULL)); + PTHREAD_REQUIRE(pthread_rwlock_init(&lk, NULL)); + PTHREAD_REQUIRE(pthread_rwlock_rdlock(&lk)); + PTHREAD_REQUIRE(pthread_rwlock_rdlock(&lk)); + PTHREAD_REQUIRE(pthread_rwlock_unlock(&lk)); + + ATF_REQUIRE_EQ(pthread_rwlock_trywrlock(&lk), EBUSY); + + ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0, + "%s", strerror(errno)); + to.tv_sec++; + error = pthread_rwlock_timedwrlock(&lk, &to); + ATF_REQUIRE_MSG(error == ETIMEDOUT || error == EDEADLK, + "%s", strerror(error)); + + PTHREAD_REQUIRE(pthread_rwlock_unlock(&lk)); + + ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0, + "%s", strerror(errno)); + to.tv_sec++; + PTHREAD_REQUIRE(pthread_rwlock_timedwrlock(&lk, &to)); + + ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0, + "%s", strerror(errno)); + to.tv_sec++; + error = pthread_rwlock_timedwrlock(&lk, &to); + ATF_REQUIRE_MSG(error == ETIMEDOUT || error == EDEADLK, + "%s", strerror(error)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rwlock1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sem.c b/contrib/netbsd-tests/lib/libpthread/t_sem.c new file mode 100644 index 0000000..467d182 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sem.c @@ -0,0 +1,307 @@ +/* $NetBSD: t_sem.c,v 1.7 2012/03/09 19:46:37 joerg Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/**************************************************************************** + * + * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sem.c,v 1.7 2012/03/09 19:46:37 joerg Exp $"); + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include "h_common.h" + +#define NTHREADS 10 + +#define _LIBC_R_ + +#define SEM_REQUIRE(x) \ + ATF_REQUIRE_EQ_MSG(x, 0, "%s", strerror(errno)) + +static sem_t sem; + +ATF_TC(named); +ATF_TC_HEAD(named, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks named semaphores"); +} +ATF_TC_BODY(named, tc) +{ + sem_t *semp; + + ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); + + printf("Test begin\n"); + + (void) sem_unlink("/foo"); + semp = sem_open("/foo", O_CREAT | O_EXCL, 0644, 0); + ATF_REQUIRE_MSG(semp != SEM_FAILED, "%s", strerror(errno)); + SEM_REQUIRE(sem_close(semp)); + SEM_REQUIRE(sem_unlink("/foo")); + + printf("Test end\n"); +} + +ATF_TC(unnamed); +ATF_TC_HEAD(unnamed, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks unnamed semaphores"); +} + +static void * +entry(void * a_arg) +{ + pthread_t self = pthread_self(); + sem_t *semp = (sem_t *) a_arg; + + printf("Thread %p waiting for semaphore...\n", self); + sem_wait(semp); + printf("Thread %p got semaphore\n", self); + + return NULL; +} + +ATF_TC_BODY(unnamed, tc) +{ + sem_t sem_a, sem_b; + pthread_t threads[NTHREADS]; + unsigned i, j; + int val; + + ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); + + printf("Test begin\n"); + + SEM_REQUIRE(sem_init(&sem_b, 0, 0)); + SEM_REQUIRE(sem_getvalue(&sem_b, &val)); + ATF_REQUIRE_EQ(0, val); + + SEM_REQUIRE(sem_post(&sem_b)); + SEM_REQUIRE(sem_getvalue(&sem_b, &val)); + ATF_REQUIRE_EQ(1, val); + + SEM_REQUIRE(sem_wait(&sem_b)); + ATF_REQUIRE_EQ(sem_trywait(&sem_b), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); + SEM_REQUIRE(sem_post(&sem_b)); + SEM_REQUIRE(sem_trywait(&sem_b)); + SEM_REQUIRE(sem_post(&sem_b)); + SEM_REQUIRE(sem_wait(&sem_b)); + SEM_REQUIRE(sem_post(&sem_b)); + + SEM_REQUIRE(sem_destroy(&sem_b)); + + SEM_REQUIRE(sem_init(&sem_a, 0, 0)); + + for (j = 0; j < 2; j++) { + for (i = 0; i < NTHREADS; i++) { + PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, + entry, (void *) &sem_a)); + } + + for (i = 0; i < NTHREADS; i++) { + usleep(10000); + printf("main loop %u: posting...\n", j+1); + SEM_REQUIRE(sem_post(&sem_a)); + } + + for (i = 0; i < NTHREADS; i++) { + PTHREAD_REQUIRE(pthread_join(threads[i], NULL)); + } + } + + SEM_REQUIRE(sem_destroy(&sem_a)); + + printf("Test end\n"); +} + +static void +sighandler(int signo) +{ + /* printf("signal %d\n", signo); */ + + ATF_REQUIRE_EQ_MSG(signo, SIGALRM, "unexpected signal"); + SEM_REQUIRE(sem_post(&sem)); +} + +static void +alarm_ms(const int ms) +{ + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = ms * 1000; + ATF_REQUIRE(setitimer(ITIMER_REAL, &timer, NULL) == 0); +} + +static void * +threadfunc(void *arg) +{ + int i, ret; + + printf("Entering loop\n"); + for (i = 0; i < 500; ) { + if ((i & 1) != 0) { + do { + ret = sem_wait(&sem); + } while (ret == -1 && errno == EINTR); + ATF_REQUIRE(ret == 0); + } else { + ret = sem_trywait(&sem); + if (ret == -1) { + ATF_REQUIRE(errno == EAGAIN); + continue; + } + } + printf("%s: %d\n", __func__, i); + alarm_ms(5); + i++; + } + + return NULL; +} + +static void +before_start_test(const bool use_pthread) +{ + pthread_t t; + + SEM_REQUIRE(sem_init(&sem, 0, 0)); + ATF_REQUIRE(SIG_ERR != signal(SIGALRM, sighandler)); + + alarm_ms(5); + + if (use_pthread) { + PTHREAD_REQUIRE(pthread_create(&t, NULL, threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_join(t, NULL)); + } else { + threadfunc(NULL); + } +} + +ATF_TC(before_start_no_threads); +ATF_TC_HEAD(before_start_no_threads, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks using semaphores without any " + "thread running"); + atf_tc_set_md_var(tc, "timeout", "40"); +} +ATF_TC_BODY(before_start_no_threads, tc) +{ + before_start_test(false); +} + +ATF_TC(before_start_one_thread); +ATF_TC_HEAD(before_start_one_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks using semaphores before " + "starting one thread"); + atf_tc_set_md_var(tc, "timeout", "40"); +} +ATF_TC_BODY(before_start_one_thread, tc) +{ + before_start_test(true); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, named); + ATF_TP_ADD_TC(tp, unnamed); + ATF_TP_ADD_TC(tp, before_start_no_threads); + ATF_TP_ADD_TC(tp, before_start_one_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c b/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c new file mode 100644 index 0000000..0a58c4e --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_sigalarm.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigalarm.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <stdio.h> +#include <signal.h> +#include <unistd.h> +#include <pthread.h> + +#include <atf-c.h> + +#include "h_common.h" + +int alarm_set; + +#ifdef SA_SIGINFO +static void +alarm_handler(int signo, siginfo_t *si, void *ctx) +{ + ATF_REQUIRE_EQ_MSG(si->si_signo, signo, "Received unexpected signal"); + alarm_set = 1; +} +#else +static void +alarm_handler(int signo) +{ + ATF_REQUIRE_EQ_MSG(SIGALRM, signo, "Received unexpected signal"); + alarm_set = 1; +} +#endif + +static void * +setup(void *dummy) +{ + struct sigaction sa; + sigset_t ss; +#ifdef SA_SIGINFO + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = alarm_handler; +#else + sa.sa_flags = 0; + sa.sa_handler = alarm_handler; +#endif + sigfillset(&ss); + sigprocmask(SIG_SETMASK, &ss, NULL); + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + alarm(1); + + return NULL; +} + +ATF_TC(sigalarm); +ATF_TC_HEAD(sigalarm, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sigsuspend in libpthread when pthread lib is initialized"); +} +ATF_TC_BODY(sigalarm, tc) +{ + sigset_t set; + pthread_t self = pthread_self(); + + PTHREAD_REQUIRE(pthread_create(&self, NULL, setup, NULL)); + + sigemptyset(&set); + sigsuspend(&set); + alarm(0); + + ATF_REQUIRE(alarm_set); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sigalarm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c b/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c new file mode 100644 index 0000000..298879c --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c @@ -0,0 +1,109 @@ +/* $NetBSD: t_siglongjmp.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_siglongjmp.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +/* + * Regression test for siglongjmp out of a signal handler back into + * its thread. + * + * Written by Christian Limpach <cl@NetBSD.org>, December 2003. + * Public domain. + */ + +#include <sys/resource.h> + +#include <pthread.h> +#include <setjmp.h> +#include <signal.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +static sigjmp_buf env; + +static void * +thread(void *arg) +{ + return NULL; +} + +static void +handler(int sig, siginfo_t *info, void *ctx) +{ + siglongjmp(env, 1); +} + +ATF_TC(siglongjmp1); +ATF_TC_HEAD(siglongjmp1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks siglongjmp() out of a signal handler back into its thread"); +} +ATF_TC_BODY(siglongjmp1, tc) +{ + pthread_t t; + sigset_t nset; + struct rlimit rlim; + struct sigaction act; + + rlim.rlim_cur = rlim.rlim_max = 0; + (void)setrlimit(RLIMIT_CORE, &rlim); + + PTHREAD_REQUIRE(pthread_create(&t, NULL, thread, NULL)); + + sigemptyset(&nset); + sigaddset(&nset, SIGUSR1); + PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &nset, NULL)); + + act.sa_sigaction = handler; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGUSR2); + act.sa_flags = 0; + sigaction(SIGSEGV, &act, NULL); + + ATF_REQUIRE_EQ(sigsetjmp(env, 1), 0); + + PTHREAD_REQUIRE(pthread_sigmask(0, NULL, &nset)); + + ATF_REQUIRE_EQ_MSG(sigismember(&nset, SIGSEGV), 0, "SIGSEGV set"); + ATF_REQUIRE_EQ_MSG(sigismember(&nset, SIGUSR2), 0, "SIGUSR2 set"); + ATF_REQUIRE_MSG(sigismember(&nset, SIGUSR1), "SIGUSR1 not set"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, siglongjmp1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigmask.c b/contrib/netbsd-tests/lib/libpthread/t_sigmask.c new file mode 100644 index 0000000..69e0577 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sigmask.c @@ -0,0 +1,261 @@ +/* $NetBSD: t_sigmask.c,v 1.3 2013/10/19 17:45:01 christos Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigmask.c,v 1.3 2013/10/19 17:45:01 christos Exp $"); + +/* + * Regression test for pthread_sigmask when SA upcalls aren't started yet. + * + * Written by Christian Limpach <cl@NetBSD.org>, December 2003. + * Public domain. + */ + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/resource.h> + +#include <atf-c.h> + +#include "h_common.h" + +static volatile sig_atomic_t flag; +static volatile sig_atomic_t flag2; + +static volatile pthread_t thr_usr1; +static volatile pthread_t thr_usr2; + +static sig_atomic_t count = 0; + +ATF_TC(upcalls_not_started); +ATF_TC_HEAD(upcalls_not_started, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_sigmask when SA upcalls " + "aren't started yet"); +} +ATF_TC_BODY(upcalls_not_started, tc) +{ + sigset_t nset; + struct rlimit rlim; + + rlim.rlim_cur = rlim.rlim_max = 0; + (void) setrlimit(RLIMIT_CORE, &rlim); + + sigemptyset(&nset); + sigaddset(&nset, SIGFPE); + pthread_sigmask(SIG_BLOCK, &nset, NULL); + + kill(getpid(), SIGFPE); +} + +static void +upcalls_not_started_handler1(int sig, siginfo_t *info, void *ctx) +{ + + kill(getpid(), SIGUSR2); + /* + * If the mask is properly set, SIGUSR2 will not be handled + * until this handler returns. + */ + flag = 1; +} + +static void +upcalls_not_started_handler2(int sig, siginfo_t *info, void *ctx) +{ + if (flag == 1) + flag = 2; +} + +ATF_TC(before_threads); +ATF_TC_HEAD(before_threads, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that signal masks are respected " + "before threads are started"); +} +ATF_TC_BODY(before_threads, tc) +{ + struct sigaction act; + + act.sa_sigaction = upcalls_not_started_handler1; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGUSR2); + act.sa_flags = SA_SIGINFO; + + ATF_REQUIRE_EQ(sigaction(SIGUSR1, &act, NULL), 0); + + act.sa_sigaction = upcalls_not_started_handler2; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + (void)sigaction(SIGUSR2, &act, NULL); + + kill(getpid(), SIGUSR1); + + ATF_REQUIRE_EQ(flag, 2); + printf("Success: Both handlers ran in order\n"); +} + +static void +respected_while_running_handler1(int sig, siginfo_t *info, void *ctx) +{ + + kill(getpid(), SIGUSR2); + /* + * If the mask is properly set, SIGUSR2 will not be handled + * by the current thread until this handler returns. + */ + flag = 1; + thr_usr1 = pthread_self(); +} + +static void +respected_while_running_handler2(int sig, siginfo_t *info, void *ctx) +{ + if (flag == 1) + flag = 2; + flag2 = 1; + thr_usr2 = pthread_self(); +} + +static void * +respected_while_running_threadroutine(void *arg) +{ + + kill(getpid(), SIGUSR1); + sleep(1); + + if (flag == 2) + printf("Success: Both handlers ran in order\n"); + else if (flag == 1 && flag2 == 1 && thr_usr1 != thr_usr2) + printf("Success: Handlers were invoked by different threads\n"); + else { + printf("Failure: flag=%d, flag2=%d, thr1=%p, thr2=%p\n", + (int)flag, (int)flag2, (void *)thr_usr1, (void *)thr_usr2); + atf_tc_fail("failure"); + } + + return NULL; +} + +ATF_TC(respected_while_running); +ATF_TC_HEAD(respected_while_running, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that signal masks are respected " + "while threads are running"); +} +ATF_TC_BODY(respected_while_running, tc) +{ + struct sigaction act; + pthread_t thread; + + act.sa_sigaction = respected_while_running_handler1; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGUSR2); + act.sa_flags = SA_SIGINFO; + + ATF_REQUIRE_EQ(sigaction(SIGUSR1, &act, NULL), 0); + + act.sa_sigaction = respected_while_running_handler2; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + (void)sigaction(SIGUSR2, &act, NULL); + + PTHREAD_REQUIRE(pthread_create(&thread, NULL, + respected_while_running_threadroutine, NULL)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +static void +incorrect_mask_bug_handler(int sig) +{ + count++; +} + +static void * +incorrect_mask_bug_sleeper(void* arg) +{ + int i; + for (i = 0; i < 10; i++) + sleep(1); + + atf_tc_fail("sleeper"); +} + +ATF_TC(incorrect_mask_bug); +ATF_TC_HEAD(incorrect_mask_bug, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks for bug in libpthread where " + "incorrect signal mask was used"); +} +ATF_TC_BODY(incorrect_mask_bug, tc) +{ + pthread_t id; + struct sigaction act; + + act.sa_sigaction = NULL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = incorrect_mask_bug_handler; + + ATF_REQUIRE_EQ_MSG(sigaction(SIGALRM, &act, NULL), 0, "%s", + strerror(errno)); + + sigaddset(&act.sa_mask, SIGALRM); + PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL)); + + PTHREAD_REQUIRE(pthread_create(&id, NULL, incorrect_mask_bug_sleeper, + NULL)); + sleep(1); + + sigemptyset(&act.sa_mask); + PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL)); + + for (;;) { + alarm(1); + if (select(1, NULL, NULL, NULL, NULL) == -1 && errno == EINTR) + if (count == 2) + return; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, upcalls_not_started); + ATF_TP_ADD_TC(tp, before_threads); + ATF_TP_ADD_TC(tp, respected_while_running); + ATF_TP_ADD_TC(tp, incorrect_mask_bug); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c b/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c new file mode 100644 index 0000000..1179657 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c @@ -0,0 +1,90 @@ +/* $NetBSD: t_sigsuspend.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigsuspend.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +/* + * Regression test for sigsuspend in libpthread when pthread lib isn't + * initialized. + * + * Written by Love FIXME strand <lha@NetBSD.org>, March 2003. + * Public domain. + */ + +#include <stdio.h> +#include <signal.h> +#include <unistd.h> + +#include <atf-c.h> + +int alarm_set; + +static void +alarm_handler(int signo) +{ + alarm_set = 1; +} + +ATF_TC(sigsuspend); +ATF_TC_HEAD(sigsuspend, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sigsuspend in libpthread when pthread lib isn't initialized"); +} +ATF_TC_BODY(sigsuspend, tc) +{ + struct sigaction sa; + sigset_t set; + + sa.sa_flags = 0; + sa.sa_handler = alarm_handler; + sigemptyset(&sa.sa_mask); + + sigaction(SIGALRM, &sa, NULL); + + alarm(1); + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + sigsuspend(&set); + + alarm(0); + + ATF_REQUIRE(alarm_set); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sigsuspend); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sleep.c b/contrib/netbsd-tests/lib/libpthread/t_sleep.c new file mode 100644 index 0000000..93a30e3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sleep.c @@ -0,0 +1,104 @@ +/* $NetBSD: t_sleep.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sleep.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include <sys/time.h> + +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "h_common.h" + +#define LONGTIME 2000000000 + +static void * +threadfunc(void *arg) +{ + sleep(LONGTIME); + + return NULL; +} + +static void +handler(int sig) +{ + /* + * Nothing to do; invoking the handler is enough to interrupt + * the sleep. + */ +} + +ATF_TC(sleep1); +ATF_TC_HEAD(sleep1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sleeping past the time when " + "time_t wraps"); +} +ATF_TC_BODY(sleep1, tc) +{ + pthread_t thread; + struct itimerval it; + struct sigaction act; + sigset_t mtsm; + + printf("Testing sleeps unreasonably far into the future.\n"); + + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + + PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL)); + + /* make sure the signal is delivered to the child thread */ + sigemptyset(&mtsm); + sigaddset(&mtsm, SIGALRM); + PTHREAD_REQUIRE(pthread_sigmask(SIG_BLOCK, &mtsm, 0)); + + timerclear(&it.it_interval); + timerclear(&it.it_value); + it.it_value.tv_sec = 1; + setitimer(ITIMER_REAL, &it, NULL); + + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sleep1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c new file mode 100644 index 0000000..8fd2314 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c @@ -0,0 +1,112 @@ +/* $NetBSD: t_swapcontext.c,v 1.2 2014/08/25 16:31:15 bouyer Exp $ */ + +/* + * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD"); + +#include <pthread.h> +#include <ucontext.h> +#include <stdio.h> +#include <stdlib.h> + +#include <atf-c.h> + +#include "h_common.h" + +#define STACKSIZE 65536 + +char stack[STACKSIZE]; +ucontext_t nctx; +ucontext_t octx; +void *oself; +void *nself; +int val1, val2; + +/* ARGSUSED0 */ +static void +swapfunc(void *arg) +{ + /* + * If the test fails, we are very likely to crash + * without the opportunity to report + */ + nself = (void *)pthread_self(); + printf("after swapcontext self = %p\n", nself); + + ATF_REQUIRE_EQ(oself, nself); + printf("Test succeeded\n"); + /* Go back in main */ + ATF_REQUIRE(swapcontext(&nctx, &octx)); + + /* NOTREACHED */ + return; +} + +/* ARGSUSED0 */ +static void * +threadfunc(void *arg) +{ + nctx.uc_stack.ss_sp = stack; + nctx.uc_stack.ss_size = sizeof(stack); + + makecontext(&nctx, (void *)*swapfunc, 0); + + oself = (void *)pthread_self(); + printf("before swapcontext self = %p\n", oself); + PTHREAD_REQUIRE(swapcontext(&octx, &nctx)); + + /* NOTREACHED */ + return NULL; +} + + +ATF_TC(swapcontext1); +ATF_TC_HEAD(swapcontext1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() " + "alters pthread_self()"); +} +ATF_TC_BODY(swapcontext1, tc) +{ + pthread_t thread; + + oself = (void *)&val1; + nself = (void *)&val2; + + printf("Testing if swapcontext() alters pthread_self()\n"); + + PTHREAD_REQUIRE(getcontext(&nctx)); + PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swapcontext1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librt/t_sched.c b/contrib/netbsd-tests/lib/librt/t_sched.c new file mode 100644 index 0000000..8796043 --- /dev/null +++ b/contrib/netbsd-tests/lib/librt/t_sched.c @@ -0,0 +1,256 @@ +/* $NetBSD: t_sched.c,v 1.5 2012/03/25 04:11:42 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sched.c,v 1.5 2012/03/25 04:11:42 christos Exp $"); + +#include <sched.h> +#include <limits.h> +#include <unistd.h> + +#include <atf-c.h> + +static void sched_priority_set(int, int); + +ATF_TC(sched_getparam); +ATF_TC_HEAD(sched_getparam, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of sched_getparam(3)"); +} + +ATF_TC_BODY(sched_getparam, tc) +{ + struct sched_param s1, s2; + pid_t p = getpid(); + + /* + * IEEE Std 1003.1-2008: if the supplied pid is zero, + * the parameters for the calling process are returned. + */ + ATF_REQUIRE(sched_getparam(0, &s1) == 0); + ATF_REQUIRE(sched_getparam(p, &s2) == 0); + + ATF_CHECK_EQ(s1.sched_priority, s2.sched_priority); + + /* + * The behavior is undefined but should error + * out in case the supplied PID is negative. + */ + ATF_REQUIRE(sched_getparam(-1, &s1) != 0); +} + +ATF_TC(sched_priority); +ATF_TC_HEAD(sched_priority, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sched(3) priority ranges"); +} + +ATF_TC_BODY(sched_priority, tc) +{ + static const int pol[3] = { SCHED_OTHER, SCHED_FIFO, SCHED_RR }; + int pmax, pmin; + size_t i; + + /* + * Test that bogus values error out. + */ + if (INT_MAX > SCHED_RR) + ATF_REQUIRE(sched_get_priority_max(INT_MAX) != 0); + + if (-INT_MAX < SCHED_OTHER) + ATF_REQUIRE(sched_get_priority_max(-INT_MAX) != 0); + + /* + * Test that we have a valid range. + */ + for (i = 0; i < __arraycount(pol); i++) { + + pmax = sched_get_priority_max(pol[i]); + pmin = sched_get_priority_min(pol[i]); + + ATF_REQUIRE(pmax != -1); + ATF_REQUIRE(pmin != -1); + ATF_REQUIRE(pmax > pmin); + } +} + +static void +sched_priority_set(int pri, int pol) +{ + struct sched_param sched; + + sched.sched_priority = pri; + + ATF_REQUIRE(pri >= 0); + ATF_REQUIRE(sched_setscheduler(0, pol, &sched) == 0); + + /* + * Test that the policy was changed. + */ + ATF_CHECK_EQ(sched_getscheduler(0), pol); + + /* + * And that sched_getparam(3) returns the new priority. + */ + sched.sched_priority = -1; + + ATF_REQUIRE(sched_getparam(0, &sched) == 0); + ATF_CHECK_EQ(sched.sched_priority, pri); +} + +ATF_TC(sched_setscheduler_1); +ATF_TC_HEAD(sched_setscheduler_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), max, RR"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_1, tc) +{ + int pri; + + pri = sched_get_priority_max(SCHED_RR); + sched_priority_set(pri, SCHED_RR); +} + +ATF_TC(sched_setscheduler_2); +ATF_TC_HEAD(sched_setscheduler_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), min, RR"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_2, tc) +{ + int pri; + + pri = sched_get_priority_min(SCHED_RR); + sched_priority_set(pri, SCHED_RR); +} + +ATF_TC(sched_setscheduler_3); +ATF_TC_HEAD(sched_setscheduler_3, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), max, FIFO"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_3, tc) +{ + int pri; + + pri = sched_get_priority_max(SCHED_FIFO); + sched_priority_set(pri, SCHED_FIFO); +} + +ATF_TC(sched_setscheduler_4); +ATF_TC_HEAD(sched_setscheduler_4, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), min, FIFO"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_4, tc) +{ + int pri; + + pri = sched_get_priority_min(SCHED_FIFO); + sched_priority_set(pri, SCHED_FIFO); +} + +ATF_TC(sched_rr_get_interval_1); +ATF_TC_HEAD(sched_rr_get_interval_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sched_rr_get_interval(3), #1" + " (PR lib/44768)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_rr_get_interval_1, tc) +{ + struct timespec tv; + int pri; + + pri = sched_get_priority_min(SCHED_RR); + sched_priority_set(pri, SCHED_RR); + + /* + * This should fail with ESRCH for invalid PID. + */ + ATF_REQUIRE(sched_rr_get_interval(-INT_MAX, &tv) != 0); +} + +ATF_TC(sched_rr_get_interval_2); +ATF_TC_HEAD(sched_rr_get_interval_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sched_rr_get_interval(3), #2"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_rr_get_interval_2, tc) +{ + struct timespec tv1, tv2; + int pri; + + pri = sched_get_priority_min(SCHED_RR); + sched_priority_set(pri, SCHED_RR); + + tv1.tv_sec = tv2.tv_sec = -1; + tv1.tv_nsec = tv2.tv_nsec = -1; + + ATF_REQUIRE(sched_rr_get_interval(0, &tv1) == 0); + ATF_REQUIRE(sched_rr_get_interval(getpid(), &tv2) == 0); + + ATF_REQUIRE(tv1.tv_sec != -1); + ATF_REQUIRE(tv2.tv_sec != -1); + + ATF_REQUIRE(tv1.tv_nsec != -1); + ATF_REQUIRE(tv2.tv_nsec != -1); + + ATF_REQUIRE(tv1.tv_sec == tv2.tv_sec); + ATF_REQUIRE(tv1.tv_nsec == tv2.tv_nsec); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sched_getparam); + ATF_TP_ADD_TC(tp, sched_priority); + + ATF_TP_ADD_TC(tp, sched_setscheduler_1); + ATF_TP_ADD_TC(tp, sched_setscheduler_2); + ATF_TP_ADD_TC(tp, sched_setscheduler_3); + ATF_TP_ADD_TC(tp, sched_setscheduler_4); + + ATF_TP_ADD_TC(tp, sched_rr_get_interval_1); + ATF_TP_ADD_TC(tp, sched_rr_get_interval_2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librt/t_sem.c b/contrib/netbsd-tests/lib/librt/t_sem.c new file mode 100644 index 0000000..b6fc4db --- /dev/null +++ b/contrib/netbsd-tests/lib/librt/t_sem.c @@ -0,0 +1,175 @@ +/* $NetBSD: t_sem.c,v 1.2 2010/11/08 13:05:49 njoly Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sem.c,v 1.2 2010/11/08 13:05:49 njoly Exp $"); + +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <semaphore.h> +#include <stdio.h> +#include <unistd.h> + +#include <atf-c.h> + +#define NCHILDREN 10 + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks basic functionality of POSIX " + "semaphores"); +} +ATF_TC_BODY(basic, tc) +{ + int val; + sem_t *sem_b; + + if (sysconf(_SC_SEMAPHORES) == -1) + atf_tc_skip("POSIX semaphores not supported"); + + sem_b = sem_open("/sem_b", O_CREAT | O_EXCL, 0644, 0); + ATF_REQUIRE(sem_b != SEM_FAILED); + + ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0); + ATF_REQUIRE_EQ(val, 0); + + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0); + ATF_REQUIRE_EQ(val, 1); + + ATF_REQUIRE_EQ(sem_wait(sem_b), 0); + ATF_REQUIRE_EQ(sem_trywait(sem_b), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + ATF_REQUIRE_EQ(sem_trywait(sem_b), 0); + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + ATF_REQUIRE_EQ(sem_wait(sem_b), 0); + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + + ATF_REQUIRE_EQ(sem_close(sem_b), 0); + ATF_REQUIRE_EQ(sem_unlink("/sem_b"), 0); +} + +ATF_TC(child); +ATF_TC_HEAD(child, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks using semaphores to synchronize " + "parent with multiple child processes"); +} +ATF_TC_BODY(child, tc) +{ + pid_t children[NCHILDREN]; + unsigned i, j; + sem_t *sem_a; + int status; + + pid_t pid; + + if (sysconf(_SC_SEMAPHORES) == -1) + atf_tc_skip("POSIX semaphores not supported"); + + sem_a = sem_open("/sem_a", O_CREAT | O_EXCL, 0644, 0); + ATF_REQUIRE(sem_a != SEM_FAILED); + + for (j = 1; j <= 2; j++) { + for (i = 0; i < NCHILDREN; i++) { + switch ((pid = fork())) { + case -1: + atf_tc_fail("fork() returned -1"); + case 0: + printf("PID %d waiting for semaphore...\n", + getpid()); + ATF_REQUIRE_MSG(sem_wait(sem_a) == 0, + "sem_wait failed; iteration %d", j); + printf("PID %d got semaphore\n", getpid()); + _exit(0); + default: + children[i] = pid; + break; + } + } + + for (i = 0; i < NCHILDREN; i++) { + sleep(1); + printf("main loop %d: posting...\n", j); + ATF_REQUIRE_EQ(sem_post(sem_a), 0); + } + + for (i = 0; i < NCHILDREN; i++) { + ATF_REQUIRE_EQ(waitpid(children[i], &status, 0), children[i]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), 0); + } + } + + ATF_REQUIRE_EQ(sem_close(sem_a), 0); + ATF_REQUIRE_EQ(sem_unlink("/sem_a"), 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, child); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librumpclient/h_exec.c b/contrib/netbsd-tests/lib/librumpclient/h_exec.c new file mode 100644 index 0000000..cf2526c --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/h_exec.c @@ -0,0 +1,132 @@ +/* $NetBSD: h_exec.c,v 1.6 2011/02/16 17:57:44 pooka Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <rump/rumpclient.h> +#include <rump/rump_syscalls.h> + +int +main(int argc, char *argv[]) +{ + struct sockaddr_in sin; + socklen_t slen; + int s1, s2; + char buf[12]; + char *eargv[4]; + char *ename; + extern char **environ; + + if (rumpclient_init() == -1) + err(1, "init"); + + if (argc > 1) { + if (strcmp(argv[1], "_didexec") == 0) { + rumpclient_daemon(0, 0); /* detach-me-notnot */ + s2 = atoi(argv[2]); + slen = sizeof(sin); + /* see below */ + rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); + } + } + + /* open and listenize two TCP4 suckets */ + if ((s1 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket 1"); + if ((s2 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket 2"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + + if (rump_sys_bind(s1, (struct sockaddr *)&sin, sizeof(sin)) == -1) + err(1, "bind1"); + sin.sin_port = htons(2345); + if (rump_sys_bind(s2, (struct sockaddr *)&sin, sizeof(sin)) == -1) + err(1, "bind2"); + + if (rump_sys_listen(s1, 1) == -1) + err(1, "listen1"); + if (rump_sys_listen(s2, 1) == -1) + err(1, "listen2"); + + if (argc == 1) { + rumpclient_daemon(0, 0); + slen = sizeof(sin); + /* + * "pause()", but conveniently gets rid of this helper + * since we were called with RUMPCLIENT_RETRYCONN_DIE set + */ + rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); + } + + if (argc == 3 && strcmp(argv[2], "cloexec1") == 0) { + if (rump_sys_fcntl(s1, F_SETFD, FD_CLOEXEC) == -1) { + err(1, "cloexec failed"); + } + } + + sprintf(buf, "%d", s2); + + if (argc == 3 && strcmp(argv[2], "vfork_please") == 0) { + switch (rumpclient_vfork()) { + case 0: + ename = __UNCONST("fourchette"); + break; + case -1: + err(1, "vfork"); + default: + ename = __UNCONST("h_ution"); + break; + } + } else { + ename = __UNCONST("h_ution"); + } + + /* omstart! */ + eargv[0] = ename; + eargv[1] = __UNCONST("_didexec"); + eargv[2] = buf; + eargv[3] = NULL; + if (rumpclient_exec(argv[1], __UNCONST(eargv), environ) == -1) + err(1, "exec"); +} diff --git a/contrib/netbsd-tests/lib/librumpclient/h_execthr.c b/contrib/netbsd-tests/lib/librumpclient/h_execthr.c new file mode 100644 index 0000000..f653fe6 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/h_execthr.c @@ -0,0 +1,187 @@ +/* $NetBSD: h_execthr.c,v 1.3 2014/08/13 00:03:00 pooka Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/sysctl.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <rump/rumpclient.h> +#include <rump/rump_syscalls.h> + +static int canreturn = 0; + +/* + * Use a fairly large number of threads so that we have + * a better chance catching races. XXX: this is rumpuser's + * MAXWORKER-1. + */ +#define NTHR 63 + +#define P1_0 3 +#define P1_1 4 +#define P2_0 5 +#define P2_1 6 + +static void * +wrk(void *arg) +{ + int fd = (uintptr_t)arg; + + rump_sys_read(fd, &fd, sizeof(fd)); + if (!canreturn) + errx(1, "should not have returned"); + if (fd != 37) + errx(1, "got invalid magic"); + + return NULL; +} + +static int +getproc(pid_t mypid, struct kinfo_proc2 *p) +{ + int name[6]; + size_t len = sizeof(*p); + + name[0] = CTL_KERN; + name[1] = KERN_PROC2; + name[2] = KERN_PROC_PID; + name[3] = mypid; + name[4] = len; + name[5] = 1; + + return rump_sys___sysctl(name, __arraycount(name), p, &len, NULL, 0); +} + +int +main(int argc, char *argv[], char *envp[]) +{ + struct kinfo_proc2 p; + char *execarg[3]; + int p1[2], p2[2]; + pid_t mypid; + pthread_t pt; + ssize_t n; + int i, execd; + char nexec[16]; + + if (argc > 1) + execd = atoi(argv[1]); + else + execd = 0; + sprintf(nexec, "%d", execd+1); + + if (rumpclient_init() == -1) { + if (execd) + err(1, "init execd"); + else + err(1, "init"); + } + mypid = rump_sys_getpid(); + + if (execd) { + canreturn = 1; + if (pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)P2_0) != 0) + errx(1, "exec pthread_create"); + + i = 37; + rump_sys_write(P2_1, &i, sizeof(i)); + pthread_join(pt, NULL); + + n = rump_sys_read(P1_0, &i, sizeof(i)); + if (n != -1 || errno != EBADF) + errx(1, "post-exec cloexec works"); + + getproc(mypid, &p); + if (p.p_nlwps != 2) + errx(1, "invalid nlwps: %lld", (long long)p.p_nlwps); + + /* we passed? */ + if (execd > 10) + exit(0); + + rump_sys_close(P2_0); + rump_sys_close(P2_1); + } + + if (rump_sys_pipe(p1) == -1) + err(1, "pipe1"); + if (p1[0] != P1_0 || p1[1] != P1_1) + errx(1, "p1 assumptions failed %d %d", p1[0], p1[1]); + if (rump_sys_pipe(p2) == -1) + err(1, "pipe1"); + if (p2[0] != P2_0 || p2[1] != P2_1) + errx(1, "p2 assumptions failed"); + if (rump_sys_fcntl(p1[0], F_SETFD, FD_CLOEXEC) == -1) + err(1, "cloexec"); + if (rump_sys_fcntl(p1[1], F_SETFD, FD_CLOEXEC) == -1) + err(1, "cloexec"); + + for (i = 0; i < NTHR; i++) + if (pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)p1[0]) != 0) + errx(1, "pthread_create 1 %d", i); + + for (i = 0; i < NTHR; i++) + if (pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)p2[0]) != 0) + errx(1, "pthread_create 2 %d", i); + + /* wait for all the threads to be enjoying themselves */ + for (;;) { + getproc(mypid, &p); + if (p.p_nlwps == 2*NTHR + 2) + break; + usleep(10000); + } + + /* + * load up one more (big) set. these won't start executing, though, + * but we're interested in if they create blockage + */ + for (i = 0; i < 3*NTHR; i++) + if (pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)p1[0]) != 0) + errx(1, "pthread_create 1 %d", i); + + /* then, we exec! */ + execarg[0] = argv[0]; + execarg[1] = nexec; + execarg[2] = NULL; + if (rumpclient_exec(argv[0], execarg, envp) == -1) + err(1, "exec"); +} diff --git a/contrib/netbsd-tests/lib/librumpclient/t_exec.sh b/contrib/netbsd-tests/lib/librumpclient/t_exec.sh new file mode 100755 index 0000000..661a3b9 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/t_exec.sh @@ -0,0 +1,154 @@ +# $NetBSD: t_exec.sh,v 1.8 2011/03/08 12:40:25 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +rumpsrv='rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet' +export RUMP_SERVER=unix://csock +export RUMPHIJACK_RETRYCONNECT='die' + +atf_test_case noexec cleanup +noexec_head() +{ + atf_set "descr" "check that we see what we expect without exec" +} + +noexec_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 env $(atf_get_srcdir)/h_exec + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o match:'^root.*h_exec.*tcp.*\*\.1234' \ + sed -n 2p sstat.out + atf_check -s exit:0 -o match:'^root.*h_exec.*tcp.*\*\.2345' \ + sed -n 3p sstat.out +} + +noexec_cleanup() +{ + rump.halt +} + +atf_test_case exec cleanup +exec_head() +{ + atf_set "descr" "check that client names changes after exec" +} + +exec_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.1234' \ + sed -n 2p sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \ + sed -n 3p sstat.out +} + +exec_cleanup() +{ + rump.halt +} + +atf_test_case cloexec cleanup +cloexec_head() +{ + atf_set "descr" "check that FD_CLOEXEC works" +} + +cloexec_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 \ + $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec cloexec1 + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o inline:'2\n' sed -n '$=' sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \ + sed -n 2p sstat.out +} + +cloexec_cleanup() +{ + rump.halt +} + +atf_test_case vfork cleanup +vfork_head() +{ + atf_set "descr" "test rumpclient_vfork()" +} + +vfork_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 \ + $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec vfork_please + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o inline:'5\n' sed -n '$=' sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.1234' \ + cat sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \ + cat sstat.out + atf_check -s exit:0 -o match:'^root.*fourchette.*tcp.*\*\.1234' \ + cat sstat.out + atf_check -s exit:0 -o match:'^root.*fourchette.*tcp.*\*\.2345' \ + cat sstat.out +} + +vfork_cleanup() +{ + rump.halt +} + +atf_test_case threxec cleanup +threxec_head() +{ + atf_set "descr" "check that threads are killed before exec continues" +} + +threxec_body() +{ + atf_check -s exit:0 rump_server ${RUMP_SERVER} + atf_check -s exit:0 $(atf_get_srcdir)/h_execthr +} + +threxec_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case noexec + atf_add_test_case exec + atf_add_test_case cloexec + atf_add_test_case vfork + atf_add_test_case threxec +} diff --git a/contrib/netbsd-tests/lib/librumpclient/t_fd.c b/contrib/netbsd-tests/lib/librumpclient/t_fd.c new file mode 100644 index 0000000..aa0d1cc --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/t_fd.c @@ -0,0 +1,146 @@ +/* $NetBSD: t_fd.c,v 1.4 2011/08/25 18:46:01 hannken Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +#include <rump/rumpclient.h> +#include <rump/rump_syscalls.h> + +#include "../../h_macros.h" + +ATF_TC_WITH_CLEANUP(bigenough); +ATF_TC_HEAD(bigenough, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that rumpclient uses " + "fd > 2"); +} +ATF_TC_WITH_CLEANUP(sigio); +ATF_TC_HEAD(sigio, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that rump client receives " + "SIGIO"); +} + +#define RUMPSERV "unix://sucket" + +ATF_TC_CLEANUP(bigenough, tc){system("env RUMP_SERVER=" RUMPSERV " rump.halt");} +ATF_TC_CLEANUP(sigio, tc) { system("env RUMP_SERVER=" RUMPSERV " rump.halt"); } + +ATF_TC_BODY(bigenough, tc) +{ + struct stat sb; + + RZ(system("rump_server " RUMPSERV)); + RL(setenv("RUMP_SERVER", RUMPSERV, 1)); + + RL(dup2(0, 10)); + RL(dup2(1, 11)); + RL(dup2(2, 12)); + + RL(close(0)); + RL(close(1)); + RL(close(2)); + + RL(rumpclient_init()); + RL(rump_sys_getpid()); + + ATF_REQUIRE_ERRNO(EBADF, fstat(0, &sb) == -1); + ATF_REQUIRE_ERRNO(EBADF, fstat(1, &sb) == -1); + ATF_REQUIRE_ERRNO(EBADF, fstat(2, &sb) == -1); + + RL(rump_sys_getpid()); + + /* restore these. does it help? */ + dup2(10, 0); + dup2(11, 1); + dup2(12, 2); +} + +static volatile sig_atomic_t sigcnt; +static void +gotsig(int sig) +{ + + sigcnt++; +} + +ATF_TC_BODY(sigio, tc) +{ + struct sockaddr_in sin; + int ls; + int cs; + int fl; + int sc; + + signal(SIGIO, gotsig); + RZ(system("rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet " + RUMPSERV)); + RL(setenv("RUMP_SERVER", RUMPSERV, 1)); + + RL(rumpclient_init()); + RL(ls = rump_sys_socket(PF_INET, SOCK_STREAM, 0)); + + RL(rump_sys_fcntl(ls, F_SETOWN, rump_sys_getpid())); + RL(fl = rump_sys_fcntl(ls, F_GETFL)); + RL(rump_sys_fcntl(ls, F_SETFL, fl | O_ASYNC)); + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(12345); + RL(rump_sys_bind(ls, (struct sockaddr *)&sin, sizeof(sin))); + RL(rump_sys_listen(ls, 5)); + + RL(cs = rump_sys_socket(PF_INET, SOCK_STREAM, 0)); + sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + + ATF_REQUIRE_EQ(sigcnt, 0); + RL(rump_sys_connect(cs, (struct sockaddr *)&sin, sizeof(sin))); + sc = sigcnt; + printf("sigcnt after connect: %d\n", sc); + ATF_REQUIRE(sc >= 1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, bigenough); + ATF_TP_ADD_TC(tp, sigio); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librumphijack/h_client.c b/contrib/netbsd-tests/lib/librumphijack/h_client.c new file mode 100644 index 0000000..20add73 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/h_client.c @@ -0,0 +1,138 @@ +/* $NetBSD: h_client.c,v 1.8 2012/04/20 05:15:11 jruoho Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/poll.h> +#include <sys/select.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int +main(int argc, char *argv[]) +{ + + if (argc != 2) { + errx(1, "need testname as param"); + } + + if (strcmp(argv[1], "select_timeout") == 0) { + fd_set rfds; + struct timeval tv; + int pipefd[2]; + int rv; + + tv.tv_sec = 0; + tv.tv_usec = 1; + + if (pipe(pipefd) == -1) + err(EXIT_FAILURE, "pipe"); + FD_ZERO(&rfds); + FD_SET(pipefd[0], &rfds); + + rv = select(pipefd[0]+1, &rfds, NULL, NULL, &tv); + if (rv == -1) + err(EXIT_FAILURE, "select"); + if (rv != 0) + errx(EXIT_FAILURE, "select succesful"); + + if (FD_ISSET(pipefd[0], &rfds)) + errx(EXIT_FAILURE, "stdin fileno is still set"); + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "select_allunset") == 0) { + fd_set fds; + struct timeval tv; + int rv; + + tv.tv_sec = 0; + tv.tv_usec = 1; + + FD_ZERO(&fds); + + rv = select(100, &fds, &fds, &fds, &tv); + if (rv == -1) + err(EXIT_FAILURE, "select"); + if (rv != 0) + errx(EXIT_FAILURE, "select succesful"); + + rv = select(0, NULL, NULL, NULL, &tv); + if (rv == -1) + err(EXIT_FAILURE, "select2"); + if (rv != 0) + errx(EXIT_FAILURE, "select2 succesful"); + + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "invafd") == 0) { + struct pollfd pfd[2]; + int fd, rv; + + fd = open("/rump/dev/null", O_RDWR); + if (fd == -1) + err(EXIT_FAILURE, "open"); + close(fd); + + pfd[0].fd = STDIN_FILENO; + pfd[0].events = POLLIN; + pfd[1].fd = fd; + pfd[1].events = POLLIN; + + if ((rv = poll(pfd, 2, INFTIM)) != 1) + errx(EXIT_FAILURE, "poll unexpected rv %d (%d)", + rv, errno); + if (pfd[1].revents != POLLNVAL || pfd[0].revents != 0) + errx(EXIT_FAILURE, "poll unexpected revents"); + + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "fdoff8") == 0) { + + (void)closefrom(0); + + int fd; + + do { + if ((fd = open("/dev/null", O_RDWR)) == -1) + err(EXIT_FAILURE, "open1"); + } while (fd < 7); + fd = open("/dev/null", O_RDWR); + if (fd != -1 || errno != ENFILE) + errx(EXIT_FAILURE, "unexpected fd8 %d %d", fd, errno); + if (fcntl(0, F_MAXFD) != 7) + errx(EXIT_FAILURE, "fd leak?"); + if ((fd = open("/rump/dev/null", O_RDWR)) != 8) + errx(EXIT_FAILURE, "rump open %d %d", fd, errno); + return EXIT_SUCCESS; + } else { + return ENOTSUP; + } +} diff --git a/contrib/netbsd-tests/lib/librumphijack/h_cwd.c b/contrib/netbsd-tests/lib/librumphijack/h_cwd.c new file mode 100644 index 0000000..dfc509d --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/h_cwd.c @@ -0,0 +1,168 @@ +/* $NetBSD: h_cwd.c,v 1.3 2012/04/17 09:23:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const char *prefix; +static size_t prefixlen; +static char buf[1024]; +static char pwd[1024]; + +static const char * +makepath(const char *tail) +{ + + strcpy(buf, prefix); + if (prefix[prefixlen-1] != '/') + strcat(buf, "/"); + strcat(buf, tail); + + return buf; +} + +static void +dochdir(const char *path, const char *errmsg) +{ + + if (chdir(path) == -1) + err(EXIT_FAILURE, "%s", errmsg); +} + +static void +dofchdir(const char *path, const char *errmsg) +{ + int fd; + + fd = open(path, O_RDONLY); + if (fd == -1) + err(EXIT_FAILURE, "open %s", errmsg); + if (fchdir(fd) == -1) + err(EXIT_FAILURE, "fchdir %s", errmsg); + close(fd); +} +static void (*thechdir)(const char *, const char *); + +static void +simple(void) +{ + + thechdir(prefix, "chdir1"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd1"); + if (strcmp(pwd, prefix) != 0) + errx(EXIT_FAILURE, "strcmp1"); + + if (mkdir("dir", 0777) == -1) + err(EXIT_FAILURE, "mkdir2"); + thechdir("dir", "chdir2"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd2"); + if (strcmp(pwd, makepath("dir")) != 0) + errx(EXIT_FAILURE, "strcmp2"); + + if (mkdir("dir", 0777) == -1) + err(EXIT_FAILURE, "mkdir3"); + thechdir("dir", "chdir3"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd3"); + if (strcmp(pwd, makepath("dir/dir")) != 0) + errx(EXIT_FAILURE, "strcmp3"); + + thechdir("..", "chdir4"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd4"); + if (strcmp(pwd, makepath("dir")) != 0) + errx(EXIT_FAILURE, "strcmp4"); + + + thechdir("../../../../../../..", "chdir5"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd5"); + if (strcmp(pwd, prefix) != 0) + errx(EXIT_FAILURE, "strcmp5"); + + thechdir("/", "chdir6"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd6"); + if (strcmp(pwd, "/") != 0) + errx(EXIT_FAILURE, "strcmp6"); +} + +static void +symlinktest(void) +{ + + thechdir(prefix, "chdir1"); + if (mkdir("adir", 0777) == -1) + err(EXIT_FAILURE, "mkdir1"); + if (mkdir("anotherdir", 0777) == -1) + err(EXIT_FAILURE, "mkdir2"); + + if (symlink("/adir", "anotherdir/lincthesink") == -1) + err(EXIT_FAILURE, "symlink"); + + thechdir("anotherdir/lincthesink", "chdir2"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd"); + if (strcmp(pwd, makepath("adir")) != 0) + errx(EXIT_FAILURE, "strcmp"); +} + +int +main(int argc, char *argv[]) +{ + + if (argc != 4) + errx(1, "usage"); + + prefix = argv[1]; + prefixlen = strlen(argv[1]); + + if (strcmp(argv[3], "chdir") == 0) + thechdir = dochdir; + else if (strcmp(argv[3], "fchdir") == 0) + thechdir = dofchdir; + else + errx(EXIT_FAILURE, "invalid chdir type"); + + if (strcmp(argv[2], "simple") == 0) + simple(); + if (strcmp(argv[2], "symlink") == 0) + symlinktest(); + + return EXIT_SUCCESS; +} diff --git a/contrib/netbsd-tests/lib/librumphijack/h_netget.c b/contrib/netbsd-tests/lib/librumphijack/h_netget.c new file mode 100644 index 0000000..4d8b408 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/h_netget.c @@ -0,0 +1,101 @@ +/* $NetBSD: h_netget.c,v 1.2 2012/04/17 09:23:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * simple utility to fetch a webpage. we wouldn't need this + * if we had something like netcat in base + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_netget.c,v 1.2 2012/04/17 09:23:21 jruoho Exp $"); + +#include <sys/types.h> +#include <sys/socket.h> + +#include <arpa/inet.h> + +#include <netinet/in.h> + +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define GETSTR "GET / HTTP/1.0\n\n" + +int +main(int argc, char *argv[]) +{ + char buf[8192]; + struct sockaddr_in sin; + ssize_t n; + int s, fd; + + setprogname(argv[0]); + if (argc != 4) { + fprintf(stderr, "usage: %s address port savefile\n", + getprogname()); + return EXIT_FAILURE; + } + + s = socket(PF_INET, SOCK_STREAM, 0); + if (s == -1) + err(EXIT_FAILURE, "socket"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(atoi(argv[2])); + sin.sin_addr.s_addr = inet_addr(argv[1]); + + fd = open(argv[3], O_CREAT | O_RDWR, 0644); + if (fd == -1) + err(EXIT_FAILURE, "open"); + if (ftruncate(fd, 0) == -1) + err(EXIT_FAILURE, "ftruncate savefile"); + + if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) + err(EXIT_FAILURE, "connect"); + + if (write(s, GETSTR, strlen(GETSTR)) != strlen(GETSTR)) + err(EXIT_FAILURE, "socket write"); + + for (;;) { + n = read(s, buf, sizeof(buf)); + if (n == 0) + break; + if (n == -1) + err(EXIT_FAILURE, "socket read"); + + if (write(fd, buf, n) != n) + err(EXIT_FAILURE, "write file"); + } + + return EXIT_SUCCESS; +} diff --git a/contrib/netbsd-tests/lib/librumphijack/index.html b/contrib/netbsd-tests/lib/librumphijack/index.html new file mode 100644 index 0000000..1d8679c --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/index.html @@ -0,0 +1,5 @@ +<html><head> +<title>test page</title> +</head><body> +i am a test, how do you do? +</body></html> diff --git a/contrib/netbsd-tests/lib/librumphijack/netstat.expout b/contrib/netbsd-tests/lib/librumphijack/netstat.expout new file mode 100644 index 0000000..1a9a2a1 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/netstat.expout @@ -0,0 +1,6 @@ +Active Internet connections (including servers) +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 *.http *.* LISTEN +Active Internet6 connections (including servers) +Proto Recv-Q Send-Q Local Address Foreign Address (state) +tcp6 0 0 *.http *.* LISTEN diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_config.in b/contrib/netbsd-tests/lib/librumphijack/ssh_config.in new file mode 100644 index 0000000..73b83c8 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/ssh_config.in @@ -0,0 +1,14 @@ +# $NetBSD: ssh_config.in,v 1.1 2011/02/14 15:14:00 pooka Exp $ + +# Basic settings. +Port 22 +Protocol 2 + +# The temporary key used for login. +IdentityFile @WORKDIR@/ssh_user_key + +# Prevent the client from complaining about unknown host keys. +GlobalKnownHostsFile @WORKDIR@/known_hosts + +# Do not attempt password authentication in case keys fail. +IdentitiesOnly yes diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_host_key b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key new file mode 100644 index 0000000..ebdbc8b --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDJnMpSG1lGmApk8F7ZH7TGtjjP/WUs+vqHyFsyS2lilJzereen +a/ME6S0d0HTOeCdKldjbtDpfNXbh+XnJMlJMEgEs4Mg1jluuEV0GOJoMt7cGzku2 +gAYGx++2+wqYw6Y+M8Tb1M4AO+PcxD/3BkdUyIKO63v6STl2VQn1BzsTQwIBIwKB +gAuFTWPHDGpvFols0jhK9GMgWwSSIwnidLdNRwowMehgQ3pwVmFWoCwqlN0h2sn4 +PMJu9nL0WxtiJAzprzARgQuPI25t9LiKTF7scC/cNUiHPplUjvoDXA9ccY1eIf4R +e6wwZz1jfCWen0eRsvMyoYvFmEH8hILAk1bY9heymOGLAkEA/WhC49n+gtloVMow +iKQOO6+u3ouxTOTQ3sV2wCaLaO2pEbHP2//5SlUJLp6QrjC7bg9Kr+f56+zT2he9 +f6GCwwJBAMus3XizmZdJyJLnkCJRiT0/3Kf57fhWKRdnFkuRLyjET9MEWavRdJmr +bx/lxmILi1iKwXiFEDM6MqYfmNImJYECQQCtw9YYlXtSaTGZOi/oqwJyEhGCqO6b +II85q/moVPHhjQY4BOZNttbT4on0FPV+wlSjPa+OkHDcSp/mAaaDZ2+bAkEAujel +6rLVkaKLfv+ZuPoXE22WivMityo0Mqdk12ArHfVQS+a4YpOdzlOYzLTSosi56o19 +sAShGOTAl+Jf1hQ/iwJAKpPviX5w292H/m5T0m4l0NRdQ3pRujOLMSVmY+/HFZTW +GJMYLr1eBKNfLsKzJgB88GzuF2O/O8hNi3XSiOP+9w== +-----END RSA PRIVATE KEY----- diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub new file mode 100644 index 0000000..8d08795 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyZzKUhtZRpgKZPBe2R+0xrY4z/1lLPr6h8hbMktpYpSc3q3np2vzBOktHdB0zngnSpXY27Q6XzV24fl5yTJSTBIBLODINY5brhFdBjiaDLe3Bs5LtoAGBsfvtvsKmMOmPjPE29TOADvj3MQ/9wZHVMiCjut7+kk5dlUJ9Qc7E0M= test@test.example.net diff --git a/contrib/netbsd-tests/lib/librumphijack/sshd_config.in b/contrib/netbsd-tests/lib/librumphijack/sshd_config.in new file mode 100644 index 0000000..9ffc47f --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/sshd_config.in @@ -0,0 +1,39 @@ +# $NetBSD: sshd_config.in,v 1.1 2011/02/14 15:14:00 pooka Exp $ + +# Basic settings. +Port 22 +Protocol 2 + +# Provide information to the user in case something goes wrong. +LogLevel DEBUG1 + +# The host key. It lives in the work directory because we need to set +# very strict permissions on it and cannot modify the copy on the source +# directory. +HostKey @WORKDIR@/ssh_host_key + +# The authorized keys file we set up during the test to allow the client +# to safely log in. We need to disable strict modes because ATF_WORKDIR +# usually lives in /tmp, which has 1777 permissions and are not liked by +# sshd. +AuthorizedKeysFile @WORKDIR@/authorized_keys +StrictModes no + +# Some settings to allow user runs of sshd. +PidFile @WORKDIR@/sshd.pid +UsePam no +UsePrivilegeSeparation no + +# The root user should also be able to run the tests. +PermitRootLogin yes + +# Be restrictive about access to the temporary server. Only allow key-based +# authentication. +ChallengeResponseAuthentication no +GSSAPIAuthentication no +HostbasedAuthentication no +KerberosAuthentication no +MaxAuthTries 1 +MaxStartups 1 +PasswordAuthentication no +PubkeyAuthentication yes diff --git a/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh b/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh new file mode 100755 index 0000000..d5d703c --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh @@ -0,0 +1,94 @@ +# $NetBSD: t_asyncio.sh,v 1.4 2014/08/27 13:32:16 gson Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +rumpsrv='rump_server' +export RUMP_SERVER=unix://csock + +atf_test_case select_timeout cleanup +select_timeout_head() +{ + atf_set "descr" "select() with timeout returns no fds set" +} + +select_timeout_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client select_timeout +} + +select_timeout_cleanup() +{ + rump.halt +} + +atf_test_case select_allunset cleanup +select_allunset_head() +{ + atf_set "descr" "select() with no set fds in fd_set should not crash" +} + +select_allunset_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client select_allunset +} + +select_allunset_cleanup() +{ + rump.halt +} + +atf_test_case invafd cleanup +invafd_head() +{ + atf_set "descr" "poll on invalid rump fd" + atf_set "timeout" "10" +} + +invafd_body() +{ + + atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER} + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client invafd +} + +invafd_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case select_timeout + atf_add_test_case select_allunset + atf_add_test_case invafd +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_config.sh b/contrib/netbsd-tests/lib/librumphijack/t_config.sh new file mode 100755 index 0000000..014bb0f --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_config.sh @@ -0,0 +1,54 @@ +# $NetBSD: t_config.sh,v 1.1 2011/03/14 15:56:40 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +rumpsrv='rump_server -lrumpvfs' +export RUMP_SERVER=unix://csock + +atf_test_case fdoff cleanup +fdoff_head() +{ + atf_set "descr" "RUMPHIJACK fdoff=8" +} + +fdoff_body() +{ + + atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER} + export RUMPHIJACK=path=/rump,fdoff=8 + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client fdoff8 +} + +fdoff_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case fdoff +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh b/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh new file mode 100755 index 0000000..3f2a50b --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh @@ -0,0 +1,72 @@ +# $NetBSD: t_cwd.sh,v 1.2 2011/02/19 19:57:28 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +rumpsrv='rump_server -lrumpvfs' +export RUMP_SERVER=unix://csock + +test_case() +{ + local name="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { }" + eval "${name}_body() { \ + export RUMPHIJACK="path=${1}" ; \ + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} ; \ + testbody " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + rump.halt + }" +} + +test_case basic_chdir /rump simple chdir +test_case basic_fchdir /rump simple fchdir +test_case slash_chdir // simple chdir +test_case slash_fchdir // simple fchdir +test_case symlink_chdir /rump symlink chdir +test_case symlink_fchdir /rump symlink fchdir +test_case symlink_slash_chdir // symlink chdir +test_case symlink_slash_fchdir // symlink fchdir + +testbody() +{ + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_cwd $* +} + +atf_init_test_cases() +{ + atf_add_test_case basic_chdir + atf_add_test_case basic_fchdir + atf_add_test_case slash_chdir + atf_add_test_case slash_fchdir + atf_add_test_case symlink_chdir + atf_add_test_case symlink_fchdir + atf_add_test_case symlink_slash_chdir + atf_add_test_case symlink_slash_fchdir +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_sh.sh b/contrib/netbsd-tests/lib/librumphijack/t_sh.sh new file mode 100755 index 0000000..c01c729 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_sh.sh @@ -0,0 +1,91 @@ +# $NetBSD: t_sh.sh,v 1.1 2011/03/03 11:54:12 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# +# Test various /bin/sh descriptor games. +# +# Note that there is an extra level of trickery here, since +# we need to run an extra level of shell to "catch" LD_PRELOAD. +# + +rumpsrv='rump_server -lrumpvfs' +export RUMP_SERVER=unix://csock +exout="this is the output you are looking for" + +atf_test_case runscript cleanup +runscript_head() +{ + atf_set "descr" "can run /bin/sh scripts from rumpfs" +} + +runscript_body() +{ + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + + export LD_PRELOAD=/usr/lib/librumphijack.so + echo "echo $exout" > thescript + atf_check -s exit:0 mv thescript /rump + atf_check -s exit:0 -o inline:"${exout}\n" -x sh /rump/thescript +} + +runscript_cleanup() +{ + rump.halt +} + +atf_test_case redirect cleanup +redirect_head() +{ + atf_set "descr" "input/output redirection works with rumphijack" +} + +redirect_body() +{ + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + export LD_PRELOAD=/usr/lib/librumphijack.so + + echo "echo $exout > /rump/thefile" > thescript + atf_check -s exit:0 -x sh thescript + + # read it without input redirection + atf_check -s exit:0 -o inline:"${exout}\n" cat /rump/thefile + + # read it with input redirection (note, need an exec'd shell again) + echo "cat < /rump/thefile" > thescript + atf_check -s exit:0 -o inline:"${exout}\n" -x sh thescript +} + +redirect_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case runscript + atf_add_test_case redirect +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh b/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh new file mode 100755 index 0000000..d6a16fa --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh @@ -0,0 +1,268 @@ +# $NetBSD: t_tcpip.sh,v 1.13 2014/01/03 13:18:00 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +rumpnetsrv='rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet' +export RUMP_SERVER=unix://csock + +atf_test_case http cleanup +http_head() +{ + atf_set "descr" "Start hijacked httpd and get webpage from it" +} + +http_body() +{ + + atf_check -s exit:0 ${rumpnetsrv} -lrumpnet_netinet6 ${RUMP_SERVER} + + # start bozo in daemon mode + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + /usr/libexec/httpd -P ./httpd.pid -b -s $(atf_get_srcdir) + + atf_check -s exit:0 -o file:"$(atf_get_srcdir)/netstat.expout" \ + rump.netstat -a + + # get the webpage + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_netget 127.0.0.1 80 webfile + + # check that we got what we wanted + atf_check -o match:'HTTP/1.0 200 OK' cat webfile + atf_check -o match:'Content-Length: 95' cat webfile + atf_check -o file:"$(atf_get_srcdir)/index.html" \ + sed -n '1,/^$/!p' webfile +} + +http_cleanup() +{ + if [ -f httpd.pid ]; then + kill -9 "$(cat httpd.pid)" + rm -f httpd.pid + fi + + rump.halt +} + +# +# Starts a SSH server and sets up the client to access it. +# Authentication is allowed and done using an RSA key exclusively, which +# is generated on the fly as part of the test case. +# XXX: Ideally, all the tests in this test program should be able to share +# the generated key, because creating it can be a very slow process on some +# machines. +# +# XXX2: copypasted from jmmv's sshd thingamob in the psshfs test. +# ideally code (and keys, like jmmv notes above) could be shared +# +start_sshd() { + echo "Setting up SSH server configuration" + sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \ + $(atf_get_srcdir)/sshd_config.in >sshd_config || \ + atf_fail "Failed to create sshd_config" + atf_check -s ignore -o empty -e ignore \ + cp $(atf_get_srcdir)/ssh_host_key . + atf_check -s ignore -o empty -e ignore \ + cp $(atf_get_srcdir)/ssh_host_key.pub . + atf_check -s eq:0 -o empty -e empty chmod 400 ssh_host_key + atf_check -s eq:0 -o empty -e empty chmod 444 ssh_host_key.pub + + env LD_PRELOAD=/usr/lib/librumphijack.so \ + /usr/sbin/sshd -e -f ./sshd_config + while [ ! -f sshd.pid ]; do + sleep 0.01 + done + echo "SSH server started (pid $(cat sshd.pid))" + + echo "Setting up SSH client configuration" + atf_check -s eq:0 -o empty -e empty \ + ssh-keygen -f ssh_user_key -t rsa -b 1024 -N "" -q + atf_check -s eq:0 -o empty -e empty \ + cp ssh_user_key.pub authorized_keys + echo "127.0.0.1,localhost,::1 " \ + "$(cat $(atf_get_srcdir)/ssh_host_key.pub)" >known_hosts || \ + atf_fail "Failed to create known_hosts" + atf_check -s eq:0 -o empty -e empty chmod 600 authorized_keys + sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \ + $(atf_get_srcdir)/ssh_config.in >ssh_config || \ + atf_fail "Failed to create ssh_config" + + echo "sshd running" +} + +atf_test_case ssh cleanup +ssh_head() +{ + atf_set "descr" "Test that hijacked ssh/sshd works" +} + +ssh_body() +{ + + atf_check -s exit:0 ${rumpnetsrv} ${RUMP_SERVER} + # make sure clients die after we nuke the server + export RUMPHIJACK_RETRYCONNECT='die' + + start_sshd + + # create some sort of directory for us to "ls" + mkdir testdir + cd testdir + jot 11 | xargs touch + jot 11 12 | xargs mkdir + cd .. + + atf_check -s exit:0 -o save:ssh.out \ + env LD_PRELOAD=/usr/lib/librumphijack.so \ + ssh -T -F ssh_config 127.0.0.1 env BLOCKSIZE=512 \ + ls -li $(pwd)/testdir + atf_check -s exit:0 -o file:ssh.out env BLOCKSIZE=512 \ + ls -li $(pwd)/testdir +} + +ssh_cleanup() +{ + rump.halt + # sshd dies due to RUMPHIJACK_RETRYCONNECT=1d6 +} + +test_nfs() +{ + + magicstr='wind in my hair' + # create ffs file system we'll be serving from + atf_check -s exit:0 -o ignore newfs -F -s 10000 ffs.img + + # start nfs kernel server. this is a mouthful + export RUMP_SERVER=unix://serversock + atf_check -s exit:0 rump_server $* ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.1 + + export RUMPHIJACK_RETRYCONNECT=die + export LD_PRELOAD=/usr/lib/librumphijack.so + + atf_check -s exit:0 mkdir -p /rump/var/run + atf_check -s exit:0 mkdir -p /rump/var/db + atf_check -s exit:0 touch /rump/var/db/mountdtab + atf_check -s exit:0 mkdir /rump/etc + atf_check -s exit:0 mkdir /rump/export + + atf_check -s exit:0 -x \ + 'echo "/export -noresvport -noresvmnt 10.1.1.100" | \ + dd of=/rump/etc/exports 2> /dev/null' + + atf_check -s exit:0 -e ignore mount_ffs /dk /rump/export + atf_check -s exit:0 -x "echo ${magicstr} > /rump/export/im_alive" + + # start rpcbind. we want /var/run/rpcbind.sock + export RUMPHIJACK='blanket=/var/run,socket=all' + atf_check -s exit:0 rpcbind + + # ok, then we want mountd in the similar fashion + export RUMPHIJACK='blanket=/var/run:/var/db:/export,socket=all,path=/rump,vfs=all' + atf_check -s exit:0 mountd /rump/etc/exports + + # finally, le nfschuck + export RUMPHIJACK='blanket=/var/run,socket=all,vfs=all' + atf_check -s exit:0 nfsd + + # + # now, time for the client server and associated madness. + # + + export RUMP_SERVER=unix://clientsock + unset RUMPHIJACK + unset LD_PRELOAD + + # at least the kernel server is easier + atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet \ + -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpfs_nfs\ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.100 + + export LD_PRELOAD=/usr/lib/librumphijack.so + + atf_check -s exit:0 mkdir /rump/mnt + atf_check -s exit:0 mount_nfs 10.1.1.1:/export /rump/mnt + + atf_check -s exit:0 -o inline:"${magicstr}\n" cat /rump/mnt/im_alive + atf_check -s exit:0 -o match:'.*im_alive$' ls -l /rump/mnt/im_alive +} + + +atf_test_case nfs cleanup +nfs_head() +{ + atf_set "descr" "Test hijacked nfsd and mount_nfs" +} + +nfs_body() +{ + test_nfs -lrumpvfs -lrumpdev -lrumpnet -lrumpnet_net \ + -lrumpnet_netinet -lrumpnet_local -lrumpnet_shmif \ + -lrumpdev_disk -lrumpfs_ffs -lrumpfs_nfs -lrumpfs_nfsserver \ + -d key=/dk,hostpath=ffs.img,size=host +} + +nfs_cleanup() +{ + RUMP_SERVER=unix://serversock rump.halt 2> /dev/null + RUMP_SERVER=unix://clientsock rump.halt 2> /dev/null + : +} + +atf_test_case nfs_autoload cleanup +nfs_autoload_head() +{ + atf_set "descr" "Test hijacked nfsd with autoload from /stand" +} + +nfs_autoload_body() +{ + [ `uname -m` = "i386" ] || atf_skip "test currently valid only on i386" + test_nfs -lrumpvfs -lrumpdev -lrumpnet -lrumpnet_net \ + -lrumpnet_netinet -lrumpnet_local -lrumpnet_shmif \ + -lrumpdev_disk -d key=/dk,hostpath=ffs.img,size=host +} + +nfs_autoload_cleanup() +{ + nfs_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case http + atf_add_test_case ssh + atf_add_test_case nfs + atf_add_test_case nfs_autoload +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh b/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh new file mode 100755 index 0000000..c803e2a --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh @@ -0,0 +1,223 @@ +# $NetBSD: t_vfs.sh,v 1.6 2012/08/04 03:56:47 riastradh Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +img=ffs.img +rumpsrv_ffs=\ +"rump_server -lrumpvfs -lrumpfs_ffs -lrumpdev_disk -d key=/img,hostpath=${img},size=host" +export RUMP_SERVER=unix://csock + +domount() +{ + + mntdir=$1 + [ $# -eq 0 ] && mntdir=/rump/mnt + atf_check -s exit:0 -e ignore mount_ffs /img ${mntdir} +} + +dounmount() +{ + + atf_check -s exit:0 umount -R ${mntdir} +} + +remount() +{ + + dounmount + domount /rump/mnt2 +} + +simpletest() +{ + local name="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { }" + eval "${name}_body() { \ + atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER} ; \ + export LD_PRELOAD=/usr/lib/librumphijack.so ; \ + ${name} " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + rump.halt + }" +} + +test_case() +{ + local name="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { }" + eval "${name}_body() { \ + atf_check -s exit:0 -o ignore newfs -F -s 20000 ${img} ; \ + atf_check -s exit:0 ${rumpsrv_ffs} ${RUMP_SERVER} ; \ + export LD_PRELOAD=/usr/lib/librumphijack.so ; \ + mkdir /rump/mnt /rump/mnt2 ; \ + domount ; \ + ${name} " "${@}" "; \ + dounmount ${mntdir} + }" + eval "${name}_cleanup() { \ + rump.halt + }" +} + +test_case paxcopy +test_case cpcopy +test_case mv_nox +test_case ln_nox + +# +# use rumphijack to cp/pax stuff onto an image, unmount it, remount it +# at a different location, and check that we have an identical copy +# (we make a local copy to avoid the minor possibility that someone +# modifies the source dir data while the test is running) +# +paxcopy() +{ + parent=$(dirname $(atf_get_srcdir)) + thedir=$(basename $(atf_get_srcdir)) + atf_check -s exit:0 pax -rw -s,${parent},, $(atf_get_srcdir) . + atf_check -s exit:0 pax -rw ${thedir} /rump/mnt + remount + atf_check -s exit:0 diff -ru ${thedir} /rump/mnt2/${thedir} +} + +cpcopy() +{ + thedir=$(basename $(atf_get_srcdir)) + atf_check -s exit:0 cp -Rp $(atf_get_srcdir) . + atf_check -s exit:0 cp -Rp ${thedir} /rump/mnt + remount + atf_check -s exit:0 diff -ru ${thedir} /rump/mnt2/${thedir} +} + +# +# non-crosskernel mv (non-simple test since this uses rename(2) +# which is not supported by rumpfs) +# + +mv_nox() +{ + # stat default format sans changetime and filename + statstr='%d %i %Sp %l %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf' + + atf_check -s exit:0 touch /rump/mnt/filename + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /rump/mnt/filename + atf_check -s exit:0 mkdir /rump/mnt/dir + atf_check -s exit:0 mv /rump/mnt/filename /rump/mnt/dir/same + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /rump/mnt/dir/same +} + +ln_nox() +{ + # Omit st_nlink too, since it will increase. + statstr='%d %i %Sp %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf' + + atf_check -s exit:0 touch /rump/mnt/filename + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /rump/mnt/filename + atf_check -s exit:0 mkdir /rump/mnt/dir + atf_check -s exit:0 ln /rump/mnt/filename /rump/mnt/dir/same + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /rump/mnt/filename + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /rump/mnt/dir/same +} + +simpletest mv_x +simpletest ln_x +simpletest runonprefix +simpletest blanket +simpletest doubleblanket + +# +# do a cross-kernel mv +# +mv_x() +{ + thedir=$(basename $(atf_get_srcdir)) + atf_check -s exit:0 cp -Rp $(atf_get_srcdir) . + atf_check -s exit:0 cp -Rp ${thedir} ${thedir}.2 + atf_check -s exit:0 mv ${thedir} /rump + atf_check -s exit:0 diff -ru ${thedir}.2 /rump/${thedir} +} + +# +# Fail to make a cross-kernel hard link. +# +ln_x() +{ + atf_check -s exit:0 touch ./loser + atf_check -s not-exit:0 -e ignore ln ./loser /rump/. +} + +runonprefix() +{ + atf_check -s exit:0 -o ignore stat /rump/dev + atf_check -s exit:1 -e ignore stat /rumpdev +} + +blanket() +{ + export RUMPHIJACK='blanket=/dev,path=/rump' + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /rump/dev/null + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /dev/null +} + +doubleblanket() +{ + atf_check -s exit:0 mkdir /rump/dir + atf_check -s exit:0 ln -s dir /rump/dirtoo + + export RUMPHIJACK='blanket=/dirtoo:/dir' + atf_check -s exit:0 touch /dir/file + + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /dir/file + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /dirtoo/file +} + +atf_init_test_cases() +{ + + atf_add_test_case paxcopy + atf_add_test_case cpcopy + atf_add_test_case mv_x + atf_add_test_case ln_x + atf_add_test_case mv_nox + atf_add_test_case ln_nox + atf_add_test_case runonprefix + atf_add_test_case blanket + atf_add_test_case doubleblanket +} diff --git a/contrib/netbsd-tests/lib/libskey/t_algorithms.c b/contrib/netbsd-tests/lib/libskey/t_algorithms.c new file mode 100644 index 0000000..2eec278 --- /dev/null +++ b/contrib/netbsd-tests/lib/libskey/t_algorithms.c @@ -0,0 +1,121 @@ +/* $NetBSD: t_algorithms.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $ */ + +/* + * Copyright (c) 2000, 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_algorithms.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $"); + +#include <stdio.h> +#include <strings.h> +#include <skey.h> + +#include <atf-c.h> + +#define H_REQUIRE(x, y) \ + ATF_REQUIRE_MSG(strcasecmp((x), (y)) == 0, "\"%s\" != \"%s\"", (x), (y)) + +static void +h_check(const char *pass, const char *seed, + const char *algo, const char *zero, + const char *one, const char *nine) +{ + char prn[64]; + char data[16]; + int i; + + skey_set_algorithm(algo); + + keycrunch(data, seed, pass); + btoa8(prn, data); + H_REQUIRE(prn, zero); + + f(data); + btoa8(prn, data); + H_REQUIRE(prn, one); + + for(i = 1; i < 99; ++i) + f(data); + btoa8(prn, data); + H_REQUIRE(prn, nine); +} + +ATF_TC(md4); +ATF_TC_HEAD(md4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks MD4 algorithm"); +} +ATF_TC_BODY(md4, tc) +{ + h_check("This is a test.", "TeSt", "md4", "D1854218EBBB0B51", + "63473EF01CD0B444", "C5E612776E6C237A"); + h_check("AbCdEfGhIjK", "alpha1", "md4", "50076F47EB1ADE4E", + "65D20D1949B5F7AB", "D150C82CCE6F62D1"); + h_check("OTP's are good", "correct", "md4", "849C79D4F6F55388", + "8C0992FB250847B1", "3F3BF4B4145FD74B"); +} + +ATF_TC(md5); +ATF_TC_HEAD(md5, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks MD5 algorithm"); +} +ATF_TC_BODY(md5, tc) +{ + h_check("This is a test.", "TeSt", "md5", "9E876134D90499DD", + "7965E05436F5029F", "50FE1962C4965880"); + h_check("AbCdEfGhIjK", "alpha1", "md5", "87066DD9644BF206", + "7CD34C1040ADD14B", "5AA37A81F212146C"); + h_check("OTP's are good", "correct", "md5", "F205753943DE4CF9", + "DDCDAC956F234937", "B203E28FA525BE47"); +} + +ATF_TC(sha1); +ATF_TC_HEAD(sha1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks SHA1 algorithm"); +} +ATF_TC_BODY(sha1, tc) +{ + h_check("This is a test.", "TeSt", "sha1","BB9E6AE1979D8FF4", + "63D936639734385B", "87FEC7768B73CCF9"); + h_check("AbCdEfGhIjK", "alpha1", "sha1","AD85F658EBE383C9", + "D07CE229B5CF119B", "27BC71035AAF3DC6"); + h_check("OTP's are good", "correct", "sha1","D51F3E99BF8E6F0B", + "82AEB52D943774E4", "4F296A74FE1567EC"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, md4); + ATF_TP_ADD_TC(tp, md5); + ATF_TP_ADD_TC(tp, sha1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libsljit/t_sljit.sh b/contrib/netbsd-tests/lib/libsljit/t_sljit.sh new file mode 100755 index 0000000..50fb860 --- /dev/null +++ b/contrib/netbsd-tests/lib/libsljit/t_sljit.sh @@ -0,0 +1,45 @@ +# $NetBSD: t_sljit.sh,v 1.1 2012/11/05 00:34:28 alnsn Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Alexander Nasonov. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case sljit +sljit_head() { + + atf_set "descr" "Run sljit unit tests." +} + +sljit_body() { + + $(atf_get_srcdir)/h_sljit 2>&1 || atf_fail "check report" +} + +atf_init_test_cases() { + + atf_add_test_case sljit +} diff --git a/contrib/netbsd-tests/lib/libutil/t_efun.c b/contrib/netbsd-tests/lib/libutil/t_efun.c new file mode 100644 index 0000000..f5187f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_efun.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_efun.c,v 1.3 2012/11/04 23:37:02 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_efun.c,v 1.3 2012/11/04 23:37:02 christos Exp $"); + +#include <atf-c.h> + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <util.h> + +static bool fail; +static void handler(int, const char *, ...); + +static void +handler(int ef, const char *fmt, ...) +{ + fail = false; +} + +ATF_TC(ecalloc); +ATF_TC_HEAD(ecalloc, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ecalloc(3)"); +} + +ATF_TC_BODY(ecalloc, tc) +{ + char *x; + + fail = true; + x = ecalloc(-1, 1); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); + + fail = true; + x = ecalloc(SIZE_MAX, 2); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TC(efopen); +ATF_TC_HEAD(efopen, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of efopen(3)"); +} + +ATF_TC_BODY(efopen, tc) +{ + FILE *f; + + fail = true; + f = efopen("XXX", "XXX"); + + ATF_REQUIRE(f == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TC(emalloc); +ATF_TC_HEAD(emalloc, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of emalloc(3)"); +} + +ATF_TC_BODY(emalloc, tc) +{ + char *x; + + fail = true; + x = emalloc(-1); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TC(erealloc); +ATF_TC_HEAD(erealloc, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of erealloc(3)"); +} + +ATF_TC_BODY(erealloc, tc) +{ + char *x; + + fail = true; + x = erealloc(NULL, -1); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_REQUIRE(esetfunc(handler) != NULL); + + ATF_TP_ADD_TC(tp, ecalloc); + ATF_TP_ADD_TC(tp, efopen); + ATF_TP_ADD_TC(tp, emalloc); + ATF_TP_ADD_TC(tp, erealloc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libutil/t_parsedate.c b/contrib/netbsd-tests/lib/libutil/t_parsedate.c new file mode 100644 index 0000000..ec035a6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_parsedate.c @@ -0,0 +1,142 @@ +/* $NetBSD: t_parsedate.c,v 1.7 2013/01/19 15:21:43 apb Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_parsedate.c,v 1.7 2013/01/19 15:21:43 apb Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <time.h> +#include <util.h> + +ATF_TC(dates); + +ATF_TC_HEAD(dates, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unambiguous dates" + " (PR lib/44255)"); +} + +ATF_TC_BODY(dates, tc) +{ + + ATF_CHECK(parsedate("69-09-10", NULL, NULL) != -1); + ATF_CHECK(parsedate("2006-11-17", NULL, NULL) != -1); + ATF_CHECK(parsedate("10/1/2000", NULL, NULL) != -1); + ATF_CHECK(parsedate("20 Jun 1994", NULL, NULL) != -1); + ATF_CHECK(parsedate("23jun2001", NULL, NULL) != -1); + ATF_CHECK(parsedate("1-sep-06", NULL, NULL) != -1); + ATF_CHECK(parsedate("1/11", NULL, NULL) != -1); + ATF_CHECK(parsedate("1500-01-02", NULL, NULL) != -1); + ATF_CHECK(parsedate("9999-12-21", NULL, NULL) != -1); +} + +ATF_TC(times); + +ATF_TC_HEAD(times, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test times" + " (PR lib/44255)"); +} + +ATF_TC_BODY(times, tc) +{ + + ATF_CHECK(parsedate("10:01", NULL, NULL) != -1); + ATF_CHECK(parsedate("10:12pm", NULL, NULL) != -1); + ATF_CHECK(parsedate("12:11:01.000012", NULL, NULL) != -1); + ATF_CHECK(parsedate("12:21-0500", NULL, NULL) != -1); +} + +ATF_TC(relative); + +ATF_TC_HEAD(relative, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test relative items" + " (PR lib/44255)"); +} + +ATF_TC_BODY(relative, tc) +{ + + ATF_CHECK(parsedate("-1 month", NULL, NULL) != -1); + ATF_CHECK(parsedate("last friday", NULL, NULL) != -1); + ATF_CHECK(parsedate("one week ago", NULL, NULL) != -1); + ATF_CHECK(parsedate("this thursday", NULL, NULL) != -1); + ATF_CHECK(parsedate("next sunday", NULL, NULL) != -1); + ATF_CHECK(parsedate("+2 years", NULL, NULL) != -1); +} + +ATF_TC(atsecs); + +ATF_TC_HEAD(atsecs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test seconds past the epoch"); +} + +ATF_TC_BODY(atsecs, tc) +{ + int tzoff; + + /* "@0" -> (time_t)0, regardless of timezone */ + ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0); + putenv(__UNCONST("TZ=Europe/Berlin")); + tzset(); + ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0); + putenv(__UNCONST("TZ=America/New_York")); + tzset(); + ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0); + tzoff = 0; + ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0); + tzoff = 3600; + ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0); + tzoff = -3600; + ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0); + + /* -1 or other negative numbers are not errors */ + errno = 0; + ATF_CHECK(parsedate("@-1", NULL, &tzoff) == (time_t)-1 && errno == 0); + ATF_CHECK(parsedate("@-2", NULL, &tzoff) == (time_t)-2 && errno == 0); + + /* junk is an error */ + errno = 0; + ATF_CHECK(parsedate("@junk", NULL, NULL) == (time_t)-1 && errno != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dates); + ATF_TP_ADD_TC(tp, times); + ATF_TP_ADD_TC(tp, relative); + ATF_TP_ADD_TC(tp, atsecs); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libutil/t_pidfile.c b/contrib/netbsd-tests/lib/libutil/t_pidfile.c new file mode 100644 index 0000000..a2aff83 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_pidfile.c @@ -0,0 +1,363 @@ +/* $NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file implements tests for the pidfile(3) functions. + * + * The tests here are tricky because we need to validate that the atexit(3) + * handler registered by pidfile(3) correctly deletes the generated pidfile. + * To do so: + * 1) We spawn a subprocess in every test case, + * 2) Run our test code in such subprocesses. We cannot call any of the ATF + * primitives from inside these. + * 3) Wait for the subprocess to terminate and ensure it exited successfully. + * 4) Check that the pidfile(s) created in the subprocess are gone. + * + * Additionally, pidfile(3) hardcodes a path to a directory writable only by + * root (/var/run). This makes us require root privileges to execute these + * tests. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $"); + +#include <sys/stat.h> +#include <sys/wait.h> + +#include <assert.h> +#include <err.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <paths.h> +#include <unistd.h> +#include <util.h> + +#include <atf-c.h> + +/* Used by routines that can be called both from the parent and the child + * code to implement proper error reporting. */ +static bool in_child = false; + +/* Callable from the test case child code. */ +static void +check_pidfile(const char *path) +{ + FILE *file; + int pid; + + printf("Validating contents of pidfile '%s'\n", path); + + if ((file = fopen(path, "r")) == NULL) + errx(EXIT_FAILURE, "Cannot open expected pidfile '%s'", path); + + if (fscanf(file, "%d", &pid) == -1) + errx(EXIT_FAILURE, "Failed to read pid from pidfile '%s'", + path); + + printf("Read pid %d, current pid %d\n", pid, getpid()); + if (pid != getpid()) + errx(EXIT_FAILURE, "Pid in pidfile (%d) does not match " + "current pid (%d)", pid, getpid()); +} + +/* Callable from the test case parent/child code. */ +static void +ensure_deleted(const char *path) +{ + printf("Ensuring pidfile %s does not exist any more\n", path); + if (access(path, R_OK) != -1) { + unlink(path); + if (in_child) + errx(EXIT_FAILURE, "The pidfile %s was not deleted", + path); + else + atf_tc_fail("The pidfile %s was not deleted", path); + } +} + +/* Callable from the test case parent code. */ +static void +run_child(void (*child)(const char *), const char *cookie) +{ + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid != -1); + if (pid == 0) { + in_child = true; + child(cookie); + assert(false); + /* UNREACHABLE */ + } else { + int status; + + ATF_REQUIRE(waitpid(pid, &status, 0) != -1); + if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) + atf_tc_fail("See stderr for details"); + } +} + +/* Callable from the test case parent/child code. */ +static char * +generate_varrun_pidfile(const char *basename) +{ + char *path; + + if (asprintf(&path, "%s%s.pid", _PATH_VARRUN, + basename == NULL ? getprogname() : basename) == -1) { + if (in_child) + errx(EXIT_FAILURE, "Cannot allocate memory for path"); + else + atf_tc_fail("Cannot allocate memory for path"); + } + + return path; +} + +static void +helper_default_path(const char *path) +{ + + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with default " + "basename"); + + check_pidfile(path); + exit(EXIT_SUCCESS); +} + +ATF_TC(default_path); +ATF_TC_HEAD(default_path, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(default_path, tc) +{ + char *path; + + path = generate_varrun_pidfile(NULL); + run_child(helper_default_path, path); + ensure_deleted(path); + free(path); +} + +static void +helper_custom_basename(const char *path) +{ + + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with custom " + "basename"); + + check_pidfile(path); + exit(EXIT_SUCCESS); +} + +ATF_TC(custom_basename); +ATF_TC_HEAD(custom_basename, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(custom_basename, tc) +{ + char *path; + + path = generate_varrun_pidfile("custom-basename"); + run_child(helper_custom_basename, path); + ensure_deleted(path); + free(path); +} + +static void +helper_custom_path(const char *path) +{ + + if (pidfile(path) == -1) + errx(EXIT_FAILURE, "Failed to create pidfile '%s'", path); + check_pidfile(path); + exit(EXIT_SUCCESS); +} + +ATF_TC_WITHOUT_HEAD(custom_path); +ATF_TC_BODY(custom_path, tc) +{ + + ATF_REQUIRE(mkdir("var", 0777) != -1); + ATF_REQUIRE(mkdir("var/run", 0777) != -1); + + run_child(helper_custom_path, "./var/run/my-pidfile.pid"); + + ensure_deleted("./var/run/my-pidfile.pid"); +} + +static void +helper_change_basenames(const char *unused_cookie) +{ + char *default_path; + char *custom_path; + + default_path = generate_varrun_pidfile(NULL); + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with default " + "basename"); + check_pidfile(default_path); + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to recreate pidfile with default " + "basename"); + check_pidfile(default_path); + + custom_path = generate_varrun_pidfile("custom-basename"); + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with custom " + "basename"); + ensure_deleted(default_path); + check_pidfile(custom_path); + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to recreate pidfile with custom " + "basename"); + check_pidfile(custom_path); + + free(custom_path); + free(default_path); + exit(EXIT_SUCCESS); +} + +ATF_TC(change_basenames); +ATF_TC_HEAD(change_basenames, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(change_basenames, tc) +{ + char *default_path; + char *custom_path; + + run_child(helper_change_basenames, NULL); + + default_path = generate_varrun_pidfile(NULL); + custom_path = generate_varrun_pidfile("custom-basename"); + + ensure_deleted(default_path); + ensure_deleted(custom_path); + + free(custom_path); + free(default_path); +} + +static void +helper_change_paths(const char *unused_cookie) +{ + + if (pidfile("./var/run/first.pid") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile " + "'./var/run/first.pid'"); + check_pidfile("./var/run/first.pid"); + + if (pidfile("./second.pid") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'"); + ensure_deleted("./var/run/first.pid"); + check_pidfile("./second.pid"); + + exit(EXIT_SUCCESS); +} + +ATF_TC_WITHOUT_HEAD(change_paths); +ATF_TC_BODY(change_paths, tc) +{ + + ATF_REQUIRE(mkdir("var", 0777) != -1); + ATF_REQUIRE(mkdir("var/run", 0777) != -1); + + run_child(helper_change_paths, NULL); + + ensure_deleted("./var/run/my-pidfile.pid"); + ensure_deleted("second.pid"); +} + +static void +helper_mix(const char *unused_cookie) +{ + char *default_path; + char *custom_path; + + default_path = generate_varrun_pidfile(NULL); + custom_path = generate_varrun_pidfile("custom-basename"); + + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to create default pidfile"); + check_pidfile(default_path); + + if (pidfile("./second.pid") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'"); + ensure_deleted(default_path); + check_pidfile("./second.pid"); + + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'"); + ensure_deleted(default_path); + ensure_deleted("./second.pid"); + ensure_deleted("./custom-basename"); + check_pidfile(custom_path); + + free(custom_path); + free(default_path); + exit(EXIT_SUCCESS); +} + +ATF_TC(change_mix); +ATF_TC_HEAD(change_mix, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(change_mix, tc) +{ + char *default_path; + + run_child(helper_mix, NULL); + + default_path = generate_varrun_pidfile(NULL); + ensure_deleted(default_path); + ensure_deleted("second.pid"); + free(default_path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, default_path); + ATF_TP_ADD_TC(tp, custom_basename); + ATF_TP_ADD_TC(tp, custom_path); + ATF_TP_ADD_TC(tp, change_basenames); + ATF_TP_ADD_TC(tp, change_paths); + ATF_TP_ADD_TC(tp, change_mix); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libutil/t_snprintb.c b/contrib/netbsd-tests/lib/libutil/t_snprintb.c new file mode 100644 index 0000000..8863e8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_snprintb.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_snprintb.c,v 1.4 2014/06/06 06:59:21 shm Exp $ */ + +/* + * Copyright (c) 2002, 2004, 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_snprintb.c,v 1.4 2014/06/06 06:59:21 shm Exp $"); + +#include <string.h> +#include <util.h> + +#include <atf-c.h> + +static void +h_snprintb(const char *fmt, uint64_t val, const char *res) +{ + char buf[1024]; + int len, slen; + + len = snprintb(buf, sizeof(buf), fmt, val); + slen = (int) strlen(res); + + ATF_REQUIRE_STREQ(res, buf); + ATF_REQUIRE_EQ(len, slen); +} + +ATF_TC(snprintb); +ATF_TC_HEAD(snprintb, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks snprintb(3)"); +} +ATF_TC_BODY(snprintb, tc) +{ + h_snprintb("\10\2BITTWO\1BITONE", 3, "03<BITTWO,BITONE>"); + h_snprintb("\177\20b\0A\0\0", 0, "0x0"); + + h_snprintb("\177\20b\05NOTBOOT\0b\06FPP\0b\013SDVMA\0b\015VIDEO\0" + "b\020LORES\0b\021FPA\0b\022DIAG\0b\016CACHE\0" + "b\017IOCACHE\0b\022LOOPBACK\0b\04DBGCACHE\0", + 0xe860, "0xe860<NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>"); +} + +static void +h_snprintb_m(const char *fmt, uint64_t val, int line_max, const char *res, + int res_len) +{ + char buf[1024]; + int len; + + len = snprintb_m(buf, sizeof(buf), fmt, val, line_max); + + ATF_REQUIRE_EQ(len, res_len); + ATF_REQUIRE_EQ(0, memcmp(res, buf, res_len + 1)); +} + +ATF_TC(snprintb_m); +ATF_TC_HEAD(snprintb_m, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks snprintb_m(3)"); +} +ATF_TC_BODY(snprintb_m, tc) +{ + h_snprintb_m("\177\020b\0LSB\0b\1_BITONE\0f\4\4NIBBLE2\0" + "f\x10\4BURST\0=\4FOUR\0=\xfSIXTEEN\0" + "b\x1fMSB\0\0", + 0x800f0701, + 33, + "0x800f0701<LSB,NIBBLE2=0x0>\0" + "0x800f0701<BURST=0xf=SIXTEEN,MSB>\0\0", + 62); + + h_snprintb_m("\177\020b\0LSB\0b\1_BITONE\0f\4\4NIBBLE2\0" + "f\x10\4BURST\0=\4FOUR\0=\xfSIXTEEN\0" + "b\x1fMSB\0\0", + 0x800f0701, + 32, + "0x800f0701<LSB,NIBBLE2=0x0>\0" + "0x800f0701<BURST=0xf=SIXTEEN>\0" + "0x800f0701<MSB>\0\0", + 74); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, snprintb); + ATF_TP_ADD_TC(tp, snprintb_m); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c b/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c new file mode 100644 index 0000000..b4e8cb3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c @@ -0,0 +1,185 @@ +/* $NetBSD: t_sockaddr_snprintf.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $ */ + +/* + * Copyright (c) 2002, 2004, 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sockaddr_snprintf.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $"); + +#include <sys/socket.h> /* AF_ */ +#include <sys/un.h> /* sun */ + +#include <net/if_dl.h> /* sdl */ +#include <netatalk/at.h> /* sat */ +#include <netinet/in.h> /* sin/sin6 */ + +#include <string.h> +#include <util.h> + +#include <atf-c.h> + +ATF_TC(sockaddr_snprintf_in); +ATF_TC_HEAD(sockaddr_snprintf_in, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_in"); +} +ATF_TC_BODY(sockaddr_snprintf_in, tc) +{ + char buf[1024]; + struct sockaddr_in sin4; + int i; + + memset(&sin4, 0, sizeof(sin4)); + sin4.sin_len = sizeof(sin4); + sin4.sin_family = AF_INET; + sin4.sin_port = ntohs(80); + sin4.sin_addr.s_addr = ntohl(INADDR_LOOPBACK); + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a", + (struct sockaddr *)&sin4); + + ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sin4"); + ATF_REQUIRE_STREQ(buf, "2 16 80 127.0.0.1"); +} + +ATF_TC(sockaddr_snprintf_in6); +ATF_TC_HEAD(sockaddr_snprintf_in6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_in6"); +} +ATF_TC_BODY(sockaddr_snprintf_in6, tc) +{ +#ifdef INET6 + char buf[1024]; + struct sockaddr_in6 sin6; + int i; + + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_len = sizeof(sin6); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = ntohs(80); + sin6.sin6_addr = in6addr_nodelocal_allnodes; + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a", + (struct sockaddr *)&sin6); + + ATF_REQUIRE_EQ_MSG(i, 16, "bad length for sin6"); + ATF_REQUIRE_STREQ(buf, "24 28 80 ff01::1"); +#else + atf_tc_skip("Tests built with USE_INET6=no"); +#endif /* INET6 */ +} + +ATF_TC(sockaddr_snprintf_un); +ATF_TC_HEAD(sockaddr_snprintf_un, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_un"); +} +ATF_TC_BODY(sockaddr_snprintf_un, tc) +{ + char buf[1024]; + struct sockaddr_un sun; + int i; + + memset(&sun, 0, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + strncpy(sun.sun_path, "/tmp/sock", sizeof(sun.sun_path)); + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a", + (struct sockaddr *)&sun); + + ATF_REQUIRE_EQ_MSG(i, 15, "bad length for sun"); + ATF_REQUIRE_STREQ(buf, "1 106 /tmp/sock"); +} + +ATF_TC(sockaddr_snprintf_at); +ATF_TC_HEAD(sockaddr_snprintf_at, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_at"); +} +ATF_TC_BODY(sockaddr_snprintf_at, tc) +{ + char buf[1024]; + struct sockaddr_at sat; + int i; + + memset(&sat, 0, sizeof(sat)); + sat.sat_len = sizeof(sat); + sat.sat_family = AF_APPLETALK; + sat.sat_addr.s_net = ntohs(101); + sat.sat_addr.s_node = 3; + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a", + (struct sockaddr *)&sat); + + ATF_REQUIRE_EQ_MSG(i, 11, "bad length for sat"); + ATF_REQUIRE_STREQ(buf, "16 16 101.3"); +} + +ATF_TC(sockaddr_snprintf_dl); +ATF_TC_HEAD(sockaddr_snprintf_dl, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_dl"); +} +ATF_TC_BODY(sockaddr_snprintf_dl, tc) +{ + char buf[1024]; + struct sockaddr_dl sdl; + int i; + + memset(&sdl, 0, sizeof(sdl)); + sdl.sdl_len = sizeof(sdl); + sdl.sdl_family = AF_LINK; + sdl.sdl_index = 0; + sdl.sdl_type = 0; + sdl.sdl_nlen = 0; + sdl.sdl_alen = 6; + sdl.sdl_slen = 0; + memcpy(sdl.sdl_data, "\01\02\03\04\05\06", 6); + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a", + (struct sockaddr *)&sdl); + + ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sdl"); + ATF_REQUIRE_STREQ(buf, "18 20 1.2.3.4.5.6"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sockaddr_snprintf_in); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_in6); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_un); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_at); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_dl); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c b/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c new file mode 100644 index 0000000..b32d954 --- /dev/null +++ b/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c @@ -0,0 +1,17 @@ +#define LIBNAME "pthread" +#include "sem.c" + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, postwait); + ATF_TP_ADD_TC(tp, initvalue); + ATF_TP_ADD_TC(tp, destroy); + ATF_TP_ADD_TC(tp, busydestroy); + ATF_TP_ADD_TC(tp, blockwait); + ATF_TP_ADD_TC(tp, blocktimedwait); + ATF_TP_ADD_TC(tp, named); + ATF_TP_ADD_TC(tp, unlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/semaphore/sem.c b/contrib/netbsd-tests/lib/semaphore/sem.c new file mode 100644 index 0000000..5967b88 --- /dev/null +++ b/contrib/netbsd-tests/lib/semaphore/sem.c @@ -0,0 +1,332 @@ +/* $NetBSD: sem.c,v 1.10 2012/03/09 14:25:34 joerg Exp $ */ + +/* + * Common code for semaphore tests. This can be included both into + * programs using librt and libpthread. + */ + +#include <sys/types.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <sched.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "../../h_macros.h" + +ATF_TC(postwait); +ATF_TC_HEAD(postwait, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests post and wait from a " + "single thread (%s)", LIBNAME); +} + +ATF_TC_BODY(postwait, tc) +{ + sem_t sem; + int rv; + + rump_init(); + + ATF_REQUIRE_EQ(sem_init(&sem, 1, 0), 0); + + sem_post(&sem); + sem_post(&sem); + + sem_wait(&sem); + sem_wait(&sem); + rv = sem_trywait(&sem); + ATF_REQUIRE(errno == EAGAIN); + ATF_REQUIRE(rv == -1); +} + +ATF_TC(initvalue); +ATF_TC_HEAD(initvalue, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests initialization with a non-zero " + "value (%s)", LIBNAME); +} + +ATF_TC_BODY(initvalue, tc) +{ + sem_t sem; + + rump_init(); + sem_init(&sem, 1, 4); + + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), -1); +} + +ATF_TC(destroy); +ATF_TC_HEAD(destroy, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_destroy works (%s)", LIBNAME); +} + +ATF_TC_BODY(destroy, tc) +{ + sem_t sem; + int rv, i; + + rump_init(); + for (i = 0; i < 2; i++) { + sem_init(&sem, 1, 1); + + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), -1); + ATF_REQUIRE_EQ(sem_destroy(&sem), 0); + rv = sem_trywait(&sem); + ATF_REQUIRE_EQ(errno, EINVAL); + ATF_REQUIRE_EQ(rv, -1); + } +} + +ATF_TC(busydestroy); +ATF_TC_HEAD(busydestroy, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_destroy report EBUSY for " + "a busy semaphore (%s)", LIBNAME); +} + +static void * +hthread(void *arg) +{ + sem_t *semmarit = arg; + + for (;;) { + sem_post(&semmarit[2]); + sem_wait(&semmarit[1]); + sem_wait(&semmarit[0]); + } + + return NULL; +} + +ATF_TC_BODY(busydestroy, tc) +{ + sem_t semmarit[3]; + pthread_t pt; + int i; + + /* use a unicpu rump kernel. this means less chance for race */ + setenv("RUMP_NCPU", "1", 1); + + rump_init(); + sem_init(&semmarit[0], 1, 0); + sem_init(&semmarit[1], 1, 0); + sem_init(&semmarit[2], 1, 0); + + pthread_create(&pt, NULL, hthread, semmarit); + + /* + * Make a best-effort to catch the other thread with its pants down. + * We can't do this for sure, can we? Although, we could reach + * inside the rump kernel and inquire about the thread's sleep + * status. + */ + for (i = 0; i < 1000; i++) { + sem_wait(&semmarit[2]); + usleep(1); + if (sem_destroy(&semmarit[1]) == -1) + if (errno == EBUSY) + break; + + /* + * Didn't catch it? ok, recreate and post to make the + * other thread run + */ + sem_init(&semmarit[1], 1, 0); + sem_post(&semmarit[0]); + sem_post(&semmarit[1]); + + } + if (i == 1000) + atf_tc_fail("sem destroy not reporting EBUSY"); + + pthread_cancel(pt); + pthread_join(pt, NULL); +} + +ATF_TC(blockwait); +ATF_TC_HEAD(blockwait, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_wait can handle blocking " + "(%s)", LIBNAME); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(blockwait, tc) +{ + sem_t semmarit[3]; + pthread_t pt; + int i; + + rump_init(); + sem_init(&semmarit[0], 1, 0); + sem_init(&semmarit[1], 1, 0); + sem_init(&semmarit[2], 1, 0); + + pthread_create(&pt, NULL, hthread, semmarit); + + /* + * Make a best-effort. Unless we're extremely unlucky, we should + * at least one blocking wait. + */ + for (i = 0; i < 10; i++) { + sem_wait(&semmarit[2]); + usleep(1); + sem_post(&semmarit[0]); + sem_post(&semmarit[1]); + + } + + pthread_cancel(pt); + pthread_join(pt, NULL); +} + +ATF_TC(blocktimedwait); +ATF_TC_HEAD(blocktimedwait, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_timedwait can handle blocking" + " (%s)", LIBNAME); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(blocktimedwait, tc) +{ + sem_t semid; + struct timespec tp; + + rump_init(); + + clock_gettime(CLOCK_REALTIME, &tp); + tp.tv_nsec += 50000000; + tp.tv_sec += tp.tv_nsec / 1000000000; + tp.tv_nsec %= 1000000000; + + ATF_REQUIRE_EQ(sem_init(&semid, 1, 0), 0); + ATF_REQUIRE_ERRNO(ETIMEDOUT, sem_timedwait(&semid, &tp) == -1); +} + +ATF_TC(named); +ATF_TC_HEAD(named, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests named semaphores (%s)", LIBNAME); +} + +/* + * Wow, easy naming rules. it's these times i'm really happy i can + * single-step into the kernel. + */ +#define SEM1 "/precious_sem" +#define SEM2 "/justsem" +ATF_TC_BODY(named, tc) +{ + sem_t *sem1, *sem2; + void *rv; + + rump_init(); + sem1 = sem_open(SEM1, 0); + ATF_REQUIRE_EQ(errno, ENOENT); + ATF_REQUIRE_EQ(sem1, NULL); + + sem1 = sem_open(SEM1, O_CREAT, 0444, 1); + if (sem1 == NULL) + atf_tc_fail_errno("sem_open O_CREAT"); + + rv = sem_open(SEM1, O_CREAT | O_EXCL); + ATF_REQUIRE_EQ(errno, EEXIST); + ATF_REQUIRE_EQ(rv, NULL); + + sem2 = sem_open(SEM2, O_CREAT, 0444, 0); + if (sem2 == NULL) + atf_tc_fail_errno("sem_open O_CREAT"); + + /* check that semaphores are independent */ + ATF_REQUIRE_EQ(sem_trywait(sem2), -1); + ATF_REQUIRE_EQ(sem_trywait(sem1), 0); + ATF_REQUIRE_EQ(sem_trywait(sem1), -1); + + /* check that unlinked remains valid */ + sem_unlink(SEM2); + ATF_REQUIRE_EQ(sem_post(sem2), 0); + ATF_REQUIRE_EQ(sem_trywait(sem2), 0); + ATF_REQUIRE_EQ(sem_trywait(sem2), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); + +#if 0 /* see unlink */ + /* close it and check that it's gone */ + if (sem_close(sem2) != 0) + atf_tc_fail_errno("sem close"); + ATF_REQUIRE_EQ(sem_trywait(sem2), -1); + ATF_REQUIRE_EQ(errno, EINVAL); +#endif + + /* check that we still have sem1 */ + sem_post(sem1); + ATF_REQUIRE_EQ(sem_trywait(sem1), 0); + ATF_REQUIRE_EQ(sem_trywait(sem1), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); +} + +ATF_TC(unlink); +ATF_TC_HEAD(unlink, tc) +{ + + /* this is currently broken. i'll append the PR number soon */ + atf_tc_set_md_var(tc, "descr", "tests unlinked semaphores can be " + "closed (%s)", LIBNAME); +} + +#define SEM "/thesem" +ATF_TC_BODY(unlink, tc) +{ + sem_t *sem; + + rump_init(); + sem = sem_open(SEM, O_CREAT, 0444, 0); + ATF_REQUIRE(sem); + + if (sem_unlink(SEM) == -1) + atf_tc_fail_errno("unlink"); + if (sem_close(sem) == -1) + atf_tc_fail_errno("close unlinked semaphore"); +} + +/* use rump calls for libpthread _ksem_foo() calls */ +#define F1(name, a) int _ksem_##name(a); \ +int _ksem_##name(a v1) {return rump_sys__ksem_##name(v1);} +#define F2(name, a, b) int _ksem_##name(a, b); \ +int _ksem_##name(a v1, b v2) {return rump_sys__ksem_##name(v1, v2);} +F2(init, unsigned int, intptr_t *); +F1(close, intptr_t); +F1(destroy, intptr_t); +F1(post, intptr_t); +F1(unlink, const char *); +F1(trywait, intptr_t); +F1(wait, intptr_t); +F2(getvalue, intptr_t, unsigned int *); +F2(timedwait, intptr_t, const struct timespec *); +int _ksem_open(const char *, int, mode_t, unsigned int, intptr_t *); +int _ksem_open(const char *a, int b, mode_t c, unsigned int d, intptr_t *e) + {return rump_sys__ksem_open(a,b,c,d,e);} |