diff options
Diffstat (limited to 'contrib/netbsd-tests/lib/libc')
319 files changed, 45537 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c new file mode 100644 index 0000000..56a1be8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S new file mode 100644 index 0000000..d237982 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2014/08/10 05:47:38 matt Exp $ */ + +#include <machine/asm.h> + +ENTRY_NP(return_one) + mov x0, #1 + ret + .globl return_one_end +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S new file mode 100644 index 0000000..18800e2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2014/01/26 20:42:06 matt Exp $ */ + +#include <machine/asm.h> + +ENTRY_NP(return_one) + mov r0, #1 + RET + .align 0 + .globl return_one_end +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c new file mode 100644 index 0000000..11a20f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c @@ -0,0 +1,65 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include <stdlib.h> +#include <sys/sysctl.h> + +#include "../../common/exec_prot.h" + +/* + * Support for executable space protection has always been erratic under i386. + * Originally IA-32 can't do per-page execute permission, so it is + * implemented using different executable segments for %cs (code segment). + * This only allows coarse grained protection, especially when memory starts + * being fragmented. + * Later, PAE was introduced together with a NX/XD bit in the page table + * entry to offer per-page permission. + */ +int +exec_prot_support(void) +{ + int pae; + size_t pae_len = sizeof(pae); + + if (sysctlbyname("machdep.pae", &pae, &pae_len, NULL, 0) == -1) + return PARTIAL_XP; + + if (pae == 1) { + if (system("cpuctl identify 0 | grep -q NOX") == 0 || + system("cpuctl identify 0 | grep -q XD") == 0) + return PERPAGE_XP; + } + + return PARTIAL_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S new file mode 100644 index 0000000..f80fd74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +_ENTRY(return_one) + movl $0x1,%eax + ret +LABEL(return_one_end) diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c new file mode 100644 index 0000000..623456b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return PERPAGE_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S new file mode 100644 index 0000000..ba3d678 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S @@ -0,0 +1,12 @@ +/* $NetBSD: return_one.S,v 1.1 2014/09/03 19:34:26 matt Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end + +ENTRY_NP(return_one) + l.addi r11, r0, 1 + l.jr lr + l.nop +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c new file mode 100644 index 0000000..81c1d86 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c @@ -0,0 +1,52 @@ +/* $NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $"); + +#include "../../common/exec_prot.h" + +#include <sys/sysctl.h> + +int +exec_prot_support(void) +{ + int execprot = 0; + size_t len = sizeof(execprot); + + if (sysctlbyname("machdep.execprot", &execprot, &len, NULL, 0) < 0) + return NOTIMPL; + + if (execprot) + return PERPAGE_XP; + + return NO_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S new file mode 100644 index 0000000..d40298e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2012/03/16 08:51:47 matt Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end + +_ENTRY(return_one) + li %r3, 1 + blr +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c new file mode 100644 index 0000000..91c5ff4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return PERPAGE_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S new file mode 100644 index 0000000..43ddd2c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.1 2014/09/19 17:36:26 matt Exp $ */ + +#include <machine/asm.h> + + .globl return_one_end + +ENTRY_NP(return_one) + li v0, 1 + ret +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include <machine/asm.h> + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c new file mode 100644 index 0000000..2d8363d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c @@ -0,0 +1,50 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $"); + +#include <stdlib.h> + +#include "../../common/exec_prot.h" + +/* + * When the NX/XD flag is present, the protection should be enabled. + */ +int +exec_prot_support(void) +{ + if (system("cpuctl identify 0 | grep -q NOX") == 0 || + system("cpuctl identify 0 | grep -q XD") == 0) + return PERPAGE_XP; + + return NO_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S new file mode 100644 index 0000000..0903001 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +#include <machine/asm.h> + +RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $"); + +_ENTRY(return_one) + movq $0x1, %rax + retq +LABEL(return_one_end) diff --git a/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c new file mode 100644 index 0000000..c9e0cc8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c @@ -0,0 +1,185 @@ +/* $NetBSD: t_faccessat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_faccessat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/faccessat" +#define BASEFILE "faccessat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/faccessaterr" + +ATF_TC(faccessat_fd); +ATF_TC_HEAD(faccessat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat works with fd"); +} +ATF_TC_BODY(faccessat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fdcwd); +ATF_TC_HEAD(faccessat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that faccessat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(faccessat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(faccessat(AT_FDCWD, BASEFILE, F_OK, 0) == 0); +} + +ATF_TC(faccessat_fdcwderr); +ATF_TC_HEAD(faccessat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that faccessat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(faccessat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(faccessat(AT_FDCWD, FILEERR, F_OK, 0) == -1); +} + +ATF_TC(faccessat_fderr1); +ATF_TC_HEAD(faccessat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fail with bad path"); +} +ATF_TC_BODY(faccessat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, FILEERR, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fderr2); +ATF_TC_HEAD(faccessat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fails with bad fdat"); +} +ATF_TC_BODY(faccessat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fderr3); +ATF_TC_HEAD(faccessat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fails with fd as -1"); +} +ATF_TC_BODY(faccessat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(faccessat(-1, FILE, F_OK, 0) == -1); +} + +ATF_TC(faccessat_fdlink); +ATF_TC_HEAD(faccessat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat works on symlink"); +} +ATF_TC_BODY(faccessat_fdlink, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, faccessat_fd); + ATF_TP_ADD_TC(tp, faccessat_fdcwd); + ATF_TP_ADD_TC(tp, faccessat_fdcwderr); + ATF_TP_ADD_TC(tp, faccessat_fderr1); + ATF_TP_ADD_TC(tp, faccessat_fderr2); + ATF_TP_ADD_TC(tp, faccessat_fderr3); + ATF_TP_ADD_TC(tp, faccessat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c new file mode 100644 index 0000000..462d53d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c @@ -0,0 +1,197 @@ +/* $NetBSD: t_fchmodat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fchmodat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/fchmodat" +#define BASEFILE "fchmodat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/fchmodaterr" + +ATF_TC(fchmodat_fd); +ATF_TC_HEAD(fchmodat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat works with fd"); +} +ATF_TC_BODY(fchmodat_fd, tc) +{ + int dfd; + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TC(fchmodat_fdcwd); +ATF_TC_HEAD(fchmodat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchmodat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(fchmodat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fchmodat(AT_FDCWD, BASEFILE, 0600, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TC(fchmodat_fdcwderr); +ATF_TC_HEAD(fchmodat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchmodat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(fchmodat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fchmodat(AT_FDCWD, FILEERR, 0600, 0) == -1); +} + +ATF_TC(fchmodat_fderr1); +ATF_TC_HEAD(fchmodat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fail with bad path"); +} +ATF_TC_BODY(fchmodat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, FILEERR, 0600, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchmodat_fderr2); +ATF_TC_HEAD(fchmodat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with bad fdat"); +} +ATF_TC_BODY(fchmodat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchmodat_fderr3); +ATF_TC_HEAD(fchmodat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with fd as -1"); +} +ATF_TC_BODY(fchmodat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmodat(-1, FILE, 0600, 0) == -1); +} + +ATF_TC(fchmodat_fdlink); +ATF_TC_HEAD(fchmodat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat works on symlink"); +} +ATF_TC_BODY(fchmodat_fdlink, tc) +{ + int dfdlink; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE((dfdlink = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, 0) == -1); + ATF_REQUIRE(errno = ENOENT); + + ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfdlink) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fchmodat_fd); + ATF_TP_ADD_TC(tp, fchmodat_fdcwd); + ATF_TP_ADD_TC(tp, fchmodat_fdcwderr); + ATF_TP_ADD_TC(tp, fchmodat_fderr1); + ATF_TP_ADD_TC(tp, fchmodat_fderr2); + ATF_TP_ADD_TC(tp, fchmodat_fderr3); + ATF_TP_ADD_TC(tp, fchmodat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c new file mode 100644 index 0000000..80c7606 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c @@ -0,0 +1,247 @@ +/* $NetBSD: t_fchownat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fchownat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/fchownat" +#define BASEFILE "fchownat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/fchownaterr" +#define USER "nobody" + +static int getuser(uid_t *, gid_t *); + +static int getuser(uid_t *uid, gid_t *gid) +{ + struct passwd *pw; + + if ((pw = getpwnam(USER)) == NULL) + return -1; + + *uid = pw->pw_uid; + *gid = pw->pw_gid; + + return 0; +} + +ATF_TC(fchownat_fd); +ATF_TC_HEAD(fchownat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat works with fd"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fd, tc) +{ + int dfd; + int fd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TC(fchownat_fdcwd); +ATF_TC_HEAD(fchownat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchownat works with fd as AT_FDCWD"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdcwd, tc) +{ + int fd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fchownat(AT_FDCWD, BASEFILE, uid, gid, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TC(fchownat_fdcwderr); +ATF_TC_HEAD(fchownat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchownat fails with fd as AT_FDCWD and bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdcwderr, tc) +{ + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fchownat(AT_FDCWD, FILEERR, uid, gid, 0) == -1); +} + +ATF_TC(fchownat_fderr1); +ATF_TC_HEAD(fchownat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fail with bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr1, tc) +{ + int dfd; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, FILEERR, uid, gid, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchownat_fderr2); +ATF_TC_HEAD(fchownat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fails with bad fdat"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchownat_fderr3); +ATF_TC_HEAD(fchownat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fails with fd as -1"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr3, tc) +{ + int fd; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchownat(-1, FILE, uid, gid, 0) == -1); +} + +ATF_TC(fchownat_fdlink); +ATF_TC_HEAD(fchownat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat works on symlink"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdlink, tc) +{ + int dfd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* Target does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid, + AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fchownat_fd); + ATF_TP_ADD_TC(tp, fchownat_fdcwd); + ATF_TP_ADD_TC(tp, fchownat_fdcwderr); + ATF_TP_ADD_TC(tp, fchownat_fderr1); + ATF_TP_ADD_TC(tp, fchownat_fderr2); + ATF_TP_ADD_TC(tp, fchownat_fderr3); + ATF_TP_ADD_TC(tp, fchownat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c new file mode 100644 index 0000000..d557b00 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c @@ -0,0 +1,94 @@ +/* $NetBSD: t_fexecve.c,v 1.2 2013/03/17 04:35:59 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fexecve.c,v 1.2 2013/03/17 04:35:59 jmmv Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +ATF_TC(fexecve); +ATF_TC_HEAD(fexecve, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fexecve works"); +} +ATF_TC_BODY(fexecve, tc) +{ + int status; + pid_t pid; + const char *const argv[] = { "touch", "test", NULL }; + const char *const envp[] = { NULL }; + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + int fd; + + if ((fd = open("/usr/bin/touch", O_RDONLY, 0)) == -1) + err(EXIT_FAILURE, "open /usr/bin/touch"); + + if (fexecve(fd, __UNCONST(argv), __UNCONST(envp)) == -1) { + int error; + if (errno == ENOSYS) + error = 76; + else + error = EXIT_FAILURE; + err(error, "fexecve"); + } + } + + ATF_REQUIRE(waitpid(pid, &status, 0) != -1); + if (!WIFEXITED(status)) + atf_tc_fail("child process did not exit cleanly"); + if (WEXITSTATUS(status) == 76) + atf_tc_expect_fail("fexecve not implemented"); + else + ATF_REQUIRE(WEXITSTATUS(status) == EXIT_SUCCESS); + + ATF_REQUIRE(access("test", F_OK) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fexecve); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c new file mode 100644 index 0000000..a48cd57 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c @@ -0,0 +1,196 @@ +/* $NetBSD: t_fstatat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fstatat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/fstatat" +#define BASEFILE "fstatat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/symlink" + +ATF_TC(fstatat_fd); +ATF_TC_HEAD(fstatat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat works with fd"); +} +ATF_TC_BODY(fstatat_fd, tc) +{ + int dfd; + int fd; + struct stat st1, st2; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, BASEFILE, &st1, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st2) == 0); + ATF_REQUIRE(memcmp(&st1, &st2, sizeof(st1)) == 0); +} + +ATF_TC(fstatat_fdcwd); +ATF_TC_HEAD(fstatat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fstatat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(fstatat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fstatat(AT_FDCWD, BASEFILE, &st, 0) == 0); +} + +ATF_TC(fstatat_fdcwderr); +ATF_TC_HEAD(fstatat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fstatat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(fstatat_fdcwderr, tc) +{ + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fstatat(AT_FDCWD, FILEERR, &st, 0) == -1); +} + +ATF_TC(fstatat_fderr1); +ATF_TC_HEAD(fstatat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fail with bad path"); +} +ATF_TC_BODY(fstatat_fderr1, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, FILEERR, &st, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fstatat_fderr2); +ATF_TC_HEAD(fstatat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fails with bad fdat"); +} +ATF_TC_BODY(fstatat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, BASEFILE, &st, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fstatat_fderr3); +ATF_TC_HEAD(fstatat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fails with fd as -1"); +} +ATF_TC_BODY(fstatat_fderr3, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fstatat(-1, FILE, &st, 0) == -1); +} + +ATF_TC(fstatat_fdlink); +ATF_TC_HEAD(fstatat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat works on symlink"); +} +ATF_TC_BODY(fstatat_fdlink, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* target does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fstatat(dfd, BASELINK, &st, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(fstatat(dfd, BASELINK, &st, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fstatat_fd); + ATF_TP_ADD_TC(tp, fstatat_fdcwd); + ATF_TP_ADD_TC(tp, fstatat_fdcwderr); + ATF_TP_ADD_TC(tp, fstatat_fderr1); + ATF_TP_ADD_TC(tp, fstatat_fderr2); + ATF_TP_ADD_TC(tp, fstatat_fderr3); + ATF_TP_ADD_TC(tp, fstatat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_linkat.c b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c new file mode 100644 index 0000000..b49a3f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c @@ -0,0 +1,217 @@ +/* $NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define TARGET "newdir/new" +#define BASETARGET "new" +#define LINK "olddir/symlink" +#define BASELINK "symlink" +#define FILEERR "olddir/olderr" + +ATF_TC(linkat_fd); +ATF_TC_HEAD(linkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works with fd"); +} +ATF_TC_BODY(linkat_fd, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASEFILE, nfd, BASETARGET, 0) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(linkat_fdcwd); +ATF_TC_HEAD(linkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that linkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(linkat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(AT_FDCWD, FILE, AT_FDCWD, TARGET, 0) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(linkat_fdcwderr); +ATF_TC_HEAD(linkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that linkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(linkat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET, 0) == -1); +} + +ATF_TC(linkat_fderr); +ATF_TC_HEAD(linkat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat fails with fd as -1"); +} +ATF_TC_BODY(linkat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(-1, FILE, AT_FDCWD, TARGET, 0) == -1); + ATF_REQUIRE(linkat(AT_FDCWD, FILE, -1, TARGET, 0) == -1); + ATF_REQUIRE(linkat(-1, FILE, -1, TARGET, 0) == -1); +} + +ATF_TC(linkat_fdlink1); +ATF_TC_HEAD(linkat_fdlink1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink target"); +} +ATF_TC_BODY(linkat_fdlink1, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + ATF_REQUIRE(symlink(RELFILE, LINK) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET, + AT_SYMLINK_FOLLOW) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(lstat(LINK, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino != nst.st_ino); + + ATF_REQUIRE(lstat(FILE, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + + +ATF_TC(linkat_fdlink2); +ATF_TC_HEAD(linkat_fdlink2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink source"); +} +ATF_TC_BODY(linkat_fdlink2, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + ATF_REQUIRE(symlink(RELFILE, LINK) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET, 0) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(lstat(LINK, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); + + ATF_REQUIRE(lstat(FILE, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino != nst.st_ino); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, linkat_fd); + ATF_TP_ADD_TC(tp, linkat_fdcwd); + ATF_TP_ADD_TC(tp, linkat_fdcwderr); + ATF_TP_ADD_TC(tp, linkat_fderr); + ATF_TP_ADD_TC(tp, linkat_fdlink1); + ATF_TP_ADD_TC(tp, linkat_fdlink2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c new file mode 100644 index 0000000..23c53d7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define DIR "dir" +#define SDIR "dir/openat" +#define BASESDIR "openat" +#define SDIRERR "dir/openaterr" + +ATF_TC(mkdirat_fd); +ATF_TC_HEAD(mkdirat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkdirat works with fd"); +} +ATF_TC_BODY(mkdirat_fd, tc) +{ + int dfd; + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(mkdirat(dfd, BASESDIR, mode) != -1); + ATF_REQUIRE(close(dfd) == 0); + ATF_REQUIRE(access(SDIR, F_OK) == 0); +} + +ATF_TC(mkdirat_fdcwd); +ATF_TC_HEAD(mkdirat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkdirat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(mkdirat_fdcwd, tc) +{ + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(mkdirat(AT_FDCWD, SDIR, mode) != -1); + ATF_REQUIRE(access(SDIR, F_OK) == 0); +} + +ATF_TC(mkdirat_fdcwderr); +ATF_TC_HEAD(mkdirat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkdirat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(mkdirat_fdcwderr, tc) +{ + mode_t mode = 0755; + + ATF_REQUIRE(mkdirat(AT_FDCWD, SDIRERR, mode) == -1); +} + +ATF_TC(mkdirat_fderr); +ATF_TC_HEAD(mkdirat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkdirat fails with fd as -1"); +} +ATF_TC_BODY(mkdirat_fderr, tc) +{ + int fd; + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(SDIR, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(mkdirat(-1, SDIR, mode) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkdirat_fd); + ATF_TP_ADD_TC(tp, mkdirat_fdcwd); + ATF_TP_ADD_TC(tp, mkdirat_fdcwderr); + ATF_TP_ADD_TC(tp, mkdirat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c new file mode 100644 index 0000000..1ae023c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c @@ -0,0 +1,124 @@ +/* $NetBSD: t_mkfifoat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mkfifoat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define DIR "dir" +#define FIFO "dir/openat" +#define BASEFIFO "openat" +#define FIFOERR "dir/openaterr" + +ATF_TC(mkfifoat_fd); +ATF_TC_HEAD(mkfifoat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkfifoat works with fd"); +} +ATF_TC_BODY(mkfifoat_fd, tc) +{ + int dfd; + int fd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = mkfifoat(dfd, BASEFIFO, mode)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FIFO, F_OK) == 0); +} + +ATF_TC(mkfifoat_fdcwd); +ATF_TC_HEAD(mkfifoat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkfifoat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(mkfifoat_fdcwd, tc) +{ + int fd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = mkfifoat(AT_FDCWD, FIFO, mode)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FIFO, F_OK) == 0); +} + +ATF_TC(mkfifoat_fdcwderr); +ATF_TC_HEAD(mkfifoat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkfifoat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(mkfifoat_fdcwderr, tc) +{ + int fd; + mode_t mode = 0600; + + ATF_REQUIRE((fd = mkfifoat(AT_FDCWD, FIFOERR, mode)) == -1); +} + +ATF_TC(mkfifoat_fderr); +ATF_TC_HEAD(mkfifoat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkfifoat fails with fd as -1"); +} +ATF_TC_BODY(mkfifoat_fderr, tc) +{ + int fd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FIFO, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE((fd = mkfifoat(-1, FIFO, mode)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkfifoat_fd); + ATF_TP_ADD_TC(tp, mkfifoat_fdcwd); + ATF_TP_ADD_TC(tp, mkfifoat_fdcwderr); + ATF_TP_ADD_TC(tp, mkfifoat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c new file mode 100644 index 0000000..b04a159 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_mknodat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mknodat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define DIR "dir" +#define FILE "dir/openat" +#define BASEFILE "openat" +#define FILEERR "dir/openaterr" + +static dev_t get_devnull(void); + +static dev_t +get_devnull(void) +{ + struct stat st; + + if (stat(_PATH_DEVNULL, &st) != 0) + return NODEV; + + return st.st_rdev; +} + + +ATF_TC(mknodat_fd); +ATF_TC_HEAD(mknodat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mknodat works with fd"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fd, tc) +{ + int dfd; + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = mknodat(dfd, BASEFILE, mode, dev)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FILE, F_OK) == 0); +} + +ATF_TC(mknodat_fdcwd); +ATF_TC_HEAD(mknodat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mknodat works with fd as AT_FDCWD"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fdcwd, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILE, mode, dev)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FILE, F_OK) == 0); +} + +ATF_TC(mknodat_fdcwderr); +ATF_TC_HEAD(mknodat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mknodat fails with fd as AT_FDCWD and bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fdcwderr, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILEERR, mode, dev)) == -1); +} + +ATF_TC(mknodat_fderr); +ATF_TC_HEAD(mknodat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mknodat fails with fd as -1"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fderr, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE((fd = mknodat(-1, FILE, mode, dev)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mknodat_fd); + ATF_TP_ADD_TC(tp, mknodat_fdcwd); + ATF_TP_ADD_TC(tp, mknodat_fdcwderr); + ATF_TP_ADD_TC(tp, mknodat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_o_search.c b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c new file mode 100644 index 0000000..d9dbe19 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c @@ -0,0 +1,278 @@ +/* $NetBSD: t_o_search.c,v 1.4 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_o_search.c,v 1.4 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> +#include <sys/param.h> + +/* + * dholland 20130112: disable tests that require O_SEARCH semantics + * until a decision is reached about the semantics of O_SEARCH and a + * non-broken implementation is available. + */ +#if (O_MASK & O_SEARCH) != 0 +#define USE_O_SEARCH +#endif + +#define DIR "dir" +#define FILE "dir/o_search" +#define BASEFILE "o_search" + + +ATF_TC(o_search_perm1); +ATF_TC_HEAD(o_search_perm1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat enforces search permission"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_perm1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1); + ATF_REQUIRE(errno == EACCES); + + ATF_REQUIRE(close(dfd) == 0); +} + +#ifdef USE_O_SEARCH + +ATF_TC(o_search_root_flag1); +ATF_TC_HEAD(o_search_root_flag1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that root openat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(o_search_root_flag1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(o_search_unpriv_flag1); +ATF_TC_HEAD(o_search_unpriv_flag1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_unpriv_flag1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + + ATF_REQUIRE(close(dfd) == 0); +} + +#endif /* USE_O_SEARCH */ + +ATF_TC(o_search_perm2); +ATF_TC_HEAD(o_search_perm2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat enforces search permission"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_perm2, tc) +{ + int dfd; + int fd; + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == -1); + ATF_REQUIRE(errno == EACCES); + + ATF_REQUIRE(close(dfd) == 0); +} + +#ifdef USE_O_SEARCH + +ATF_TC(o_search_root_flag2); +ATF_TC_HEAD(o_search_root_flag2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that root fstatat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(o_search_root_flag2, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(o_search_unpriv_flag2); +ATF_TC_HEAD(o_search_unpriv_flag2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_unpriv_flag2, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +#endif /* USE_O_SEARCH */ + + +ATF_TC(o_search_notdir); +ATF_TC_HEAD(o_search_notdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with non dir fd"); +} +ATF_TC_BODY(o_search_notdir, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(FILE, O_CREAT|O_RDWR|O_SEARCH, 0644)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1); + ATF_REQUIRE(errno == ENOTDIR); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, o_search_perm1); +#ifdef USE_O_SEARCH + ATF_TP_ADD_TC(tp, o_search_root_flag1); + ATF_TP_ADD_TC(tp, o_search_unpriv_flag1); +#endif + ATF_TP_ADD_TC(tp, o_search_perm2); +#ifdef USE_O_SEARCH + ATF_TP_ADD_TC(tp, o_search_root_flag2); + ATF_TP_ADD_TC(tp, o_search_unpriv_flag2); +#endif + ATF_TP_ADD_TC(tp, o_search_notdir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_openat.c b/contrib/netbsd-tests/lib/libc/c063/t_openat.c new file mode 100644 index 0000000..79b5f38 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_openat.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_openat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_openat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/openat" +#define BASEFILE "openat" +#define FILEERR "dir/openaterr" + +ATF_TC(openat_fd); +ATF_TC_HEAD(openat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat works with fd"); +} +ATF_TC_BODY(openat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) != -1); + ATF_REQUIRE(close(dfd) == 0); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(openat_fdcwd); +ATF_TC_HEAD(openat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that openat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(openat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE((fd = openat(AT_FDCWD, BASEFILE, O_RDONLY, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(openat_fdcwderr); +ATF_TC_HEAD(openat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that openat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(openat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = openat(AT_FDCWD, FILEERR, O_RDONLY, 0)) == -1); +} + +ATF_TC(openat_fderr1); +ATF_TC_HEAD(openat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fail with bad path"); +} +ATF_TC_BODY(openat_fderr1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, FILEERR, O_RDONLY, 0)) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(openat_fderr2); +ATF_TC_HEAD(openat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with bad fdat"); +} +ATF_TC_BODY(openat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(openat_fderr3); +ATF_TC_HEAD(openat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with fd as -1"); +} +ATF_TC_BODY(openat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((fd = openat(-1, FILE, O_RDONLY, 0)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, openat_fd); + ATF_TP_ADD_TC(tp, openat_fdcwd); + ATF_TP_ADD_TC(tp, openat_fdcwderr); + ATF_TP_ADD_TC(tp, openat_fderr1); + ATF_TP_ADD_TC(tp, openat_fderr2); + ATF_TP_ADD_TC(tp, openat_fderr3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c new file mode 100644 index 0000000..d354ff5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c @@ -0,0 +1,157 @@ +/* $NetBSD: t_readlinkat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_readlinkat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/readlinkat" +#define BASEFILE "readlinkat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/readlinkaterr" + +ATF_TC(readlinkat_fd); +ATF_TC_HEAD(readlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat works with fd"); +} +ATF_TC_BODY(readlinkat_fd, tc) +{ + int dfd; + int fd; + ssize_t len; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + len = readlinkat(dfd, BASELINK, buf, sizeof(buf)-1); + ATF_REQUIRE(len != -1); + buf[len] = 0; + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(strcmp(buf, FILE) == 0); +} + +ATF_TC(readlinkat_fdcwd); +ATF_TC_HEAD(readlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that readlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(readlinkat_fdcwd, tc) +{ + int fd; + ssize_t len; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + len = readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)-1); + ATF_REQUIRE(len != -1); + buf[len] = 0; + + ATF_REQUIRE(strcmp(buf, FILE) == 0); +} + +ATF_TC(readlinkat_fdcwderr); +ATF_TC_HEAD(readlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that readlinkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(readlinkat_fdcwderr, tc) +{ + char buf[MAXPATHLEN]; + + ATF_REQUIRE(readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)) == -1); +} + +ATF_TC(readlinkat_fderr1); +ATF_TC_HEAD(readlinkat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat fail with bad path"); +} +ATF_TC_BODY(readlinkat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(readlinkat(dfd, FILEERR, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(readlinkat_fderr2); +ATF_TC_HEAD(readlinkat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat fails with fd as -1"); +} +ATF_TC_BODY(readlinkat_fderr2, tc) +{ + int fd; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE(readlinkat(-1, LINK, buf, sizeof(buf)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, readlinkat_fd); + ATF_TP_ADD_TC(tp, readlinkat_fdcwd); + ATF_TP_ADD_TC(tp, readlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, readlinkat_fderr1); + ATF_TP_ADD_TC(tp, readlinkat_fderr2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_renameat.c b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c new file mode 100644 index 0000000..e297f2a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define TARGET "newdir/new" +#define BASETARGET "new" +#define FILEERR "olddir/olderr" + +ATF_TC(renameat_fd); +ATF_TC_HEAD(renameat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that renameat works with fd"); +} +ATF_TC_BODY(renameat_fd, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(renameat(ofd, BASEFILE, nfd, BASETARGET) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(renameat_fdcwd); +ATF_TC_HEAD(renameat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that renameat works with fd as AT_FDCWD"); +} + +ATF_TC_BODY(renameat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + + ATF_REQUIRE(renameat(AT_FDCWD, FILE, AT_FDCWD, TARGET) == 0); + + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(renameat_fdcwderr); +ATF_TC_HEAD(renameat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that renameat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(renameat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(renameat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET) == -1); +} + +ATF_TC(renameat_fderr); +ATF_TC_HEAD(renameat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that renameat fails with fd as -1"); +} +ATF_TC_BODY(renameat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(renameat(-1, FILE, AT_FDCWD, TARGET) == -1); + ATF_REQUIRE(renameat(AT_FDCWD, FILE, -1, TARGET) == -1); + ATF_REQUIRE(renameat(-1, FILE, -1, TARGET) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, renameat_fd); + ATF_TP_ADD_TC(tp, renameat_fdcwd); + ATF_TP_ADD_TC(tp, renameat_fdcwderr); + ATF_TP_ADD_TC(tp, renameat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c new file mode 100644 index 0000000..d62f289 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define LINK "newdir/symlink" +#define BASELINK "symlink" +#define FILEERR "olddir/olderr" + +ATF_TC(symlinkat_fd); +ATF_TC_HEAD(symlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that symlinkat works with fd"); +} +ATF_TC_BODY(symlinkat_fd, tc) +{ + int dfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE((dfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(symlinkat(RELFILE, dfd, BASELINK) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(LINK, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(symlinkat_fdcwd); +ATF_TC_HEAD(symlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that symlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(symlinkat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(RELFILE, AT_FDCWD, LINK) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(LINK, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(symlinkat_fdcwderr); +ATF_TC_HEAD(symlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that symlinkat works with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(symlinkat_fdcwderr, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(FILEERR, AT_FDCWD, LINK) == 0); + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(stat(LINK, &st) == -1); + ATF_REQUIRE(errno == ENOENT); + +} + +ATF_TC(symlinkat_fderr); +ATF_TC_HEAD(symlinkat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that symlinkat fails with fd as -1"); +} +ATF_TC_BODY(symlinkat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(RELFILE, -1, LINK) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, symlinkat_fd); + ATF_TP_ADD_TC(tp, symlinkat_fdcwd); + ATF_TP_ADD_TC(tp, symlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, symlinkat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c new file mode 100644 index 0000000..79aa7aa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c @@ -0,0 +1,176 @@ +/* $NetBSD: t_unlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_unlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> + +#define DIR "dir" +#define FILE "dir/unlinkat" +#define BASEFILE "unlinkat" +#define FILEERR "dir/unlinkaterr" + +ATF_TC(unlinkat_fd); +ATF_TC_HEAD(unlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat works with fd"); +} +ATF_TC_BODY(unlinkat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fdcwd); +ATF_TC_HEAD(unlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(unlinkat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(unlinkat(AT_FDCWD, BASEFILE, 0) == 0); +} + +ATF_TC(unlinkat_fdcwderr); +ATF_TC_HEAD(unlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(unlinkat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(unlinkat(AT_FDCWD, FILEERR, 0) == -1); +} + +ATF_TC(unlinkat_fderr1); +ATF_TC_HEAD(unlinkat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fail with bad path"); +} +ATF_TC_BODY(unlinkat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, FILEERR, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fderr2); +ATF_TC_HEAD(unlinkat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with bad fdat"); +} +ATF_TC_BODY(unlinkat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fderr3); +ATF_TC_HEAD(unlinkat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with fd as -1"); +} +ATF_TC_BODY(unlinkat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(unlinkat(-1, FILE, 0) == -1); +} + +ATF_TC(unlinkat_dir); +ATF_TC_HEAD(unlinkat_dir, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat can remove directories"); +} +ATF_TC_BODY(unlinkat_dir, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + + ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, 0) == -1); + ATF_REQUIRE(errno == EPERM); + ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, AT_REMOVEDIR) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, unlinkat_fd); + ATF_TP_ADD_TC(tp, unlinkat_fdcwd); + ATF_TP_ADD_TC(tp, unlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, unlinkat_fderr1); + ATF_TP_ADD_TC(tp, unlinkat_fderr2); + ATF_TP_ADD_TC(tp, unlinkat_fderr3); + ATF_TP_ADD_TC(tp, unlinkat_dir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c new file mode 100644 index 0000000..9f21fd6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c @@ -0,0 +1,212 @@ +/* $NetBSD: t_utimensat.c,v 1.5 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_utimensat.c,v 1.5 2013/03/17 04:46:06 jmmv Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/time.h> + +#define DIR "dir" +#define FILE "dir/utimensat" +#define BASEFILE "utimensat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/symlink" + +const struct timespec tptr[] = { + { 0x12345678, 987654321 }, + { 0x15263748, 123456789 }, +}; + +ATF_TC(utimensat_fd); +ATF_TC_HEAD(utimensat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat works with fd"); +} +ATF_TC_BODY(utimensat_fd, tc) +{ + int dfd; + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TC(utimensat_fdcwd); +ATF_TC_HEAD(utimensat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that utimensat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(utimensat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(utimensat(AT_FDCWD, BASEFILE, tptr, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TC(utimensat_fdcwderr); +ATF_TC_HEAD(utimensat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that utimensat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(utimensat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(utimensat(AT_FDCWD, FILEERR, tptr, 0) == -1); +} + +ATF_TC(utimensat_fderr1); +ATF_TC_HEAD(utimensat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fail with bad path"); +} +ATF_TC_BODY(utimensat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, FILEERR, tptr, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(utimensat_fderr2); +ATF_TC_HEAD(utimensat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fails with bad fdat"); +} +ATF_TC_BODY(utimensat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(utimensat_fderr3); +ATF_TC_HEAD(utimensat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fails with fd as -1"); +} +ATF_TC_BODY(utimensat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(utimensat(-1, FILE, tptr, 0) == -1); +} + +ATF_TC(utimensat_fdlink); +ATF_TC_HEAD(utimensat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat works on symlink"); +} +ATF_TC_BODY(utimensat_fdlink, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, 0) == -1); + ATF_REQUIRE(errno = ENOENT); + + ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, utimensat_fd); + ATF_TP_ADD_TC(tp, utimensat_fdcwd); + ATF_TP_ADD_TC(tp, utimensat_fdcwderr); + ATF_TP_ADD_TC(tp, utimensat_fderr1); + ATF_TP_ADD_TC(tp, utimensat_fderr2); + ATF_TP_ADD_TC(tp, utimensat_fderr3); + ATF_TP_ADD_TC(tp, utimensat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/common/exec_prot.h b/contrib/netbsd-tests/lib/libc/common/exec_prot.h new file mode 100644 index 0000000..6e17f97 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/common/exec_prot.h @@ -0,0 +1,61 @@ +/* $NetBSD: exec_prot.h,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TESTS_EXEC_PROT_H_ +#define _TESTS_EXEC_PROT_H_ + +/* + * Prototype definitions of external helper functions for executable + * mapping tests. + */ + +/* + * Trivial MD shellcode that justs returns 1. + */ +int return_one(void); /* begin marker -- shellcode entry */ +int return_one_end(void); /* end marker */ + +/* + * MD callback to verify whether host offers executable space protection. + * Returns execute protection level. + */ +int exec_prot_support(void); + +/* execute protection level */ +enum { + NOTIMPL = -1, /* callback not implemented */ + NO_XP, /* no execute protection */ + PERPAGE_XP, /* per-page execute protection */ + PARTIAL_XP /* partial execute protection. Depending on where the + page is located in virtual memory, executable space + protection may be enforced or not. */ +}; +#endif diff --git a/contrib/netbsd-tests/lib/libc/db/README b/contrib/netbsd-tests/lib/libc/db/README new file mode 100644 index 0000000..68f0ec7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/README @@ -0,0 +1,66 @@ +# $NetBSD: README,v 1.1 2011/01/07 15:05:58 pgoyette Exp $ +# @(#)README 8.8 (Berkeley) 7/31/94 + +Fairly large files (the command files) are built in this directory during +the test runs, and even larger files (the database files) are created in +"/var/tmp". If the latter directory doesn't exist, set the environmental +variable TMPDIR to a directory where the files can be built. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +The script file consists of lines with an initial character which is +the command for that line, or an initial character indicating a key +or data entry for a previous command. + +Legal command characters are as follows: + +c: compare a record + + must be followed by [kK][dD]; the data value in the database + associated with the specified key is compared to the specified + data value. +e: echo a string + + writes out the rest of the line into the output file; if the + last character is not a carriage-return, a newline is appended. +f: set the flags for the next command + + no value zero's the flags +g: do a get command + + must be followed by [kK] + + writes out the retrieved data DBT. +o [r]: dump [reverse] + + dump the database out, if 'r' is set, in reverse order. +p: do a put command + + must be followed by [kK][dD] +r: do a del command + + must be followed by [kK] unless R_CURSOR flag set. +S: sync the database +s: do a seq command + + must be followed by [kK] if R_CURSOR flag set. + + writes out the retrieved data DBT. + +Legal key/data characters are as follows: + +D [file]: data file + + set the current data value to the contents of the file +d [data]: + + set the current key value to the contents of the line. +K [file]: key file + + set the current key value to the contents of the file +k [data]: + + set the current key value to the contents of the line. + +Blank lines, lines with leading white space, and lines with leading +hash marks (#) are ignored. + +Options to dbtest are as follows: + + -d: Set the DB_LOCK flag. + -f: Use the file argument as the database file. + -i: Use the rest of the argument to set elements in the info + structure. If the type is btree, then "-i cachesize=10240" + will set BTREEINFO.cachesize to 10240. + -o: The rest of the argument is the output file instead of + using stdout. + -s: Don't delete the database file before opening it, i.e. + use the database file from a previous run. + +Dbtest requires two arguments, the type of access "hash", "recno" +or "btree", and the script name or "-" to indicate stdin. diff --git a/contrib/netbsd-tests/lib/libc/db/h_db.c b/contrib/netbsd-tests/lib/libc/db/h_db.c new file mode 100644 index 0000000..dfb1385 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/h_db.c @@ -0,0 +1,731 @@ +/* $NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $ */ + +/*- + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; +#else +__RCSID("$NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $"); +#endif +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/stat.h> + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <unistd.h> +#include <err.h> +#include <db.h> + +enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; + +static void compare(DBT *, DBT *); +static DBTYPE dbtype(const char *); +static void dump(DB *, int); +static void get(DB *, DBT *); +static void getdata(DB *, DBT *, DBT *); +static void put(DB *, DBT *, DBT *); +static void rem(DB *, DBT *); +static const char *sflags(int); +static void synk(DB *); +static void *rfile(char *, size_t *); +static void seq(DB *, DBT *); +static u_int setflags(char *); +static void *setinfo(DBTYPE, char *); +static void usage(void) __attribute__((__noreturn__)); +static void *xcopy(void *, size_t); +static void chkcmd(enum S); +static void chkdata(enum S); +static void chkkey(enum S); + +#ifdef STATISTICS +extern void __bt_stat(DB *); +#endif + +static DBTYPE type; /* Database type. */ +static void *infop; /* Iflags. */ +static size_t lineno; /* Current line in test script. */ +static u_int flags; /* Current DB flags. */ +static int ofd = STDOUT_FILENO; /* Standard output fd. */ + +static DB *XXdbp; /* Global for gdb. */ +static size_t XXlineno; /* Fast breakpoint for gdb. */ + +int +main(int argc, char *argv[]) +{ + extern int optind; + extern char *optarg; + enum S command = COMMAND, state; + DB *dbp; + DBT data, key, keydata; + size_t len; + int ch, oflags, sflag; + char *fname, *infoarg, *p, *t, buf[8 * 1024]; + bool unlink_dbfile; + + infoarg = NULL; + fname = NULL; + unlink_dbfile = false; + oflags = O_CREAT | O_RDWR; + sflag = 0; + while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) + switch (ch) { + case 'f': + fname = optarg; + break; + case 'i': + infoarg = optarg; + break; + case 'l': + oflags |= DB_LOCK; + break; + case 'o': + if ((ofd = open(optarg, + O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) + err(1, "Cannot create `%s'", optarg); + break; + case 's': + sflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + /* Set the type. */ + type = dbtype(*argv++); + + /* Open the descriptor file. */ + if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) + err(1, "Cannot reopen `%s'", *argv); + + /* Set up the db structure as necessary. */ + if (infoarg == NULL) + infop = NULL; + else + for (p = strtok(infoarg, ",\t "); p != NULL; + p = strtok(0, ",\t ")) + if (*p != '\0') + infop = setinfo(type, p); + + /* + * Open the DB. Delete any preexisting copy, you almost never + * want it around, and it often screws up tests. + */ + if (fname == NULL) { + const char *q = getenv("TMPDIR"); + if (q == NULL) + q = "/var/tmp"; + (void)snprintf(buf, sizeof(buf), "%s/__dbtest", q); + fname = buf; + (void)unlink(buf); + unlink_dbfile = true; + } else if (!sflag) + (void)unlink(fname); + + if ((dbp = dbopen(fname, + oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) + err(1, "Cannot dbopen `%s'", fname); + XXdbp = dbp; + if (unlink_dbfile) + (void)unlink(fname); + + state = COMMAND; + for (lineno = 1; + (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { + /* Delete the newline, displaying the key/data is easier. */ + if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) + *t = '\0'; + if ((len = strlen(buf)) == 0 || isspace((unsigned char)*p) || + *p == '#') + continue; + + /* Convenient gdb break point. */ + if (XXlineno == lineno) + XXlineno = 1; + switch (*p) { + case 'c': /* compare */ + chkcmd(state); + state = KEY; + command = COMPARE; + break; + case 'e': /* echo */ + chkcmd(state); + /* Don't display the newline, if CR at EOL. */ + if (p[len - 2] == '\r') + --len; + if (write(ofd, p + 1, len - 1) != (ssize_t)len - 1 || + write(ofd, "\n", 1) != 1) + err(1, "write failed"); + break; + case 'g': /* get */ + chkcmd(state); + state = KEY; + command = GET; + break; + case 'p': /* put */ + chkcmd(state); + state = KEY; + command = PUT; + break; + case 'r': /* remove */ + chkcmd(state); + if (flags == R_CURSOR) { + rem(dbp, &key); + state = COMMAND; + } else { + state = KEY; + command = REMOVE; + } + break; + case 'S': /* sync */ + chkcmd(state); + synk(dbp); + state = COMMAND; + break; + case 's': /* seq */ + chkcmd(state); + if (flags == R_CURSOR) { + state = KEY; + command = SEQ; + } else + seq(dbp, &key); + break; + case 'f': + flags = setflags(p + 1); + break; + case 'D': /* data file */ + chkdata(state); + data.data = rfile(p + 1, &data.size); + goto ldata; + case 'd': /* data */ + chkdata(state); + data.data = xcopy(p + 1, len - 1); + data.size = len - 1; +ldata: switch (command) { + case COMPARE: + compare(&keydata, &data); + break; + case PUT: + put(dbp, &key, &data); + break; + default: + errx(1, "line %zu: command doesn't take data", + lineno); + } + if (type != DB_RECNO) + free(key.data); + free(data.data); + state = COMMAND; + break; + case 'K': /* key file */ + chkkey(state); + if (type == DB_RECNO) + errx(1, "line %zu: 'K' not available for recno", + lineno); + key.data = rfile(p + 1, &key.size); + goto lkey; + case 'k': /* key */ + chkkey(state); + if (type == DB_RECNO) { + static recno_t recno; + recno = atoi(p + 1); + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = xcopy(p + 1, len - 1); + key.size = len - 1; + } +lkey: switch (command) { + case COMPARE: + getdata(dbp, &key, &keydata); + state = DATA; + break; + case GET: + get(dbp, &key); + if (type != DB_RECNO) + free(key.data); + state = COMMAND; + break; + case PUT: + state = DATA; + break; + case REMOVE: + rem(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + case SEQ: + seq(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + default: + errx(1, "line %zu: command doesn't take a key", + lineno); + } + break; + case 'o': + dump(dbp, p[1] == 'r'); + break; + default: + errx(1, "line %zu: %s: unknown command character", + lineno, p); + } + } +#ifdef STATISTICS + /* + * -l must be used (DB_LOCK must be set) for this to be + * used, otherwise a page will be locked and it will fail. + */ + if (type == DB_BTREE && oflags & DB_LOCK) + __bt_stat(dbp); +#endif + if ((*dbp->close)(dbp)) + err(1, "db->close failed"); + (void)close(ofd); + return 0; +} + +#define NOOVERWRITE "put failed, would overwrite key\n" + +static void +compare(DBT *db1, DBT *db2) +{ + size_t len; + u_char *p1, *p2; + + if (db1->size != db2->size) + printf("compare failed: key->data len %zu != data len %zu\n", + db1->size, db2->size); + + len = MIN(db1->size, db2->size); + for (p1 = db1->data, p2 = db2->data; len--;) + if (*p1++ != *p2++) { + printf("compare failed at offset %lu\n", + (unsigned long)(p1 - (u_char *)db1->data)); + break; + } +} + +static void +get(DB *dbp, DBT *kp) +{ + DBT data; + + switch ((*dbp->get)(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err(1, "line %zu: get failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "get failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, + NOSUCHKEY); +#undef NOSUCHKEY + break; + } +} + +static void +getdata(DB *dbp, DBT *kp, DBT *dp) +{ + switch ((*dbp->get)(dbp, kp, dp, flags)) { + case 0: + return; + case -1: + err(1, "line %zu: getdata failed", lineno); + /* NOTREACHED */ + case 1: + errx(1, "line %zu: getdata failed, no such key", lineno); + /* NOTREACHED */ + } +} + +static void +put(DB *dbp, DBT *kp, DBT *dp) +{ + switch ((*dbp->put)(dbp, kp, dp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: put failed", lineno); + /* NOTREACHED */ + case 1: + (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); + break; + } +} + +static void +rem(DB *dbp, DBT *kp) +{ + switch ((*dbp->del)(dbp, kp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: rem failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "rem failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags != R_CURSOR) + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%zu: rem of cursor failed\n", lineno); +#undef NOSUCHKEY + break; + } +} + +static void +synk(DB *dbp) +{ + switch ((*dbp->sync)(dbp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: synk failed", lineno); + /* NOTREACHED */ + } +} + +static void +seq(DB *dbp, DBT *kp) +{ + DBT data; + + switch (dbp->seq(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err(1, "line %zu: seq failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "seq failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags == R_CURSOR) + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%zu: seq (%s) failed\n", lineno, sflags(flags)); +#undef NOSUCHKEY + break; + } +} + +static void +dump(DB *dbp, int rev) +{ + DBT key, data; + int xflags, nflags; + + if (rev) { + xflags = R_LAST; + nflags = R_PREV; + } else { + xflags = R_FIRST; + nflags = R_NEXT; + } + for (;; xflags = nflags) + switch (dbp->seq(dbp, &key, &data, xflags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case 1: + goto done; + case -1: + err(1, "line %zu: (dump) seq failed", lineno); + /* NOTREACHED */ + } +done: return; +} + +static u_int +setflags(char *s) +{ + char *p; + + for (; isspace((unsigned char)*s); ++s); + if (*s == '\n' || *s == '\0') + return 0; + if ((p = strchr(s, '\n')) != NULL) + *p = '\0'; + if (!strcmp(s, "R_CURSOR")) return R_CURSOR; + if (!strcmp(s, "R_FIRST")) return R_FIRST; + if (!strcmp(s, "R_IAFTER")) return R_IAFTER; + if (!strcmp(s, "R_IBEFORE")) return R_IBEFORE; + if (!strcmp(s, "R_LAST")) return R_LAST; + if (!strcmp(s, "R_NEXT")) return R_NEXT; + if (!strcmp(s, "R_NOOVERWRITE")) return R_NOOVERWRITE; + if (!strcmp(s, "R_PREV")) return R_PREV; + if (!strcmp(s, "R_SETCURSOR")) return R_SETCURSOR; + + errx(1, "line %zu: %s: unknown flag", lineno, s); + /* NOTREACHED */ +} + +static const char * +sflags(int xflags) +{ + switch (xflags) { + case R_CURSOR: return "R_CURSOR"; + case R_FIRST: return "R_FIRST"; + case R_IAFTER: return "R_IAFTER"; + case R_IBEFORE: return "R_IBEFORE"; + case R_LAST: return "R_LAST"; + case R_NEXT: return "R_NEXT"; + case R_NOOVERWRITE: return "R_NOOVERWRITE"; + case R_PREV: return "R_PREV"; + case R_SETCURSOR: return "R_SETCURSOR"; + } + + return "UNKNOWN!"; +} + +static DBTYPE +dbtype(const char *s) +{ + if (!strcmp(s, "btree")) + return DB_BTREE; + if (!strcmp(s, "hash")) + return DB_HASH; + if (!strcmp(s, "recno")) + return DB_RECNO; + errx(1, "%s: unknown type (use btree, hash or recno)", s); + /* NOTREACHED */ +} + +static void * +setinfo(DBTYPE dtype, char *s) +{ + static BTREEINFO ib; + static HASHINFO ih; + static RECNOINFO rh; + char *eq; + + if ((eq = strchr(s, '=')) == NULL) + errx(1, "%s: illegal structure set statement", s); + *eq++ = '\0'; + if (!isdigit((unsigned char)*eq)) + errx(1, "%s: structure set statement must be a number", s); + + switch (dtype) { + case DB_BTREE: + if (!strcmp("flags", s)) { + ib.flags = atoi(eq); + return &ib; + } + if (!strcmp("cachesize", s)) { + ib.cachesize = atoi(eq); + return &ib; + } + if (!strcmp("maxkeypage", s)) { + ib.maxkeypage = atoi(eq); + return &ib; + } + if (!strcmp("minkeypage", s)) { + ib.minkeypage = atoi(eq); + return &ib; + } + if (!strcmp("lorder", s)) { + ib.lorder = atoi(eq); + return &ib; + } + if (!strcmp("psize", s)) { + ib.psize = atoi(eq); + return &ib; + } + break; + case DB_HASH: + if (!strcmp("bsize", s)) { + ih.bsize = atoi(eq); + return &ih; + } + if (!strcmp("ffactor", s)) { + ih.ffactor = atoi(eq); + return &ih; + } + if (!strcmp("nelem", s)) { + ih.nelem = atoi(eq); + return &ih; + } + if (!strcmp("cachesize", s)) { + ih.cachesize = atoi(eq); + return &ih; + } + if (!strcmp("lorder", s)) { + ih.lorder = atoi(eq); + return &ih; + } + break; + case DB_RECNO: + if (!strcmp("flags", s)) { + rh.flags = atoi(eq); + return &rh; + } + if (!strcmp("cachesize", s)) { + rh.cachesize = atoi(eq); + return &rh; + } + if (!strcmp("lorder", s)) { + rh.lorder = atoi(eq); + return &rh; + } + if (!strcmp("reclen", s)) { + rh.reclen = atoi(eq); + return &rh; + } + if (!strcmp("bval", s)) { + rh.bval = atoi(eq); + return &rh; + } + if (!strcmp("psize", s)) { + rh.psize = atoi(eq); + return &rh; + } + break; + } + errx(1, "%s: unknown structure value", s); + /* NOTREACHED */ +} + +static void * +rfile(char *name, size_t *lenp) +{ + struct stat sb; + void *p; + int fd; + char *np; + + for (; isspace((unsigned char)*name); ++name) + continue; + if ((np = strchr(name, '\n')) != NULL) + *np = '\0'; + if ((fd = open(name, O_RDONLY, 0)) == -1 || fstat(fd, &sb) == -1) + err(1, "Cannot open `%s'", name); +#ifdef NOT_PORTABLE + if (sb.st_size > (off_t)SIZE_T_MAX) { + errno = E2BIG; + err("Cannot process `%s'", name); + } +#endif + if ((p = malloc((size_t)sb.st_size)) == NULL) + err(1, "Cannot allocate %zu bytes", (size_t)sb.st_size); + if (read(fd, p, (ssize_t)sb.st_size) != (ssize_t)sb.st_size) + err(1, "read failed"); + *lenp = (size_t)sb.st_size; + (void)close(fd); + return p; +} + +static void * +xcopy(void *text, size_t len) +{ + void *p; + + if ((p = malloc(len)) == NULL) + err(1, "Cannot allocate %zu bytes", len); + (void)memmove(p, text, len); + return p; +} + +static void +chkcmd(enum S state) +{ + if (state != COMMAND) + errx(1, "line %zu: not expecting command", lineno); +} + +static void +chkdata(enum S state) +{ + if (state != DATA) + errx(1, "line %zu: not expecting data", lineno); +} + +static void +chkkey(enum S state) +{ + if (state != KEY) + errx(1, "line %zu: not expecting a key", lineno); +} + +static void +usage(void) +{ + (void)fprintf(stderr, + "Usage: %s [-l] [-f file] [-i info] [-o file] type script\n", + getprogname()); + exit(1); +} diff --git a/contrib/netbsd-tests/lib/libc/db/t_db.sh b/contrib/netbsd-tests/lib/libc/db/t_db.sh new file mode 100755 index 0000000..d256508 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/t_db.sh @@ -0,0 +1,940 @@ +# $NetBSD: t_db.sh,v 1.4 2013/07/29 10:43:15 skrll Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +prog() +{ + echo $(atf_get_srcdir)/h_db +} + +dict() +{ + if [ -f /usr/share/dict/words ]; then + echo /usr/share/dict/words + elif [ -f /usr/dict/words ]; then + echo /usr/dict/words + else + atf_fail "no dictionary found" + fi +} + +# Begin FreeBSD +dict() +{ + if [ -f /usr/share/dict/words ]; then + echo /usr/share/dict/words + else + echo /nonexistent + atf_skip "Test requires dict/words" + fi +} +# End FreeBSD + +SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg" + +atf_test_case small_btree +small_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." +} +small_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + for i in `sed 200q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" btree in +} + +atf_test_case small_hash +small_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." +} +small_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + for i in `sed 200q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" hash in +} + +atf_test_case small_recno +small_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." +} +small_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + sed 200q $(dict) | + awk '{ + ++i; + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case medium_btree +medium_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." +} +medium_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + for i in $(sed 200q $(dict)); do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" btree in +} + +atf_test_case medium_hash +medium_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." +} +medium_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + for i in $(sed 200q $(dict)); do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" hash in +} + +atf_test_case medium_recno +medium_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." +} +medium_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case big_btree +big_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + for psize in 512 16384 65536; do + echo "checking page size: $psize" + + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done >in + + atf_check "$(prog)" -o out btree in + cmp -s exp out || atf_fail "test failed for page size: $psize" + done +} + +atf_test_case big_hash +big_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done >in + + atf_check "$(prog)" -o out hash in + cmp -s exp out || atf_fail "test failed" +} + +atf_test_case big_recno +big_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + find /bin -type f -print | + awk '{ + ++i; + printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i); + }' >in + + for psize in 512 16384 65536; do + echo "checking page size: $psize" + + atf_check "$(prog)" -o out recno in + cmp -s exp out || atf_fail "test failed for page size: $psize" + done +} + +atf_test_case random_recno +random_recno_head() +{ + atf_set "descr" "Checks recno database using random entries" +} +random_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 37; i <= 37 + 88 * 17; i += 17) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 1; i <= 15; ++i) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 19234; i <= 19234 + 61 * 27; i += 27) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit + }' >exp + + cat exp | + awk 'BEGIN { + i = 37; + incr = 17; + } + { + printf("p\nk%d\nd%s\n", i, $0); + if (i == 19234 + 61 * 27) + exit; + if (i == 37 + 88 * 17) { + i = 1; + incr = 1; + } else if (i == 15) { + i = 19234; + incr = 27; + } else + i += incr; + } + END { + for (i = 37; i <= 37 + 88 * 17; i += 17) + printf("g\nk%d\n", i); + for (i = 1; i <= 15; ++i) + printf("g\nk%d\n", i); + for (i = 19234; i <= 19234 + 61 * 27; i += 27) + printf("g\nk%d\n", i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case reverse_recno +reverse_recno_head() +{ + atf_set "descr" "Checks recno database using reverse order entries" +} +reverse_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk ' { + for (i = 1500; i; --i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' >exp + + cat exp | + awk 'BEGIN { + i = 1500; + } + { + printf("p\nk%d\nd%s\n", i, $0); + --i; + } + END { + for (i = 1500; i; --i) + printf("g\nk%d\n", i); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case alternate_recno +alternate_recno_head() +{ + atf_set "descr" "Checks recno database using alternating order entries" +} +alternate_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk ' { + for (i = 1; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 2; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' >exp + + cat exp | + awk 'BEGIN { + i = 1; + even = 0; + } + { + printf("p\nk%d\nd%s\n", i, $0); + i += 2; + if (i >= 1200) { + if (even == 1) + exit; + even = 1; + i = 2; + } + } + END { + for (i = 1; i < 1200; ++i) + printf("g\nk%d\n", i); + }' >in + + atf_check "$(prog)" -o out recno in + + sort -o exp exp + sort -o out out + + cmp -s exp out || atf_fail "test failed" +} + +h_delete() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 120; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + }' >exp + + cat exp | + awk '{ + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_NEXT\n"); + for (i = 1; i <= 120; ++i) + printf("s\n"); + printf("fR_CURSOR\ns\nkXX\n"); + printf("r\n"); + printf("fR_NEXT\ns\n"); + printf("fR_CURSOR\ns\nk1\n"); + printf("r\n"); + printf("fR_FIRST\ns\n"); + }' >in + + # For btree, the records are ordered by the string representation + # of the key value. So sort the expected output file accordingly, + # and set the seek_last key to the last expected key value. + + if [ "$type" = "btree" ] ; then + sed -e 's/kXX/k99/' < in > tmp + mv tmp in + sort -d -k4 < exp > tmp + mv tmp exp + echo $SEVEN_SEVEN | + awk '{ + printf("%05d: input key %d: %s\n", 99, 99, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 10, 10, $0); + exit; + }' >> exp + else + # For recno, records are ordered by numerical key value. No sort + # is needed, but still need to set proper seek_last key value. + sed -e 's/kXX/k120/' < in > tmp + mv tmp in + echo $SEVEN_SEVEN | + awk '{ + printf("%05d: input key %d: %s\n", 120, 120, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 2, 2, $0); + exit; + }' >> exp + fi + + atf_check "$(prog)" -o out $type in + atf_check -o file:exp cat out +} + +atf_test_case delete_btree +delete_btree_head() +{ + atf_set "descr" "Checks removing records in btree database" +} +delete_btree_body() +{ + h_delete btree +} + +atf_test_case delete_recno +delete_recno_head() +{ + atf_set "descr" "Checks removing records in recno database" +} +delete_recno_body() +{ + h_delete recno +} + +h_repeated() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo "" | + awk 'BEGIN { + for (i = 1; i <= 10; ++i) { + printf("p\nkkey1\nD/bin/sh\n"); + printf("p\nkkey2\nD/bin/csh\n"); + if (i % 8 == 0) { + printf("c\nkkey2\nD/bin/csh\n"); + printf("c\nkkey1\nD/bin/sh\n"); + printf("e\t%d of 10 (comparison)\n", i); + } else + printf("e\t%d of 10 \n", i); + printf("r\nkkey1\nr\nkkey2\n"); + } + }' >in + + $(prog) btree in +} + +atf_test_case repeated_btree +repeated_btree_head() +{ + atf_set "descr" \ + "Checks btree database with repeated small keys and" \ + "big data pairs. Makes sure that overflow pages are reused" +} +repeated_btree_body() +{ + h_repeated btree +} + +atf_test_case repeated_hash +repeated_hash_head() +{ + atf_set "descr" \ + "Checks hash database with repeated small keys and" \ + "big data pairs. Makes sure that overflow pages are reused" +} +repeated_hash_body() +{ + h_repeated hash +} + +atf_test_case duplicate_btree +duplicate_btree_head() +{ + atf_set "descr" "Checks btree database with duplicate keys" +} +duplicate_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 543; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + cat exp | + awk '{ + if (i++ % 2) + printf("p\nkduplicatekey\nd%s\n", $0); + else + printf("p\nkunique%dkey\nd%s\n", i, $0); + } + END { + printf("o\n"); + }' >in + + atf_check -o file:exp -x "$(prog) -iflags=1 btree in | sort" +} + +h_cursor_flags() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 20; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + # Test that R_CURSOR doesn't succeed before cursor initialized + cat exp | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\nr\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' >in + + atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in + atf_check -s ne:0 test -s out + + cat exp | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\np\nk1\ndsome data\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' >in + + atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in + atf_check -s ne:0 test -s out +} + +atf_test_case cursor_flags_btree +cursor_flags_btree_head() +{ + atf_set "descr" \ + "Checks use of cursor flags without initialization in btree database" +} +cursor_flags_btree_body() +{ + h_cursor_flags btree +} + +atf_test_case cursor_flags_recno +cursor_flags_recno_head() +{ + atf_set "descr" \ + "Checks use of cursor flags without initialization in recno database" +} +cursor_flags_recno_body() +{ + h_cursor_flags recno +} + +atf_test_case reverse_order_recno +reverse_order_recno_head() +{ + atf_set "descr" "Checks reverse order inserts in recno database" +} +reverse_order_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 779; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + cat exp | + awk '{ + if (i == 0) { + i = 1; + printf("p\nk1\nd%s\n", $0); + printf("%s\n", "fR_IBEFORE"); + } else + printf("p\nk1\nd%s\n", $0); + } + END { + printf("or\n"); + }' >in + + atf_check -o file:exp "$(prog)" recno in +} + +atf_test_case small_page_btree +small_page_btree_head() +{ + atf_set "descr" \ + "Checks btree database with lots of keys and small page" \ + "size: takes the first 20000 entries in the dictionary," \ + "reverses them, and gives them each a small size data" \ + "entry. Uses a small page size to make sure the btree" \ + "split code gets hammered." +} +small_page_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxy + echo $mdata | + awk '{ for (i = 1; i < 20001; ++i) print $0 }' >exp + + for i in `sed 20000q $(dict) | rev`; do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" -i psize=512 btree in +} + +h_byte_orders() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + sed 50q $(dict) >exp + for order in 1234 4321; do + for i in `sed 50q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" -ilorder=$order -f byte.file $type in + + for i in `sed 50q $(dict)`; do + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog)" -s -ilorder=$order -f byte.file $type in + done +} + +atf_test_case byte_orders_btree +byte_orders_btree_head() +{ + atf_set "descr" "Checks btree database using differing byte orders" +} +byte_orders_btree_body() +{ + h_byte_orders btree +} + +atf_test_case byte_orders_hash +byte_orders_hash_head() +{ + atf_set "descr" "Checks hash database using differing byte orders" +} +byte_orders_hash_body() +{ + h_byte_orders hash +} + +h_bsize_ffactor() +{ + bsize=$1 + ffactor=$2 + + echo "bucketsize $bsize, fill factor $ffactor" + atf_check -o file:exp "$(prog)" "-ibsize=$bsize,\ +ffactor=$ffactor,nelem=25000,cachesize=65536" hash in +} + +atf_test_case bsize_ffactor +bsize_ffactor_head() +{ + atf_set "timeout" "480" + atf_set "descr" "Checks hash database with various" \ + "bucketsizes and fill factors" +} +bsize_ffactor_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 10000; ++i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("%s\n", s); + } + exit; + + }' >exp + + sed 10000q $(dict) | + awk 'BEGIN { + ds="'$SEVEN_SEVEN'" + } + { + if (++i % 34) + s = substr(ds, 1, i % 34); + else + s = substr(ds, 1); + printf("p\nk%s\nd%s\n", $0, s); + }' >in + + sed 10000q $(dict) | + awk '{ + ++i; + printf("g\nk%s\n", $0); + }' >>in + + h_bsize_ffactor 256 11 + h_bsize_ffactor 256 14 + h_bsize_ffactor 256 21 + + h_bsize_ffactor 512 21 + h_bsize_ffactor 512 28 + h_bsize_ffactor 512 43 + + h_bsize_ffactor 1024 43 + h_bsize_ffactor 1024 57 + h_bsize_ffactor 1024 85 + + h_bsize_ffactor 2048 85 + h_bsize_ffactor 2048 114 + h_bsize_ffactor 2048 171 + + h_bsize_ffactor 4096 171 + h_bsize_ffactor 4096 228 + h_bsize_ffactor 4096 341 + + h_bsize_ffactor 8192 341 + h_bsize_ffactor 8192 455 + h_bsize_ffactor 8192 683 +} + +# FIXME: what does it test? +atf_test_case four_char_hash +four_char_hash_head() +{ + atf_set "descr" \ + "Checks hash database with 4 char key and" \ + "value insert on a 65536 bucket size" +} +four_char_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + cat >in <<EOF +p +k1234 +d1234 +r +k1234 +EOF + + # Begin FreeBSD + if true; then + atf_check "$(prog)" -i bsize=32768 hash in + else + # End FreeBSD + atf_check "$(prog)" -i bsize=65536 hash in + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_init_test_cases() +{ + atf_add_test_case small_btree + atf_add_test_case small_hash + atf_add_test_case small_recno + atf_add_test_case medium_btree + atf_add_test_case medium_hash + atf_add_test_case medium_recno + atf_add_test_case big_btree + atf_add_test_case big_hash + atf_add_test_case big_recno + atf_add_test_case random_recno + atf_add_test_case reverse_recno + atf_add_test_case alternate_recno + atf_add_test_case delete_btree + atf_add_test_case delete_recno + atf_add_test_case repeated_btree + atf_add_test_case repeated_hash + atf_add_test_case duplicate_btree + atf_add_test_case cursor_flags_btree + atf_add_test_case cursor_flags_recno + atf_add_test_case reverse_order_recno + atf_add_test_case small_page_btree + atf_add_test_case byte_orders_btree + atf_add_test_case byte_orders_hash + atf_add_test_case bsize_ffactor + atf_add_test_case four_char_hash +} diff --git a/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c new file mode 100644 index 0000000..32de6e7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_execve.c,v 1.1 2014/04/29 06:29:02 uebayasi Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> + +ATF_TC(t_execve_null); + +ATF_TC_HEAD(t_execve_null, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests an empty execve(2) executing"); +} + +ATF_TC_BODY(t_execve_null, tc) +{ + int err; + + err = execve(NULL, NULL, NULL); + ATF_REQUIRE(err == -1); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_execve_null); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/isqemu.h b/contrib/netbsd-tests/lib/libc/gen/isqemu.h new file mode 100644 index 0000000..7d73a22 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/isqemu.h @@ -0,0 +1,63 @@ +/* $NetBSD: isqemu.h,v 1.3 2013/04/14 12:46:29 martin Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/sysctl.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> +#include <err.h> + +static __inline bool +isQEMU(void) { +#if defined(__i386__) || defined(__x86_64__) + char name[1024]; + size_t len = sizeof(name); + + if (sysctlbyname("machdep.cpu_brand", name, &len, NULL, 0) == -1) { + if (errno == ENOENT) + return false; + err(EXIT_FAILURE, "sysctl"); + } + return strstr(name, "QEMU") != NULL; +#else + return false; +#endif +} + +#ifdef TEST +int +main(void) { + return isQEMU(); +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c new file mode 100644 index 0000000..d923370 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c @@ -0,0 +1,104 @@ +/* $NetBSD: h_fileactions.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <sys/stat.h> + +#define BUFSIZE 16 + +/* + * This checks (hardcoded) the assumptions that are setup from the + * main test program via posix spawn file actions. + * Program exits with EXIT_SUCCESS or EXIT_FAILURE accordingly + * (and does some stderr diagnostics in case of errors). + */ +int +main(int argc, char **argv) +{ + int res = EXIT_SUCCESS; + char buf[BUFSIZE]; + struct stat sb0, sb1; + + strcpy(buf, "test..."); + /* file desc 3 should be closed via addclose */ + if (read(3, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 3 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 4 should be closed via closeonexec */ + if (read(4, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 4 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 5 remains open */ + if (write(5, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 5\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 6 should be open (via addopen) */ + if (write(6, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 6\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 7 should refer to stdout */ + fflush(stdout); + if (fstat(fileno(stdout), &sb0) != 0) { + fprintf(stderr, "%s: could not fstat stdout\n", + getprogname()); + res = EXIT_FAILURE; + } + if (fstat(7, &sb1) != 0) { + fprintf(stderr, "%s: could not fstat filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (write(7, buf, strlen(buf)) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (memcmp(&sb0, &sb1, sizeof sb0) != 0) { + fprintf(stderr, "%s: stat results differ\n", getprogname()); + res = EXIT_FAILURE; + } + + return res; +} + diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh new file mode 100755 index 0000000..deee6fe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh @@ -0,0 +1,3 @@ +#! /nonexistent + +# this is just a dummy script, trying to be non-executable diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c new file mode 100644 index 0000000..dbf5da5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c @@ -0,0 +1,50 @@ +/* $NetBSD: h_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char **argv) +{ + unsigned long ret; + char *endp; + + if (argc < 2) { + fprintf(stderr, "usage:\n\t%s (retcode)\n", getprogname()); + exit(255); + } + ret = strtoul(argv[1], &endp, 10); + + fprintf(stderr, "%s exiting with status %lu\n", getprogname(), ret); + return ret; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c new file mode 100644 index 0000000..1f13c54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c @@ -0,0 +1,90 @@ +/* $NetBSD: h_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +/* + * Helper to test the hardcoded assumptions from t_spawnattr.c + * Exit with apropriate exit status and print diagnostics to + * stderr explaining what is wrong. + */ +int +main(int argc, char **argv) +{ + int parent_pipe, res = EXIT_SUCCESS; + sigset_t sig; + struct sigaction act; + ssize_t rd; + char tmp; + + sigemptyset(&sig); + if (sigprocmask(0, NULL, &sig) < 0) { + fprintf(stderr, "%s: sigprocmask error\n", getprogname()); + res = EXIT_FAILURE; + } + if (!sigismember(&sig, SIGUSR1)) { + fprintf(stderr, "%s: SIGUSR not in procmask\n", getprogname()); + res = EXIT_FAILURE; + } + if (sigaction(SIGUSR1, NULL, &act) < 0) { + fprintf(stderr, "%s: sigaction error\n", getprogname()); + res = EXIT_FAILURE; + } + if (act.sa_sigaction != (void *)SIG_DFL) { + fprintf(stderr, "%s: SIGUSR1 action != SIG_DFL\n", + getprogname()); + res = EXIT_FAILURE; + } + + if (argc >= 2) { + parent_pipe = atoi(argv[1]); + if (parent_pipe > 2) { + printf("%s: waiting for command from parent on pipe " + "%d\n", getprogname(), parent_pipe); + rd = read(parent_pipe, &tmp, 1); + if (rd == 1) { + printf("%s: got command %c from parent\n", + getprogname(), tmp); + } else if (rd == -1) { + printf("%s: %d is no pipe, errno %d\n", + getprogname(), parent_pipe, errno); + res = EXIT_FAILURE; + } + } + } + + return res; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c new file mode 100644 index 0000000..5bbf337 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c @@ -0,0 +1,392 @@ +/* $NetBSD: t_fileactions.c,v 1.5 2012/04/09 19:42:07 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifdef __FreeBSD__ +#include <sys/stat.h> +#endif +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <spawn.h> +#include <unistd.h> +#include <sys/wait.h> + + +ATF_TC(t_spawn_openmode); + +ATF_TC_HEAD(t_spawn_openmode, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the proper handling of 'mode' for 'open' fileactions"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +static off_t +filesize(const char * restrict fname) +{ + struct stat st; + int err; + + err = stat(fname, &st); + ATF_REQUIRE(err == 0); + return st.st_size; +} + +#define TESTFILE "./the_input_data" +#define CHECKFILE "./the_output_data" +#define TESTCONTENT "marry has a little lamb" + +static void +make_testfile(const char *restrict file) +{ + FILE *f; + size_t written; + + f = fopen(file, "w"); + ATF_REQUIRE(f != NULL); + written = fwrite(TESTCONTENT, 1, strlen(TESTCONTENT), f); + fclose(f); + ATF_REQUIRE(written == strlen(TESTCONTENT)); +} + +static void +empty_outfile(const char *restrict filename) +{ + FILE *f; + + f = fopen(filename, "w"); + ATF_REQUIRE(f != NULL); + fclose(f); +} + +ATF_TC_BODY(t_spawn_openmode, tc) +{ + int status, err; + pid_t pid; + size_t insize, outsize; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * try a "cat < testfile > checkfile" + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_CREAT, 0600); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); + + /* + * try a "cat < testfile >> checkfile" + */ + make_testfile(TESTFILE); + make_testfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_APPEND, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that output is twice as long as input */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize*2 == outsize); + + /* + * try a "cat < testfile > checkfile" with input and output swapped + */ + make_testfile(TESTFILE); + empty_outfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + CHECKFILE, O_WRONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_FAILURE); + + /* now check that input and output are still the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(outsize == 0); +} + +ATF_TC(t_spawn_reopen); + +ATF_TC_HEAD(t_spawn_reopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "an open filehandle can be replaced by a 'open' fileaction"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_reopen, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * make sure stdin is open in the parent + */ + freopen("/dev/zero", "r", stdin); + /* + * now request an open for this fd again in the child + */ + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + "/dev/null", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_open_nonexistent); + +ATF_TC_HEAD(t_spawn_open_nonexistent, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent, tc) +{ + int err, status; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + if (err == 0) { + /* + * The child has been created - it should fail and + * return exit code 127 + */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 127); + } else { + /* + * The error has been noticed early enough, no child has + * been run + */ + ATF_REQUIRE(err == ENOENT); + } + posix_spawn_file_actions_destroy(&fa); +} + +#ifdef __NetBSD__ +ATF_TC(t_spawn_open_nonexistent_diag); + +ATF_TC_HEAD(t_spawn_open_nonexistent_diag, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist " + "and delivers proper diagnostic"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent_diag, tc) +{ + int err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawnattr_t attr; + posix_spawn_file_actions_t fa; + + posix_spawnattr_init(&attr); + /* + * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that + * will cause a "proper" return value from posix_spawn(2) + * instead of a (potential) success there and a 127 exit + * status from the child process (c.f. the non-diag variant + * of this test). + */ + posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, &attr, args, NULL); + ATF_REQUIRE(err == ENOENT); + posix_spawn_file_actions_destroy(&fa); + posix_spawnattr_destroy(&attr); +} +#endif + +ATF_TC(t_spawn_fileactions); + +ATF_TC_HEAD(t_spawn_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests various complex fileactions"); +} + +ATF_TC_BODY(t_spawn_fileactions, tc) +{ + int fd1, fd2, fd3, status, err; + pid_t pid; + char * const args[2] = { __UNCONST("h_fileactions"), NULL }; + char helper[FILENAME_MAX]; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + + closefrom(fileno(stderr)+1); + + fd1 = open("/dev/null", O_RDONLY); + ATF_REQUIRE(fd1 == 3); + + fd2 = open("/dev/null", O_WRONLY, O_CLOEXEC); + ATF_REQUIRE(fd2 == 4); + + fd3 = open("/dev/null", O_WRONLY); + ATF_REQUIRE(fd3 == 5); + + posix_spawn_file_actions_addclose(&fa, fd1); + posix_spawn_file_actions_addopen(&fa, 6, "/dev/null", O_RDWR, 0); + posix_spawn_file_actions_adddup2(&fa, 1, 7); + + snprintf(helper, sizeof helper, "%s/h_fileactions", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(&pid, helper, &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_empty_fileactions); + +ATF_TC_HEAD(t_spawn_empty_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn with empty fileactions (PR kern/46038)"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_empty_fileactions, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + size_t insize, outsize; + + /* + * try a "cat < testfile > checkfile", but set up stdin/stdout + * already in the parent and pass empty file actions to the child. + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + freopen(TESTFILE, "r", stdin); + freopen(CHECKFILE, "w", stdout); + + posix_spawn_file_actions_init(&fa); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_fileactions); + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag); +#endif + ATF_TP_ADD_TC(tp, t_spawn_reopen); + ATF_TP_ADD_TC(tp, t_spawn_openmode); + ATF_TP_ADD_TC(tp, t_spawn_empty_fileactions); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c new file mode 100644 index 0000000..178374b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c @@ -0,0 +1,184 @@ +/* $NetBSD: t_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include <atf-c.h> +#include <spawn.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/wait.h> + +ATF_TC(t_spawn_ls); + +ATF_TC_HEAD(t_spawn_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawn executing /bin/ls"); +} + +ATF_TC_BODY(t_spawn_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawnp_ls); + +ATF_TC_HEAD(t_spawnp_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawnp executing ls via $PATH"); +} + +ATF_TC_BODY(t_spawnp_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawn_zero); + +ATF_TC_HEAD(t_spawn_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn an invalid binary"); +} + +ATF_TC_BODY(t_spawn_zero, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_zero"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf); +} + +ATF_TC(t_spawn_missing); + +ATF_TC_HEAD(t_spawn_missing, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a non existant binary"); +} + +ATF_TC_BODY(t_spawn_missing, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexist"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexist", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_nonexec); + +ATF_TC_HEAD(t_spawn_nonexec, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a script with non existing interpreter"); +} + +ATF_TC_BODY(t_spawn_nonexec, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexec"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexec", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_child); + +ATF_TC_HEAD(t_spawn_child, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a child and get it's return code"); +} + +ATF_TC_BODY(t_spawn_child, tc) +{ + char buf[FILENAME_MAX]; + char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL }; + char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL }; + char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL }; + int err, status; + pid_t pid; + + snprintf(buf, sizeof buf, "%s/h_spawn", + atf_tc_get_config_var(tc, "srcdir")); + + err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); + + err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1); + + err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_ls); + ATF_TP_ADD_TC(tp, t_spawnp_ls); + ATF_TP_ADD_TC(tp, t_spawn_zero); + ATF_TP_ADD_TC(tp, t_spawn_missing); + ATF_TP_ADD_TC(tp, t_spawn_nonexec); + ATF_TP_ADD_TC(tp, t_spawn_child); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c new file mode 100644 index 0000000..eb99c41 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c @@ -0,0 +1,173 @@ +/* $NetBSD: t_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <sched.h> +#include <signal.h> +#include <spawn.h> +#include <unistd.h> +#include <sys/wait.h> + +#define MAX(a, b) (a) > (b) ? (a) : (b) +#define MIN(a, b) (a) > (b) ? (b) : (a) + +static int get_different_scheduler(void); +static int get_different_priority(void); + +static int +get_different_scheduler() +{ + int scheduler, max, min, new; + + max = MAX(MAX(SCHED_FIFO, SCHED_OTHER), SCHED_RR); + min = MIN(MIN(SCHED_FIFO, SCHED_OTHER), SCHED_RR); + + /* get current schedule policy */ + scheduler = sched_getscheduler(0); + + /* new scheduler */ + new = (scheduler + 1); + if (new > max) + new = min; + + return new; +} + +static int +get_different_priority() +{ + int scheduler, max, min, new, priority; + struct sched_param param; + + /* get current schedule policy */ + scheduler = sched_getscheduler(0); + + max = sched_get_priority_max(scheduler); + min = sched_get_priority_min(scheduler); + + sched_getparam(0, ¶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..ef372f7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_floatunditf.c,v 1.6 2014/11/04 00:20:19 justin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <inttypes.h> +#include <math.h> + +#ifdef __HAVE_LONG_DOUBLE +static const struct { + uint64_t u64; + long double ld; +} testcases[] = { + { 0xffffffffffffffffULL, 0xf.fffffffffffffffp+60L }, + { 0xfffffffffffffffeULL, 0xf.ffffffffffffffep+60L }, + { 0xfffffffffffffffdULL, 0xf.ffffffffffffffdp+60L }, + { 0xfffffffffffffffcULL, 0xf.ffffffffffffffcp+60L }, + { 0x7fffffffffffffffULL, 0xf.ffffffffffffffep+59L }, + { 0x3fffffffffffffffULL, 0xf.ffffffffffffffcp+58L }, + { 0x1fffffffffffffffULL, 0xf.ffffffffffffff8p+57L }, + { 0xfffffffffffffffULL, 0xf.ffffffffffffffp+56L }, + { 0x7ffffffffffffffULL, 0xf.fffffffffffffep+55L }, + { 0x3ffffffffffffffULL, 0xf.fffffffffffffcp+54L }, + { 0x1ffffffffffffffULL, 0xf.fffffffffffff8p+53L }, + { 0xffffffffffffffULL, 0xf.fffffffffffffp+52L }, + { 0x7fffffffffffffULL, 0xf.ffffffffffffep+51L }, + { 0x3fffffffffffffULL, 0xf.ffffffffffffcp+50L }, + { 0x1fffffffffffffULL, 0xf.ffffffffffff8p+49L }, + { 0xfffffffffffffULL, 0xf.ffffffffffffp+48L }, + { 0x7ffffffffffffULL, 0xf.fffffffffffep+47L }, + { 0x3ffffffffffffULL, 0xf.fffffffffffcp+46L }, + { 0x1ffffffffffffULL, 0xf.fffffffffff8p+45L }, + { 0xffffffffffffULL, 0xf.fffffffffffp+44L }, + { 0x7fffffffffffULL, 0xf.ffffffffffep+43L }, + { 0x3fffffffffffULL, 0xf.ffffffffffcp+42L }, + { 0x1fffffffffffULL, 0xf.ffffffffff8p+41L }, + { 0xfffffffffffULL, 0xf.ffffffffffp+40L }, + { 0x7ffffffffffULL, 0xf.fffffffffep+39L }, + { 0x3ffffffffffULL, 0xf.fffffffffcp+38L }, + { 0x1ffffffffffULL, 0xf.fffffffff8p+37L }, + { 0xffffffffffULL, 0xf.fffffffffp+36L }, + { 0x7fffffffffULL, 0xf.ffffffffep+35L }, + { 0x3fffffffffULL, 0xf.ffffffffcp+34L }, + { 0x1fffffffffULL, 0xf.ffffffff8p+33L }, + { 0xfffffffffULL, 0xf.ffffffffp+32L }, + { 0x7ffffffffULL, 0xf.fffffffep+31L }, + { 0x3ffffffffULL, 0xf.fffffffcp+30L }, + { 0x1ffffffffULL, 0xf.fffffff8p+29L }, + { 0xffffffffULL, 0xf.fffffffp+28L }, + { 0x7fffffffULL, 0xf.ffffffep+27L }, + { 0x3fffffffULL, 0xf.ffffffcp+26L }, + { 0x1fffffffULL, 0xf.ffffff8p+25L }, + { 0xfffffffULL, 0xf.ffffffp+24L }, + { 0x7ffffffULL, 0xf.fffffep+23L }, + { 0x3ffffffULL, 0xf.fffffcp+22L }, + { 0x1ffffffULL, 0xf.fffff8p+21L }, + { 0xffffffULL, 0xf.fffffp+20L }, + { 0x7fffffULL, 0xf.ffffep+19L }, + { 0x3fffffULL, 0xf.ffffcp+18L }, + { 0x1fffffULL, 0xf.ffff8p+17L }, + { 0xfffffULL, 0xf.ffffp+16L }, + { 0x7ffffULL, 0xf.fffep+15L }, + { 0x3ffffULL, 0xf.fffcp+14L }, + { 0x1ffffULL, 0xf.fff8p+13L }, + { 0xffffULL, 0xf.fffp+12L }, + { 0x7fffULL, 0xf.ffep+11L }, + { 0x3fffULL, 0xf.ffcp+10L }, + { 0x1fffULL, 0xf.ff8p+9L }, + { 0xfffULL, 0xf.ffp+8L }, + { 0x7ffULL, 0xf.fep+7L }, + { 0x3ffULL, 0xf.fcp+6L }, + { 0x1ffULL, 0xf.f8p+5L }, + { 0xffULL, 0xf.fp+4L }, + { 0x7fULL, 0xf.ep+3L }, + { 0x3fULL, 0xf.cp+2L }, + { 0x1fULL, 0xf.8p+1L }, + { 0xfULL, 0xfp+0L }, + { 0x7ULL, 0xep-1L }, + { 0x3ULL, 0xcp-2L }, + { 0x1ULL, 0x8p-3L }, +}; +#endif + +ATF_TC(floatunditf); +ATF_TC_HEAD(floatunditf, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that uint64 -> long double conversion works"); +} + +ATF_TC_BODY(floatunditf, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + size_t i; + + for (i = 0; i < __arraycount(testcases); ++i) + ATF_CHECK_MSG( + testcases[i].ld == (long double)testcases[i].u64, + "#%zu: expected %.20Lf, got %.20Lf\n", i, + testcases[i].ld, + (long double)testcases[i].u64); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, floatunditf); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c new file mode 100644 index 0000000..ab95400 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_fmtcheck.c,v 1.3 2014/06/14 08:19:02 apb Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Allen Briggs. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> + +const char *fmtcheck(const char *f1, const char *f2) + __attribute__((__format_arg__(2))); + +#include <err.h> + +struct test_fmt { + const char *fmt1; + const char *fmt2; + int correct; +} test_fmts[] = { + { "%d", "%d", 1 }, + { "%2d", "%2.2d", 1 }, + { "%x", "%d", 1 }, + { "%u", "%d", 1 }, + { "%03d", "%d", 1 }, + { "%-2d", "%d", 1 }, + { "%d", "%-12.1d", 1 }, + { "%d", "%-01.3d", 1 }, + { "%X", "%-01.3d", 1 }, + { "%D", "%ld", 1 }, + { "%s", "%s", 1 }, + { "%s", "This is a %s test", 1 }, + { "Hi, there. This is a %s test", "%s", 1 }, + { "%d", "%s", 2 }, + { "%e", "%s", 2 }, + { "%r", "%d", 2 }, + { "%*.2d", "%*d", 1 }, + { "%2.*d", "%*d", 2 }, + { "%*d", "%*d", 1 }, + { "%-3", "%d", 2 }, + { "%d %s", "%d", 2 }, + { "%*.*.*d", "%*.*.*d", 2 }, + { "%d", "%d %s", 1 }, + { "%40s", "%20s", 1 }, + { "%x %x %x", "%o %u %d", 1 }, + { "%o %u %d", "%x %x %X", 1 }, + { "%#o %u %#-d", "%x %#x %X", 1 }, + { "%qd", "%llx", 1 }, + { "%%", "%llx", 1 }, + { "%ld %30s %#llx %-10.*e", "This number %lu%% and string %s has %qd numbers and %.*g floats", 1 }, + { "%o", "%lx", 2 }, + { "%p", "%lu", 2 }, +}; + +ATF_TC(fmtcheck_basic); +ATF_TC_HEAD(fmtcheck_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test fmtcheck(3)"); +} + +ATF_TC_BODY(fmtcheck_basic, tc) +{ + unsigned int i, r; + const char *f, *cf, *f1, *f2; + + r = 0; + for (i = 0 ; i < __arraycount(test_fmts); i++) { + f1 = test_fmts[i].fmt1; + f2 = test_fmts[i].fmt2; + f = fmtcheck(f1, f2); + if (test_fmts[i].correct == 1) { + cf = f1; + } else { + cf = f2; + } + if (f != cf) { + r++; + atf_tc_fail_nonfatal("Test %d: (%s) vs. (%s) failed " + "(should have returned %s)", i, f1, f2, + (test_fmts[i].correct == 1) ? "1st" : "2nd"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fmtcheck_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c new file mode 100644 index 0000000..f90d8cf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c @@ -0,0 +1,167 @@ +/* $NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $"); + +#include <atf-c.h> +#include <fnmatch.h> +#include <stdio.h> + +ATF_TC(fnmatch_backslashes); +ATF_TC_HEAD(fnmatch_backslashes, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test translation of '\\' with fnmatch(3) (PR lib/41558)"); +} + +ATF_TC_BODY(fnmatch_backslashes, tc) +{ + const int rv = fnmatch(/* pattern */ "\\", "\\", 0); + + if (rv != FNM_NOMATCH) + atf_tc_fail("fnmatch(3) did not translate '\\'"); +} + +ATF_TC(fnmatch_casefold); +ATF_TC_HEAD(fnmatch_casefold, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_CASEFOLD"); +} + +ATF_TC_BODY(fnmatch_casefold, tc) +{ + ATF_CHECK(fnmatch("xxx", "XXX", 0) != 0); + ATF_CHECK(fnmatch("XXX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("xxx", "XxX", 0) != 0); + ATF_CHECK(fnmatch("XxX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("x*x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("**x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("*?x", "XXX", 0) != 0); + + ATF_CHECK(fnmatch("xxx", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XXX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("xxx", "XxX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XxX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("x*x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("**x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("*?x", "XXX", FNM_CASEFOLD) == 0); +} + +ATF_TC(fnmatch_leadingdir); +ATF_TC_HEAD(fnmatch_leadingdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_LEADING_DIR"); +} + +ATF_TC_BODY(fnmatch_leadingdir, tc) +{ + ATF_CHECK(fnmatch("", "/*", 0) != 0); + ATF_CHECK(fnmatch(" ", " /*", 0) != 0); + ATF_CHECK(fnmatch("x", "x/*", 0) != 0); + ATF_CHECK(fnmatch("///", "////*", 0) != 0); + + ATF_CHECK(fnmatch("", "/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch(" ", " /*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("x", "x/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("///", "////*", FNM_LEADING_DIR) == 0); +} + +ATF_TC(fnmatch_noescape); +ATF_TC_HEAD(fnmatch_noescape, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_NOESCAPE"); +} + +ATF_TC_BODY(fnmatch_noescape, tc) +{ + ATF_CHECK(fnmatch(" \\x", " \\x", 0) != 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", 0) != 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", 0) != 0); + + ATF_CHECK(fnmatch(" \\x", " \\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", FNM_NOESCAPE) == 0); +} + +ATF_TC(fnmatch_pathname); +ATF_TC_HEAD(fnmatch_pathname, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PATHNAME"); +} + +ATF_TC_BODY(fnmatch_pathname, tc) +{ + ATF_CHECK(fnmatch("???x", "xxx/x", FNM_PATHNAME) != 0); + ATF_CHECK(fnmatch("***x", "xxx/x", FNM_PATHNAME) != 0); + + ATF_CHECK(fnmatch("???x", "xxxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("*/xxx", "/xxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("x/*.y", "x/z.y", FNM_PATHNAME) == 0); +} + +ATF_TC(fnmatch_period); +ATF_TC_HEAD(fnmatch_period, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PERIOD"); +} + +ATF_TC_BODY(fnmatch_period, tc) +{ + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD | FNM_CASEFOLD) == 0); + + ATF_CHECK(fnmatch("x?y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x*y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*.c", "x.c", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/?", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/*", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch(".*/?", ".x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/.?", "x/.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x[.]y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + + ATF_CHECK(fnmatch("?x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/?y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/*y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fnmatch_backslashes); + ATF_TP_ADD_TC(tp, fnmatch_casefold); + ATF_TP_ADD_TC(tp, fnmatch_leadingdir); + ATF_TP_ADD_TC(tp, fnmatch_noescape); + ATF_TP_ADD_TC(tp, fnmatch_pathname); + ATF_TP_ADD_TC(tp, fnmatch_period); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c new file mode 100644 index 0000000..21dea9e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c @@ -0,0 +1,206 @@ +/* $NetBSD: t_fpclassify.c,v 1.3 2011/10/01 21:47:08 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <float.h> +#include <math.h> +#include <stdio.h> +#include <string.h> + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + atf_tc_set_md_var(tc, "descr", "Dummy test"); +} + +ATF_TC_BODY(no_test,tc) +{ + atf_tc_skip("Test not available on this architecture"); +} + +#else /* defined(_FLOAT_IEEE754) */ + +ATF_TC(fpclassify_float); +ATF_TC_HEAD(fpclassify_float, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test float operations"); +} + +ATF_TC_BODY(fpclassify_float, tc) +{ + float d0, d1, d2, f, ip; + int e, i; + + d0 = FLT_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpf(d0, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < FLT_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpf(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modff(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +ATF_TC(fpclassify_double); +ATF_TC_HEAD(fpclassify_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test double operations"); +} + +ATF_TC_BODY(fpclassify_double, tc) +{ + double d0, d1, d2, f, ip; + int e, i; + + d0 = DBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexp(d0, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < DBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexp(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modf(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +/* + * XXX NetBSD doesn't have long-double flavors of frexp, ldexp, and modf, + * XXX so this test is disabled. + */ + +#ifdef TEST_LONG_DOUBLE + +ATF_TC(fpclassify_long_double); +ATF_TC_HEAD(fpclassify_long_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test long double operations"); +} + +ATF_TC_BODY(fpclassify_long_double, tc) +{ + long double d0, d1, d2, f, ip; + int e, i; + + d0 = LDBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpl(d0, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < LDBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpl(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modfl(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpclassify_float); + ATF_TP_ADD_TC(tp, fpclassify_double); +#ifdef TEST_LONG_DOUBLE + ATF_TP_ADD_TC(tp, fpclassify_long_double); +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c new file mode 100644 index 0000000..3366c1f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c @@ -0,0 +1,354 @@ +/* $NetBSD: t_fpsetmask.c,v 1.14 2014/11/04 00:20:19 justin Exp $ */ + +/*- + * Copyright (c) 1995 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> + +#include <atf-c.h> + +#include <stdio.h> +#include <signal.h> +#include <float.h> +#include <setjmp.h> +#include <stdlib.h> +#include <string.h> + +#include "isqemu.h" + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Dummy test case"); +} + +ATF_TC_BODY(no_test, tc) +{ + + atf_tc_skip("Test not available on this architecture."); +} + +#else /* defined(_FLOAT_IEEE754) */ + +#include <ieeefp.h> + +const char *skip_mesg; +const char *skip_arch; + +void sigfpe(int, siginfo_t *, void *); + +volatile sig_atomic_t signal_caught; +volatile int sicode; + +static volatile const float f_one = 1.0; +static volatile const float f_zero = 0.0; +static volatile const double d_one = 1.0; +static volatile const double d_zero = 0.0; +static volatile const long double ld_one = 1.0; +static volatile const long double ld_zero = 0.0; + +static volatile const float f_huge = FLT_MAX; +static volatile const float f_tiny = FLT_MIN; +static volatile const double d_huge = DBL_MAX; +static volatile const double d_tiny = DBL_MIN; +static volatile const long double ld_huge = LDBL_MAX; +static volatile const long double ld_tiny = LDBL_MIN; + +static volatile float f_x; +static volatile double d_x; +static volatile long double ld_x; + +/* trip divide by zero */ +static void +f_dz(void) +{ + + f_x = f_one / f_zero; +} + +static void +d_dz(void) +{ + + d_x = d_one / d_zero; +} + +static void +ld_dz(void) +{ + + ld_x = ld_one / ld_zero; +} + +/* trip invalid operation */ +static void +d_inv(void) +{ + + d_x = d_zero / d_zero; +} + +static void +ld_inv(void) +{ + + ld_x = ld_zero / ld_zero; +} + +static void +f_inv(void) +{ + + f_x = f_zero / f_zero; +} + +/* trip overflow */ +static void +f_ofl(void) +{ + + f_x = f_huge * f_huge; +} + +static void +d_ofl(void) +{ + + d_x = d_huge * d_huge; +} + +static void +ld_ofl(void) +{ + + ld_x = ld_huge * ld_huge; +} + +/* trip underflow */ +static void +f_ufl(void) +{ + + f_x = f_tiny * f_tiny; +} + +static void +d_ufl(void) +{ + + d_x = d_tiny * d_tiny; +} + +static void +ld_ufl(void) +{ + + ld_x = ld_tiny * ld_tiny; +} + +struct ops { + void (*op)(void); + fp_except mask; + int sicode; +}; + +static const struct ops float_ops[] = { + { f_dz, FP_X_DZ, FPE_FLTDIV }, + { f_inv, FP_X_INV, FPE_FLTINV }, + { f_ofl, FP_X_OFL, FPE_FLTOVF }, + { f_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops double_ops[] = { + { d_dz, FP_X_DZ, FPE_FLTDIV }, + { d_inv, FP_X_INV, FPE_FLTINV }, + { d_ofl, FP_X_OFL, FPE_FLTOVF }, + { d_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops long_double_ops[] = { + { ld_dz, FP_X_DZ, FPE_FLTDIV }, + { ld_inv, FP_X_INV, FPE_FLTINV }, + { ld_ofl, FP_X_OFL, FPE_FLTOVF }, + { ld_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static sigjmp_buf b; + +static void +fpsetmask_masked(const struct ops *test_ops) +{ + struct sigaction sa; + fp_except ex1, ex2; + const struct ops *t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exceptions masked, check whether "sticky" bits are set correctly + */ + for (t = test_ops; t->op != NULL; t++) { + (*t->op)(); + ex1 = fpgetsticky(); + ATF_CHECK_EQ(ex1 & t->mask, t->mask); + ATF_CHECK_EQ(signal_caught, 0); + + /* check correct fpsetsticky() behaviour */ + ex2 = fpsetsticky(0); + ATF_CHECK_EQ(fpgetsticky(), 0); + ATF_CHECK_EQ(ex1, ex2); + } +} + +/* force delayed exceptions to be delivered */ +#define BARRIER() fpsetmask(0); f_x = f_one * f_one + +static void +fpsetmask_unmasked(const struct ops *test_ops) +{ + struct sigaction sa; + int r; + const struct ops *volatile t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exception unmasked, check SIGFPE delivery and correct siginfo + */ + for (t = test_ops; t->op != NULL; t++) { + fpsetmask(t->mask); + r = sigsetjmp(b, 1); + if (!r) { + (*t->op)(); + BARRIER(); + } + ATF_CHECK_EQ(signal_caught, 1); + ATF_CHECK_EQ(sicode, t->sicode); + signal_caught = 0; + } +} + +void +sigfpe(int s, siginfo_t *si, void *c) +{ + signal_caught = 1; + sicode = si->si_code; + siglongjmp(b, 1); +} + +#define TEST(m, t) \ + ATF_TC(m##_##t); \ + \ + ATF_TC_HEAD(m##_##t, tc) \ + { \ + \ + atf_tc_set_md_var(tc, "descr", \ + "Test " ___STRING(m) " exceptions for " \ + ___STRING(t) "values"); \ + } \ + \ + ATF_TC_BODY(m##_##t, tc) \ + { \ + if (strcmp(MACHINE, "macppc") == 0) \ + atf_tc_expect_fail("PR port-macppc/46319"); \ + \ + if (isQEMU()) \ + atf_tc_expect_fail("PR misc/44767"); \ + \ + m(t##_ops); \ + } + +TEST(fpsetmask_masked, float) +TEST(fpsetmask_masked, double) +TEST(fpsetmask_masked, long_double) +TEST(fpsetmask_unmasked, float) +TEST(fpsetmask_unmasked, double) +TEST(fpsetmask_unmasked, long_double) + +ATF_TC(fpsetmask_basic); +ATF_TC_HEAD(fpsetmask_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fpsetmask(3)"); +} + +ATF_TC_BODY(fpsetmask_basic, tc) +{ + size_t i; + fp_except_t msk, lst[] = { FP_X_INV, FP_X_DZ, FP_X_OFL, FP_X_UFL }; + + msk = fpgetmask(); + for (i = 0; i < __arraycount(lst); i++) { + fpsetmask(msk | lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) != 0); + fpsetmask(msk & lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) == 0); + } + +} + +#endif /* defined(_FLOAT_IEEE754) */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpsetmask_basic); + ATF_TP_ADD_TC(tp, fpsetmask_masked_float); + ATF_TP_ADD_TC(tp, fpsetmask_masked_double); + ATF_TP_ADD_TC(tp, fpsetmask_masked_long_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_float); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_long_double); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c new file mode 100644 index 0000000..0f23e74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $"); + +#include <float.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <atf-c.h> + +ATF_TC(fpsetround_basic); +ATF_TC_HEAD(fpsetround_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Minimal testing of fpgetround(3) and fpsetround(3)"); +} + +#ifdef _FLOAT_IEEE754 +#include <ieeefp.h> + +static const struct { + const char *n; + int rm; + int rf; +} rnd[] = { + { "RN", FP_RN, 1 }, + { "RP", FP_RP, 2 }, + { "RM", FP_RM, 3 }, + { "RZ", FP_RZ, 0 }, + +}; + +static const struct { + const char *n; + int v[4]; +} tst[] = { /* RN RP RM RZ */ + { "1.1", { 1, 1, 2, 1 } }, + { "1.5", { 1, 2, 2, 1 } }, + { "1.9", { 1, 2, 2, 1 } }, + { "2.1", { 2, 2, 3, 2 } }, + { "2.5", { 2, 2, 3, 2 } }, + { "2.9", { 2, 3, 3, 2 } }, + { "-1.1", { -1, -1, -1, -2 } }, + { "-1.5", { -1, -2, -1, -2 } }, + { "-1.9", { -1, -2, -1, -2 } }, + { "-2.1", { -2, -2, -2, -3 } }, + { "-2.5", { -2, -2, -2, -3 } }, + { "-2.9", { -2, -3, -2, -3 } }, +}; + +static const char * +getname(int r) +{ + for (size_t i = 0; i < __arraycount(rnd); i++) + if (rnd[i].rm == r) + return rnd[i].n; + return "*unknown*"; +} + +static void +test(int r) +{ + int did = 0; + for (size_t i = 0; i < __arraycount(tst); i++) { + double d = strtod(tst[i].n, NULL); + int g = (int)rint(d); + int e = tst[i].v[r]; + ATF_CHECK_EQ(g, e); + if (g != e) { + if (!did) { + fprintf(stderr, "Mode Value Result Expected\n"); + did = 1; + } + fprintf(stderr, "%4.4s %-5.5s %6d %8d\n", rnd[r].n, + tst[i].n, (int)rint(d), tst[i].v[r]); + } + } +} +#endif + + +ATF_TC_BODY(fpsetround_basic, tc) +{ + +#ifndef _FLOAT_IEEE754 + atf_tc_skip("Test not applicable on this architecture."); +#else + int r; + + ATF_CHECK_EQ(r = fpgetround(), FP_RN); + if (FP_RN != r) + fprintf(stderr, "default expected=%s got=%s\n", getname(FP_RN), + getname(r)); + ATF_CHECK_EQ(FLT_ROUNDS, 1); + + for (size_t i = 0; i < __arraycount(rnd); i++) { + const size_t j = (i + 1) & 3; + const int o = rnd[i].rm; + const int n = rnd[j].rm; + + ATF_CHECK_EQ(r = fpsetround(n), o); + if (o != r) + fprintf(stderr, "set %s expected=%s got=%s\n", + getname(n), getname(o), getname(r)); + ATF_CHECK_EQ(r = fpgetround(), n); + if (n != r) + fprintf(stderr, "get expected=%s got=%s\n", getname(n), + getname(r)); + ATF_CHECK_EQ(r = FLT_ROUNDS, rnd[j].rf); + if (r != rnd[j].rf) + fprintf(stderr, "rounds expected=%x got=%x\n", + rnd[j].rf, r); + test(r); + } +#endif /* _FLOAT_IEEE754 */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fpsetround_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ftok.c b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c new file mode 100644 index 0000000..100bd1b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $"); + +#include <sys/types.h> +#include <sys/ipc.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <unistd.h> + +static const char *path = "ftok"; +static const char *hlnk = "hlnk"; +static const char *slnk = "slnk"; +static const int key = 123456789; + +ATF_TC(ftok_err); +ATF_TC_HEAD(ftok_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from ftok(3)"); +} + +ATF_TC_BODY(ftok_err, tc) +{ + ATF_REQUIRE(ftok("/a/b/c/d/e/f/g/h/i", key) == -1); +} + +ATF_TC_WITH_CLEANUP(ftok_link); +ATF_TC_HEAD(ftok_link, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that links return the same key"); +} + +ATF_TC_BODY(ftok_link, tc) +{ + key_t k1, k2, k3; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(link(path, hlnk) == 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + + k1 = ftok(path, key); + k2 = ftok(hlnk, key); + k3 = ftok(slnk, key); + + ATF_REQUIRE(k1 != -1); + ATF_REQUIRE(k2 != -1); + ATF_REQUIRE(k3 != -1); + + if (k1 != k2) + atf_tc_fail("ftok(3) gave different key for a hard link"); + + if (k1 != k3) + atf_tc_fail("ftok(3) gave different key for a symbolic link"); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(hlnk) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TC_CLEANUP(ftok_link, tc) +{ + (void)unlink(path); + (void)unlink(hlnk); + (void)unlink(slnk); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ftok_err); + ATF_TP_ADD_TC(tp, ftok_link); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c new file mode 100644 index 0000000..1f39984 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c @@ -0,0 +1,153 @@ +/* $NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fts.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(getcwd_err); +ATF_TC_HEAD(getcwd_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in getcwd(3)"); +} + +ATF_TC_BODY(getcwd_err, tc) +{ + char buf[MAXPATHLEN]; + + errno = 0; + + ATF_REQUIRE(getcwd(buf, 0) == NULL); + ATF_REQUIRE(errno == EINVAL); + +#ifdef __NetBSD__ + errno = 0; + + ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL); + ATF_REQUIRE(errno == EFAULT); +#endif +} + +ATF_TC(getcwd_fts); +ATF_TC_HEAD(getcwd_fts, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of getcwd(3)"); +} + +ATF_TC_BODY(getcwd_fts, tc) +{ + const char *str = NULL; + char buf[MAXPATHLEN]; + char *argv[2]; + FTSENT *ftse; + FTS *fts; + int ops; + short depth; + + /* + * Do not traverse too deep; cf. PR bin/45180. + */ + depth = 2; + + argv[1] = NULL; + argv[0] = __UNCONST("/"); + + /* + * Test that getcwd(3) works with basic + * system directories. Note that having + * no FTS_NOCHDIR specified should ensure + * that the current directory is visited. + */ + ops = FTS_PHYSICAL | FTS_NOSTAT; + fts = fts_open(argv, ops, NULL); + + if (fts == NULL) { + str = "failed to initialize fts(3)"; + goto out; + } + + while ((ftse = fts_read(fts)) != NULL) { + + if (ftse->fts_level < 1) + continue; + + if (ftse->fts_level > depth) { + (void)fts_set(fts, ftse, FTS_SKIP); + continue; + } + + switch(ftse->fts_info) { + + case FTS_DP: + + (void)memset(buf, 0, sizeof(buf)); + + if (getcwd(buf, sizeof(buf)) == NULL) { + str = "getcwd(3) failed"; + goto out; + } + + if (strstr(ftse->fts_path, buf) == NULL) { + str = "getcwd(3) returned incorrect path"; + goto out; + } + + break; + + default: + break; + } + } + +out: + if (fts != NULL) + (void)fts_close(fts); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getcwd_err); + ATF_TP_ADD_TC(tp, getcwd_fts); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c new file mode 100644 index 0000000..df9cdd1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c @@ -0,0 +1,181 @@ +/* $NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <grp.h> +#include <stdlib.h> +#include <unistd.h> + +ATF_TC(getgrent_loop); +ATF_TC_HEAD(getgrent_loop, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sequential getgrent(2)"); +} + +ATF_TC_BODY(getgrent_loop, tc) +{ + struct group *gr; + size_t i, j; + + /* + * Loop over the group database. The first + * call returns the first entry and subsequent + * calls return the rest of the entries. + */ + i = j = 0; + + while((gr = getgrent()) != NULL) + i++; + + /* + * Rewind the database to the beginning + * and loop over again until the end. + */ + setgrent(); + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("sequential getgrent(3) failed"); + + /* + * Close the database and reopen it. + * The getgrent(3) call should always + * automatically rewind the database. + */ + endgrent(); + + j = 0; + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("getgrent(3) did not rewind"); +} + +ATF_TC(getgrent_setgid); +ATF_TC_HEAD(getgrent_setgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test consistency of the group db"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(getgrent_setgid, tc) +{ + struct group *gr, *gr1, *gr2; + int rv, sta; + pid_t pid; + + /* + * Verify that the database is consistent. + * + * Note that because of the static buffers + * used by getgrent(3), fork(2) is required, + * even without the setgid(2) check. + */ + while((gr = getgrent()) != NULL) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + gr1 = getgrgid(gr->gr_gid); + + if (gr1 == NULL) + _exit(EXIT_FAILURE); + + gr2 = getgrnam(gr->gr_name); + + if (gr2 == NULL) + _exit(EXIT_FAILURE); + + rv = setgid(gr->gr_gid); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + goto fail; + } + + return; + +fail: + atf_tc_fail("group database is inconsistent"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgrent_loop); + ATF_TP_ADD_TC(tp, getgrent_setgid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_glob.c b/contrib/netbsd-tests/lib/libc/gen/t_glob.c new file mode 100644 index 0000000..198148c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c @@ -0,0 +1,287 @@ +/* $NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $"); + +#include <atf-c.h> + +#include <sys/param.h> +#include <sys/stat.h> + +#include <dirent.h> +#include <glob.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#ifdef __FreeBSD__ +#include "h_macros.h" +#define __gl_stat_t struct stat +#define _S_IFDIR S_IFDIR +#else +#include "../../../h_macros.h" +#endif + + +#ifdef DEBUG +#define DPRINTF(a) printf a +#else +#define DPRINTF(a) +#endif + +struct gl_file { + const char *name; + int dir; +}; + +static struct gl_file a[] = { + { "1", 0 }, + { "b", 1 }, + { "3", 0 }, + { "4", 0 }, +}; + +static struct gl_file b[] = { + { "x", 0 }, + { "y", 0 }, + { "z", 0 }, + { "w", 0 }, +}; + +struct gl_dir { + const char *name; /* directory name */ + const struct gl_file *dir; + size_t len, pos; +}; + +static struct gl_dir d[] = { + { "a", a, __arraycount(a), 0 }, + { "a/b", b, __arraycount(b), 0 }, +}; + +static const char *glob_star[] = { + "a/1", "a/3", "a/4", "a/b", "a/b/w", "a/b/x", "a/b/y", "a/b/z", +}; + +static const char *glob_star_not[] = { + "a/1", "a/3", "a/4", "a/b", +}; + +static void +trim(char *buf, size_t len, const char *name) +{ + char *path = buf, *epath = buf + len; + while (path < epath && (*path++ = *name++) != '\0') + continue; + path--; + while (path > buf && *--path == '/') + *path = '\0'; +} + +static void * +gl_opendir(const char *dir) +{ + size_t i; + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), dir); + + for (i = 0; i < __arraycount(d); i++) + if (strcmp(buf, d[i].name) == 0) { + DPRINTF(("opendir %s %zu\n", buf, i)); + return &d[i]; + } + errno = ENOENT; + return NULL; +} + +static struct dirent * +gl_readdir(void *v) +{ + static struct dirent dir; + struct gl_dir *dd = v; + if (dd->pos < dd->len) { + const struct gl_file *f = &dd->dir[dd->pos++]; + strcpy(dir.d_name, f->name); + dir.d_namlen = strlen(f->name); + dir.d_ino = dd->pos; + dir.d_type = f->dir ? DT_DIR : DT_REG; + DPRINTF(("readdir %s %d\n", dir.d_name, dir.d_type)); +#ifdef __FreeBSD__ + dir.d_reclen = -1; /* Does not have _DIRENT_RECLEN */ +#else + dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen); +#endif + return &dir; + } + return NULL; +} + +static int +gl_stat(const char *name , __gl_stat_t *st) +{ + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), name); + memset(st, 0, sizeof(*st)); + + if (strcmp(buf, "a") == 0 || strcmp(buf, "a/b") == 0) { + st->st_mode |= _S_IFDIR; + return 0; + } + + if (buf[0] == 'a' && buf[1] == '/') { + struct gl_file *f; + size_t offs, count; + + if (buf[2] == 'b' && buf[3] == '/') { + offs = 4; + count = __arraycount(b); + f = b; + } else { + offs = 2; + count = __arraycount(a); + f = a; + } + + for (size_t i = 0; i < count; i++) + if (strcmp(f[i].name, buf + offs) == 0) + return 0; + } + DPRINTF(("stat %s %d\n", buf, st->st_mode)); + errno = ENOENT; + return -1; +} + +static int +gl_lstat(const char *name , __gl_stat_t *st) +{ + return gl_stat(name, st); +} + +static void +gl_closedir(void *v) +{ + struct gl_dir *dd = v; + dd->pos = 0; + DPRINTF(("closedir %p\n", dd)); +} + +static void +run(const char *p, int flags, const char **res, size_t len) +{ + glob_t gl; + size_t i; + + memset(&gl, 0, sizeof(gl)); + gl.gl_opendir = gl_opendir; + gl.gl_readdir = gl_readdir; + gl.gl_closedir = gl_closedir; + gl.gl_stat = gl_stat; + gl.gl_lstat = gl_lstat; + + RZ(glob(p, GLOB_ALTDIRFUNC | flags, NULL, &gl)); + + for (i = 0; i < gl.gl_pathc; i++) + DPRINTF(("%s\n", gl.gl_pathv[i])); + + ATF_CHECK(len == gl.gl_pathc); + for (i = 0; i < gl.gl_pathc; i++) + ATF_CHECK_STREQ(gl.gl_pathv[i], res[i]); + + globfree(&gl); +} + + +#ifndef __FreeBSD__ +ATF_TC(glob_star); +ATF_TC_HEAD(glob_star, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** with GLOB_STAR"); +} + +ATF_TC_BODY(glob_star, tc) +{ + run("a/**", GLOB_STAR, glob_star, __arraycount(glob_star)); +} +#endif + +ATF_TC(glob_star_not); +ATF_TC_HEAD(glob_star_not, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** without GLOB_STAR"); +} + + +ATF_TC_BODY(glob_star_not, tc) +{ + run("a/**", 0, glob_star_not, __arraycount(glob_star_not)); +} + +#if 0 +ATF_TC(glob_nocheck); +ATF_TC_HEAD(glob_nocheck, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) pattern with backslash and GLOB_NOCHECK"); +} + + +ATF_TC_BODY(glob_nocheck, tc) +{ + static const char pattern[] = { 'f', 'o', 'o', '\\', ';', 'b', 'a', + 'r', '\0' }; + static const char *glob_nocheck[] = { + pattern + }; + run(pattern, GLOB_NOCHECK, glob_nocheck, __arraycount(glob_nocheck)); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ +#ifndef __FreeBSD__ + ATF_TP_ADD_TC(tp, glob_star); +#endif + ATF_TP_ADD_TC(tp, glob_star_not); +/* + * Remove this test for now - the GLOB_NOCHECK return value has been + * re-defined to return a modified pattern in revision 1.33 of glob.c + * + * ATF_TP_ADD_TC(tp, glob_nocheck); + */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c new file mode 100644 index 0000000..5836c86 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c @@ -0,0 +1,318 @@ +/* $NetBSD: t_humanize_number.c,v 1.8 2012/03/18 07:14:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <err.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef __FreeBSD__ +#include <libutil.h> +#else +#include <util.h> +#endif + +const struct hnopts { + size_t ho_len; + int64_t ho_num; + const char *ho_suffix; + int ho_scale; + int ho_flags; + int ho_retval; /* expected return value */ + const char *ho_retstr; /* expected string in buffer */ +} hnopts[] = { + /* + * Rev. 1.6 produces "10.0". + */ + { 5, 10737418236ULL * 1024, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10T" }, + + { 5, 10450000, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + { 5, 10500000, "", /* just for reference */ + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + + /* + * Trailing space. Rev. 1.7 produces "1 ". + */ + { 5, 1, "", 0, HN_NOSPACE, 1, "1" }, + + { 5, 1, "", 0, 0, 2, "1 " }, /* just for reference */ + { 5, 1, "", 0, HN_B, 3, "1 B" }, /* and more ... */ + { 5, 1, "", 0, HN_DECIMAL, 2, "1 " }, + { 5, 1, "", 0, HN_NOSPACE | HN_B, 2, "1B" }, + { 5, 1, "", 0, HN_B | HN_DECIMAL, 3, "1 B" }, + { 5, 1, "", 0, HN_NOSPACE | HN_B | HN_DECIMAL, 2, "1B" }, + + /* + * Space and HN_B. Rev. 1.7 produces "1B". + */ + { 5, 1, "", HN_AUTOSCALE, HN_B, 3, "1 B" }, + { 5, 1000, "", /* just for reference */ + HN_AUTOSCALE, HN_B, 3, "1 K" }, + + /* + * Truncated output. Rev. 1.7 produces "1.0 K". + */ +#ifndef __FreeBSD__ + { 6, 1000, "A", HN_AUTOSCALE, HN_DECIMAL, -1, "" }, + + /* + * Failure case reported by Greg Troxel <gdt@NetBSD.org>. + * Rev. 1.11 incorrectly returns 5 with filling the buffer + * with "1000". + */ + { 5, 1048258238, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0G" }, + /* Similar case it prints 1000 where it shouldn't */ + { 5, 1023488, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, +#endif + { 5, 1023999, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, +}; + +struct hnflags { + int hf_flags; + const char *hf_name; +}; + +const struct hnflags scale_flags[] = { + { HN_GETSCALE, "HN_GETSCALE" }, + { HN_AUTOSCALE, "HN_AUTOSCALE" }, +}; +const struct hnflags normal_flags[] = { + { HN_DECIMAL, "HN_DECIMAL" }, + { HN_NOSPACE, "HN_NOSPACE" }, + { HN_B, "HN_B" }, + { HN_DIVISOR_1000, "HN_DIVISOR_1000" }, +}; + +const char *formatflags(char *, size_t, const struct hnflags *, size_t, int); +void newline(void); +void w_printf(const char *, ...) __printflike(1, 2); +int main(int, char *[]); + +const char * +formatflags(char *buf, size_t buflen, const struct hnflags *hfs, + size_t hfslen, int flags) +{ + const struct hnflags *hf; + char *p = buf; + ssize_t len = buflen; + unsigned int i, found; + int n; + + if (flags == 0) { + snprintf(buf, buflen, "0"); + return (buf); + } + for (i = found = 0; i < hfslen && flags & ~found; i++) { + hf = &hfs[i]; + if (flags & hf->hf_flags) { + found |= hf->hf_flags; + n = snprintf(p, len, "|%s", hf->hf_name); + if (n >= len) { + p = buf; + len = buflen; + /* Print `flags' as number */ + goto bad; + } + p += n; + len -= n; + } + } + flags &= ~found; + if (flags) +bad: + snprintf(p, len, "|0x%x", flags); + return (*buf == '|' ? buf + 1 : buf); +} + +static int col, bol = 1; +void +newline(void) +{ + + fprintf(stderr, "\n"); + col = 0; + bol = 1; +} + +void +w_printf(const char *fmt, ...) +{ + char buf[80]; + va_list ap; + int n; + + va_start(ap, fmt); + if (col >= 0) { + n = vsnprintf(buf, sizeof(buf), fmt, ap); + if (n >= (int)sizeof(buf)) { + col = -1; + goto overflow; + } else if (n == 0) + goto out; + + if (!bol) { + if (col + n > 75) + fprintf(stderr, "\n "), col = 4; + else + fprintf(stderr, " "), col++; + } + fprintf(stderr, "%s", buf); + col += n; + bol = 0; + } else { +overflow: + vfprintf(stderr, fmt, ap); + } +out: + va_end(ap); +} + +ATF_TC(humanize_number_basic); +ATF_TC_HEAD(humanize_number_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize_number(3)"); +} + +ATF_TC_BODY(humanize_number_basic, tc) +{ + char fbuf[128]; + const struct hnopts *ho; + char *buf = NULL; + size_t buflen = 0; + unsigned int i; + int rv = 0; + + for (i = 0; i < __arraycount(hnopts); i++) { + ho = &hnopts[i]; + if (buflen < ho->ho_len) { + buflen = ho->ho_len; + buf = realloc(buf, buflen); + if (buf == NULL) + atf_tc_fail("realloc(..., %zu) failed", buflen); + } + + rv = humanize_number(buf, ho->ho_len, ho->ho_num, + ho->ho_suffix, ho->ho_scale, ho->ho_flags); + + if (rv == ho->ho_retval && + (rv == -1 || strcmp(buf, ho->ho_retstr) == 0)) + continue; + + w_printf("humanize_number(\"%s\", %zu, %" PRId64 ",", + ho->ho_retstr, ho->ho_len, ho->ho_num); + w_printf("\"%s\",", ho->ho_suffix); + w_printf("%s,", formatflags(fbuf, sizeof(fbuf), scale_flags, + sizeof(scale_flags) / sizeof(scale_flags[0]), + ho->ho_scale)); + w_printf("%s)", formatflags(fbuf, sizeof(fbuf), normal_flags, + sizeof(normal_flags) / sizeof(normal_flags[0]), + ho->ho_flags)); + w_printf("= %d,", ho->ho_retval); + w_printf("but got"); + w_printf("%d/[%s]", rv, rv == -1 ? "" : buf); + newline(); + atf_tc_fail_nonfatal("Failed for table entry %d", i); + } +} + +ATF_TC(humanize_number_big); +ATF_TC_HEAD(humanize_number_big, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize " + "big numbers (PR lib/44097)"); +} + +ATF_TC_BODY(humanize_number_big, tc) +{ + char buf[1024]; + int rv; + + /* + * Seems to work. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, 10000, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_CHECK_STREQ(buf, "10000"); + + /* + * A bogus value with large number. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, INT64_MAX, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0") != 0); + + /* + * Large buffer with HN_AUTOSCALE. Entirely bogus. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, sizeof(buf), 10000, "", + HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0%d%s%d%s%s%s") != 0); + + /* + * Tight buffer. + * + * The man page says that len must be at least 4. + * 3 works, but anything less that will not. This + * is because baselen starts with 2 for positive + * numbers. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 3, 1, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, humanize_number_basic); + ATF_TP_ADD_TC(tp, humanize_number_big); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_isnan.c b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c new file mode 100644 index 0000000..2871e31 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c @@ -0,0 +1,66 @@ +/* $NetBSD: t_isnan.c,v 1.5 2014/11/04 00:20:19 justin Exp $ */ + +/* + * This file is in the Public Domain. + * + * The nan test is blatently copied by Simon Burge from the infinity + * test by Ben Harris. + */ + +#include <sys/param.h> + +#include <atf-c.h> + +#include <math.h> +#include <string.h> + +ATF_TC(isnan_basic); +ATF_TC_HEAD(isnan_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isnan(3) works"); +} + +ATF_TC_BODY(isnan_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + +#ifdef NAN + /* NAN is meant to be a (float)NaN. */ + ATF_CHECK(isnan(NAN) != 0); + ATF_CHECK(isnan((double)NAN) != 0); +#else + atf_tc_skip("Test not applicable"); +#endif +} + +ATF_TC(isinf_basic); +ATF_TC_HEAD(isinf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isinf(3) works"); +} + +ATF_TC_BODY(isinf_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + + /* HUGE_VAL is meant to be an infinity. */ + ATF_CHECK(isinf(HUGE_VAL) != 0); + + /* HUGE_VALF is the float analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALF) != 0); + + /* HUGE_VALL is the long double analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALL) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, isnan_basic); + ATF_TP_ADD_TC(tp, isinf_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_nice.c b/contrib/netbsd-tests/lib/libc/gen/t_nice.c new file mode 100644 index 0000000..10b8df7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c @@ -0,0 +1,221 @@ +/* $NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); + +#include <sys/resource.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <stdlib.h> +#include <unistd.h> + +static void *threadfunc(void *); + +static void * +threadfunc(void *arg) +{ + int pri, val; + + val = *(int *)arg; + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (pri != val) + atf_tc_fail("nice(3) value was not propagated to threads"); + + return NULL; +} + +ATF_TC(nice_err); +ATF_TC_HEAD(nice_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test nice(3) for invalid parameters (PR lib/42587)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(nice_err, tc) +{ + int i; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("nice(incr) with incr < 0 fails with unprivileged " + "users and sets errno == EPERM; see PR # 189821 for more details"); +#endif + + /* + * The call should fail with EPERM if the + * supplied parameter is negative and the + * caller does not have privileges. + */ + for (i = -20; i < 0; i++) { + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1); + } +} + +ATF_TC(nice_priority); +ATF_TC_HEAD(nice_priority, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)"); +} + +ATF_TC_BODY(nice_priority, tc) +{ +#ifdef __FreeBSD__ + int i, pri, pri2, nic; +#else + int i, pri, nic; +#endif + pid_t pid; + int sta; + + for (i = 0; i <= 20; i++) { + + nic = nice(i); + ATF_REQUIRE(nic != -1); + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + +#ifdef __NetBSD__ + if (nic != pri) + atf_tc_fail("nice(3) and getpriority(2) conflict"); +#endif + + /* + * Also verify that the nice(3) values + * are inherited by child processes. + */ + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; +#ifdef __FreeBSD__ + pri = getpriority(PRIO_PROCESS, 0); +#else + pri2 = getpriority(PRIO_PROCESS, 0); +#endif + ATF_REQUIRE(errno == 0); + +#ifdef __FreeBSD__ + if (pri != pri2) +#else + if (nic != pri) +#endif + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("nice(3) value was not inherited"); + } +} + +ATF_TC(nice_root); +ATF_TC_HEAD(nice_root, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that nice(3) works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(nice_root, tc) +{ + int i; + + for (i = -20; i <= 20; i++) { + + ATF_REQUIRE(nice(i) != -1); + } +} + +ATF_TC(nice_thread); +ATF_TC_HEAD(nice_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads"); +} + +ATF_TC_BODY(nice_thread, tc) +{ + pthread_t tid[5]; +#ifdef __FreeBSD__ + int pri, rv, val; +#else + int rv, val; +#endif + size_t i; + + /* + * Test that the scheduling priority is + * propagated to all system scope threads. + */ + for (i = 0; i < __arraycount(tid); i++) { + + val = nice(i); + ATF_REQUIRE(val != -1); + +#ifdef __FreeBSD__ + pri = getpriority(PRIO_PROCESS, 0); + rv = pthread_create(&tid[i], NULL, threadfunc, &pri); +#else + rv = pthread_create(&tid[i], NULL, threadfunc, &val); +#endif + ATF_REQUIRE(rv == 0); + + rv = pthread_join(tid[i], NULL); + ATF_REQUIRE(rv == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nice_err); + ATF_TP_ADD_TC(tp, nice_priority); + ATF_TP_ADD_TC(tp, nice_root); + ATF_TP_ADD_TC(tp, nice_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_pause.c b/contrib/netbsd-tests/lib/libc/gen/t_pause.c new file mode 100644 index 0000000..62a74c9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_pause.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +static bool fail; +static void handler(int); + +static void +handler(int signo) +{ + + if (signo == SIGALRM) + fail = false; +} + +ATF_TC(pause_basic); +ATF_TC_HEAD(pause_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #1"); +} + +ATF_TC_BODY(pause_basic, tc) +{ + + fail = true; + + ATF_REQUIRE(signal(SIGALRM, handler) == 0); + + (void)alarm(1); + + if (pause() != -1 || fail != false) + atf_tc_fail("pause(3) did not cancel out from a signal"); +} + +ATF_TC(pause_kill); +ATF_TC_HEAD(pause_kill, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #2"); +} + +ATF_TC_BODY(pause_kill, tc) +{ + pid_t pid; + int sta; + + fail = true; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)pause(); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + + if (fail != true) + atf_tc_fail("child terminated before signal"); + + (void)kill(pid, SIGKILL); + (void)sleep(1); + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("pause(3) did not cancel from SIGKILL"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pause_basic); + ATF_TP_ADD_TC(tp, pause_kill); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_raise.c b/contrib/netbsd-tests/lib/libc/gen/t_raise.c new file mode 100644 index 0000000..d6f888f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $"); + +#include <atf-c.h> + +#include <signal.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +static bool fail; +static int count; +static void handler_err(int); +static void handler_ret(int); +static void handler_stress(int); +#ifdef __FreeBSD__ +static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2 }; +#else +static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR }; +#endif + +static void +handler_stress(int signo) +{ + count++; +} + +static void +handler_err(int signo) +{ + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + if (sig[i] == signo) { + fail = false; + break; + } + } +} + +static void +handler_ret(int signo) +{ + + (void)sleep(1); + + fail = false; +} + +ATF_TC(raise_err); +ATF_TC_HEAD(raise_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test raise(3) for invalid parameters"); +} + +ATF_TC_BODY(raise_err, tc) +{ + int i = 0; + + while (i < 10) { + + ATF_REQUIRE(raise(10240 + i) == -1); + + i++; + } +} + +ATF_TC(raise_ret); +ATF_TC_HEAD(raise_ret, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test return order of raise(3)"); +} + +ATF_TC_BODY(raise_ret, tc) +{ + struct sigaction sa; + + fail = true; + + sa.sa_flags = 0; + sa.sa_handler = handler_ret; + + /* + * Verify that raise(3) does not return + * before the signal handler returns. + */ + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + ATF_REQUIRE(raise(SIGUSR1) == 0); + + if (fail != false) + atf_tc_fail("raise(3) returned before signal handler"); +} + +ATF_TC(raise_sig); +ATF_TC_HEAD(raise_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of raise(3)"); +} + +ATF_TC_BODY(raise_sig, tc) +{ + struct timespec tv, tr; + struct sigaction sa; + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + (void)memset(&sa, 0, sizeof(struct sigaction)); + + fail = true; + + tv.tv_sec = 0; + tv.tv_nsec = 2; + + sa.sa_flags = 0; + sa.sa_handler = handler_err; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(sig[i], &sa, 0) == 0); + + ATF_REQUIRE(raise(sig[i]) == 0); + ATF_REQUIRE(nanosleep(&tv, &tr) == 0); + + if (fail != false) + atf_tc_fail("raise(3) did not raise a signal"); + } +} + +ATF_TC(raise_stress); +ATF_TC_HEAD(raise_stress, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic stress test with raise(3)"); +} + +ATF_TC_BODY(raise_stress, tc) +{ + static const int maxiter = 1000 * 10; + struct sigaction sa; + int i; + + sa.sa_flags = 0; + sa.sa_handler = handler_stress; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + + for (count = i = 0; i < maxiter; i++) + (void)raise(SIGUSR1); + + if (count != maxiter) + atf_tc_fail("not all signals were catched"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, raise_err); + ATF_TP_ADD_TC(tp, raise_ret); + ATF_TP_ADD_TC(tp, raise_sig); + ATF_TP_ADD_TC(tp, raise_stress); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_randomid.c b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c new file mode 100644 index 0000000..8377806 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_randomid.c,v 1.3 2011/07/07 09:49:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <sys/types.h> + +#include <assert.h> +#include <inttypes.h> +#include <randomid.h> +#include <stdio.h> +#include <string.h> + +#define PERIOD 30000 + +uint64_t last[65536]; + +ATF_TC(randomid_basic); +ATF_TC_HEAD(randomid_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check randomid(3)"); +} + +ATF_TC_BODY(randomid_basic, tc) +{ + static randomid_t ctx = NULL; + uint64_t lowest, n, diff; + uint16_t id; + + memset(last, 0, sizeof(last)); + ctx = randomid_new(16, (long)3600); + + lowest = UINT64_MAX; + + for (n = 0; n < 1000000; n++) { + id = randomid(ctx); + + if (last[id] > 0) { + diff = n - last[id]; + + if (diff <= lowest) { + if (lowest != UINT64_MAX) + printf("id %5d: last call at %9"PRIu64 + ", current call %9"PRIu64 + " (diff %5"PRIu64"), " + "lowest %"PRIu64"\n", + id, last[id], n, diff, lowest); + + ATF_REQUIRE_MSG(diff >= PERIOD, + "diff (%"PRIu64") less than minimum " + "period (%d)", diff, PERIOD); + + lowest = diff; + } + } + + last[id] = n; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, randomid_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_realpath.c b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c new file mode 100644 index 0000000..d4998c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const struct { + const char *path; + const char *result; +} paths[] = { + + { "/", "/" }, + { "///////", "/" }, + { "", NULL }, + { " ", NULL }, + { "/ ", NULL }, + { " /", NULL }, + { "/etc///", "/etc" }, + { "///////etc", "/etc" }, + { "/a/b/c/d/e", NULL }, + { " /usr/bin ", NULL }, + { "\\//////usr//bin", NULL }, + { "//usr//bin//", "/usr/bin" }, + { "//////usr//bin//", "/usr/bin" }, + { "/usr/bin//////////", "/usr/bin" }, +}; + +ATF_TC(realpath_basic); +ATF_TC_HEAD(realpath_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)"); +} + +ATF_TC_BODY(realpath_basic, tc) +{ + char buf[MAXPATHLEN]; + char *ptr; + size_t i; + + for (i = 0; i < __arraycount(paths); i++) { + + (void)memset(buf, '\0', sizeof(buf)); + + ptr = realpath(paths[i].path, buf); + + if (ptr == NULL && paths[i].result == NULL) + continue; + + if (ptr == NULL && paths[i].result != NULL) + atf_tc_fail("realpath failed for '%s'", paths[i].path); + + if (strcmp(paths[i].result, buf) != 0) + atf_tc_fail("expected '%s', got '%s'", + paths[i].result, buf); + } +} + +ATF_TC(realpath_huge); +ATF_TC_HEAD(realpath_huge, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)"); +} + +ATF_TC_BODY(realpath_huge, tc) +{ + char result[MAXPATHLEN] = { 0 }; + char buffer[MAXPATHLEN] = { 0 }; + + (void)memset(buffer, '/', sizeof(buffer) - 1); + + ATF_CHECK(realpath(buffer, result) != NULL); + ATF_CHECK(strlen(result) == 1); + ATF_CHECK(result[0] == '/'); +} + +ATF_TC(realpath_symlink); +ATF_TC_HEAD(realpath_symlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)"); +} + +ATF_TC_BODY(realpath_symlink, tc) +{ + char path[MAXPATHLEN] = { 0 }; + char slnk[MAXPATHLEN] = { 0 }; + char resb[MAXPATHLEN] = { 0 }; + int fd; + + (void)getcwd(path, sizeof(path)); + (void)getcwd(slnk, sizeof(slnk)); + + (void)strlcat(path, "/realpath", sizeof(path)); + (void)strlcat(slnk, "/symbolic", sizeof(slnk)); + + fd = open(path, O_RDONLY | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(realpath(slnk, resb) != NULL); + ATF_REQUIRE(strcmp(resb, path) == 0); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, realpath_basic); + ATF_TP_ADD_TC(tp, realpath_huge); + ATF_TP_ADD_TC(tp, realpath_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c new file mode 100644 index 0000000..f51eb2a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +static char domain[MAXHOSTNAMELEN]; + +static const char domains[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(setdomainname_basic); +ATF_TC_HEAD(setdomainname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setdomainname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + for (i = 0; i < __arraycount(domains); i++) { + + (void)memset(name, 0, sizeof(name)); + +#ifdef __FreeBSD__ + /* + * Sanity checks to ensure that the wrong invariant isn't being + * tested for per PR # 181127 + */ + ATF_REQUIRE_EQ(sizeof(domains[i]), MAXHOSTNAMELEN); + ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN); + + ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i]) - 1) == 0); + ATF_REQUIRE(getdomainname(name, sizeof(name) - 1) == 0); +#else + ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0); + ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0); +#endif + ATF_REQUIRE(strcmp(domains[i], name) == 0); + } + + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_CLEANUP(setdomainname_basic, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_limit); +ATF_TC_HEAD(setdomainname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long domain name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + +#ifdef __FreeBSD__ + ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN - 1 ) == 0); + ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN) == -1); +#endif + ATF_REQUIRE(setdomainname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_limit, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_perm); +ATF_TC_HEAD(setdomainname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setdomainname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_perm, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(domain, 0, sizeof(domain)); + + ATF_REQUIRE(getdomainname(domain, sizeof(domain)) == 0); + + ATF_TP_ADD_TC(tp, setdomainname_basic); + ATF_TP_ADD_TC(tp, setdomainname_limit); + ATF_TP_ADD_TC(tp, setdomainname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c new file mode 100644 index 0000000..1972f7d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +static char host[MAXHOSTNAMELEN]; + +static const char hosts[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(sethostname_basic); +ATF_TC_HEAD(sethostname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of sethostname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + atf_tc_skip("screws up the test host's hostname on FreeBSD"); + + for (i = 0; i < __arraycount(hosts); i++) { + + (void)memset(name, 0, sizeof(name)); + +#ifdef __FreeBSD__ + /* + * Sanity checks to ensure that the wrong invariant isn't being + * tested for per PR # 181127 + */ + ATF_REQUIRE_EQ(sizeof(hosts[i]), MAXHOSTNAMELEN); + ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN); + + ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i]) - 1) == 0); + ATF_REQUIRE(gethostname(name, sizeof(name) - 1) == 0); +#else + ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i])) == 0); + ATF_REQUIRE(gethostname(name, sizeof(name)) == 0); +#endif + ATF_REQUIRE(strcmp(hosts[i], name) == 0); + } + + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_CLEANUP(sethostname_basic, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_limit); +ATF_TC_HEAD(sethostname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long host name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(sethostname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(sethostname_limit, tc) +{ +#ifdef __FreeBSD__ + ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN - 1 ) == 0); + ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN) == -1); +#endif + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_perm); +ATF_TC_HEAD(sethostname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the host name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(sethostname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, sethostname(host, sizeof(host)) == -1); +} + +ATF_TC_CLEANUP(sethostname_perm, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(host, 0, sizeof(host)); + + ATF_REQUIRE(gethostname(host, sizeof(host)) == 0); + + ATF_TP_ADD_TC(tp, sethostname_basic); + ATF_TP_ADD_TC(tp, sethostname_limit); + ATF_TP_ADD_TC(tp, sethostname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c new file mode 100644 index 0000000..9c9a3c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c @@ -0,0 +1,505 @@ +/* $NetBSD: t_siginfo.c,v 1.24 2014/11/04 00:20:19 justin Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#ifdef __NetBSD__ +#include <sys/inttypes.h> +#endif +#include <sys/resource.h> +#include <sys/sysctl.h> +#include <sys/time.h> +#include <sys/ucontext.h> +#include <sys/wait.h> + +#include <assert.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <setjmp.h> +#include <float.h> + +#ifdef HAVE_FENV +#include <fenv.h> +#elif defined(_FLOAT_IEEE754) +#include <ieeefp.h> +#endif + +#include "isqemu.h" + +/* for sigbus */ +volatile char *addr; + +/* for sigchild */ +pid_t child; +int code; +int status; + +/* for sigfpe */ +sig_atomic_t fltdiv_signalled = 0; +sig_atomic_t intdiv_signalled = 0; + +static void +sig_debug(int signo, siginfo_t *info, ucontext_t *ctx) +{ + unsigned int i; + + printf("%d %p %p\n", signo, info, ctx); + if (info != NULL) { + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_value.sival_int=%d\n", info->si_value.sival_int); + } + if (ctx != NULL) { + printf("uc_flags 0x%x\n", ctx->uc_flags); + printf("uc_link %p\n", ctx->uc_link); + for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++) + printf("uc_sigmask[%d] 0x%x\n", i, + ctx->uc_sigmask.__bits[i]); + printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp, + (unsigned long)ctx->uc_stack.ss_size, + ctx->uc_stack.ss_flags); +#ifdef __NetBSD__ + for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++) + printf("uc_mcontext.greg[%d] 0x%lx\n", i, + (long)ctx->uc_mcontext.__gregs[i]); +#endif + } +} + +static void +sigalrm_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGALRM); + ATF_REQUIRE_EQ(info->si_code, SI_TIMER); + ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigalarm); + +ATF_TC_HEAD(sigalarm, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGALRM handler"); +} + +ATF_TC_BODY(sigalarm, tc) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigalrm_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + for (;;) { + alarm(1); + sleep(1); + } + atf_tc_fail("SIGALRM handler wasn't called"); +} + +static void +sigchild_action(int signo, siginfo_t *info, void *ptr) +{ + if (info != NULL) { + printf("info=%p\n", info); + printf("ptr=%p\n", ptr); + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_uid=%d\n", info->si_uid); + printf("si_pid=%d\n", info->si_pid); + printf("si_status=%d\n", info->si_status); +#ifdef __NetBSD__ + printf("si_utime=%lu\n", (unsigned long int)info->si_utime); + printf("si_stime=%lu\n", (unsigned long int)info->si_stime); +#endif + } + ATF_REQUIRE_EQ(info->si_code, code); + ATF_REQUIRE_EQ(info->si_signo, SIGCHLD); + ATF_REQUIRE_EQ(info->si_uid, getuid()); + ATF_REQUIRE_EQ(info->si_pid, child); + if (WIFEXITED(info->si_status)) + ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status); + else if (WIFSTOPPED(info->si_status)) + ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status); + else if (WIFSIGNALED(info->si_status)) + ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status); +} + +static void +setchildhandler(void (*action)(int, siginfo_t *, void *)) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = action; + sigemptyset(&sa.sa_mask); + sigaction(SIGCHLD, &sa, NULL); +} + +static void +sigchild_setup(void) +{ + sigset_t set; + struct rlimit rlim; + + (void)getrlimit(RLIMIT_CORE, &rlim); + rlim.rlim_cur = rlim.rlim_max; + (void)setrlimit(RLIMIT_CORE, &rlim); + + setchildhandler(sigchild_action); + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, NULL); +} + +ATF_TC(sigchild_normal); +ATF_TC_HEAD(sigchild_normal, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child exits normally"); +} + +ATF_TC_BODY(sigchild_normal, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = 25; + code = CLD_EXITED; + + switch ((child = fork())) { + case 0: + sleep(1); + exit(status); + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_dump); +ATF_TC_HEAD(sigchild_dump, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child segfaults"); +} + +ATF_TC_BODY(sigchild_dump, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGSEGV; + code = CLD_DUMPED; + + switch ((child = fork())) { + case 0: + sleep(1); + *(volatile long *)0 = 0; + atf_tc_fail("Child did not segfault"); + /* NOTREACHED */ + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_kill); +ATF_TC_HEAD(sigchild_kill, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child is killed"); +} + +ATF_TC_BODY(sigchild_kill, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGPIPE; + code = CLD_KILLED; + + switch ((child = fork())) { + case 0: + sigemptyset(&set); + sigsuspend(&set); + break; + case -1: + atf_tc_fail("fork failed"); + default: + kill(child, SIGPIPE); + sigemptyset(&set); + sigsuspend(&set); + } +} + +static sigjmp_buf sigfpe_flt_env; +static void +sigfpe_flt_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (fltdiv_signalled++ != 0) + atf_tc_fail("FPE handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_flt_env, 1); +} + +ATF_TC(sigfpe_flt); +ATF_TC_HEAD(sigfpe_flt, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for floating div-by-zero"); +} + +ATF_TC_BODY(sigfpe_flt, tc) +{ + struct sigaction sa; + double d = strtod("0", NULL); + + if (isQEMU()) + atf_tc_skip("Test does not run correctly under QEMU"); +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#endif + if (sigsetjmp(sigfpe_flt_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_flt_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%g\n", 1 / d); + } + if (fltdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static sigjmp_buf sigfpe_int_env; +static void +sigfpe_int_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (intdiv_signalled++ != 0) + atf_tc_fail("INTDIV handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV); + atf_tc_expect_pass(); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_int_env, 1); +} + +ATF_TC(sigfpe_int); +ATF_TC_HEAD(sigfpe_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for integer div-by-zero (PR port-i386/43655)"); +} + +ATF_TC_BODY(sigfpe_int, tc) +{ + struct sigaction sa; + long l = strtol("0", NULL, 10); + +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#endif + if (sigsetjmp(sigfpe_int_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_int_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%ld\n", 1 / l); + } + if (intdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static void +sigsegv_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGSEGV); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR); + ATF_REQUIRE_EQ(info->si_addr, (void *)0); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigsegv); +ATF_TC_HEAD(sigsegv, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGSEGV handler"); +} + +ATF_TC_BODY(sigsegv, tc) +{ + struct sigaction sa; + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigsegv_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + + *(volatile long *)0 = 0; + atf_tc_fail("Test did not fault as expected"); +} + +static void +sigbus_action(int signo, siginfo_t *info, void *ptr) +{ + + printf("si_addr = %p\n", info->si_addr); + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGBUS); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN); + +#if defined(__i386__) || defined(__x86_64__) + atf_tc_expect_fail("x86 architecture does not correctly " + "report the address where the unaligned access occured"); +#endif + ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigbus_adraln); +ATF_TC_HEAD(sigbus_adraln, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGBUS handler " + "for invalid address alignment"); +} + +ATF_TC_BODY(sigbus_adraln, tc) +{ + struct sigaction sa; + +#if defined(__alpha__) + int rv, val; + size_t len = sizeof(val); + rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0); + ATF_REQUIRE(rv == 0); + if (val == 0) + atf_tc_skip("SIGBUS signal not enabled for unaligned accesses"); +#endif + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigbus_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGBUS, &sa, NULL); + + /* Enable alignment checks for x86. 0x40000 is PSL_AC. */ +#if defined(__i386__) + __asm__("pushf; orl $0x40000, (%esp); popf"); +#elif defined(__amd64__) + __asm__("pushf; orl $0x40000, (%rsp); popf"); +#endif + + addr = calloc(2, sizeof(int)); + ATF_REQUIRE(addr != NULL); + + if (isQEMU()) + atf_tc_expect_fail("QEMU fails to trap unaligned accesses"); + + /* Force an unaligned access */ + addr++; + printf("now trying to access unaligned address %p\n", addr); + ATF_REQUIRE_EQ(*(volatile int *)addr, 0); + + atf_tc_fail("Test did not fault as expected"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigalarm); + ATF_TP_ADD_TC(tp, sigchild_normal); + ATF_TP_ADD_TC(tp, sigchild_dump); + ATF_TP_ADD_TC(tp, sigchild_kill); + ATF_TP_ADD_TC(tp, sigfpe_flt); + ATF_TP_ADD_TC(tp, sigfpe_int); + ATF_TP_ADD_TC(tp, sigsegv); + ATF_TP_ADD_TC(tp, sigbus_adraln); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sleep.c b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c new file mode 100644 index 0000000..f722ec9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c @@ -0,0 +1,350 @@ +/* $NetBSD: t_sleep.c,v 1.8 2014/07/15 14:56:34 gson Exp $ */ + +/*- + * Copyright (c) 2006 Frank Kardel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <errno.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <sys/cdefs.h> +#include <sys/event.h> +#include <sys/signal.h> + +#include "isqemu.h" + +#define BILLION 1000000000LL /* nano-seconds per second */ +#define MILLION 1000000LL /* nano-seconds per milli-second */ + +#define ALARM 6 /* SIGALRM after this many seconds */ +#define MAXSLEEP 22 /* Maximum delay in seconds */ +#define KEVNT_TIMEOUT 10300 /* measured in milli-seconds */ +#define FUZZ (40 * MILLION) /* scheduling fuzz accepted - 40 ms */ + +#ifdef __FreeBSD__ +#include <sys/time.h> +#include <inttypes.h> +#endif + +/* + * Timer notes + * + * Most tests use FUZZ as their initial delay value, but 'sleep' + * starts at 1sec (since it cannot handle sub-second intervals). + * Subsequent passes double the previous interval, up to MAXSLEEP. + * + * The current values result in 5 passes for the 'sleep' test (at 1, + * 2, 4, 8, and 16 seconds) and 10 passes for the other tests (at + * 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, and 20.48 + * seconds). + * + * The ALARM is only set if the current pass's delay is longer, and + * only if the ALARM has not already been triggered. + * + * The 'kevent' test needs the ALARM to be set on a different pass + * from when the KEVNT_TIMEOUT fires. So set ALARM to fire on the + * penultimate pass, and the KEVNT_TIMEOUT on the final pass. We + * set KEVNT_TIMEOUT just barely long enough to put it into the + * last test pass, and set MAXSLEEP a couple seconds longer than + * necessary, in order to avoid a QEMU bug which nearly doubles + * some timers. + */ + +static volatile int sig; + +int sleeptest(int (*)(struct timespec *, struct timespec *), bool, bool); +int do_nanosleep(struct timespec *, struct timespec *); +int do_select(struct timespec *, struct timespec *); +#ifdef __NetBSD__ +int do_poll(struct timespec *, struct timespec *); +#endif +int do_sleep(struct timespec *, struct timespec *); +int do_kevent(struct timespec *, struct timespec *); +void sigalrm(int); + +void +sigalrm(int s) +{ + + sig++; +} + +int +do_nanosleep(struct timespec *delay, struct timespec *remain) +{ + int ret; + + if (nanosleep(delay, remain) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_select(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (select(0, NULL, NULL, NULL, &tv) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +#ifdef __NetBSD__ +int +do_poll(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (pollts(NULL, 0, delay, NULL) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} +#endif + +int +do_sleep(struct timespec *delay, struct timespec *remain) +{ + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + remain->tv_sec = sleep(delay->tv_sec); + remain->tv_nsec = 0; + + return 0; +} + +int +do_kevent(struct timespec *delay, struct timespec *remain) +{ + struct kevent ktimer; + struct kevent kresult; + int rtc, kq, kerrno; + int tmo; + + ATF_REQUIRE_MSG((kq = kqueue()) != -1, "kqueue: %s", strerror(errno)); + + tmo = KEVNT_TIMEOUT; + + /* + * If we expect the KEVNT_TIMEOUT to fire, and we're running + * under QEMU, make sure the delay is long enough to account + * for the effects of PR kern/43997 ! + */ + if (isQEMU() && + tmo/1000 < delay->tv_sec && tmo/500 > delay->tv_sec) + delay->tv_sec = MAXSLEEP; + + EV_SET(&ktimer, 1, EVFILT_TIMER, EV_ADD, 0, tmo, 0); + + rtc = kevent(kq, &ktimer, 1, &kresult, 1, delay); + kerrno = errno; + + (void)close(kq); + + if (rtc == -1) { + ATF_REQUIRE_MSG(kerrno == EINTR, "kevent: %s", strerror(errno)); + return 0; + } + + if (delay->tv_sec * BILLION + delay->tv_nsec > tmo * MILLION) + ATF_REQUIRE_MSG(rtc > 0, + "kevent: KEVNT_TIMEOUT did not cause EVFILT_TIMER event"); + + return 0; +} + +ATF_TC(nanosleep); +ATF_TC_HEAD(nanosleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test nanosleep(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(nanosleep, tc) +{ + + sleeptest(do_nanosleep, true, false); +} + +ATF_TC(select); +ATF_TC_HEAD(select, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test select(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(select, tc) +{ + + sleeptest(do_select, true, true); +} + +#ifdef __NetBSD__ +ATF_TC(poll); +ATF_TC_HEAD(poll, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test poll(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(poll, tc) +{ + + sleeptest(do_poll, true, true); +} +#endif + +ATF_TC(sleep); +ATF_TC_HEAD(sleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sleep(3) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(sleep, tc) +{ + + sleeptest(do_sleep, false, false); +} + +ATF_TC(kevent); +ATF_TC_HEAD(kevent, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test kevent(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(kevent, tc) +{ + + sleeptest(do_kevent, true, true); +} + +int +sleeptest(int (*test)(struct timespec *, struct timespec *), + bool subsec, bool sim_remain) +{ + struct timespec tsa, tsb, tslp, tremain; + int64_t delta1, delta2, delta3, round; + + sig = 0; + signal(SIGALRM, sigalrm); + + if (subsec) { + round = 1; + delta3 = FUZZ; + } else { + round = 1000000000; + delta3 = round; + } + + tslp.tv_sec = delta3 / 1000000000; + tslp.tv_nsec = delta3 % 1000000000; + + while (tslp.tv_sec <= MAXSLEEP) { + /* + * disturb sleep by signal on purpose + */ + if (tslp.tv_sec > ALARM && sig == 0) + alarm(ALARM); + + clock_gettime(CLOCK_REALTIME, &tsa); + (*test)(&tslp, &tremain); + clock_gettime(CLOCK_REALTIME, &tsb); + + if (sim_remain) { + timespecsub(&tsb, &tsa, &tremain); + timespecsub(&tslp, &tremain, &tremain); + } + + delta1 = (int64_t)tsb.tv_sec - (int64_t)tsa.tv_sec; + delta1 *= BILLION; + delta1 += (int64_t)tsb.tv_nsec - (int64_t)tsa.tv_nsec; + + delta2 = (int64_t)tremain.tv_sec * BILLION; + delta2 += (int64_t)tremain.tv_nsec; + + delta3 = (int64_t)tslp.tv_sec * BILLION; + delta3 += (int64_t)tslp.tv_nsec - delta1 - delta2; + + delta3 /= round; + delta3 *= round; + + if (delta3 > FUZZ || delta3 < -FUZZ) { + if (!sim_remain) + atf_tc_expect_fail("Long reschedule latency " + "due to PR kern/43997"); + + atf_tc_fail("Reschedule latency %"PRId64" exceeds " + "allowable fuzz %lld", delta3, FUZZ); + } + delta3 = (int64_t)tslp.tv_sec * 2 * BILLION; + delta3 += (int64_t)tslp.tv_nsec * 2; + + delta3 /= round; + delta3 *= round; + if (delta3 < FUZZ) + break; + tslp.tv_sec = delta3 / BILLION; + tslp.tv_nsec = delta3 % BILLION; + } + ATF_REQUIRE_MSG(sig == 1, "Alarm did not fire!"); + + atf_tc_pass(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, nanosleep); + ATF_TP_ADD_TC(tp, select); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, poll); +#endif + ATF_TP_ADD_TC(tp, sleep); + ATF_TP_ADD_TC(tp, kevent); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_syslog.c b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c new file mode 100644 index 0000000..c9417c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c @@ -0,0 +1,56 @@ +/* $NetBSD: t_syslog.c,v 1.2 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> + +#include <atf-c.h> +#include <syslog.h> + +ATF_TC(syslog_pthread); +ATF_TC_HEAD(syslog_pthread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test that syslog(3) " + "works when linked to pthread(3) (PR lib/44248)"); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(syslog_pthread, tc) +{ + syslog(LOG_DEBUG, "from tests/lib/libc/gen/t_syslog"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, syslog_pthread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_time.c b/contrib/netbsd-tests/lib/libc/gen/t_time.c new file mode 100644 index 0000000..790f3ca --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $"); + +#ifdef __FreeBSD__ +#include <sys/time.h> +#endif +#include <atf-c.h> +#include <errno.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +ATF_TC(time_copy); +ATF_TC_HEAD(time_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test the return values of time(3)"); +} + +ATF_TC_BODY(time_copy, tc) +{ + time_t t1, t2 = 0; + + t1 = time(&t2); + + if (t1 != t2) + atf_tc_fail("incorrect return values from time(3)"); +} + +ATF_TC(time_mono); +ATF_TC_HEAD(time_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test monotonicity of time(3)"); +} + +ATF_TC_BODY(time_mono, tc) +{ + const size_t maxiter = 10; + time_t t1, t2; + size_t i; + + for (i = 0; i < maxiter; i++) { + + t1 = time(NULL); + (void)sleep(1); + t2 = time(NULL); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t1, (int64_t)t2); + + if (t1 >= t2) + atf_tc_fail("time(3) is not monotonic"); + } +} + +ATF_TC(time_timeofday); +ATF_TC_HEAD(time_timeofday, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test time(3) vs. gettimeofday(2)"); +} + +ATF_TC_BODY(time_timeofday, tc) +{ + struct timeval tv = { 0, 0 }; + time_t t; + + t = time(NULL); + ATF_REQUIRE(gettimeofday(&tv, NULL) == 0); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t, (int64_t)tv.tv_sec); + + if (t != tv.tv_sec) + atf_tc_fail("time(3) and gettimeofday(2) differ"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, time_copy); + ATF_TP_ADD_TC(tp, time_mono); + ATF_TP_ADD_TC(tp, time_timeofday); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c new file mode 100644 index 0000000..bb9d264 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c @@ -0,0 +1,191 @@ +/* $NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static long ttymax = 0; + +ATF_TC(ttyname_err); +ATF_TC_HEAD(ttyname_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname(3)"); +} + +ATF_TC_BODY(ttyname_err, tc) +{ + int fd; + + fd = open("XXX", O_RDONLY); + + if (fd < 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == EBADF); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == EBADF); + } + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == ENOTTY); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == ENOTTY); + } +} + +ATF_TC(ttyname_r_err); +ATF_TC_HEAD(ttyname_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname_r(3)"); +} + +ATF_TC_BODY(ttyname_r_err, tc) +{ + char sbuf[0]; + char *buf; + int fd; + int rv; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + if (isatty(STDIN_FILENO) != 0) { + + rv = ttyname_r(STDIN_FILENO, sbuf, sizeof(sbuf)); + ATF_REQUIRE(rv == ERANGE); + } + +#ifdef __FreeBSD__ + atf_tc_expect_fail("FreeBSD returns ENOTTY instead of EBADF; see bin/191936"); +#endif + rv = ttyname_r(-1, buf, ttymax); + ATF_REQUIRE(rv == EBADF); + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + rv = ttyname_r(fd, buf, ttymax); + ATF_REQUIRE(rv == ENOTTY); + ATF_REQUIRE(close(fd) == 0); + } + + free(buf); +} + +ATF_TC(ttyname_r_stdin); +ATF_TC_HEAD(ttyname_r_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname_r(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_r_stdin, tc) +{ + const char *str; + char *buf; + int rv; + + if (isatty(STDIN_FILENO) == 0) + return; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + str = ttyname(STDIN_FILENO); + rv = ttyname_r(STDIN_FILENO, buf, ttymax); + + ATF_REQUIRE(rv == 0); + ATF_REQUIRE(str != NULL); + + if (strcmp(str, buf) != 0) + atf_tc_fail("ttyname(3) and ttyname_r(3) conflict"); + + free(buf); +} + +ATF_TC(ttyname_stdin); +ATF_TC_HEAD(ttyname_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_stdin, tc) +{ + + if (isatty(STDIN_FILENO) != 0) + ATF_REQUIRE(ttyname(STDIN_FILENO) != NULL); + + (void)close(STDIN_FILENO); + + ATF_REQUIRE(isatty(STDIN_FILENO) != 1); + ATF_REQUIRE(ttyname(STDIN_FILENO) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ttymax = sysconf(_SC_TTY_NAME_MAX); + ATF_REQUIRE(ttymax >= 0); + + ATF_TP_ADD_TC(tp, ttyname_err); + ATF_TP_ADD_TC(tp, ttyname_r_err); + ATF_TP_ADD_TC(tp, ttyname_r_stdin); + ATF_TP_ADD_TC(tp, ttyname_stdin); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_vis.c b/contrib/netbsd-tests/lib/libc/gen/t_vis.c new file mode 100644 index 0000000..525bafa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_vis.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_vis.c,v 1.7 2014/09/08 19:01:03 christos Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <string.h> +#include <stdlib.h> +#include <err.h> +#include <vis.h> + +static int styles[] = { + VIS_OCTAL, + VIS_CSTYLE, + VIS_SP, + VIS_TAB, + VIS_NL, + VIS_WHITE, + VIS_SAFE, +#if 0 /* Not reversible */ + VIS_NOSLASH, +#endif + VIS_HTTP1808, + VIS_MIMESTYLE, +#if 0 /* Not supported by vis(3) */ + VIS_HTTP1866, +#endif +}; + +#define SIZE 256 + +ATF_TC(strvis_basic); +ATF_TC_HEAD(strvis_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test strvis(3)"); +} + +ATF_TC_BODY(strvis_basic, tc) +{ + char *srcbuf, *dstbuf, *visbuf; + unsigned int i, j; + + ATF_REQUIRE((dstbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((srcbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((visbuf = malloc(SIZE * 4 + 1)) != NULL); + + for (i = 0; i < SIZE; i++) + srcbuf[i] = (char)i; + + for (i = 0; i < __arraycount(styles); i++) { + ATF_REQUIRE(strsvisx(visbuf, srcbuf, SIZE, styles[i], "") > 0); + memset(dstbuf, 0, SIZE); + ATF_REQUIRE(strunvisx(dstbuf, visbuf, + styles[i] & (VIS_HTTP1808|VIS_MIMESTYLE)) > 0); + for (j = 0; j < SIZE; j++) + if (dstbuf[j] != (char)j) + atf_tc_fail_nonfatal("Failed for style %x, " + "char %d [%d]", styles[i], j, dstbuf[j]); + } + free(dstbuf); + free(srcbuf); + free(visbuf); +} + +ATF_TC(strvis_null); +ATF_TC_HEAD(strvis_null, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) NULL"); +} + +ATF_TC_BODY(strvis_null, tc) +{ + char dst[] = "fail"; + strvis(dst, NULL, VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strvis_empty); +ATF_TC_HEAD(strvis_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) empty"); +} + +ATF_TC_BODY(strvis_empty, tc) +{ + char dst[] = "fail"; + strvis(dst, "", VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strunvis_hex); +ATF_TC_HEAD(strunvis_hex, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strunvis(3) \\xXX"); +} + +ATF_TC_BODY(strunvis_hex, tc) +{ + static const struct { + const char *e; + const char *d; + int error; + } ed[] = { + { "\\xff", "\xff", 1 }, + { "\\x1", "\x1", 1 }, + { "\\x1\\x02", "\x1\x2", 2 }, + { "\\x1x", "\x1x", 2 }, + { "\\xx", "", -1 }, + }; + char uv[10]; + + for (size_t i = 0; i < __arraycount(ed); i++) { + ATF_REQUIRE(strunvis(uv, ed[i].e) == ed[i].error); + if (ed[i].error > 0) + ATF_REQUIRE(memcmp(ed[i].d, uv, ed[i].error) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strvis_basic); + ATF_TP_ADD_TC(tp, strvis_null); + ATF_TP_ADD_TC(tp, strvis_empty); + ATF_TP_ADD_TC(tp, strunvis_hex); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-in b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in new file mode 100644 index 0000000..763e4f9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in @@ -0,0 +1,7 @@ + +a +abc +message digest +abcdefghijklmnopqrstuvwxyz +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-out b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out new file mode 100644 index 0000000..bb86bb6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out @@ -0,0 +1,7 @@ +d41d8cd98f00b204e9800998ecf8427e +0cc175b9c0f1b6a831c399e269772661 +900150983cd24fb0d6963f7d28e17f72 +f96b697d7cb7938d525a2f31aaf161d0 +c3fcd3d76192e4007dfb496cca67e13b +d174ab98d277d9f5a5611c2c9f419d9f +57edf4a22be3c955ac49da2e2107b67a diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in new file mode 100644 index 0000000..632d133 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in @@ -0,0 +1,2 @@ +abc +abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out new file mode 100644 index 0000000..c23a058 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out @@ -0,0 +1,2 @@ +a9993e364706816aba3e25717850c26c9cd0d89d +84983e441c3bd26ebaae4aa1f95129e5e54670f1 diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out new file mode 100644 index 0000000..a483a0e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out @@ -0,0 +1 @@ +34aa973cd4c4daa4f61eeb2bdbad27316534016f diff --git a/contrib/netbsd-tests/lib/libc/hash/h_hash.c b/contrib/netbsd-tests/lib/libc/hash/h_hash.c new file mode 100644 index 0000000..6e20a48 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/h_hash.c @@ -0,0 +1,187 @@ +/* $NetBSD: h_hash.c,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Combined MD5/SHA1 time and regression test. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <md5.h> +#ifdef __NetBSD__ +#include <sha1.h> +#endif + +#ifdef __FreeBSD__ +#include <sha.h> +#endif + +int mflag, rflag, sflag, tflag; + +static void +usage(void) +{ + (void)fprintf(stderr, + "Usage:\t%s -r[ms] < test-file\n" + "\t%s -t[ms]\n", + getprogname(), getprogname()); + exit(1); + /* NOTREACHED */ +} + +static void +hexdump (unsigned char *buf, int len) +{ + int i; + for (i=0; i<len; i++) { + printf("%02x", buf[i]); + } + printf("\n"); +} + + +static void +timetest(void) +{ + printf("sorry, not yet\n"); +} + +#define CHOMP(buf, len, last) \ + if ((len > 0) && \ + (buf[len-1] == '\n')) { \ + buf[len-1] = '\0'; \ + len--; \ + last = 1; \ + } + +static void +regress(void) +{ + unsigned char buf[1024]; + unsigned char out[20]; + int len, outlen, last; + + while (fgets((char *)buf, sizeof(buf), stdin) != NULL) { + last = 0; + + len = strlen((char *)buf); + CHOMP(buf, len, last); + if (mflag) { + MD5_CTX ctx; + + MD5Init(&ctx); + MD5Update(&ctx, buf, len); + while (!last && + fgets((char *)buf, sizeof(buf), stdin) != NULL) { + len = strlen((char *)buf); + CHOMP(buf, len, last); + MD5Update(&ctx, buf, len); + } + MD5Final(out, &ctx); + outlen = 16; + } else { +#ifdef __FreeBSD__ + SHA_CTX ctx; + + SHA1_Init(&ctx); + SHA1_Update(&ctx, buf, len); +#else + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, buf, len); +#endif + while (!last && + fgets((char *)buf, sizeof(buf), stdin) != NULL) { + len = strlen((char *)buf); + CHOMP(buf, len, last); +#ifdef __FreeBSD__ + SHA1_Update(&ctx, buf, len); +#else + SHA1Update(&ctx, buf, len); +#endif + } +#ifdef __FreeBSD__ + SHA1_Final(out, &ctx); +#else + SHA1Final(out, &ctx); +#endif + outlen = 20; + } + hexdump(out, outlen); + } +} + +int +main(int argc, char **argv) +{ + int ch; + + while ((ch = getopt(argc, argv, "mrst")) != -1) + switch (ch) { + case 'm': + mflag = 1; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = 1; + break; + case 't': + tflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); + + if (!(mflag || sflag)) + mflag = 1; + + if ((mflag ^ sflag) != 1) + usage(); + + if ((tflag ^ rflag) != 1) + usage(); + + if (tflag) + timetest(); + + if (rflag) + regress(); + + exit(0); + +} diff --git a/contrib/netbsd-tests/lib/libc/hash/t_hash.sh b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh new file mode 100755 index 0000000..719f19d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_hash.sh,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +prog() +{ + echo "$(atf_get_srcdir)/h_hash" +} + +datadir() +{ + echo "$(atf_get_srcdir)/data" +} + +atf_test_case md5 +md5_head() +{ + atf_set "descr" "Checks MD5 functions" +} +md5_body() +{ + atf_check -o file:"$(datadir)/md5test-out" -x \ + "$(prog) -r < $(datadir)/md5test-in" +} + +atf_test_case sha1 +sha1_head() +{ + atf_set "descr" "Checks SHA1 functions" +} +sha1_body() +{ + atf_check -o file:"$(datadir)/sha1test-out" -x \ + "$(prog) -rs < $(datadir)/sha1test-in" + + atf_check -o file:"$(datadir)/sha1test2-out" -x \ + "jot -s '' -b 'a' -n 1000000 | $(prog) -rs" +} + +atf_init_test_cases() +{ + atf_add_test_case md5 + atf_add_test_case sha1 +} diff --git a/contrib/netbsd-tests/lib/libc/hash/t_sha2.c b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c new file mode 100644 index 0000000..ce2c80d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c @@ -0,0 +1,257 @@ +/* $NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $"); + +#include <atf-c.h> +#include <sys/types.h> +#ifdef __NetBSD__ +#include <sha2.h> +#endif +#include <string.h> + +#ifdef __FreeBSD__ +#include <openssl/sha.h> +typedef SHA512_CTX SHA384_CTX; +/* From /usr/src/crypto/openssh/openbsd-compat/sha2.h */ +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) +#endif + +ATF_TC(t_sha256); +ATF_TC(t_sha384); +ATF_TC(t_sha512); + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_sha256); + ATF_TP_ADD_TC(tp, t_sha384); + ATF_TP_ADD_TC(tp, t_sha512); + + return atf_no_error(); +} + +struct testvector { + const char *vector; + const char *hash; +}; + +static const struct testvector test256[] = { + { "hello, world", "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b" }, + { "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, + { "a", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" }, + { "ab", "fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603" }, + { "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" }, + { "abcd", "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589" }, + { "abcde", "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c" }, + { "abcdef", "bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721" }, + { "abcdefg", "7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a" }, + { "abcdefgh", "9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab" }, + { "abcdefghi", "19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f" }, + { "abcdefghij", "72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0" }, + { "abcdefghijk", "ca2f2069ea0c6e4658222e06f8dd639659cbb5e67cbbba6734bc334a3799bc68" }, + { "abcdefghijkl", "d682ed4ca4d989c134ec94f1551e1ec580dd6d5a6ecde9f3d35e6e4a717fbde4" }, + { "abcdefghijklm", "ff10304f1af23606ede1e2d8abcdc94c229047a61458d809d8bbd53ede1f6598" }, + { "abcdefghijklmn", "0653c7e992d7aad40cb2635738b870e4c154afb346340d02c797d490dd52d5f9" }, + { "abcdefghijklmno", "41c7760c50efde99bf574ed8fffc7a6dd3405d546d3da929b214c8945acf8a97" }, + { "abcdefghijklmnop", "f39dac6cbaba535e2c207cd0cd8f154974223c848f727f98b3564cea569b41cf" }, + { "abcdefghijklmnopq", "918a954ac4dfb54ac39f068d9868227f69ab39bc362e2c9b0083bf6a109d6ad7" }, + { "abcdefghijklmnopqr", "2d1222692afaf56e95a8ab00879ed023a00db3e26fa14236e542748579285efa" }, + { "abcdefghijklmnopqrs", "e250f886728b77ba63722c7e65fc73e203101a84281b32332fd67cc6a1ae3e22" }, + { "abcdefghijklmnopqrst", "dd65eea0329dcb94b17187af9dff28c31a1d78026737a16af75979a1fa4618e5" }, + { "abcdefghijklmnopqrstu", "25f62a5a3d414ec6e20907df7f367f2b72625aade552db64c07933f6044fc49a" }, + { "abcdefghijklmnopqrstuv", "f69f9b70d1c9a5442258ca76f8b0a7a45fcb4e31c36141b6357ec591328b0624" }, + { "abcdefghijklmnopqrstuvw", "7f07818e14d08944ce145629ca54332f5cfad148c590efbcb5c377f4d336e5f4" }, + { "abcdefghijklmnopqrstuvwq", "063132d7fbec0acb79b2f228777eec8885e7f09bc1896b3ce5aa1843e83de048" }, +}; + +static const struct testvector test384[] = { + { "hello, world", "1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e" }, + { "", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" }, + { "a", "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31" }, + { "ab", "c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd" }, + { "abc", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" }, + { "abcd", "1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b" }, + { "abcde", "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0" }, + { "abcdef", "c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5" }, + { "abcdefg", "9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22" }, + { "abcdefgh", "9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806" }, + { "abcdefghi", "ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df" }, + { "abcdefghij", "a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c" }, + { "abcdefghijk", "2440d0e751fe5b8b1aba067e20be00b9deecc5e218b0b4b37202de824bcd04294d67c8d0b73e393afa844fa9ca25fa51" }, + { "abcdefghijkl", "103ca96c06a1ce798f08f8eff0dfb0ccdb567d48b285b23d0cd773454667a3c2fa5f1b58d9cdf2329bd9979730bfaaff" }, + { "abcdefghijklm", "89a7179df195462f047393c36e4843183eb38404bdfbacfd0b0f9c2556632a2799f19c3ecf48bdb7c9bdf95d3f6c3704" }, + { "abcdefghijklmn", "3bc463b0a5614d39fd207cbfd108534bce68d5438235c6c577b34b70fe219954adceaf8808d1fad4a44fc9c420ea8ff1" }, + { "abcdefghijklmno", "5149860ee76dd6666308189e60090d615e36ce0c0ef753a610cca0524a022900489d70167a47cc74c4dd9f9f340066af" }, + { "abcdefghijklmnop", "96d3c1b54b1938600abe5b57232e185df1c5856f74656b8f9837c5317cf5b22ac38226fafc8c946b9d20aca1b0c53a98" }, + { "abcdefghijklmnopq", "dae0d8c29d8f1137df3afb8f502dc474d3bbb56de0c10fc219547826f23f38f37ec29e4ed203908e6e7955c83a138129" }, + { "abcdefghijklmnopqr", "5cfa62716d985d3b1efab0ed3460e7b7f6af9439ae8ee5c58b20e68607eeec3e8c6df8481f5f36e726eaa56512acea6e" }, + { "abcdefghijklmnopqrs", "c5d404fc93b0e59ecb5f40446da201876faf18a0af46e577ae2f7a4fe56dc4c419afff7edec90ff3de160d0c5e7a5ec1" }, + { "abcdefghijklmnopqrst", "bc1511cd8b813544cb60b13d1ceb63e81f46aa3ca114a23fc5c3aba54f9965cdf9afa68e2dc2a680934e429dff5aa7f2" }, + { "abcdefghijklmnopqrstu", "8f18622d37e0aceabba191e3836b30e8970aca202ce6e811f586ec5f950edb7bf799cc88a18468a3effb063397242d95" }, + { "abcdefghijklmnopqrstuv", "c8a4f46e609626543ce6c1362721fcbe95c8e7405aaee61da4f2da1740f0351172c98a66530f8607bf8609e387ff8456" }, + { "abcdefghijklmnopqrstuvw", "2daff33b3bd67de61550070696b431d54b1397b40d053912b07a94260812185907726e3efbe9ae9fc078659cd2ce36db" }, + { "abcdefghijklmnopqrstuvwq", "87dc70a2eaa0dd0b687f91f26383866161026e41bb310a9e32b7a17c99284db85b9743476a30caeedf3fbb3c8072bc5e" }, +}; + +static const struct testvector test512[] = { + { "hello, world", "8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9" }, + { "", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" }, + { "a", "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75" }, + { "ab", "2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d" }, + { "abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" }, + { "abcd", "d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f" }, + { "abcde", "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1" }, + { "abcdef", "e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7" }, + { "abcdefg", "d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c" }, + { "abcdefgh", "a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce" }, + { "abcdefghi", "f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe" }, + { "abcdefghij", "ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745" }, + { "abcdefghijk", "2798fd001ee8800e3da09ee99ae9600de2d0ccf464ab782c92fcc06ce3847cef0743365f1d49c2c8b4426db1635433f937d508672a9d0cb673b84f368eca1b23" }, + { "abcdefghijkl", "17807c728ee3ba35e7cf7af823116d26e41e5d4d6c2ff1f3720d3d96aacb6f69de642e63d5b73fc396c12be38b2bd5d884257c32c8f6d0854ae6b540f86dda2e" }, + { "abcdefghijklm", "e11a66f7b9a2acda5663e9434377137d73ea560a32782230412642a463c8558123bfb7c0dbf17851e9aa58cc9587c3b4f5e3f7f38dcb6f890702e5bed4d5b54a" }, + { "abcdefghijklmn", "8334134081070bf7fcc8bf1c242d24bb3182a5119e5fb19d8bbf6b9d0cdb7fed5336e83415fce93094c0e55123cf69e14d7ae41b22289232699824e31125b6d9" }, + { "abcdefghijklmno", "db723f341a042d8de1aa813efd5e02fc1745ccbe259486257514804e2ec4bcebb2a46f1e4ad442154943f9e97e1bc47c3ae0eddab7de0c01a9c51f15342a5b19" }, + { "abcdefghijklmnop", "d0cadd6834fa0c157b36cca30ee8b0b1435d841aa5b5ac850c11ae80a1440f51743e98fb1f1e7376c70f2f65404f088c28bcb4a511df2e64111f8f7424364b60" }, + { "abcdefghijklmnopq", "6196942a8495b721f82bbc385c74c1f10eeadf35db8adc9cf1a05ddeed19351228279644cd5d686ee48a31631ebb64747a2b68b733dd6015e3d27750878fa875" }, + { "abcdefghijklmnopqr", "fb3bd1fc157ea6f7a6728986a59b271b766fb723f6b7cf2b4194437435f2c497f33b6a56ae7eb3830fa9e04d5ebb4cb5e3f4d4bd812c498bdf0167e125de3fba" }, + { "abcdefghijklmnopqrs", "836f9ecf2aa02f522a94f1370af45a9fd538ac3c70e3b709d614b2f8981881d6b0070fc6387b74ee371fc2549309f82926e78084b401deb61a106c399089bee8" }, + { "abcdefghijklmnopqrst", "8cd9c137651425fb32d193d99b281735ec68eb5fd296f16459d1b33eac7badcfce0dca22eadaa5f209fa4ac3bbecd41342bac8b8a5dc3626e7f22cdc96e17cb4" }, + { "abcdefghijklmnopqrstu", "7079853a3e36241a8d83639f168ef38e883d7f72851a84ef3ed4d91c6a3896cf542b8b4518c2816fb19d4692a4b9aae65cb857e3642ce0a3936e20363bcbd4ca" }, + { "abcdefghijklmnopqrstuv", "a4e8a90b7058fb078e6cdcfd0c6a33c366437eb9084eac657830356804c9f9b53f121496d8e972d8707a4cf02615e6f58ed1a770c28ac79ffd845401fe18a928" }, + { "abcdefghijklmnopqrstuvw", "d91b1fd7c7785975493826719f333d090b214ff42351c84d8f8b2538509a28d2d59a36d0ac798d99d3908083b072a4be606ae391def5daa74156350fec71dd24" }, + { "abcdefghijklmnopqrstuvwq", "404eb5652173323320cac6bf8d9714aef0747693a8ab4570700c6262268d367f30e31c44fa66860568ff058fe39c9aa8dac76bc78566c691a884cb9052c4aa0a" }, +}; + +static void +digest2string(const uint8_t *digest, char *string, size_t len) +{ + while (len--) { + if (*digest / 16 < 10) + *string++ = '0' + *digest / 16; + else + *string++ = 'a' + *digest / 16 - 10; + if (*digest % 16 < 10) + *string++ = '0' + *digest % 16; + else + *string++ = 'a' + *digest % 16 - 10; + ++digest; + } + *string = '\0'; +} + +ATF_TC_HEAD(t_sha256, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA256 functions for consistent results"); +} + +ATF_TC_BODY(t_sha256, tc) +{ + size_t i, j, len; + SHA256_CTX ctx; + unsigned char buf[256]; + unsigned char digest[8 + SHA256_DIGEST_LENGTH]; + char output[SHA256_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test256) / sizeof(test256[0]); ++i) { + len = strlen(test256[i].vector); + for (j = 0; j < 8; ++j) { + SHA256_Init(&ctx); + memcpy(buf + j, test256[i].vector, len); + SHA256_Update(&ctx, buf + j, len); + SHA256_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA256_DIGEST_LENGTH); + ATF_CHECK_STREQ(test256[i].hash, output); + } + } +} + +ATF_TC_HEAD(t_sha384, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA384 functions for consistent results"); +} + +ATF_TC_BODY(t_sha384, tc) +{ + size_t i, j, len; + SHA384_CTX ctx; + unsigned char buf[384]; + unsigned char digest[8 + SHA384_DIGEST_LENGTH]; + char output[SHA384_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test384) / sizeof(test384[0]); ++i) { + len = strlen(test384[i].vector); + for (j = 0; j < 8; ++j) { + SHA384_Init(&ctx); + memcpy(buf + j, test384[i].vector, len); + SHA384_Update(&ctx, buf + j, len); + SHA384_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA384_DIGEST_LENGTH); + ATF_CHECK_STREQ(test384[i].hash, output); + } + } +} + +ATF_TC_HEAD(t_sha512, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA512 functions for consistent results"); +} + +ATF_TC_BODY(t_sha512, tc) +{ + size_t i, j, len; + SHA512_CTX ctx; + unsigned char buf[512]; + unsigned char digest[8 + SHA512_DIGEST_LENGTH]; + char output[SHA512_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test512) / sizeof(test512[0]); ++i) { + len = strlen(test512[i].vector); + for (j = 0; j < 8; ++j) { + SHA512_Init(&ctx); + memcpy(buf + j, test512[i].vector, len); + SHA512_Update(&ctx, buf + j, len); + SHA512_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA512_DIGEST_LENGTH); + ATF_CHECK_STREQ(test512[i].hash, output); + } + } +} diff --git a/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c new file mode 100644 index 0000000..a6a6c62 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Brian Ginsbach. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $"); + +#include <arpa/inet.h> + +#include <atf-c.h> +#include <stdio.h> +#include <string.h> + +#define H_REQUIRE(input, expected) \ + ATF_REQUIRE_EQ_MSG(inet_network(input), (in_addr_t) expected, \ + "inet_network(%s) returned: 0x%08X, expected: %s", #input, \ + inet_network(input), #expected) + +ATF_TC(inet_addr_basic); +ATF_TC_HEAD(inet_addr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks inet_addr(3)"); +} + +ATF_TC_BODY(inet_addr_basic, tc) +{ + static const char *addrs[] = { + "127.0.0.1", "99.99.99.99", "0.0.0.0", "255.255.255.255" }; + + struct in_addr ia; + const char *ian; + in_addr_t addr; + size_t i; + + for (i = 0; i < __arraycount(addrs); i++) { + + (void)fprintf(stderr, "checking %s\n", addrs[i]);; + + addr = inet_addr(addrs[i]); + ia.s_addr = addr; + ian = inet_ntoa(ia); + + ATF_REQUIRE(ian != NULL); + ATF_CHECK(strcmp(ian, addrs[i]) == 0); + } +} + +ATF_TC(inet_addr_err); +ATF_TC_HEAD(inet_addr_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Invalid addresses with inet_addr(3)"); +} + +ATF_TC_BODY(inet_addr_err, tc) +{ + static const char *addrs[] = { + ". . . .", "1.2.3.", "0.0.0.256", "255.255.255.256", + "................................................", + "a.b.c.d", "0x0.0x1.0x2.0x3", "-1.-1.-1.-1", "", " "}; + + struct in_addr ia; + const char *ian; + in_addr_t addr; + size_t i; + + for (i = 0; i < __arraycount(addrs); i++) { + + (void)fprintf(stderr, "checking %s\n", addrs[i]);; + + addr = inet_addr(addrs[i]); + ia.s_addr = addr; + ian = inet_ntoa(ia); + + ATF_REQUIRE(ian != NULL); + ATF_CHECK(strcmp(ian, addrs[i]) != 0); + } +} + +ATF_TC(inet_network_basic); +ATF_TC_HEAD(inet_network_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks inet_network(3)"); +} + +ATF_TC_BODY(inet_network_basic, tc) +{ + + H_REQUIRE("0x12", 0x00000012); + H_REQUIRE("127.1", 0x00007f01); + H_REQUIRE("127.1.2.3", 0x7f010203); + H_REQUIRE("0X12", 0x00000012); + H_REQUIRE("0", 0x0); + H_REQUIRE("01.02.07.077", 0x0102073f); + H_REQUIRE("0x1.23.045.0", 0x01172500); + H_REQUIRE("0x12.0x34", 0x00001234); + + /* This is valid (because of the trailing space after the digit). */ + H_REQUIRE("1 bar", 0x00000001); +} + +ATF_TC(inet_network_err); +ATF_TC_HEAD(inet_network_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Invalid addresses w/ inet_network(3)"); +} + +ATF_TC_BODY(inet_network_err, tc) +{ + /* Malformed requests. */ + H_REQUIRE("4.2.3.1.", 0xffffffff); + H_REQUIRE("0x123456", 0xffffffff); + H_REQUIRE("0x12.0x345", 0xffffffff); + H_REQUIRE("1.2.3.4.5", 0xffffffff); + H_REQUIRE("1..3.4", 0xffffffff); + H_REQUIRE(".", 0xffffffff); + H_REQUIRE("1.", 0xffffffff); + H_REQUIRE(".1", 0xffffffff); +#if defined(__FreeBSD__) || defined(__APPLE__) + H_REQUIRE("0x", 0x0); +#else + H_REQUIRE("0x", 0xffffffff); +#endif + H_REQUIRE("", 0xffffffff); + H_REQUIRE(" ", 0xffffffff); + H_REQUIRE("bar", 0xffffffff); + H_REQUIRE("1.2bar", 0xffffffff); + H_REQUIRE("1.", 0xffffffff); + H_REQUIRE("\xc3\x8a\xc3\x83\xc3\x95\xc3\x8b\xc3\x85\xc3\x8e", + 0xffffffff); + H_REQUIRE("255.255.255.255", 0xffffffff); + H_REQUIRE("x", 0xffffffff); + H_REQUIRE("078", 0xffffffff); + H_REQUIRE("127.0xfff", 0xffffffff); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, inet_addr_basic); + ATF_TP_ADD_TC(tp, inet_addr_err); + ATF_TP_ADD_TC(tp, inet_network_basic); + ATF_TP_ADD_TC(tp, inet_network_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_io.c b/contrib/netbsd-tests/lib/libc/locale/t_io.c new file mode 100644 index 0000000..86029e9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_io.c @@ -0,0 +1,193 @@ +/* $NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $"); + +#include <sys/param.h> +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#include <atf-c.h> + + +ATF_TC(bad_big5_wprintf); +ATF_TC_HEAD(bad_big5_wprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar wprintf"); +} + +ATF_TC_BODY(bad_big5_wprintf, tc) +{ +#ifdef __FreeBSD__ + atf_tc_skip("does not fail as expected (may be implementation " + "specific issue with the test)"); +#endif + + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf10, 0 }; + setlocale(LC_CTYPE, "zh_TW.Big5"); + + ATF_REQUIRE_ERRNO(EILSEQ, wprintf(L"%ls\n", ibuf) < 0); + ATF_REQUIRE(ferror(stdout)); +} + +ATF_TC(bad_big5_swprintf); +ATF_TC_HEAD(bad_big5_swprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar swprintf"); +} + +ATF_TC_BODY(bad_big5_swprintf, tc) +{ +#ifdef __FreeBSD__ + atf_tc_skip("does not fail as expected (may be implementation " + "specific issue with the test)"); +#endif + + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf10, 0 }; + wchar_t obuf[20]; + setlocale(LC_CTYPE, "zh_TW.Big5"); + + ATF_REQUIRE_ERRNO(EILSEQ, + swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf) < 0); +} + +ATF_TC(good_big5_wprintf); +ATF_TC_HEAD(good_big5_wprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar wprintf"); +} + +ATF_TC_BODY(good_big5_wprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf40, 0 }; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_EQ(wprintf(L"%ls\n", ibuf), 2); +} + +ATF_TC(good_big5_swprintf); +ATF_TC_HEAD(good_big5_swprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar swprintf"); +} + +ATF_TC_BODY(good_big5_swprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf40, 0 }; + wchar_t obuf[20]; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_EQ(swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf), 2); +} + +struct ibuf { + off_t off; + size_t buflen; + const char *buf; +}; + +static int +readfn(void *vp, char *buf, int len) +{ + struct ibuf *ib = vp; + size_t todo = MIN((size_t)len, ib->buflen - ib->off); + + memcpy(buf, ib->buf + ib->off, todo); + ib->off += todo; + return todo; +} + +ATF_TC(good_big5_getwc); +ATF_TC_HEAD(good_big5_getwc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar getwc"); +} + +ATF_TC_BODY(good_big5_getwc, tc) +{ + const char buf[] = { 0xcf, 0x40 }; + struct ibuf ib = { + .buf = buf, + .buflen = sizeof(buf), + }; + FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL); + + ATF_REQUIRE(fp != NULL); + setlocale(LC_CTYPE, "zh_TW.Big5"); + /* XXX implementation detail knowledge (wchar_t encoding) */ + ATF_REQUIRE_EQ(getwc(fp), 0xcf40); + fclose(fp); +} + +ATF_TC(bad_big5_getwc); +ATF_TC_HEAD(bad_big5_getwc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar getwc"); +} + +ATF_TC_BODY(bad_big5_getwc, tc) +{ + const char buf[] = { 0xcf, 0x20 }; + struct ibuf ib = { + .buf = buf, + .buflen = sizeof(buf), + }; + FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL); + + ATF_REQUIRE(fp != NULL); + setlocale(LC_CTYPE, "zh_TW.Big5"); +#ifdef __FreeBSD__ + atf_tc_expect_fail("does not return WEOF as expected"); +#endif + ATF_REQUIRE_EQ(getwc(fp), WEOF); + fclose(fp); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, bad_big5_wprintf); + ATF_TP_ADD_TC(tp, bad_big5_swprintf); + ATF_TP_ADD_TC(tp, good_big5_wprintf); + ATF_TP_ADD_TC(tp, good_big5_swprintf); + ATF_TP_ADD_TC(tp, good_big5_getwc); + ATF_TP_ADD_TC(tp, bad_big5_getwc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c new file mode 100644 index 0000000..8b3876f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c @@ -0,0 +1,277 @@ +/* $NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by YAMAMOTO Takashi + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $"); + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vis.h> +#include <wchar.h> + +#include <atf-c.h> + +#define SIZE 256 + +static struct test { + const char *locale; + const char *data; + const wchar_t wchars[64]; + const wchar_t widths[64]; + size_t length; +} tests[] = { +{ + "C", + "ABCD01234_\\", + { 0x41, 0x42, 0x43, 0x44, 0x30, 0x31, 0x32, 0x33, 0x34, 0x5F, 0x5C }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + 11 +}, { + "en_US.UTF-8", + "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200" + "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374" + "\204\200\200\200\200\375\277\277\277\277\277]", + { 0x5b, 0x01, 0x7f, 0x5d, 0x5b, 0x80, 0x7ff, 0x5d, 0x5b, 0x800, 0xffff, + 0x5d, 0x5b, 0x10000, 0x1fffff, 0x5d, 0x5b, 0x200000, 0x3ffffff, 0x5d, + 0x5b, 0x4000000, 0x7fffffff, 0x5d }, + { 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1, 5, 5, 1, 1, 6, 6, 1 }, + 24 +}, { + "ja_JP.ISO2022-JP2", + "\033$BF|K\1348l\033(BA\033$B$\"\033(BB\033$B$$\033(B", + { 0x4200467c, 0x42004b5c, 0x4200386c, 0x41, 0x42002422, 0x42, 0x42002424 }, + { 5, 2, 2, 4, 5, 4, 5 }, + 7 +}, { + "ja_JP.SJIS", + "\223\372\226{\214\352A\202\240B\202\242", + { 0x93fa, 0x967b, 0x8cea, 0x41, 0x82a0, 0x42, 0x82a2 }, + { 2, 2, 2, 1, 2, 1, 2 }, + 7 +}, { + "ja_JP.eucJP", + "\306\374\313\334\270\354A\244\242B\244\244", + { 0xc6fc, 0xcbdc, 0xb8ec, 0x41, 0xa4a2, 0x42, 0xa4a4 }, + { 2, 2, 2, 1, 2, 1, 2 }, + 7 +}, { + NULL, + NULL, + { }, + { }, + 0 +} +}; + +static void +h_ctype2(const struct test *t, bool use_mbstate) +{ + mbstate_t *stp; + mbstate_t st; + char buf[SIZE]; + char *str; + size_t n; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); +#else + if (setlocale(LC_CTYPE, t->locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", t->locale); + return; + } +#endif + + (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking string: \"%s\"\n", buf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + (void)printf("Using mbstate: %s\n", use_mbstate ? "yes" : "no"); + + (void)memset(&st, 0, sizeof(st)); +// mbrtowc(0, 0, 0, &st); /* XXX for ISO2022-JP */ + stp = use_mbstate ? &st : 0; + + for (n = 9; n > 0; n--) { + const char *src = t->data; + wchar_t dst; + size_t nchar = 0; + int width = 0; + + ATF_REQUIRE(mbsinit(stp) != 0); + + for (;;) { + size_t rv = mbrtowc(&dst, src, n, stp); + + if (rv == 0) + break; + + if (rv == (size_t)-2) { + src += n; + width += n; + + continue; + } + if (rv == (size_t)-1) { + ATF_REQUIRE_EQ(errno, EILSEQ); + atf_tc_fail("Invalid sequence"); + /* NOTREACHED */ + } + + width += rv; + src += rv; + + if (dst != t->wchars[nchar] || + width != t->widths[nchar]) { + (void)printf("At position %zd:\n", nchar); + (void)printf(" expected: 0x%04X (%u)\n", + t->wchars[nchar], t->widths[nchar]); + (void)printf(" got : 0x%04X (%u)\n", + dst, width); + atf_tc_fail("Test failed"); + } + + nchar++; + width = 0; + } + + ATF_REQUIRE_EQ_MSG(dst, 0, "Incorrect terminating character: " + "0x%04X (expected: 0x00)", dst); + + ATF_REQUIRE_EQ_MSG(nchar, t->length, "Incorrect length: " + "%zd (expected: %zd)", nchar, t->length); + } + + { + wchar_t wbuf[SIZE]; + size_t rv; + char const *src = t->data; + int i; + + (void)memset(wbuf, 0xFF, sizeof(wbuf)); + + rv = mbsrtowcs(wbuf, &src, SIZE, stp); + + ATF_REQUIRE_EQ_MSG(rv, t->length, "Incorrect length: %zd " + "(expected: %zd)", rv, t->length); + ATF_REQUIRE_EQ(src, NULL); + + for (i = 0; wbuf[i] != 0; ++i) { + if (wbuf[i] == t->wchars[i]) + continue; + + (void)printf("At position %d:\n", i); + (void)printf(" expected: 0x%04X\n", t->wchars[i]); + (void)printf(" got : 0x%04X\n", wbuf[i]); + atf_tc_fail("Test failed"); + } + + ATF_REQUIRE_EQ_MSG((size_t)i, t->length, "Incorrect length: " + "%d (expected: %zd)", i, t->length); + } + + (void)printf("Ok.\n"); +} + +ATF_TC(mbrtowc_internal); +ATF_TC_HEAD(mbrtowc_internal, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbrtowc(3) and mbsrtowcs(3) (using internal " + "state) with different locales"); +} +ATF_TC_BODY(mbrtowc_internal, tc) +{ + struct test *t; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("ja_* locale fails"); +#endif + for (t = &tests[0]; t->data != NULL; ++t) + h_ctype2(t, false); +} + +ATF_TC(mbrtowc_object); +ATF_TC_HEAD(mbrtowc_object, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbrtowc(3) and mbsrtowcs(3) (using state " + "object) with different locales"); +} +ATF_TC_BODY(mbrtowc_object, tc) +{ + struct test *t; + + for (t = &tests[0]; t->data != NULL; ++t) + h_ctype2(t, true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mbrtowc_internal); + ATF_TP_ADD_TC(tp, mbrtowc_object); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c new file mode 100644 index 0000000..446d7ef --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $"); + +#include <locale.h> +#include <string.h> +#include <wchar.h> + +#include <atf-c.h> + +static const struct test { + const char *locale; + const char *data; + size_t limit; + const wchar_t output1[64]; + size_t output1_len; + const wchar_t output2[64]; + size_t output2_len; +} tests[] = { + { "C", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4, + { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 }, + { "en_US.UTF-8", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4, + { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 }, + { "en_US.UTF-8", "ABC\303\2440123", 4, { 0x41, 0x42, 0x43, }, 3, + { 0xe4, 0x30, 0x31, 0x32, 0x33, 0x0 }, 6 }, +}; + +ATF_TC(mbsnrtowcs); +ATF_TC_HEAD(mbsnrtowcs, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbsnrtowc(3) with different locales"); +} +ATF_TC_BODY(mbsnrtowcs, tc) +{ + size_t i; + const struct test *t; + mbstate_t state; + wchar_t buf[64]; + const char *src; + size_t len; + + for (i = 0; i < __arraycount(tests); ++i) { + t = &tests[i]; + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); + memset(&state, 0, sizeof(state)); + src = t->data; + len = mbsnrtowcs(buf, &src, t->limit, + __arraycount(buf), &state); + ATF_REQUIRE_EQ(src, t->data + t->limit); + ATF_REQUIRE_EQ(len, t->output1_len); + ATF_REQUIRE(wmemcmp(t->output1, buf, len) == 0); + len = mbsnrtowcs(buf, &src, strlen(src) + 1, + __arraycount(buf), &state); + ATF_REQUIRE_EQ(len, strlen(t->data) - t->limit); + ATF_REQUIRE(wmemcmp(t->output2, buf, len + 1) == 0); + ATF_REQUIRE_EQ(src, NULL); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mbsnrtowcs); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c new file mode 100644 index 0000000..f8c06d3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c @@ -0,0 +1,209 @@ +/* $NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $"); + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vis.h> +#include <wchar.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x, v) \ + ATF_REQUIRE_MSG((x) != (v), "%s: %s", #x, strerror(errno)) + +#define SIZE 256 + +static struct test { + const char *locale; + const char *data; + wchar_t wchars[64]; + int widths[64]; + int width; +} tests[] = { +{ + "en_US.UTF-8", + "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200" + "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374" + "\204\200\200\200\200\375\277\277\277\277\277]", + { + 0x5B, 0x01, 0x7F, 0x5D, 0x5B, 0x80, 0x07FF, 0x5D, 0x5B, 0x0800, + 0xFFFF, 0x5D, 0x5B, 0x10000, 0x1FFFFF, 0x5D, 0x5B, 0x200000, + 0x3FFFFFF, 0x5D, 0x5B, 0x4000000, 0x7FFFFFFF, 0x5D, 0x0A + }, + { 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, + 1, 1, -1, -1, 1, 1, -1, -1, 1, -1 + }, + -1 +}, { + "ja_JP.ISO2022-JP", + "\033$B#J#I#S$G$9!#\033(Baaaa\033$B$\"$$$&$($*\033(B", + { + 0x4200234A, 0x42002349, 0x42002353, 0x42002447, 0x42002439, + 0x42002123, 0x61, 0x61, 0x61, 0x61, 0x42002422, 0x42002424, + 0x42002426, 0x42002428, 0x4200242A, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 26 +}, { + "ja_JP.SJIS", + "\202r\202i\202h\202r\202\305\202\267\201Baaaa\202\240\202\242" + "\202\244\202\246\202\250", + { + 0x8272, 0x8269, 0x8268, 0x8272, 0x82C5, 0x82B7, 0x8142, 0x61, + 0x61, 0x61, 0x61, 0x82A0, 0x82A2, 0x82A4, 0x82A6, 0x82A8, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 28 +}, { + "ja_JP.eucJP", + "\243\305\243\325\243\303\244\307\244\271\241\243aaaa\244\242\244" + "\244\244\246\244\250\244\252", + { + 0xA3C5, 0xA3D5, 0xA3C3, 0xA4C7, 0xA4B9, 0xA1A3, 0x61, 0x61, 0x61, + 0x61, 0xA4A2, 0xA4A4, 0xA4A6, 0xA4A8, 0xA4AA, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 26 +}, { + NULL, + NULL, + {}, + {}, + 0 +} +}; + +ATF_TC(mbstowcs_basic); +ATF_TC_HEAD(mbstowcs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wide character functions with different locales"); +} +ATF_TC_BODY(mbstowcs_basic, tc) +{ + struct test *t; + + for (t = &tests[0]; t->data != NULL; ++t) { + wchar_t wbuf[SIZE]; + char buf[SIZE]; + char visbuf[SIZE]; + char *str; + int i; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); +#else + if (setlocale(LC_CTYPE, t->locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", t->locale); + continue; + } +#endif + + (void)strvis(visbuf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking string: \"%s\"\n", visbuf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + REQUIRE_ERRNO((ssize_t)mbstowcs(wbuf, t->data, SIZE-1), -1); + REQUIRE_ERRNO((ssize_t)wcstombs(buf, wbuf, SIZE-1), -1); + + if (strcmp(buf, t->data) != 0) { + (void)strvis(visbuf, buf, VIS_WHITE | VIS_OCTAL); + (void)printf("Conversion to wcs and back failed: " + "\"%s\"\n", visbuf); + atf_tc_fail("Test failed"); + } + + /* The output here is implementation-dependent. */ + + for (i = 0; wbuf[i] != 0; ++i) { + if (wbuf[i] == t->wchars[i] && + wcwidth(wbuf[i]) == t->widths[i]) + continue; + + (void)printf("At position %d:\n", i); + (void)printf(" expected: 0x%04X (%d)\n", + t->wchars[i], t->widths[i]); + (void)printf(" got : 0x%04X (%d)\n", wbuf[i], + wcwidth(wbuf[i])); + atf_tc_fail("Test failed"); + } + + if (wcswidth(wbuf, SIZE-1) != t->width) { + (void)printf("Incorrect wcswidth:\n"); + (void)printf(" expected: %d\n", t->width); + (void)printf(" got : %d\n", wcswidth(wbuf, SIZE-1)); + atf_tc_fail("Test failed"); + } + + (void)printf("Ok.\n"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mbstowcs_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c new file mode 100644 index 0000000..7816260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c @@ -0,0 +1,157 @@ +/* $NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2007 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $"); + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vis.h> +#include <wchar.h> + +#include <atf-c.h> + +static void +h_mbtowc(const char *locale, const char *illegal, const char *legal) +{ + char buf[64]; + size_t stateful, ret; + char *str; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL); +#else + if (setlocale(LC_CTYPE, locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", locale); + return; + } +#endif + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + stateful = wctomb(NULL, L'\0'); + (void)printf("Locale is state-%sdependent\n", + stateful ? "in" : ""); + + /* initialize internal state */ + ret = mbtowc(NULL, NULL, 0); + ATF_REQUIRE(stateful ? ret : !ret); + + (void)strvis(buf, illegal, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking illegal sequence: \"%s\"\n", buf); + + ret = mbtowc(NULL, illegal, strlen(illegal)); + (void)printf("mbtowc() returned: %zd\n", ret); + ATF_REQUIRE_EQ(ret, (size_t)-1); + (void)printf("errno: %s\n", strerror(errno)); + ATF_REQUIRE_EQ(errno, EILSEQ); + + /* if this is stateless encoding, this re-initialization is not required. */ + if (stateful) { + /* re-initialize internal state */ + ret = mbtowc(NULL, NULL, 0); + ATF_REQUIRE(stateful ? ret : !ret); + } + + /* valid multibyte sequence case */ + (void)strvis(buf, legal, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking legal sequence: \"%s\"\n", buf); + + errno = 0; + ret = mbtowc(NULL, legal, strlen(legal)); + (void)printf("mbtowc() returned: %zd\n", ret); + ATF_REQUIRE(ret != (size_t)-1); + (void)printf("errno: %s\n", strerror(errno)); + ATF_REQUIRE_EQ(errno, 0); + + (void)printf("Ok.\n"); +} + +ATF_TC(mbtowc); +ATF_TC_HEAD(mbtowc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mbtowc(3)"); +} +ATF_TC_BODY(mbtowc, tc) +{ + h_mbtowc("en_US.UTF-8", "\240", "\302\240"); + h_mbtowc("ja_JP.ISO2022-JP", "\033$B", "\033$B$\"\033(B"); + h_mbtowc("ja_JP.SJIS", "\202", "\202\240"); + h_mbtowc("ja_JP.eucJP", "\244", "\244\242"); +#ifndef __FreeBSD__ + /* Moved last as it fails */ + h_mbtowc("zh_CN.GB18030", "\241", "\241\241"); +#endif + h_mbtowc("zh_TW.Big5", "\241", "\241@"); + h_mbtowc("zh_TW.eucTW", "\241", "\241\241"); +#ifdef __FreeBSD__ + atf_tc_expect_fail("zh_CN.GB18030"); + h_mbtowc("zh_CN.GB18030", "\241", "\241\241"); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mbtowc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c new file mode 100644 index 0000000..10756b5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <wchar.h> + +ATF_TC(wcscspn); +ATF_TC_HEAD(wcscspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcscspn(3)"); +} + +ATF_TC_BODY(wcscspn, tc) +{ + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L""), 16); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"a"), 0); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"b"), 1); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"cd"), 2); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"qrstuvwxyz"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcscspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c new file mode 100644 index 0000000..57c1ac5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c @@ -0,0 +1,62 @@ +/* $NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <wchar.h> + +ATF_TC(wcspbrk); +ATF_TC_HEAD(wcspbrk, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcspbrk(3)"); +} + +ATF_TC_BODY(wcspbrk, tc) +{ + static const wchar_t s[] = L"abcdefghijklmnop"; + + ATF_CHECK_EQ(wcspbrk(s, L""), NULL); + ATF_CHECK_EQ(wcspbrk(s, L"qrst"), NULL); + ATF_CHECK_EQ(wcspbrk(s, L"a"), s); + ATF_CHECK_EQ(wcspbrk(s, L"b"), s + 1); + ATF_CHECK_EQ(wcspbrk(s, L"ab"), s); + ATF_CHECK_EQ(wcspbrk(s, L"cdef"), s + 2); + ATF_CHECK_EQ(wcspbrk(s, L"fedc"), s + 2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcspbrk); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c new file mode 100644 index 0000000..2083650 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c @@ -0,0 +1,60 @@ +/* $NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <wchar.h> + +ATF_TC(wcsspn); +ATF_TC_HEAD(wcsspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcsspn(3)"); +} + +ATF_TC_BODY(wcsspn, tc) +{ + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L""), 0); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"a"), 1); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"b"), 0); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"ab"), 2); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abc"), 3); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abce"), 3); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abcdefghijklmnop"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcsspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c new file mode 100644 index 0000000..8d1ef33 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c @@ -0,0 +1,460 @@ +/* $NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2005 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $"); + +#include <errno.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#include <atf-c.h> + +#ifdef __FreeBSD__ +#include <stdio.h> +#endif + +#define ALT_HUGE_VAL -1 +#define ALT_MINUS_HUGE_VAL -2 +#define ALT_NAN -3 + +#if !defined(__vax__) +static struct test { + const wchar_t *wcs; + size_t len; + double val; + int err; +} tests[] = { +{ L"IN", 0, 0, 0 }, +{ L"+IN", 0, 0, 0 }, +{ L"-IN", 0, 0, 0 }, +{ L"INX", 0, 0, 0 }, +{ L"+INX", 0, 0, 0 }, +{ L"-INX", 0, 0, 0 }, +{ L"INF", 3, ALT_HUGE_VAL, 0 }, +{ L"+INF", 4, ALT_HUGE_VAL, 0 }, +{ L"-INF", 4, ALT_MINUS_HUGE_VAL, 0 }, +{ L"INFX", 3, ALT_HUGE_VAL, 0 }, +{ L"+INFX", 4, ALT_HUGE_VAL, 0 }, +{ L"-INFX", 4, ALT_MINUS_HUGE_VAL, 0 }, +{ L" IN", 0, 0, 0 }, +{ L" +IN", 0, 0, 0 }, +{ L" -IN", 0, 0, 0 }, +{ L" INX", 0, 0, 0 }, +{ L" +INX", 0, 0, 0 }, +{ L" -INX", 0, 0, 0 }, +{ L"+ INF", 0, 0, 0 }, +{ L"- INF", 0, 0, 0 }, +{ L" INF", 8, ALT_HUGE_VAL, 0 }, +{ L" +INF", 9, ALT_HUGE_VAL, 0 }, +{ L" -INF", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFX", 8, ALT_HUGE_VAL, 0 }, +{ L" +INFX", 9, ALT_HUGE_VAL, 0 }, +{ L" -INFX", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINIT", 8, ALT_HUGE_VAL, 0 }, +{ L" +INFINIT", 9, ALT_HUGE_VAL, 0 }, +{ L" -INFINIT", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINITY", 13, ALT_HUGE_VAL, 0 }, +{ L" +INFINITY", 14, ALT_HUGE_VAL, 0 }, +{ L" -INFINITY", 14, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINITYX", 13, ALT_HUGE_VAL, 0 }, +{ L" +INFINITYX", 14, ALT_HUGE_VAL, 0 }, +{ L" -INFINITYX", 14, ALT_MINUS_HUGE_VAL, 0 }, + +/* NAN */ +{ L"NA", 0, 0, 0 }, +{ L"+NA", 0, 0, 0 }, +{ L"-NA", 0, 0, 0 }, +{ L"NAX", 0, 0, 0 }, +{ L"+NAX", 0, 0, 0 }, +{ L"-NAX", 0, 0, 0 }, +{ L"NAN", 3, ALT_NAN, 0 }, +{ L"+NAN", 4, ALT_NAN, 0 }, +{ L"-NAN", 4, ALT_NAN, 0 }, +{ L"NANX", 3, ALT_NAN, 0 }, +{ L"+NANX", 4, ALT_NAN, 0 }, +{ L"-NANX", 4, ALT_NAN, 0 }, +{ L" NA", 0, 0, 0 }, +{ L" +NA", 0, 0, 0 }, +{ L" -NA", 0, 0, 0 }, +{ L" NAX", 0, 0, 0 }, +{ L" +NAX", 0, 0, 0 }, +{ L" -NAX", 0, 0, 0 }, +{ L"+ NAN", 0, 0, 0 }, +{ L"- NAN", 0, 0, 0 }, +{ L" NAN", 8, ALT_NAN, 0 }, +{ L" +NAN", 9, ALT_NAN, 0 }, +{ L" -NAN", 9, ALT_NAN, 0 }, +{ L" NANX", 8, ALT_NAN, 0 }, +{ L" +NANX", 9, ALT_NAN, 0 }, +{ L" -NANX", 9, ALT_NAN, 0 }, + +{ L"0", 1, 0, 0 }, +{ L"+0", 2, 0, 0 }, +{ L"-0", 2, 0, 0 }, +{ L" 0", 11, 0, 0 }, +{ L" +0", 12, 0, 0 }, +{ L" -0", 12, 0, 0 }, +{ L"+ 0", 0, 0, 0 }, +{ L"- 0", 0, 0, 0 }, + +{ L".", 0, 0, 0 }, +{ L".0", 2, 0, 0 }, +{ L".00", 3, 0, 0 }, +{ L".000", 4, 0, 0 }, + +{ L"0.", 2, 0, 0 }, +{ L"+0.", 3, 0, 0 }, +{ L"-0.", 3, 0, 0 }, +{ L" 0.", 12, 0, 0 }, +{ L" +0.", 13, 0, 0 }, +{ L" -0.", 13, 0, 0 }, + +{ L"0.0", 3, 0, 0 }, +{ L"+0.0", 4, 0, 0 }, +{ L"-0.0", 4, 0, 0 }, +{ L" 0.0", 13, 0, 0 }, +{ L" +0.0", 14, 0, 0 }, +{ L" -0.0", 14, 0, 0 }, + +{ L"000", 3, 0, 0 }, +{ L"+000", 4, 0, 0 }, +{ L"-000", 4, 0, 0 }, +{ L" 000", 13, 0, 0 }, +{ L" +000", 14, 0, 0 }, +{ L" -000", 14, 0, 0 }, + +{ L"000.", 4, 0, 0 }, +{ L"+000.", 5, 0, 0 }, +{ L"-000.", 5, 0, 0 }, +{ L" 000.", 14, 0, 0 }, +{ L" +000.", 15, 0, 0 }, +{ L" -000.", 15, 0, 0 }, + +{ L"000.0", 5, 0, 0 }, +{ L"+000.0", 6, 0, 0 }, +{ L"-000.0", 6, 0, 0 }, +{ L" 000.0", 15, 0, 0 }, +{ L" +000.0", 16, 0, 0 }, +{ L" -000.0", 16, 0, 0 }, + + +{ L"0.0.", 3, 0, 0 }, +{ L"+0.0.", 4, 0, 0 }, +{ L"-0.0.", 4, 0, 0 }, +{ L" 0.0.", 13, 0, 0 }, +{ L" +0.0.", 14, 0, 0 }, +{ L" -0.0.", 14, 0, 0 }, + +{ L"0.0.0", 3, 0, 0 }, +{ L"+0.0.0", 4, 0, 0 }, +{ L"-0.0.0", 4, 0, 0 }, +{ L" 0.0.0", 13, 0, 0 }, +{ L" +0.0.0", 14, 0, 0 }, +{ L" -0.0.0", 14, 0, 0 }, + +/* XXX: FIXME */ +#if defined(__linux__) +{ L"0X", 2, 0, 0 }, +{ L"+0X", 3, 0, 0 }, +{ L"-0X", 3, 0, 0 }, +#else +{ L"0X", 1, 0, 0 }, +{ L"+0X", 2, 0, 0 }, +{ L"-0X", 2, 0, 0 }, +#endif + +/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */ +#if !defined(__SunOS__) +#if defined(__linux__) +{ L"0X.", 3, 0, 0 }, +{ L"+0X.", 4, 0, 0 }, +{ L"-0X.", 4, 0, 0 }, +{ L" 0X.", 13, 0, 0 }, +{ L" +0X.", 14, 0, 0 }, +{ L" -0X.", 14, 0, 0 }, +#else +{ L"0X.", 1, 0, 0 }, +{ L"+0X.", 2, 0, 0 }, +{ L"-0X.", 2, 0, 0 }, +{ L" 0X.", 11, 0, 0 }, +{ L" +0X.", 12, 0, 0 }, +{ L" -0X.", 12, 0, 0 }, +#endif +/* XXX: FIXME */ +#if defined(__NetBSD__) || defined(__linux__) || defined(__FreeBSD__) +{ L"0X.0", 4, 0, 0 }, +{ L"+0X.0", 5, 0, 0 }, +{ L"-0X.0", 5, 0, 0 }, +{ L" 0X.0", 14, 0, 0 }, +{ L" +0X.0", 15, 0, 0 }, +{ L" -0X.0", 15, 0, 0 }, + +{ L"0X.0P", 4, 0, 0 }, +{ L"+0X.0P", 5, 0, 0 }, +{ L"-0X.0P", 5, 0, 0 }, +{ L" 0X.0P", 14, 0, 0 }, +{ L" +0X.0P", 15, 0, 0 }, +{ L" -0X.0P", 15, 0, 0 }, +#else +{ L"0X.0", 1, 0, 0 }, +{ L"+0X.0", 2, 0, 0 }, +{ L"-0X.0", 2, 0, 0 }, +{ L" 0X.0", 11, 0, 0 }, +{ L" +0X.0", 12, 0, 0 }, +{ L" -0X.0", 12, 0, 0 }, + +{ L"0X.0P", 1, 0, 0 }, +{ L"+0X.0P", 2, 0, 0 }, +{ L"-0X.0P", 2, 0, 0 }, +{ L" 0X.0P", 11, 0, 0 }, +{ L" +0X.0P", 12, 0, 0 }, +{ L" -0X.0P", 12, 0, 0 }, +#endif + +{ L"0X0", 3, 0, 0 }, +{ L"+0X0", 4, 0, 0 }, +{ L"-0X0", 4, 0, 0 }, +{ L" 0X0", 13, 0, 0 }, +{ L" +0X0", 14, 0, 0 }, +{ L" -0X0", 14, 0, 0 }, + +{ L"00X0.0", 2, 0, 0 }, +{ L"+00X0.0", 3, 0, 0 }, +{ L"-00X0.0", 3, 0, 0 }, +{ L" 00X0.0", 12, 0, 0 }, +{ L" +00X0.0", 13, 0, 0 }, +{ L" -00X0.0", 13, 0, 0 }, + +{ L"0X0P", 3, 0, 0 }, +{ L"+0X0P", 4, 0, 0 }, +{ L"-0X0P", 4, 0, 0 }, +{ L" 0X0P", 13, 0, 0 }, +{ L" +0X0P", 14, 0, 0 }, +{ L" -0X0P", 14, 0, 0 }, + +{ L"0X0.", 4, 0, 0 }, +{ L"+0X0.", 5, 0, 0 }, +{ L"-0X0.", 5, 0, 0 }, +{ L" 0X0.", 14, 0, 0 }, +{ L" +0X0.", 15, 0, 0 }, +{ L" -0X0.", 15, 0, 0 }, + +{ L"0X0.0", 5, 0, 0 }, +{ L"+0X0.0", 6, 0, 0 }, +{ L"-0X0.0", 6, 0, 0 }, +{ L" 0X0.0", 15, 0, 0 }, +{ L" +0X0.0", 16, 0, 0 }, +{ L" -0X0.0", 16, 0, 0 }, + +{ L"0X0.P", 4, 0, 0 }, +{ L"+0X0.P", 5, 0, 0 }, +{ L"-0X0.P", 5, 0, 0 }, +{ L" 0X0.P", 14, 0, 0 }, +{ L" +0X0.P", 15, 0, 0 }, +{ L" -0X0.P", 15, 0, 0 }, + +{ L"0X0.P", 4, 0, 0 }, +{ L"+0X0.P", 5, 0, 0 }, +{ L"-0X0.P", 5, 0, 0 }, +{ L" 0X0.P", 14, 0, 0 }, +{ L" +0X0.P", 15, 0, 0 }, +{ L" -0X0.P", 15, 0, 0 }, + +#endif +{ L"0.12345678", 10, 0.12345678, 0 }, +{ L"+0.12345678", 11, +0.12345678, 0 }, +{ L"-0.12345678", 11, -0.12345678, 0 }, +{ L" 0.12345678", 15, 0.12345678, 0 }, +{ L" +0.12345678", 16, +0.12345678, 0 }, +{ L" -0.12345678", 16, -0.12345678, 0 }, + +{ L"0.12345E67", 10, 0.12345E67, 0 }, +{ L"+0.12345E67", 11, +0.12345E67, 0 }, +{ L"-0.12345E67", 11, -0.12345E67, 0 }, +{ L" 0.12345E67", 15, 0.12345E67, 0 }, +{ L" +0.12345E67", 16, +0.12345E67, 0 }, +{ L" -0.12345E67", 16, -0.12345E67, 0 }, + +{ L"0.12345E+6", 10, 0.12345E+6, 0 }, +{ L"+0.12345E+6", 11, +0.12345E+6, 0 }, +{ L"-0.12345E+6", 11, -0.12345E+6, 0 }, +{ L" 0.12345E+6", 15, 0.12345E+6, 0 }, +{ L" +0.12345E+6", 16, +0.12345E+6, 0 }, +{ L" -0.12345E+6", 16, -0.12345E+6, 0 }, + +{ L"0.98765E-4", 10, 0.98765E-4, 0 }, +{ L"+0.98765E-4", 11, +0.98765E-4, 0 }, +{ L"-0.98765E-4", 11, -0.98765E-4, 0 }, +{ L" 0.98765E-4", 15, 0.98765E-4, 0 }, +{ L" +0.98765E-4", 16, +0.98765E-4, 0 }, +{ L" -0.98765E-4", 16, -0.98765E-4, 0 }, + +{ L"12345678E9", 10, 12345678E9, 0 }, +{ L"+12345678E9", 11, +12345678E9, 0 }, +{ L"-12345678E9", 11, -12345678E9, 0 }, +{ L" 12345678E9", 15, 12345678E9, 0 }, +{ L" +12345678E9", 16, +12345678E9, 0 }, +{ L" -12345678E9", 16, -12345678E9, 0 }, + +/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */ +#if !defined(__SunOS__) +{ L"0x1P+2", 6, 4, 0 }, +{ L"+0x1P+2", 7, +4, 0 }, +{ L"-0x1P+2", 7, -4, 0 }, +{ L" 0x1P+2", 11, 4, 0 }, +{ L" +0x1P+2", 12, +4, 0 }, +{ L" -0x1P+2", 12, -4, 0 }, + +{ L"0x1.0P+2", 8, 4, 0 }, +{ L"+0x1.0P+2", 9, +4, 0 }, +{ L"-0x1.0P+2", 9, -4, 0 }, +{ L" 0x1.0P+2", 13, 4, 0 }, +{ L" +0x1.0P+2", 14, +4, 0 }, +{ L" -0x1.0P+2", 14, -4, 0 }, + +{ L"0x1P-2", 6, 0.25, 0 }, +{ L"+0x1P-2", 7, +0.25, 0 }, +{ L"-0x1P-2", 7, -0.25, 0 }, +{ L" 0x1P-2", 11, 0.25, 0 }, +{ L" +0x1P-2", 12, +0.25, 0 }, +{ L" -0x1P-2", 12, -0.25, 0 }, + +{ L"0x1.0P-2", 8, 0.25, 0 }, +{ L"+0x1.0P-2", 9, +0.25, 0 }, +{ L"-0x1.0P-2", 9, -0.25, 0 }, +{ L" 0x1.0P-2", 13, 0.25, 0 }, +{ L" +0x1.0P-2", 14, +0.25, 0 }, +{ L" -0x1.0P-2", 14, -0.25, 0 }, +#endif + +{ NULL, 0, 0, 0 } +}; +#endif /* !defined(__vax__) */ + +ATF_TC(wcstod); +ATF_TC_HEAD(wcstod, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks wcstod(3)"); +} +ATF_TC_BODY(wcstod, tc) +{ +#if defined(__vax__) +#else + struct test *t; +#endif + +#if !defined(__vax__) + for (t = &tests[0]; t->wcs != NULL; ++t) { + double d; + size_t n; + wchar_t *tail; + char *buf; + + /* we do not supported %ls nor %S yet. */ + n = wcstombs(NULL, t->wcs, 0); + ATF_REQUIRE((buf = (void *)malloc(n + 1)) != NULL); + (void)wcstombs(buf, t->wcs, n + 1); + (void)printf("Checking wcstod(\"%s\", &tail):\n", buf); + free(buf); + + errno = 0; + d = wcstod(t->wcs, &tail); + (void)printf("[errno]\n"); + (void)printf(" got : %s\n", strerror(errno)); + (void)printf(" expected: %s\n", strerror(t->err)); + ATF_REQUIRE_EQ(errno, t->err); + + n = (size_t)(tail - t->wcs); + (void)printf("[endptr - nptr]\n"); + (void)printf(" got : %zd\n", n); + (void)printf(" expected: %zd\n", t->len); + ATF_REQUIRE_EQ(n, t->len); + + (void)printf("[result]\n"); + (void)printf(" real: %F\n", d); + if (t->val == ALT_HUGE_VAL) { + (void)printf(" expected: %F\n", HUGE_VAL); + ATF_REQUIRE(isinf(d)); + ATF_REQUIRE_EQ(d, HUGE_VAL); + } else if (t->val == ALT_MINUS_HUGE_VAL) { + (void)printf(" expected: %F\n", -HUGE_VAL); + ATF_REQUIRE(isinf(d)); + ATF_REQUIRE_EQ(d, -HUGE_VAL); + } else if (t->val == ALT_NAN) { + (void)printf(" expected: %F\n", NAN); + ATF_REQUIRE(isnan(d)); + } else { + (void)printf(" expected: %F\n", t->val); + ATF_REQUIRE_EQ(d, t->val); + } + + (void)printf("\n"); + } +#else /* !defined(__vax__) */ + atf_tc_skip("Test is unavailable on vax."); +#endif /* !defined(__vax__) */ +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, wcstod); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c new file mode 100644 index 0000000..3405e97 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c @@ -0,0 +1,212 @@ +/* $NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2004 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <vis.h> +#include <wchar.h> +#include <string.h> +#include <limits.h> + +#include <atf-c.h> + +#define TC_WCTOMB 0 +#define TC_WCRTOMB 1 +#define TC_WCRTOMB_ST 2 + +static struct test { + const char *locale; + const char *data; + size_t wclen; + size_t mblen[16]; +} tests[] = { +{ + "ja_JP.ISO2022-JP", + "\x1b$B" /* JIS X 0208-1983 */ + "\x46\x7c\x4b\x5c\x38\x6c" /* "nihongo" */ + "\x1b(B" /* ISO 646 */ + "ABC" + "\x1b(I" /* JIS X 0201 katakana */ + "\xb1\xb2\xb3" /* "aiu" */ + "\x1b(B", /* ISO 646 */ + 3 + 3 + 3, + { 3+2, 2, 2, 3+1, 1, 1, 3+1, 1, 1, 3+1 } +}, { + "C", + "ABC", + 3, + { 1, 1, 1, 1 } +}, { NULL, NULL, 0, { } } +}; + +static void +h_wctomb(const struct test *t, char tc) +{ + wchar_t wcs[16 + 2]; + char buf[128]; + char cs[MB_LEN_MAX]; + const char *pcs; + char *str; + mbstate_t st; + mbstate_t *stp = NULL; + size_t sz, ret, i; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); +#else + if (setlocale(LC_CTYPE, t->locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", t->locale); + return; + } +#endif + + (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking sequence: \"%s\"\n", buf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + if (tc == TC_WCRTOMB_ST) { + (void)memset(&st, 0, sizeof(st)); + stp = &st; + } + + wcs[t->wclen] = L'X'; /* poison */ + pcs = t->data; + sz = mbsrtowcs(wcs, &pcs, t->wclen + 2, NULL); + ATF_REQUIRE_EQ_MSG(sz, t->wclen, "mbsrtowcs() returned: " + "%zu, expected: %zu", sz, t->wclen); + ATF_REQUIRE_EQ(wcs[t->wclen], 0); + + for (i = 0; i < t->wclen + 1; i++) { + if (tc == TC_WCTOMB) + ret = wctomb(cs, wcs[i]); + else + ret = wcrtomb(cs, wcs[i], stp); + + if (ret == t->mblen[i]) + continue; + + (void)printf("At position %zd:\n", i); + (void)printf(" expected: %zd\n", t->mblen[i]); + (void)printf(" got : %zd\n", ret); + atf_tc_fail("Test failed"); + /* NOTREACHED */ + } + + (void)printf("Ok.\n"); +} + +ATF_TC(wctomb); +ATF_TC_HEAD(wctomb, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks wctomb(3)"); +} +ATF_TC_BODY(wctomb, tc) +{ + struct test *t; + + (void)printf("Checking wctomb()\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCTOMB); +} + +ATF_TC(wcrtomb_state); +ATF_TC_HEAD(wcrtomb_state, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wcrtomb(3) (using state object)"); +} +ATF_TC_BODY(wcrtomb_state, tc) +{ + struct test *t; + + (void)printf("Checking wcrtomb() (with state object)\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCRTOMB_ST); +} + +ATF_TC(wcrtomb); +ATF_TC_HEAD(wcrtomb, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wcrtomb(3) (using internal state)"); +} +ATF_TC_BODY(wcrtomb, tc) +{ + struct test *t; + + (void)printf("Checking wcrtomb() (using internal state)\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCRTOMB); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, wctomb); + ATF_TP_ADD_TC(tp, wcrtomb); + ATF_TP_ADD_TC(tp, wcrtomb_state); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/gen_ether_subr b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr new file mode 100755 index 0000000..9f9b63c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr @@ -0,0 +1,25 @@ +#!/bin/sh + +awk ' +BEGIN { + print + print "#include <ctype.h>" + print "#include <sys/types.h>" + print "#include <errno.h>" + print + print "#define ETHER_ADDR_LEN 6" + print + print "int ether_aton_r(u_char *dest, size_t len, const char *str);" + print +} +/^ether_aton_r/ { + print prevline + out = 1 +} +{ + if (out) print + else prevline = $0 +} +/^}$/ { + if (out) exit(0) +}' $1 >$2 diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README new file mode 100644 index 0000000..e856fe7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README @@ -0,0 +1,7 @@ +This test may fail if + + - your /etc/services file is not in sync with what this test expects + - your /etc/hosts file or DNS have unusual entries for "localhost" + (a duplicate "localhost 127.0.0.1" line in /etc/hosts for example) + +On kernels without IPv6 support some of the tests are skipped. diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp new file mode 100644 index 0000000..d2945f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp @@ -0,0 +1,36 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp new file mode 100644 index 0000000..0238f83 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp @@ -0,0 +1,42 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c new file mode 100644 index 0000000..939fcdb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c @@ -0,0 +1,186 @@ +/* $NetBSD: h_gai.c,v 1.1 2011/01/12 02:58:40 pgoyette Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <arpa/inet.h> + +struct addrinfo ai; + +char host[NI_MAXHOST]; +char serv[NI_MAXSERV]; +int vflag = 0; + +static void usage(void); +static void print1(const char *, const struct addrinfo *, char *, char *); +int main(int, char *[]); + +static void +usage() +{ + fprintf(stderr, "usage: test [-f family] [-s socktype] [-p proto] [-DPRSv46] host serv\n"); +} + +static void +print1(const char *title, const struct addrinfo *res, char *h, char *s) +{ + const char *start, *end; + int error; + const int niflag = NI_NUMERICHOST; + + if (res->ai_addr) { + error = getnameinfo(res->ai_addr, res->ai_addr->sa_len, + host, sizeof(host), serv, sizeof(serv), + niflag); + h = host; + s = serv; + } else + error = 0; + + if (vflag) { + start = "\t"; + end = "\n"; + } else { + start = " "; + end = ""; + } + printf("%s%s", title, end); + printf("%sflags 0x%x%s", start, res->ai_flags, end); + printf("%sfamily %d%s", start, res->ai_family, end); + printf("%ssocktype %d%s", start, res->ai_socktype, end); + printf("%sprotocol %d%s", start, res->ai_protocol, end); + printf("%saddrlen %d%s", start, res->ai_addrlen, end); + if (error) + printf("%serror %d%s", start, error, end); + else { + printf("%shost %s%s", start, h, end); + printf("%sserv %s%s", start, s, end); + } +#if 0 + if (res->ai_canonname) + printf("%scname \"%s\"%s", start, res->ai_canonname, end); +#endif + if (!vflag) + printf("\n"); + +} + +int +main(int argc, char *argv[]) +{ + struct addrinfo *res; + int error, i; + char *p, *q; + extern int optind; + extern char *optarg; + int c; + char nbuf[10]; + + memset(&ai, 0, sizeof(ai)); + ai.ai_family = PF_UNSPEC; + ai.ai_flags |= AI_CANONNAME; + while ((c = getopt(argc, argv, "Df:p:PRs:Sv46")) != -1) { + switch (c) { + case 'D': + ai.ai_socktype = SOCK_DGRAM; + break; + case 'f': + ai.ai_family = atoi(optarg); + break; + case 'p': + ai.ai_protocol = atoi(optarg); + break; + case 'P': + ai.ai_flags |= AI_PASSIVE; + break; + case 'R': + ai.ai_socktype = SOCK_RAW; + break; + case 's': + ai.ai_socktype = atoi(optarg); + break; + case 'S': + ai.ai_socktype = SOCK_STREAM; + break; + case 'v': + vflag++; + break; + case '4': + ai.ai_family = PF_INET; + break; + case '6': + ai.ai_family = PF_INET6; + break; + default: + usage(); + exit(1); + } + } + argc -= optind; + argv += optind; + + if (argc != 2){ + usage(); + exit(1); + } + + p = *argv[0] ? argv[0] : NULL; + q = *argv[1] ? argv[1] : NULL; + + strncpy(nbuf, "(empty)", sizeof(nbuf)); + print1("arg:", &ai, p ? p : nbuf , q ? q : nbuf); + + error = getaddrinfo(p, q, &ai, &res); + if (error) { + printf("%s\n", gai_strerror(error)); + exit(1); + } + + i = 1; + do { + snprintf(nbuf, sizeof(nbuf), "ai%d:", i); + print1(nbuf, res, NULL, NULL); + + i++; + } while ((res = res->ai_next) != NULL); + printf("\n"); + + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp new file mode 100644 index 0000000..21059c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp @@ -0,0 +1,38 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp new file mode 100644 index 0000000..7d30fea --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp @@ -0,0 +1,56 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv echo +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv echo +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv tftp +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv tftp +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp new file mode 100644 index 0000000..9de5c56 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp @@ -0,0 +1,14 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty) +hostname nor servname provided, or not known diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp new file mode 100644 index 0000000..1df5663 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp @@ -0,0 +1,16 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty) +hostname nor servname provided, or not known diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp new file mode 100644 index 0000000..d06d163 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp @@ -0,0 +1,4 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host fe80::1%lo0 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host fe80::1%lo0 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host fe80::1%lo0 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp new file mode 100644 index 0000000..bc850e0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp @@ -0,0 +1,13 @@ +arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80 +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp new file mode 100644 index 0000000..a4f2fb8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp @@ -0,0 +1,15 @@ +arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 0 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80 +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp new file mode 100644 index 0000000..1c0ce43 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp @@ -0,0 +1,6 @@ +arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http +No address associated with hostname diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp new file mode 100644 index 0000000..e24036e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp @@ -0,0 +1,8 @@ +arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh new file mode 100755 index 0000000..94a3c0b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh @@ -0,0 +1,198 @@ +# $NetBSD: t_getaddrinfo.sh,v 1.2 2011/06/15 07:54:32 jmmv Exp $ + +# +# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +check_output() +{ + if [ "$2" = "none" ] ; then + exp="${1}.exp" + elif [ "$2" = "hosts" ] ; then + # Determine if localhost has an IPv6 address or not + lcl=$( cat /etc/hosts | \ + sed -e 's/#.*$//' -e 's/[ ][ ]*/ /g' | \ + awk '/ localhost($| )/ {printf "%s ", $1}' ) + if [ "${lcl%*::*}" = "${lcl}" ] ; then + exp="${1}_v4.exp" + else + exp="${1}_v4v6.exp" + fi + elif [ "$2" = "ifconfig" ] ; then + lcl=$( ifconfig lo0 | grep inet6 ) + if [ -n "${lcl}" ] ; then + exp="${1}_v4v6.exp" + else + exp="${1}_v4.exp" + fi + else + atf_fail "Invalid family_match_type $2 requested." + fi + + cmp -s $(atf_get_srcdir)/data/${exp} out && return + diff -u $(atf_get_srcdir)/data/${exp} out && \ + atf_fail "Actual output does not match expected output" +} + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Testing basic ones" +} +basic_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST ::1 http + $TEST 127.0.0.1 http + $TEST localhost http + $TEST ::1 tftp + $TEST 127.0.0.1 tftp + $TEST localhost tftp + $TEST ::1 echo + $TEST 127.0.0.1 echo + $TEST localhost echo ) > out 2>&1 + + check_output basics hosts +} + +atf_test_case specific +specific_head() +{ + atf_set "descr" "Testing specific address family" +} +specific_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -4 localhost http + $TEST -6 localhost http ) > out 2>&1 + + check_output spec_fam hosts +} + +atf_test_case empty_hostname +empty_hostname_head() +{ + atf_set "descr" "Testing empty hostname" +} +empty_hostname_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST '' http + $TEST '' echo + $TEST '' tftp + $TEST '' 80 + $TEST -P '' http + $TEST -P '' echo + $TEST -P '' tftp + $TEST -P '' 80 + $TEST -S '' 80 + $TEST -D '' 80 ) > out 2>&1 + + check_output no_host ifconfig +} + +atf_test_case empty_servname +empty_servname_head() +{ + atf_set "descr" "Testing empty service name" +} +empty_servname_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST ::1 '' + $TEST 127.0.0.1 '' + $TEST localhost '' + $TEST '' '' ) > out 2>&1 + + check_output no_serv hosts +} + +atf_test_case sock_raw +sock_raw_head() +{ + atf_set "descr" "Testing raw socket" +} +sock_raw_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -R -p 0 localhost '' + $TEST -R -p 59 localhost '' + $TEST -R -p 59 localhost 80 + $TEST -R -p 59 localhost www + $TEST -R -p 59 ::1 '' ) > out 2>&1 + + check_output sock_raw hosts +} + +atf_test_case unsupported_family +unsupported_family_head() +{ + atf_set "descr" "Testing unsupported family" +} +unsupported_family_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -f 99 localhost '' ) > out 2>&1 + + check_output unsup_fam none +} + +atf_test_case scopeaddr +scopeaddr_head() +{ + atf_set "descr" "Testing scoped address format" +} +scopeaddr_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST fe80::1%lo0 http +# IF=`ifconfig -a | grep -v '^ ' | \ +# sed -e 's/:.*//' | head -1 | awk '{print $1}'` +# $TEST fe80::1%$IF http + ) > out 2>&1 + + check_output scoped none +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case specific + atf_add_test_case empty_hostname + atf_add_test_case empty_servname + atf_add_test_case sock_raw + atf_add_test_case unsupported_family + atf_add_test_case scopeaddr +} diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp new file mode 100644 index 0000000..b6133c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp @@ -0,0 +1,2 @@ +arg: flags 0x2 family 99 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai_family not supported diff --git a/contrib/netbsd-tests/lib/libc/net/h_dns_server.c b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c new file mode 100644 index 0000000..a8f0caa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c @@ -0,0 +1,415 @@ +/* $NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andreas Gustafsson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * A minimal DNS server capable of providing canned answers to the + * specific queries issued by t_hostent.sh and nothing more. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $"); + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <memory.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <sys/socket.h> + +#include <netinet/in.h> +#ifdef __NetBSD__ +#include <netinet6/in6.h> +#endif + +#ifdef __FreeBSD__ +#include <paths.h> +#endif + +union sockaddr_either { + struct sockaddr s; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; +}; + +#ifdef DEBUG +#define DPRINTF(...) fprintf(stderr, __VA_ARGS__) +#else +#define DPRINTF(...) +#endif + +/* A DNS question and its corresponding answer */ + +struct dns_data { + size_t qname_size; + const char *qname; /* Wire-encode question name */ + int qtype; + size_t answer_size; + const char *answer; /* One wire-encoded answer RDATA */ +}; + +/* Convert C string constant to length + data pair */ +#define STR_DATA(s) sizeof(s) - 1, s + +/* Canned DNS queestion-answer pairs */ +struct dns_data data[] = { + /* Forward mappings */ + /* localhost IN A -> 127.0.0.1 */ + { STR_DATA("\011localhost\000"), 1, + STR_DATA("\177\000\000\001") }, + /* localhost IN AAAA -> ::1 */ + { STR_DATA("\011localhost\000"), 28, + STR_DATA("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001") }, + /* sixthavenue.astron.com IN A -> 38.117.134.16 */ + { STR_DATA("\013sixthavenue\006astron\003com\000"), 1, + STR_DATA("\046\165\206\020") }, + /* sixthavenue.astron.com IN AAAA -> 2620:106:3003:1f00:3e4a:92ff:fef4:e180 */ + { STR_DATA("\013sixthavenue\006astron\003com\000"), 28, + STR_DATA("\x26\x20\x01\x06\x30\x03\x1f\x00\x3e\x4a\x92\xff\xfe\xf4\xe1\x80") }, + /* Reverse mappings */ + { STR_DATA("\0011\0010\0010\003127\007in-addr\004arpa\000"), 12, + STR_DATA("\011localhost\000") }, + { STR_DATA("\0011\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\003ip6\004arpa\000"), 12, + STR_DATA("\011localhost\000") }, + { STR_DATA("\00216\003134\003117\00238" + "\007in-addr\004arpa\000"), 12, + STR_DATA("\013sixthavenue\006astron\003com\000") }, + { STR_DATA("\0010\0018\0011\001e\0014\001f\001e\001f" + "\001f\001f\0012\0019\001a\0014\001e\0013" + "\0010\0010\001f\0011\0013\0010\0010\0013" + "\0016\0010\0011\0010\0010\0012\0016\0012" + "\003ip6\004arpa\000"), 12, + STR_DATA("\013sixthavenue\006astron\003com\000") }, + /* End marker */ + { STR_DATA(""), 0, STR_DATA("") } +}; + +/* + * Compare two DNS names for equality. If equal, return their + * length, and if not, return zero. Does not handle compression. + */ +static int +name_eq(const unsigned char *a, const unsigned char *b) { + const unsigned char *a_save = a; + for (;;) { + int i; + int lena = *a++; + int lenb = *b++; + if (lena != lenb) + return 0; + if (lena == 0) + return a - a_save; + for (i = 0; i < lena; i++) + if (tolower(a[i]) != tolower(b[i])) + return 0; + a += lena; + b += lena; + } +} + +#ifdef DEBUG +static char * +name2str(const void *v, char *buf, size_t buflen) { + const unsigned char *a = v; + char *b = buf; + char *eb = buf + buflen; + +#define ADDC(c) do { \ + if (b < eb) \ + *b++ = c; \ + else \ + return NULL; \ + } while (/*CONSTCOND*/0) + for (int did = 0;; did++) { + int lena = *a++; + if (lena == 0) { + ADDC('\0'); + return buf; + } + if (did) + ADDC('.'); + for (int i = 0; i < lena; i++) + ADDC(a[i]); + a += lena; + } +} +#endif + +#ifdef __FreeBSD__ +/* XXX the daemon2_* functions should be in a library */ + +int __daemon2_detach_pipe[2]; + +static int +daemon2_fork(void) +{ + int r; + int fd; + int i; + + /* + * Set up the pipe, making sure the write end does not + * get allocated one of the file descriptors that will + * be closed in daemon2_detach(). + */ + for (i = 0; i < 3; i++) { + r = pipe(__daemon2_detach_pipe); + if (r < 0) + return -1; + if (__daemon2_detach_pipe[1] <= STDERR_FILENO && + (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, __daemon2_detach_pipe[0]); + (void)dup2(fd, __daemon2_detach_pipe[1]); + if (fd > STDERR_FILENO) + (void)close(fd); + continue; + } + break; + } + + r = fork(); + if (r < 0) { + return -1; + } else if (r == 0) { + /* child */ + close(__daemon2_detach_pipe[0]); + return 0; + } + /* Parent */ + + (void) close(__daemon2_detach_pipe[1]); + + for (;;) { + char dummy; + r = read(__daemon2_detach_pipe[0], &dummy, 1); + if (r < 0) { + if (errno == EINTR) + continue; + _exit(1); + } else if (r == 0) { + _exit(1); + } else { /* r > 0 */ + _exit(0); + } + } +} + +static int +daemon2_detach(int nochdir, int noclose) +{ + int r; + int fd; + + if (setsid() == -1) + return -1; + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + (void)close(fd); + } + + while (1) { + r = write(__daemon2_detach_pipe[1], "", 1); + if (r < 0) { + if (errno == EINTR) + continue; + /* May get "broken pipe" here if parent is killed */ + return -1; + } else if (r == 0) { + /* Should not happen */ + return -1; + } else { + break; + } + } + + (void) close(__daemon2_detach_pipe[1]); + + return 0; +} +#endif + +int main(int argc, char **argv) { + int s, r, protocol; + union sockaddr_either saddr; + struct dns_data *dp; + unsigned char *p; + char pidfile_name[40]; + FILE *f; + int one = 1; +#ifdef DEBUG + char buf1[1024], buf2[1024]; +#endif + +#ifdef __FreeBSD__ + daemon2_fork(); +#endif + if (argc < 2 || ((protocol = argv[1][0]) != '4' && protocol != '6')) + errx(1, "usage: dns_server 4 | 6"); + s = socket(protocol == '4' ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (s < 0) + err(1, "socket"); + if (protocol == '4') { + memset(&saddr.sin, 0, sizeof(saddr.sin)); + saddr.sin.sin_family = AF_INET; + saddr.sin.sin_len = sizeof(saddr.sin); + saddr.sin.sin_port = htons(53); + saddr.sin.sin_addr.s_addr = INADDR_ANY; + } else { + static struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT; + memset(&saddr.sin6, 0, sizeof(saddr.sin6)); + saddr.sin6.sin6_family = AF_INET6; + saddr.sin6.sin6_len = sizeof(saddr.sin6); + saddr.sin6.sin6_port = htons(53); + saddr.sin6.sin6_addr = loopback; + } + + r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); + if (r < 0) + err(1, "setsockopt"); + + r = bind(s, + (struct sockaddr *) &saddr, + protocol == '4' ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); + if (r < 0) + err(1, "bind"); + + snprintf(pidfile_name, sizeof pidfile_name, + "dns_server_%c.pid", protocol); + f = fopen(pidfile_name, "w"); + fprintf(f, "%d", getpid()); + fclose(f); +#ifdef __FreeBSD__ +#ifdef DEBUG + daemon2_detach(0, 1); +#else + daemon2_detach(0, 0); +#endif +#else +#ifdef DEBUG + daemon(0, 1); +#else + daemon(0, 0); +#endif +#endif + + for (;;) { + unsigned char buf[512]; + union sockaddr_either from; + ssize_t nrecv, nsent; + socklen_t fromlen = + protocol == '4' ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6); + memset(buf, 0, sizeof buf); + nrecv = recvfrom(s, buf, sizeof buf, 0, &from.s, &fromlen); + if (nrecv < 0) + err(1, "recvfrom"); + if (nrecv < 12) { + DPRINTF("Too short %zd\n", nrecv); + continue; + } + if ((buf[2] & 0x80) != 0) { + DPRINTF("Not a query 0x%x\n", buf[2]); + continue; + } + if (!(buf[4] == 0 && buf[5] == 1)) { + DPRINTF("QCOUNT is not 1 0x%x 0x%x\n", buf[4], buf[5]); + continue; /* QDCOUNT is not 1 */ + } + + for (dp = data; dp->qname_size != 0; dp++) { + int qtype, qclass; + p = buf + 12; /* Point to QNAME */ + int n = name_eq(p, (const unsigned char *) dp->qname); + if (n == 0) { + DPRINTF("no match name %s != %s\n", + name2str(p, buf1, sizeof(buf1)), + name2str(dp->qname, buf2, sizeof(buf2))); + continue; /* Name does not match */ + } + DPRINTF("match name %s\n", + name2str(p, buf1, sizeof(buf1))); + p += n; /* Skip QNAME */ + qtype = *p++ << 8; + qtype |= *p++; + if (qtype != dp->qtype) { + DPRINTF("no match name 0x%x != 0x%x\n", + qtype, dp->qtype); + continue; + } + DPRINTF("match type 0x%x\n", qtype); + qclass = *p++ << 8; + qclass |= *p++; + if (qclass != 1) { /* IN */ + DPRINTF("no match class %d != 1\n", qclass); + continue; + } + DPRINTF("match class %d\n", qclass); + goto found; + } + continue; + found: + buf[2] |= 0x80; /* QR */ + buf[3] |= 0x80; /* RA */ + memset(buf + 6, 0, 6); /* Clear ANCOUNT, NSCOUNT, ARCOUNT */ + buf[7] = 1; /* ANCOUNT */ + memcpy(p, dp->qname, dp->qname_size); + p += dp->qname_size; + *p++ = dp->qtype >> 8; + *p++ = dp->qtype & 0xFF; + *p++ = 0; + *p++ = 1; /* IN */ + memset(p, 0, 4); /* TTL = 0 */ + p += 4; + *p++ = 0; /* RDLENGTH MSB */ + *p++ = dp->answer_size; /* RDLENGTH LSB */ + memcpy(p, dp->answer, dp->answer_size); + p += dp->answer_size; + nsent = sendto(s, buf, p - buf, 0, &from.s, fromlen); + DPRINTF("sent %zd\n", nsent); + if (nsent != p - buf) + warn("sendto"); + } +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_hostent.c b/contrib/netbsd-tests/lib/libc/net/h_hostent.c new file mode 100644 index 0000000..4a72923 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_hostent.c @@ -0,0 +1,195 @@ +/* $NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $"); + +#include <stdio.h> +#include <string.h> +#include <nsswitch.h> +#include <netdb.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> + +#include <netinet/in.h> +#include <sys/types.h> +#include <arpa/nameser.h> +#include <arpa/inet.h> + +#include "hostent.h" + +extern const char *__res_conf_name; + +static void +phostent(const struct hostent *h) +{ + size_t i; + char buf[1024]; + const int af = h->h_length == NS_INADDRSZ ? AF_INET : AF_INET6; + + printf("name=%s, length=%d, addrtype=%d, aliases=[", + h->h_name, h->h_length, h->h_addrtype); + + for (i = 0; h->h_aliases[i]; i++) + printf("%s%s", i == 0 ? "" : " ", h->h_aliases[i]); + + printf("] addr_list=["); + + for (i = 0; h->h_addr_list[i]; i++) + printf("%s%s", i == 0 ? "" : " ", inet_ntop(af, + h->h_addr_list[i], buf, (socklen_t)sizeof(buf))); + + printf("]\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s [-f <hostsfile>] " + "[-t <any|dns|nis|files>] " + "[-46a] <name|address>\n", getprogname()); + exit(EXIT_FAILURE); +} + +static void +getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...) +{ + va_list ap; + int e; + + va_start(ap, info); + e = (*f)(info, NULL, ap); + va_end(ap); + switch (e) { + case NS_SUCCESS: + phostent(info->hp); + break; + default: + printf("error %d\n", e); + break; + } +} + +static void +geta(struct hostent *hp) { + if (hp == NULL) + printf("error %d\n", h_errno); + else + phostent(hp); +} + +int +main(int argc, char *argv[]) +{ + int (*f)(void *, void *, va_list) = NULL; + const char *type = "any"; + int c, af, e, byaddr, len; + struct hostent hent; + struct getnamaddr info; + char buf[4096]; + + af = AF_INET; + byaddr = 0; + len = 0; + info.hp = &hent; + info.buf = buf; + info.buflen = sizeof(buf); + info.he = &e; + + while ((c = getopt(argc, argv, "46af:r:t:")) != -1) { + switch (c) { + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; + case 'a': + byaddr++; + break; + case 'f': + _hf_sethostsfile(optarg); + break; + case 'r': + __res_conf_name = optarg; + break; + case 't': + type = optarg; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + switch (*type) { + case 'a': + break; + case 'd': + f = byaddr ? _dns_gethtbyaddr : _dns_gethtbyname; + break; +#ifdef YP + case 'n': + f = byaddr ? _yp_gethtbyaddr : _yp_gethtbyname; + break; +#endif + case 'f': + f = byaddr ? _hf_gethtbyaddr : _hf_gethtbyname; + break; + default: + errx(EXIT_FAILURE, "Unknown db type `%s'", type); + } + + if (byaddr) { + struct in6_addr addr; + af = strchr(*argv, ':') ? AF_INET6 : AF_INET; + len = af == AF_INET ? NS_INADDRSZ : NS_IN6ADDRSZ; + if (inet_pton(af, *argv, &addr) == -1) + err(EXIT_FAILURE, "Can't parse `%s'", *argv); + if (*type == 'a') + geta(gethostbyaddr((const char *)&addr, len, af)); + else + getby(f, &info, &addr, len, af); + } else { + if (*type == 'a') + geta(gethostbyname2(*argv, af)); + else + getby(f, &info, *argv, len, af); + } + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c new file mode 100644 index 0000000..2f315d2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c @@ -0,0 +1,107 @@ +/* $NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $"); + +#define _REENTRANT + +#include <assert.h> +#include <nsswitch.h> +#include <pthread.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +static const ns_src testsrc[] = { + { "test", NS_SUCCESS }, + { NULL, 0 } +}; + +static int +func3(void *rv, void *cb_data, va_list ap) +{ + (void)printf("func3: enter\n"); + (void)printf("func3: exit\n"); + + return NS_SUCCESS; +} + +static int +func2(void *rv, void *cb_data, va_list ap) +{ + static const ns_dtab dtab[] = { + { "test", func3, NULL }, + { NULL, NULL, NULL } + }; + int r; + + (void)printf("func2: enter\n"); + r = nsdispatch(NULL, dtab, "test", "test", testsrc); + (void)printf("func2: exit\n"); + + return r; +} + +static int +func1(void) +{ + static const ns_dtab dtab[] = { + { "test", func2, NULL }, + { NULL, NULL, NULL } + }; + int r; + + (void)printf("func1: enter\n"); + r = nsdispatch(NULL, dtab, "test", "test", testsrc); + (void)printf("func1: exit\n"); + + return r; +} + +static void * +thrfunc(void *arg) +{ + pthread_exit(NULL); +} + +int +main(int argc, char *argv[]) +{ + pthread_t thr; + void *threval; + + assert(pthread_create(&thr, NULL, thrfunc, NULL) == 0); + assert(func1() == NS_SUCCESS); + assert(pthread_join(thr, &threval) == 0); +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_protoent.c b/contrib/netbsd-tests/lib/libc/net/h_protoent.c new file mode 100644 index 0000000..f37a85c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_protoent.c @@ -0,0 +1,97 @@ +/* $NetBSD: h_protoent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <netdb.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <stdio.h> + +static void +pserv(const struct protoent *prp) +{ + char **pp; + + printf("name=%s, proto=%d, aliases=", + prp->p_name, prp->p_proto); + for (pp = prp->p_aliases; *pp; pp++) + printf("%s ", *pp); + printf("\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s\n" + "\t%s -p <proto>\n" + "\t%s -n <name>\n", getprogname(), getprogname(), + getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct protoent *prp; + const char *proto = NULL, *name = NULL; + int c; + + while ((c = getopt(argc, argv, "p:n:")) != -1) { + switch (c) { + case 'n': + name = optarg; + break; + case 'p': + proto = optarg; + break; + default: + usage(); + } + } + + if (proto && name) + usage(); + if (proto) { + if ((prp = getprotobynumber(atoi(proto))) != NULL) + pserv(prp); + return 0; + } + if (name) { + if ((prp = getprotobyname(name)) != NULL) + pserv(prp); + return 0; + } + + setprotoent(0); + while ((prp = getprotoent()) != NULL) + pserv(prp); + endprotoent(); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_servent.c b/contrib/netbsd-tests/lib/libc/net/h_servent.c new file mode 100644 index 0000000..6d7efd8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_servent.c @@ -0,0 +1,100 @@ +/* $NetBSD: h_servent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <netdb.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <stdio.h> + +static void +pserv(const struct servent *svp) +{ + char **pp; + + printf("name=%s, port=%d, proto=%s, aliases=", + svp->s_name, ntohs((uint16_t)svp->s_port), svp->s_proto); + for (pp = svp->s_aliases; *pp; pp++) + printf("%s ", *pp); + printf("\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s\n" + "\t%s -p <port> [-P <proto>]\n" + "\t%s -n <name> [-P <proto>]\n", getprogname(), getprogname(), + getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct servent *svp; + const char *port = NULL, *proto = NULL, *name = NULL; + int c; + + while ((c = getopt(argc, argv, "p:n:P:")) != -1) { + switch (c) { + case 'n': + name = optarg; + break; + case 'p': + port = optarg; + break; + case 'P': + proto = optarg; + break; + default: + usage(); + } + } + + if (port && name) + usage(); + if (port) { + if ((svp = getservbyport(htons(atoi(port)), proto)) != NULL) + pserv(svp); + return 0; + } + if (name) { + if ((svp = getservbyname(name, proto)) != NULL) + pserv(svp); + return 0; + } + + setservent(0); + while ((svp = getservent()) != NULL) + pserv(svp); + endservent(); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/hosts b/contrib/netbsd-tests/lib/libc/net/hosts new file mode 100644 index 0000000..87ccbe8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/hosts @@ -0,0 +1,11 @@ +# $NetBSD: hosts,v 1.1 2013/08/16 15:29:45 christos Exp $ +# +# Host Database +# This file should contain the addresses and aliases +# for local hosts that share this file. +# It is used only for "ifconfig" and other operations +# before the nameserver is started. +# +# +::1 localhost localhost. localhost.localdomain. +127.0.0.1 localhost localhost. localhost.localdomain. diff --git a/contrib/netbsd-tests/lib/libc/net/resolv.conf b/contrib/netbsd-tests/lib/libc/net/resolv.conf new file mode 100644 index 0000000..bbc8559 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/resolv.conf @@ -0,0 +1 @@ +nameserver 127.0.0.1 diff --git a/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c new file mode 100644 index 0000000..2a91060 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c @@ -0,0 +1,137 @@ +/* $NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <err.h> +#include <string.h> +#include <errno.h> + +#ifndef __NetBSD__ +#ifdef __linux__ +#include <netinet/ether.h> +#endif +#include <net/ethernet.h> +#endif + +#ifdef __NetBSD__ +#define ETHER_ADDR_LEN 6 + +int ether_aton_r(u_char *dest, size_t len, const char *str); +#endif + +static const struct { + u_char res[ETHER_ADDR_LEN]; + const char *str; + int error; +} tests[] = { + { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }, "01:23:45:67:89:ab", 0 }, +#ifdef __NetBSD__ + { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "0:1:22-3:14:05", 0 }, + { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "000122031405", 0 }, + { { 0x0a, 0x0B, 0xcc, 0xdD, 0xEE, 0x0f }, "0a0BccdDEE0f", 0 }, +#endif +#define ZERO { 0, 0, 0, 0, 0, 0 } + { ZERO, "0:1:2-3:04:05:06", ENAMETOOLONG }, + { ZERO, "0:1:2-3:04:", ENOBUFS }, + { ZERO, "0:1:2-3:04:x7", EINVAL }, + { ZERO, "1:x-3:04:05:7", EINVAL }, + { ZERO, NULL, 0 }, +}; + +ATF_TC(tc_ether_aton); +ATF_TC_HEAD(tc_ether_aton, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that ether_aton(3) works"); +} + +ATF_TC_BODY(tc_ether_aton, tc) +{ +#ifdef __NetBSD__ + u_char dest[ETHER_ADDR_LEN]; +#else + struct ether_addr dest; +#endif + size_t t; +#ifdef __NetBSD__ + int e, r; +#else + int e; + struct ether_addr *r; +#endif + const char *s; + + for (t = 0; tests[t].str; t++) { + s = tests[t].str; + if ((e = tests[t].error) == 0) { +#ifdef __NetBSD__ + if (ether_aton_r(dest, sizeof(dest), s) != e) + atf_tc_fail("failed on `%s'", s); + if (memcmp(dest, tests[t].res, sizeof(dest)) != 0) + atf_tc_fail("unexpected result on `%s'", s); +#else + if (ether_aton_r(s, &dest) == NULL && e == 0) + atf_tc_fail("failed on `%s'", s); + if (memcmp(&dest, tests[t].res, sizeof(dest)) != 0) + atf_tc_fail("unexpected result on `%s'", s); +#endif + } else { +#ifdef __NetBSD__ + if ((r = ether_aton_r(dest, sizeof(dest), s)) != e) + atf_tc_fail("unexpectedly succeeded on `%s' " + "(%d != %d)", s, r, e); +#else + if ((r = ether_aton_r(s, &dest)) != NULL && e != 0) + atf_tc_fail("unexpectedly succeeded on `%s' " + "(%p != %d)", s, r, e); +#endif + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tc_ether_aton); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c new file mode 100644 index 0000000..1c1a0e0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c @@ -0,0 +1,233 @@ +/* $NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $"); + +#include <atf-c.h> +#include <netdb.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> + +static const struct { + const char *name; + int number; +} protos[] = { + + { "icmp", 1 }, { "tcp", 6 }, { "udp", 17 }, { "gre", 47 }, + { "esp", 50 }, { "ah", 51 }, { "sctp", 132}, { "ipv6-icmp", 58 } +}; + +ATF_TC(endprotoent_rewind); +ATF_TC_HEAD(endprotoent_rewind, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that endprotoent(3) rewinds"); +} + +ATF_TC_BODY(endprotoent_rewind, tc) +{ + struct protoent *p; + int i = 0; + + setprotoent(0); + + while ((p = getprotoent()) != NULL && i <= 10) { + ATF_REQUIRE(p->p_proto == i); + i++; + } + + i = 0; + endprotoent(); + + while ((p = getprotoent()) != NULL && i <= 10) { + ATF_REQUIRE(p->p_proto == i); + i++; + } + + endprotoent(); +} + +ATF_TC(getprotobyname_basic); +ATF_TC_HEAD(getprotobyname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of getprotobyname(3)"); +} + +ATF_TC_BODY(getprotobyname_basic, tc) +{ + struct protoent *p; + size_t i; + + for (i = 0; i < __arraycount(protos); i++) { + + p = getprotobyname(protos[i].name); + + ATF_REQUIRE(p != NULL); + ATF_REQUIRE(p->p_proto == protos[i].number); + ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0); + } + + endprotoent(); +} + +ATF_TC(getprotobyname_err); +ATF_TC_HEAD(getprotobyname_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobyname(3)"); +} + +ATF_TC_BODY(getprotobyname_err, tc) +{ + static const char * name[] = + { "xxx", "yyy", "xyz", ".as.d}9x.._?!!#\xa4,\xa8^//&%%,", + "0", "", "tCp", "uDp", "t c p", "tcp ", " tcp" }; + + size_t i; + + for (i = 0; i < __arraycount(name); i++) + ATF_REQUIRE(getprotobyname(name[i]) == NULL); + + endprotoent(); +} + +ATF_TC(getprotobynumber_basic); +ATF_TC_HEAD(getprotobynumber_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of getprotobynumber(3)"); +} + +ATF_TC_BODY(getprotobynumber_basic, tc) +{ + struct protoent *p; + size_t i; + + /* + * No ATF_CHECK() due static storage. + */ + for (i = 0; i < __arraycount(protos); i++) { + + p = getprotobynumber(protos[i].number); + + ATF_REQUIRE(p != NULL); + ATF_REQUIRE(p->p_proto == protos[i].number); + ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0); + } + + endprotoent(); +} + +ATF_TC(getprotobynumber_err); +ATF_TC_HEAD(getprotobynumber_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobynumber(3)"); +} + +ATF_TC_BODY(getprotobynumber_err, tc) +{ + static const int number[] = { -1, -99999, INT_MAX, 1000000000 }; + size_t i; + + for (i = 0; i < __arraycount(number); i++) + ATF_REQUIRE(getprotobynumber(number[i]) == NULL); + + endprotoent(); +} + +ATF_TC(getprotoent_next); +ATF_TC_HEAD(getprotoent_next, tc) +{ + atf_tc_set_md_var(tc, "descr", "getprotoent(3) returns next line?"); +} + +ATF_TC_BODY(getprotoent_next, tc) +{ + struct protoent *p; + int i = 0; + + /* + * The range [0, 60] is already reserved by IANA. + */ + while ((p = getprotoent()) != NULL && i <= 60) { + ATF_CHECK(p->p_proto == i); + i++; + } + + endprotoent(); +} + +ATF_TC(setprotoent_rewind); +ATF_TC_HEAD(setprotoent_rewind, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that setprotoent(3) rewinds"); +} + +ATF_TC_BODY(setprotoent_rewind, tc) +{ + struct protoent *p; + + setprotoent(0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 1); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 2); + + setprotoent(0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 1); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 2); + + endprotoent(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getprotobyname_basic); + ATF_TP_ADD_TC(tp, getprotobyname_err); + ATF_TP_ADD_TC(tp, getprotobynumber_basic); + ATF_TP_ADD_TC(tp, getprotobynumber_err); + ATF_TP_ADD_TC(tp, endprotoent_rewind); + ATF_TP_ADD_TC(tp, getprotoent_next); + ATF_TP_ADD_TC(tp, setprotoent_rewind); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_hostent.sh b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh new file mode 100755 index 0000000..b597b6d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh @@ -0,0 +1,240 @@ +# $NetBSD: t_hostent.sh,v 1.10 2014/01/13 11:08:14 gson Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +n6="sixthavenue.astron.com" +a6="2620:106:3003:1f00:3e4a:92ff:fef4:e180" +ans6="name=$n6, length=16, addrtype=24, aliases=[] addr_list=[$a6]\n" + +n4="sixthavenue.astron.com" +a4="38.117.134.16" +ans4="name=$n4, length=4, addrtype=2, aliases=[] addr_list=[$a4]\n" + +l6="localhost" +al6="::1" +loc6="name=$l6, length=16, addrtype=24, aliases=[localhost. localhost.localdomain.] addr_list=[$al6]\n" + +l4="localhost" +al4="127.0.0.1" +loc4="name=$l4, length=4, addrtype=2, aliases=[localhost. localhost.localdomain.] addr_list=[$al4]\n" + +dir="$(atf_get_srcdir)" +res="-r ${dir}/resolv.conf" + +# Hijack DNS traffic using a single rump server instance and a DNS +# server listening on its loopback address. + +start_dns_server() { + export RUMP_SERVER=unix:///tmp/rumpserver + rump_server -lrumpdev -lrumpnet -lrumpnet_net -lrumpnet_netinet \ + -lrumpnet_netinet6 -lrumpnet_local $RUMP_SERVER + HIJACK_DNS="LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK='socket=inet:inet6'" + eval $HIJACK_DNS ${dir}/h_dns_server $1 +} + +stop_dns_server() { + export RUMP_SERVER=unix:///tmp/rumpserver + kill $(cat dns_server_$1.pid) + rump.halt +} + +atf_test_case gethostbyname4 cleanup +gethostbyname4_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyname4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -4 $n4" +} +gethostbyname4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyname6 cleanup cleanup +gethostbyname6_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyname6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -6 $n6" +} +gethostbyname6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyaddr4 cleanup +gethostbyaddr4_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a4" +} +gethostbyaddr4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyaddr6 cleanup +gethostbyaddr6_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a6" +} +gethostbyaddr6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case hostsbynamelookup4 +hostsbynamelookup4_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET" +} +hostsbynamelookup4_body() +{ + atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 $l4" +} + +atf_test_case hostsbynamelookup6 +hostsbynamelookup6_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET6" +} +hostsbynamelookup6_body() +{ + atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 $l6" +} + +atf_test_case hostsbyaddrlookup4 +hostsbyaddrlookup4_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET" +} +hostsbyaddrlookup4_body() +{ + atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 -a $al4" +} + +atf_test_case hostsbyaddrlookup6 +hostsbyaddrlookup6_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET6" +} +hostsbyaddrlookup6_body() +{ + atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 -a $al6" +} + +atf_test_case dnsbynamelookup4 cleanup +dnsbynamelookup4_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET" +} +dnsbynamelookup4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 $n4" +} +dnsbynamelookup4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbynamelookup6 cleanup +dnsbynamelookup6_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET6" +} +dnsbynamelookup6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 $n6" +} +dnsbynamelookup6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbyaddrlookup4 cleanup +dnsbyaddrlookup4_head() +{ + atf_set "descr" "Checks DNS address lookup for AF_INET" +} +dnsbyaddrlookup4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 -a $a4" +} +dnsbyaddrlookup4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbyaddrlookup6 cleanup +dnsbyaddrlookup6_head() +{ + atf_set "descr" "Checks dns address lookup for AF_INET6" +} +dnsbyaddrlookup6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 -a $a6" +} +dnsbyaddrlookup6_cleanup() +{ + stop_dns_server 4 +} + +atf_init_test_cases() +{ + atf_add_test_case gethostbyname4 + atf_add_test_case gethostbyname6 + atf_add_test_case gethostbyaddr4 + atf_add_test_case gethostbyaddr6 + + atf_add_test_case hostsbynamelookup4 + atf_add_test_case hostsbynamelookup6 + atf_add_test_case hostsbyaddrlookup4 + atf_add_test_case hostsbyaddrlookup6 + + atf_add_test_case dnsbynamelookup4 + atf_add_test_case dnsbynamelookup6 + atf_add_test_case dnsbyaddrlookup4 + atf_add_test_case dnsbyaddrlookup6 +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh new file mode 100755 index 0000000..b584369 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh @@ -0,0 +1,51 @@ +# $NetBSD: t_nsdispatch.sh,v 1.1 2011/01/13 01:56:44 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case recurse +recurse_head() +{ + atf_set "descr" "Checks recursive calls to nsdispatch()" \ + "within threaded program" +} +recurse_body() +{ + cat >exp <<EOF +func1: enter +func2: enter +func3: enter +func3: exit +func2: exit +func1: exit +EOF + + atf_check -o file:exp "$(atf_get_srcdir)/h_nsd_recurse" +} + +atf_init_test_cases() +{ + atf_add_test_case recurse +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_protoent.sh b/contrib/netbsd-tests/lib/libc/net/t_protoent.sh new file mode 100755 index 0000000..322d426 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_protoent.sh @@ -0,0 +1,91 @@ +# $NetBSD: t_protoent.sh,v 1.2 2012/09/03 15:32:18 christos Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case protoent +protoent_head() +{ + atf_set "descr" "Checks {get,set,end}protoent(3)" +} +protoent_body() +{ + # + # Munge original to: + # (1) match output format of the test program + # (2) fold all names for the same port/proto together + # (3) prune duplicates + # + tr '\t' ' ' </etc/protocols | awk ' + function add(key, name, i, n, ar) { + n = split(names[key], ar); + for (i = 1; i <= n; i++) { + if (name == ar[i]) { + return; + } + } + delete ar; + names[key] = names[key] " " name; + } + { + sub("#.*", "", $0); + gsub(" *", " ", $0); + if (NF == 0) { + next; + } + add($2, $1, 0); + for (i = 3; i <= NF; i++) { + add($2, $i, 1); + } + } + END { + for (key in names) { + proto = key; + + n = split(names[key], ar); + printf "name=%s, proto=%s, aliases=", ar[1], proto; + for (i=2; i<=n; i++) { + if (i>2) { + printf " "; + } + printf "%s", ar[i]; + } + printf "\n"; + delete ar; + } + } + ' | sort >exp + + # run test program + "$(atf_get_srcdir)/h_protoent" | sed 's/ *$//' | sort >out + + diff -u exp out || \ + atf_fail "Observed output does not match reference output" +} + +atf_init_test_cases() +{ + atf_add_test_case protoent +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_servent.sh b/contrib/netbsd-tests/lib/libc/net/t_servent.sh new file mode 100755 index 0000000..0979eb3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_servent.sh @@ -0,0 +1,111 @@ +# $NetBSD: t_servent.sh,v 1.1 2011/01/12 17:32:27 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case servent +servent_head() +{ + atf_set "descr" "Checks {get,set,end}servent(3)" +} +servent_body() +{ + # + # Munge original to: + # (1) match output format of the test program + # (2) fold all names for the same port/proto together + # (3) prune duplicates + # + tr '\t' ' ' </etc/services | awk ' + function add(key, name, i, n, ar) { + n = split(names[key], ar); + for (i=1; i<=n; i++) { + if (name == ar[i]) { + return; + } + } + delete ar; + names[key] = names[key] " " name; + } + + { + sub("#.*", "", $0); + gsub(" *", " ", $0); + if (NF==0) { + next; + } + add($2, $1, 0); + for (i=3; i<=NF; i++) { + add($2, $i, 1); + } + } + END { + for (key in names) { + portproto = key; + sub("/", ", proto=", portproto); + portproto = "port=" portproto; + + n = split(names[key], ar); + printf "name=%s, %s, aliases=", ar[1], portproto; + for (i=2; i<=n; i++) { + if (i>2) { + printf " "; + } + printf "%s", ar[i]; + } + printf "\n"; + delete ar; + } + } + ' | sort >exp + + case "$(uname)" in + FreeBSD) + # (3) Don't prune duplicates + tr '\t' ' ' < /etc/services | + sed 's/#.*//;s/ */ /g; /^$/d;s#\([0-9]\)/#\1 #;s/ *$//' | + sort | + while read l; do + set $l + name=$1; shift + port=$1; shift + proto=$1; shift + alias="$@" + printf "name=%s, port=%s, proto=%s, aliases=%s\n" \ + $name $port $proto "$alias" + done > exp + ;; + esac + + # run test program + "$(atf_get_srcdir)/h_servent" | sed 's/ *$//' | sort >out + + diff -u exp out || atf_fail "Observed output does not match reference output" +} + +atf_init_test_cases() +{ + atf_add_test_case servent +} diff --git a/contrib/netbsd-tests/lib/libc/regex/README b/contrib/netbsd-tests/lib/libc/regex/README new file mode 100644 index 0000000..6d9a28c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/README @@ -0,0 +1,33 @@ +regular expression test set +Lines are at least three fields, separated by one or more tabs. "" stands +for an empty field. First field is an RE. Second field is flags. If +C flag given, regcomp() is expected to fail, and the third field is the +error name (minus the leading REG_). + +Otherwise it is expected to succeed, and the third field is the string to +try matching it against. If there is no fourth field, the match is +expected to fail. If there is a fourth field, it is the substring that +the RE is expected to match. If there is a fifth field, it is a comma- +separated list of what the subexpressions should match, with - indicating +no match for that one. In both the fourth and fifth fields, a (sub)field +starting with @ indicates that the (sub)expression is expected to match +a null string followed by the stuff after the @; this provides a way to +test where null strings match. The character `N' in REs and strings +is newline, `S' is space, `T' is tab, `Z' is NUL. + +The full list of flags: + - placeholder, does nothing + b RE is a BRE, not an ERE + & try it as both an ERE and a BRE + C regcomp() error expected, third field is error name + i REG_ICASE + m ("mundane") REG_NOSPEC + s REG_NOSUB (not really testable) + n REG_NEWLINE + ^ REG_NOTBOL + $ REG_NOTEOL + # REG_STARTEND (see below) + p REG_PEND + +For REG_STARTEND, the start/end offsets are those of the substring +enclosed in (). diff --git a/contrib/netbsd-tests/lib/libc/regex/data/anchor.in b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in new file mode 100644 index 0000000..d145408 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in @@ -0,0 +1,33 @@ +# anchoring and REG_NEWLINE +^abc$ & abc abc +a^b - a^b +a^b b a^b a^b +a$b - a$b +a$b b a$b a$b +^ & abc @abc +$ & abc @ +^$ & "" @ +$^ - "" @ +\($\)\(^\) b "" @ +# stop retching, those are legitimate (although disgusting) +^^ - "" @ +$$ - "" @ +b$ & abNc +b$ &n abNc b +^b$ & aNbNc +^b$ &n aNbNc b +^$ &n aNNb @Nb +^$ n abc +^$ n abcN @ +$^ n aNNb @Nb +\($\)\(^\) bn aNNb @Nb +^^ n^ aNNb @Nb +$$ n aNNb @NN +^a ^ a +a$ $ a +^a ^n aNb +^b ^n aNb b +a$ $n bNa +b$ $n bNa b +a*(^b$)c* - b b +a*\(^b$\)c* b b b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/README b/contrib/netbsd-tests/lib/libc/regex/data/att/README new file mode 100644 index 0000000..e2ee6f6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/README @@ -0,0 +1,8 @@ +AT&T test data from: http://www2.research.att.com/~gsf/testregex/ + +Quoting from the page: + testregex.c 2004-05-31 is the latest source for the AT&T Research + regression test harness for the X/Open regex pattern match interface. + See testregex(1) for option and test input details. The source and + test data posted here are license free. + diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat new file mode 100644 index 0000000..4399ca1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat @@ -0,0 +1,216 @@ +NOTE all standard compliant implementations should pass these : 2002-05-31 + +BE abracadabra$ abracadabracadabra (7,18) +BE a...b abababbb (2,7) +BE XXXXXX ..XXXXXX (2,8) +E \) () (1,2) +BE a] a]a (0,2) +B } } (0,1) +E \} } (0,1) +BE \] ] (0,1) +B ] ] (0,1) +E ] ] (0,1) +B { { (0,1) +B } } (0,1) +BE ^a ax (0,1) +BE \^a a^a (1,3) +BE a\^ a^ (0,2) +BE a$ aa (1,2) +BE a\$ a$ (0,2) +BE ^$ NULL (0,0) +E $^ NULL (0,0) +E a($) aa (1,2)(2,2) +E a*(^a) aa (0,1)(0,1) +E (..)*(...)* a (0,0) +E (..)*(...)* abcd (0,4)(2,4) +E (ab|a)(bc|c) abc (0,3)(0,2)(2,3) +E (ab)c|abc abc (0,3)(0,2) +E a{0}b ab (1,2) +E (a*)(b?)(b+)b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7) +E (a*)(b{0,1})(b{1,})b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7) +E a{9876543210} NULL BADBR +E ((a|a)|a) a (0,1)(0,1)(0,1) +E (a*)(a|aa) aaaa (0,4)(0,3)(3,4) +E a*(a.|aa) aaaa (0,4)(2,4) +E a(b)|c(d)|a(e)f aef (0,3)(?,?)(?,?)(1,2) +E (a|b)?.* b (0,1)(0,1) +E (a|b)c|a(b|c) ac (0,2)(0,1) +E (a|b)c|a(b|c) ab (0,2)(?,?)(1,2) +E (a|b)*c|(a|ab)*c abc (0,3)(1,2) +E (a|b)*c|(a|ab)*c xc (1,2) +E (.a|.b).*|.*(.a|.b) xa (0,2)(0,2) +E a?(ab|ba)ab abab (0,4)(0,2) +E a?(ac{0}b|ba)ab abab (0,4)(0,2) +E ab|abab abbabab (0,2) +E aba|bab|bba baaabbbaba (5,8) +E aba|bab baaabbbaba (6,9) +E (aa|aaa)*|(a|aaaaa) aa (0,2)(0,2) +E (a.|.a.)*|(a|.a...) aa (0,2)(0,2) +E ab|a xabc (1,3) +E ab|a xxabc (2,4) +Ei (Ab|cD)* aBcD (0,4)(2,4) +BE [^-] --a (2,3) +BE [a-]* --a (0,3) +BE [a-m-]* --amoma-- (0,4) +E :::1:::0:|:::1:1:0: :::0:::1:::1:::0: (8,17) +E :::1:::0:|:::1:1:1: :::0:::1:::1:::0: (8,17) +{E [[:upper:]] A (0,1) [[<element>]] not supported +E [[:lower:]]+ `az{ (1,3) +E [[:upper:]]+ @AZ[ (1,3) +BE [[-]] [[-]] (2,4) +BE [[.NIL.]] NULL ECOLLATE +BE [[=aleph=]] NULL ECOLLATE +} +BE$ \n \n (0,1) +BEn$ \n \n (0,1) +BE$ [^a] \n (0,1) +BE$ \na \na (0,2) +E (a)(b)(c) abc (0,3)(0,1)(1,2)(2,3) +BE xxx xxx (0,3) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 6, (0,6) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) 2/7 (0,3) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 1,Feb 6 (5,11) +E3 ((((((((((((((((((((((((((((((x)))))))))))))))))))))))))))))) x (0,1)(0,1)(0,1) +E3 ((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))* xx (0,2)(1,2)(1,2) +E a?(ab|ba)* ababababababababababababababababababababababababababababababababababababababababa (0,81)(79,81) +E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabbbbaa (18,25) +E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabaa (18,22) +E aaac|aabc|abac|abbc|baac|babc|bbac|bbbc baaabbbabac (7,11) +BE$ .* \x01\xff (0,2) +E aaaa|bbbb|cccc|ddddd|eeeeee|fffffff|gggg|hhhh|iiiii|jjjjj|kkkkk|llll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa (53,57) +L aaaa\nbbbb\ncccc\nddddd\neeeeee\nfffffff\ngggg\nhhhh\niiiii\njjjjj\nkkkkk\nllll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa NOMATCH +E a*a*a*a*a*b aaaaaaaaab (0,10) +BE ^ NULL (0,0) +BE $ NULL (0,0) +BE ^$ NULL (0,0) +BE ^a$ a (0,1) +BE abc abc (0,3) +BE abc xabcy (1,4) +BE abc ababc (2,5) +BE ab*c abc (0,3) +BE ab*bc abc (0,3) +BE ab*bc abbc (0,4) +BE ab*bc abbbbc (0,6) +E ab+bc abbc (0,4) +E ab+bc abbbbc (0,6) +E ab?bc abbc (0,4) +E ab?bc abc (0,3) +E ab?c abc (0,3) +BE ^abc$ abc (0,3) +BE ^abc abcc (0,3) +BE abc$ aabc (1,4) +BE ^ abc (0,0) +BE $ abc (3,3) +BE a.c abc (0,3) +BE a.c axc (0,3) +BE a.*c axyzc (0,5) +BE a[bc]d abd (0,3) +BE a[b-d]e ace (0,3) +BE a[b-d] aac (1,3) +BE a[-b] a- (0,2) +BE a[b-] a- (0,2) +BE a] a] (0,2) +BE a[]]b a]b (0,3) +BE a[^bc]d aed (0,3) +BE a[^-b]c adc (0,3) +BE a[^]b]c adc (0,3) +E ab|cd abc (0,2) +E ab|cd abcd (0,2) +E a\(b a(b (0,3) +E a\(*b ab (0,2) +E a\(*b a((b (0,4) +E ((a)) abc (0,1)(0,1)(0,1) +E (a)b(c) abc (0,3)(0,1)(2,3) +E a+b+c aabbabc (4,7) +E a* aaa (0,3) +E (a*)* - (0,0)(0,0) +E (a*)+ - (0,0)(0,0) +E (a*|b)* - (0,0)(0,0) +E (a+|b)* ab (0,2)(1,2) +E (a+|b)+ ab (0,2)(1,2) +E (a+|b)? ab (0,1)(0,1) +BE [^ab]* cde (0,3) +E (^)* - (0,0)(0,0) +BE a* NULL (0,0) +E ([abc])*d abbbcd (0,6)(4,5) +E ([abc])*bcd abcd (0,4)(0,1) +E a|b|c|d|e e (0,1) +E (a|b|c|d|e)f ef (0,2)(0,1) +E ((a*|b))* - (0,0)(0,0)(0,0) +BE abcd*efg abcdefg (0,7) +BE ab* xabyabbbz (1,3) +BE ab* xayabbbz (1,2) +E (ab|cd)e abcde (2,5)(2,4) +BE [abhgefdc]ij hij (0,3) +E (a|b)c*d abcd (1,4)(1,2) +E (ab|ab*)bc abc (0,3)(0,1) +E a([bc]*)c* abc (0,3)(1,3) +E a([bc]*)(c*d) abcd (0,4)(1,3)(3,4) +E a([bc]+)(c*d) abcd (0,4)(1,3)(3,4) +E a([bc]*)(c+d) abcd (0,4)(1,2)(2,4) +E a[bcd]*dcdcde adcdcde (0,7) +E (ab|a)b*c abc (0,3)(0,2) +E ((a)(b)c)(d) abcd (0,4)(0,3)(0,1)(1,2)(3,4) +BE [A-Za-z_][A-Za-z0-9_]* alpha (0,5) +E ^a(bc+|b[eh])g|.h$ abh (1,3) +E (bc+d$|ef*g.|h?i(j|k)) effgz (0,5)(0,5) +E (bc+d$|ef*g.|h?i(j|k)) ij (0,2)(0,2)(1,2) +E (bc+d$|ef*g.|h?i(j|k)) reffgz (1,6)(1,6) +E (((((((((a))))))))) a (0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1) +BE multiple words multiple words yeah (0,14) +E (.*)c(.*) abcde (0,5)(0,2)(3,5) +BE abcd abcd (0,4) +E a(bc)d abcd (0,4)(1,3) +E a[-]?c ac (0,3) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qaddafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mo'ammar Gadhafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Kaddafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qadhafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gadafi (0,14)(?,?)(10,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadafi (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moamar Gaddafi (0,14)(?,?)(9,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadhdhafi (0,18)(?,?)(13,15) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Khaddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafy (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghadafi (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muamar Kaddafi (0,14)(?,?)(9,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Quathafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gheddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Khadafy (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Qudhafi (0,15)(?,?)(10,12) +E a+(b|c)*d+ aabcdd (0,6)(3,4) +E ^.+$ vivi (0,4) +E ^(.+)$ vivi (0,4)(0,4) +E ^([^!.]+).att.com!(.+)$ gryphon.att.com!eby (0,19)(0,7)(16,19) +E ^([^!]+!)?([^!]+)$ bas (0,3)(?,?)(0,3) +E ^([^!]+!)?([^!]+)$ bar!bas (0,7)(0,4)(4,7) +E ^([^!]+!)?([^!]+)$ foo!bas (0,7)(0,4)(4,7) +E ^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(4,8)(8,11) +E ((foo)|(bar))!bas bar!bas (0,7)(0,3)(?,?)(0,3) +E ((foo)|(bar))!bas foo!bar!bas (4,11)(4,7)(?,?)(4,7) +E ((foo)|(bar))!bas foo!bas (0,7)(0,3)(0,3) +E ((foo)|bar)!bas bar!bas (0,7)(0,3) +E ((foo)|bar)!bas foo!bar!bas (4,11)(4,7) +E ((foo)|bar)!bas foo!bas (0,7)(0,3)(0,3) +E (foo|(bar))!bas bar!bas (0,7)(0,3)(0,3) +E (foo|(bar))!bas foo!bar!bas (4,11)(4,7)(4,7) +E (foo|(bar))!bas foo!bas (0,7)(0,3) +E (foo|bar)!bas bar!bas (0,7)(0,3) +E (foo|bar)!bas foo!bar!bas (4,11)(4,7) +E (foo|bar)!bas foo!bas (0,7)(0,3) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bas (0,3)(?,?)(0,3) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bar!bas (0,7)(0,4)(4,7) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(?,?)(?,?)(4,8)(8,11) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bas (0,7)(0,4)(4,7) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bas (0,3)(0,3)(?,?)(0,3) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bar!bas (0,7)(0,7)(0,4)(4,7) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bas (0,7)(0,7)(0,4)(4,7) +E .*(/XXX).* /XXX (0,4)(0,4) +E .*(\\XXX).* \XXX (0,4)(0,4) +E \\XXX \XXX (0,4) +E .*(/000).* /000 (0,4)(0,4) +E .*(\\000).* \000 (0,4)(0,4) +E \\000 \000 (0,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat new file mode 100644 index 0000000..d348512 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat @@ -0,0 +1,62 @@ +NOTE regex implementation categorization 2004-05-31 + +?E aa* xaxaax (1,2) POSITION=leftmost +; POSITION=bug + +?E (a*)(ab)*(b*) abc (0,2)(0,1)(?,?)(1,2) ASSOCIATIVITY=right +|E (a*)(ab)*(b*) abc (0,2)(0,0)(0,2)(2,2) ASSOCIATIVITY=left +; ASSOCIATIVITY=bug + +?E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,2)(0,0)(0,2)(2,3)(2,2)(2,3) SUBEXPRESSION=precedence +|E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,1)(0,1)(?,?)(1,3)(1,2)(2,3) SUBEXPRESSION=grouping +; SUBEXPRESSION=bug + +?E (...?.?)* xxxxxx (0,6)(4,6) REPEAT_LONGEST=first +|E (...?.?)* xxxxxx (0,6)(2,6) REPEAT_LONGEST=last +|E (...?.?)* xxxxxx OK REPEAT_LONGEST=unknown +; REPEAT_LONGEST=bug + +?E (a|ab)(bc|c) abcabc (0,3)(0,2)(2,3) EXPECTED +|E (a|ab)(bc|c) abcabc (0,3)(0,1)(1,3) BUG=alternation-order +; BUG=alternation-order-UNKNOWN + +?E (aba|a*b)(aba|a*b) ababa (0,5)(0,2)(2,5) EXPECTED +|E (aba|a*b)(aba|a*b) ababa (0,4)(0,3)(3,4) BUG=first-match +; BUG=unknown-match + +?B a\(b\)*\1 a NOMATCH EXPECTED +|B a\(b\)*\1 a (0,1) BUG=nomatch-match +|B a\(b\)*\1 abab (0,2)(1,2) # BUG=repeat-any +; BUG=nomatch-match-UNKNOWN + +?E (a*){2} xxxxx (0,0)(0,0) EXPECTED +|E (a*){2} xxxxx (5,5)(5,5) BUG=range-null +; BUG=range-null-UNKNOWN + +?B a\(b\)*\1 abab NOMATCH EXPECTED +|B a\(b\)*\1 abab (0,1) # BUG=nomatch-match +|B a\(b\)*\1 abab (0,2)(1,2) BUG=repeat-any +; BUG=repeat-any-UNKNOWN + +?E (a*)* a (0,1)(0,1) EXPECTED +|E (a*)* ax (0,1)(0,1) BUG=repeat-null-unknown +|E (a*)* a (0,1)(1,1) BUG=repeat-null +; BUG=repeat-null-UNKNOWN + +?E (aba|a*b)* ababa (0,5)(2,5) EXPECTED +|E (aba|a*b)* ababa (0,5)(3,4) BUG=repeat-short +|E (aba|a*b)* ababa (0,4)(3,4) # LENGTH=first +; BUG=repeat-short-UNKNOWN + +?E (a(b)?)+ aba (0,3)(2,3) EXPECTED +|E (a(b)?)+ aba (0,3)(2,3)(1,2) BUG=repeat-artifact +; BUG=repeat-artifact-UNKNOWN + +?B \(a\(b\)*\)*\2 abab NOMATCH EXPECTED +|B \(a\(b\)*\)*\2 abab (0,4)(2,3)(1,2) BUG=repeat-artifact-nomatch +; BUG=repeat-artifact-nomatch-UNKNOWN + +?E (a?)((ab)?)(b?)a?(ab)?b? abab (0,4)(0,1)(1,1)(?,?)(1,2)(2,4) BUG=subexpression-first +|E .*(.*) ab (0,2)(2,2) EXPECTED +|E .*(.*) ab (0,2)(0,2) BUG=subexpression-first +; BUG=subexpression-first-UNKNOWN diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat new file mode 100644 index 0000000..39f3111 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat @@ -0,0 +1,30 @@ +NOTE left-assoc:pass-all right-assoc:pass-all : 2002-04-29 + +E (a|ab)(c|bcd) abcd (0,4)(0,1)(1,4) +E (a|ab)(bcd|c) abcd (0,4)(0,1)(1,4) +E (ab|a)(c|bcd) abcd (0,4)(0,1)(1,4) +E (ab|a)(bcd|c) abcd (0,4)(0,1)(1,4) +E ((a|ab)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((a|ab)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((ab|a)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((ab|a)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E (a|ab)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (a|ab)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (ab|a)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (ab|a)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (a*)(b|abc) abc (0,3)(0,0)(0,3) +E (a*)(abc|b) abc (0,3)(0,0)(0,3) +E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)(b|abc) abc (0,3)(0,0)(0,3) +E (a*)(abc|b) abc (0,3)(0,0)(0,3) +E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a|ab) ab (0,2)(0,2) +E (ab|a) ab (0,2)(0,2) +E (a|ab)(b*) ab (0,2)(0,2)(2,2) +E (ab|a)(b*) ab (0,2)(0,2)(2,2) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat new file mode 100644 index 0000000..9c068c6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat @@ -0,0 +1,16 @@ +NOTE left-assoc:pass-all right-assoc:pass-none : 2002-04-29 + +E (a|ab)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (a|ab)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4) + +E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3) + +E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat new file mode 100644 index 0000000..c73d8f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat @@ -0,0 +1,73 @@ +NOTE null subexpression matches : 2002-06-06 + +E (a*)* a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a*)+ a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a+)* a (0,1)(0,1) +E SAME x (0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a+)+ a (0,1)(0,1) +E SAME x NOMATCH +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) + +E ([a]*)* a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E ([a]*)+ a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E ([^b]*)* a (0,1)(0,1) +E SAME b (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaab (0,6)(0,6) +E ([ab]*)* a (0,1)(0,1) +E SAME aaaaaa (0,6)(0,6) +E SAME ababab (0,6)(0,6) +E SAME bababa (0,6)(0,6) +E SAME b (0,1)(0,1) +E SAME bbbbbb (0,6)(0,6) +E SAME aaaabcde (0,5)(0,5) +E ([^a]*)* b (0,1)(0,1) +E SAME bbbbbb (0,6)(0,6) +E SAME aaaaaa (0,0)(0,0) +E ([^ab]*)* ccccxx (0,6)(0,6) +E SAME ababab (0,0)(0,0) + +E ((z)+|a)* zabcde (0,2)(1,2) + +{E a+? aaaaaa (0,1) no *? +? mimimal match ops +E (a) aaa (0,1)(0,1) +E (a*?) aaa (0,0)(0,0) +E (a)*? aaa (0,0) +E (a*?)*? aaa (0,0) +} + +B \(a*\)*\(x\) x (0,1)(0,0)(0,1) +B \(a*\)*\(x\) ax (0,2)(0,1)(1,2) +B \(a*\)*\(x\) axa (0,2)(0,1)(1,2) +B \(a*\)*\(x\)\(\1\) x (0,1)(0,0)(0,1)(1,1) +B \(a*\)*\(x\)\(\1\) ax (0,2)(1,1)(1,2)(2,2) +B \(a*\)*\(x\)\(\1\) axa (0,3)(0,1)(1,2)(2,3) +B \(a*\)*\(x\)\(\1\)\(x\) axax (0,4)(0,1)(1,2)(2,3)(3,4) +B \(a*\)*\(x\)\(\1\)\(x\) axxa (0,3)(1,1)(1,2)(2,2)(2,3) + +E (a*)*(x) x (0,1)(0,0)(0,1) +E (a*)*(x) ax (0,2)(0,1)(1,2) +E (a*)*(x) axa (0,2)(0,1)(1,2) + +E (a*)+(x) x (0,1)(0,0)(0,1) +E (a*)+(x) ax (0,2)(0,1)(1,2) +E (a*)+(x) axa (0,2)(0,1)(1,2) + +E (a*){2}(x) x (0,1)(0,0)(0,1) +E (a*){2}(x) ax (0,2)(1,1)(1,2) +E (a*){2}(x) axa (0,2)(1,1)(1,2) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat new file mode 100644 index 0000000..c24749c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat @@ -0,0 +1,140 @@ +NOTE implicit vs. explicit repetitions : 2009-02-02 + +# Glenn Fowler <gsf@research.att.com> +# conforming matches (column 4) must match one of the following BREs +# NOMATCH +# (0,.)\((\(.\),\(.\))(?,?)(\2,\3)\)* +# (0,.)\((\(.\),\(.\))(\2,\3)(?,?)\)* +# i.e., each 3-tuple has two identical elements and one (?,?) + +E ((..)|(.)) NULL NOMATCH +E ((..)|(.))((..)|(.)) NULL NOMATCH +E ((..)|(.))((..)|(.))((..)|(.)) NULL NOMATCH + +E ((..)|(.)){1} NULL NOMATCH +E ((..)|(.)){2} NULL NOMATCH +E ((..)|(.)){3} NULL NOMATCH + +E ((..)|(.))* NULL (0,0) + +E ((..)|(.)) a (0,1)(0,1)(?,?)(0,1) +E ((..)|(.))((..)|(.)) a NOMATCH +E ((..)|(.))((..)|(.))((..)|(.)) a NOMATCH + +E ((..)|(.)){1} a (0,1)(0,1)(?,?)(0,1) +E ((..)|(.)){2} a NOMATCH +E ((..)|(.)){3} a NOMATCH + +E ((..)|(.))* a (0,1)(0,1)(?,?)(0,1) + +E ((..)|(.)) aa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aa (0,2)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2) +E ((..)|(.))((..)|(.))((..)|(.)) aa NOMATCH + +E ((..)|(.)){1} aa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aa (0,2)(1,2)(?,?)(1,2) +E ((..)|(.)){3} aa NOMATCH + +E ((..)|(.))* aa (0,2)(0,2)(0,2)(?,?) + +E ((..)|(.)) aaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaa (0,3)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3) +E ((..)|(.))((..)|(.))((..)|(.)) aaa (0,3)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2)(2,3)(?,?)(2,3) + +E ((..)|(.)){1} aaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaa (0,3)(2,3)(?,?)(2,3) +E ((..)|(.)){3} aaa (0,3)(2,3)(?,?)(2,3) + +E ((..)|(.))* aaa (0,3)(2,3)(?,?)(2,3) + +E ((..)|(.)) aaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3)(3,4)(?,?)(3,4) + +E ((..)|(.)){1} aaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaa (0,4)(3,4)(?,?)(3,4) + +E ((..)|(.))* aaaa (0,4)(2,4)(2,4)(?,?) + +E ((..)|(.)) aaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaaa (0,5)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,5)(?,?)(4,5) + +E ((..)|(.)){1} aaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaaa (0,5)(4,5)(?,?)(4,5) + +E ((..)|(.))* aaaaa (0,5)(4,5)(?,?)(4,5) + +E ((..)|(.)) aaaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaaaa (0,6)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,6)(4,6)(?,?) + +E ((..)|(.)){1} aaaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaaaa (0,6)(4,6)(4,6)(?,?) + +E ((..)|(.))* aaaaaa (0,6)(4,6)(4,6)(?,?) + +NOTE additional repetition tests graciously provided by Chris Kuklewicz www.haskell.org 2009-02-02 + +# These test a bug in OS X / FreeBSD / NetBSD, and libtree. +# Linux/GLIBC gets the {8,} and {8,8} wrong. + +:HA#100:E X(.?){0,}Y X1234567Y (0,9)(7,8) +:HA#101:E X(.?){1,}Y X1234567Y (0,9)(7,8) +:HA#102:E X(.?){2,}Y X1234567Y (0,9)(7,8) +:HA#103:E X(.?){3,}Y X1234567Y (0,9)(7,8) +:HA#104:E X(.?){4,}Y X1234567Y (0,9)(7,8) +:HA#105:E X(.?){5,}Y X1234567Y (0,9)(7,8) +:HA#106:E X(.?){6,}Y X1234567Y (0,9)(7,8) +:HA#107:E X(.?){7,}Y X1234567Y (0,9)(7,8) +:HA#108:E X(.?){8,}Y X1234567Y (0,9)(8,8) +:HA#110:E X(.?){0,8}Y X1234567Y (0,9)(7,8) +:HA#111:E X(.?){1,8}Y X1234567Y (0,9)(7,8) +:HA#112:E X(.?){2,8}Y X1234567Y (0,9)(7,8) +:HA#113:E X(.?){3,8}Y X1234567Y (0,9)(7,8) +:HA#114:E X(.?){4,8}Y X1234567Y (0,9)(7,8) +:HA#115:E X(.?){5,8}Y X1234567Y (0,9)(7,8) +:HA#116:E X(.?){6,8}Y X1234567Y (0,9)(7,8) +:HA#117:E X(.?){7,8}Y X1234567Y (0,9)(7,8) +:HA#118:E X(.?){8,8}Y X1234567Y (0,9)(8,8) + +# These test a fixed bug in my regex-tdfa that did not keep the expanded +# form properly grouped, so right association did the wrong thing with +# these ambiguous patterns (crafted just to test my code when I became +# suspicious of my implementation). The first subexpression should use +# "ab" then "a" then "bcd". + +# OS X / FreeBSD / NetBSD badly fail many of these, with impossible +# results like (0,6)(4,5)(6,6). + +:HA#260:E (a|ab|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#261:E (a|ab|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#262:E (a|ab|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#263:E (a|ab|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#264:E (a|ab|c|bcd){4,}(d*) ababcd NOMATCH +:HA#265:E (a|ab|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#266:E (a|ab|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#267:E (a|ab|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#268:E (a|ab|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#269:E (a|ab|c|bcd){4,10}(d*) ababcd NOMATCH +:HA#270:E (a|ab|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6) +:HA#271:E (a|ab|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6) + +# The above worked on Linux/GLIBC but the following often fail. +# They also trip up OS X / FreeBSD / NetBSD: + +:HA#280:E (ab|a|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#281:E (ab|a|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#282:E (ab|a|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#283:E (ab|a|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#284:E (ab|a|c|bcd){4,}(d*) ababcd NOMATCH +:HA#285:E (ab|a|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#286:E (ab|a|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#287:E (ab|a|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#288:E (ab|a|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#289:E (ab|a|c|bcd){4,10}(d*) ababcd NOMATCH +:HA#290:E (ab|a|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6) +:HA#291:E (ab|a|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat new file mode 100644 index 0000000..ed7f28e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat @@ -0,0 +1,16 @@ +NOTE left-assoc:pass-none right-assoc:pass-all : 2002-04-29 + +E (a|ab)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (a|ab)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4) + +E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3) + +E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/backref.in b/contrib/netbsd-tests/lib/libc/regex/data/backref.in new file mode 100644 index 0000000..cc59b06 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/backref.in @@ -0,0 +1,21 @@ +# back references, ugh +a\(b\)\2c bC ESUBREG +a\(b\1\)c bC ESUBREG +a\(b*\)c\1d b abbcbbd abbcbbd bb +a\(b*\)c\1d b abbcbd +a\(b*\)c\1d b abbcbbbd +^\(.\)\1 b abc +a\([bc]\)\1d b abcdabbd abbd b +a\(\([bc]\)\2\)*d b abbccd abbccd +a\(\([bc]\)\2\)*d b abbcbd +# actually, this next one probably ought to fail, but the spec is unclear +a\(\(b\)*\2\)*d b abbbd abbbd +# here is a case that no NFA implementation does right +\(ab*\)[ab]*\1 b ababaaa ababaaa a +# check out normal matching in the presence of back refs +\(a\)\1bcd b aabcd aabcd +\(a\)\1bc*d b aabcd aabcd +\(a\)\1bc*d b aabd aabd +\(a\)\1bc*d b aabcccd aabcccd +\(a\)\1bc*[ce]d b aabcccd aabcccd +^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd diff --git a/contrib/netbsd-tests/lib/libc/regex/data/basic.in b/contrib/netbsd-tests/lib/libc/regex/data/basic.in new file mode 100644 index 0000000..d1e3aa9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/basic.in @@ -0,0 +1,5 @@ +# basics +a & a a +abc & abc abc +abc|de - abc abc +a|b|c - abc a diff --git a/contrib/netbsd-tests/lib/libc/regex/data/bracket.in b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in new file mode 100644 index 0000000..53a0b20 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in @@ -0,0 +1,55 @@ +# brackets, and numerous perversions thereof +a[b]c & abc abc +a[ab]c & abc abc +a[^ab]c & adc adc +a[]b]c & a]c a]c +a[[b]c & a[c a[c +a[-b]c & a-c a-c +a[^]b]c & adc adc +a[^-b]c & adc adc +a[b-]c & a-c a-c +a[b &C EBRACK +a[] &C EBRACK +a[1-3]c & a2c a2c +a[3-1]c &C ERANGE +a[1-3-5]c &C ERANGE +a[[.-.]--]c & a-c a-c +a[1- &C ERANGE +a[[. &C EBRACK +a[[.x &C EBRACK +a[[.x. &C EBRACK +a[[.x.] &C EBRACK +a[[.x.]] & ax ax +a[[.x,.]] &C ECOLLATE +a[[.one.]]b & a1b a1b +a[[.notdef.]]b &C ECOLLATE +a[[.].]]b & a]b a]b +a[[:alpha:]]c & abc abc +a[[:notdef:]]c &C ECTYPE +a[[: &C EBRACK +a[[:alpha &C EBRACK +a[[:alpha:] &C EBRACK +a[[:alpha,:] &C ECTYPE +a[[:]:]]b &C ECTYPE +a[[:-:]]b &C ECTYPE +a[[:alph:]] &C ECTYPE +a[[:alphabet:]] &C ECTYPE +[[:alnum:]]+ - -%@a0X- a0X +[[:alpha:]]+ - -%@aX0- aX +[[:blank:]]+ - aSSTb SST +[[:cntrl:]]+ - aNTb NT +[[:digit:]]+ - a019b 019 +[[:graph:]]+ - Sa%bS a%b +[[:lower:]]+ - AabC ab +[[:print:]]+ - NaSbN aSb +[[:punct:]]+ - S%-&T %-& +[[:space:]]+ - aSNTb SNT +[[:upper:]]+ - aBCd BC +[[:xdigit:]]+ - p0f3Cq 0f3C +a[[=b=]]c & abc abc +a[[= &C EBRACK +a[[=b &C EBRACK +a[[=b= &C EBRACK +a[[=b=] &C EBRACK +a[[=b,=]] &C ECOLLATE +a[[=one=]]b & a1b a1b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in new file mode 100644 index 0000000..ea3faf9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in @@ -0,0 +1,17 @@ +# Let's have some fun -- try to match a C comment. +# first the obvious, which looks okay at first glance... +/\*.*\*/ - /*x*/ /*x*/ +# but... +/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/ +# okay, we must not match */ inside; try to do that... +/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/ +/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/ +# but... +/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/ +# and a still fancier version, which does it right (I think)... +/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/ +/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/ diff --git a/contrib/netbsd-tests/lib/libc/regex/data/complex.in b/contrib/netbsd-tests/lib/libc/regex/data/complex.in new file mode 100644 index 0000000..e114058 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/complex.in @@ -0,0 +1,23 @@ +# complexities +a(((b)))c - abc abc +a(b|(c))d - abd abd +a(b*|c)d - abbd abbd +# just gotta have one DFA-buster, of course +a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and an inline expansion in case somebody gets tricky +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and in case somebody just slips in an NFA... +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights +# fish for anomalies as the number of states passes 32 +12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789 +123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890 +1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901 +12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012 +123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123 +# and one really big one, beyond any plausible word width +1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890 +# fish for problems as brackets go past 8 +[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm +[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo +[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq +[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq diff --git a/contrib/netbsd-tests/lib/libc/regex/data/error.in b/contrib/netbsd-tests/lib/libc/regex/data/error.in new file mode 100644 index 0000000..61e0ea4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/error.in @@ -0,0 +1,30 @@ +# certain syntax errors and non-errors +| C EMPTY +| b | | +* C BADRPT +* b * * ++ C BADRPT +? C BADRPT +"" &C EMPTY +() - abc @abc +\(\) b abc @abc +a||b C EMPTY +|ab C EMPTY +ab| C EMPTY +(|a)b C EMPTY +(a|)b C EMPTY +(*a) C BADRPT +(+a) C BADRPT +(?a) C BADRPT +({1}a) C BADRPT +\(\{1\}a\) bC BADRPT +(a|*b) C BADRPT +(a|+b) C BADRPT +(a|?b) C BADRPT +(a|{1}b) C BADRPT +^* C BADRPT +^* b * * +^+ C BADRPT +^? C BADRPT +^{1} C BADRPT +^\{1\} bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/meta.in b/contrib/netbsd-tests/lib/libc/regex/data/meta.in new file mode 100644 index 0000000..4533d35 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/meta.in @@ -0,0 +1,21 @@ +# metacharacters, backslashes +a.c & abc abc +a[bc]d & abd abd +a\*c & a*c a*c +a\\b & a\b a\b +a\\\*b & a\*b a\*b +a\bc & abc abc +a\ &C EESCAPE +a\\bc & a\bc a\bc +\{ bC BADRPT +a\[b & a[b a[b +a[b &C EBRACK +# trailing $ is a peculiar special case for the BRE code +a$ & a a +a$ & a$ +a\$ & a +a\$ & a$ a$ +a\\$ & a +a\\$ & a$ +a\\$ & a\$ +a\\$ & a\ a\ diff --git a/contrib/netbsd-tests/lib/libc/regex/data/nospec.in b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in new file mode 100644 index 0000000..baf8d04 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in @@ -0,0 +1,7 @@ +# plain strings, with the NOSPEC flag +abc m abc abc +abc m xabcy abc +abc m xyz +a*b m aba*b a*b +a*b m ab +"" mC EMPTY diff --git a/contrib/netbsd-tests/lib/libc/regex/data/paren.in b/contrib/netbsd-tests/lib/libc/regex/data/paren.in new file mode 100644 index 0000000..9d206ce --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/paren.in @@ -0,0 +1,19 @@ +# parentheses and perversions thereof +a(b)c - abc abc +a\(b\)c b abc abc +a( C EPAREN +a( b a( a( +a\( - a( a( +a\( bC EPAREN +a\(b bC EPAREN +a(b C EPAREN +a(b b a(b a(b +# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly) +a) - a) a) +) - ) ) +# end gagging (in a just world, those *should* give EPAREN) +a) b a) a) +a\) bC EPAREN +\) bC EPAREN +a()b - ab ab +a\(\)b b ab ab diff --git a/contrib/netbsd-tests/lib/libc/regex/data/regress.in b/contrib/netbsd-tests/lib/libc/regex/data/regress.in new file mode 100644 index 0000000..afd832a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/regress.in @@ -0,0 +1,9 @@ +# past problems, and suspected problems +(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1 +abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop +abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv +(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11 +CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11 +Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz +a?b - ab ab +-\{0,1\}[0-9]*$ b -5 -5 diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in new file mode 100644 index 0000000..ee6ff4c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in @@ -0,0 +1,45 @@ +# the dreaded bounded repetitions +{ & { { +{abc & {abc {abc +{1 C BADRPT +{1} C BADRPT +a{b & a{b a{b +a{1}b - ab ab +a\{1\}b b ab ab +a{1,}b - ab ab +a\{1,\}b b ab ab +a{1,2}b - aab aab +a\{1,2\}b b aab aab +a{1 C EBRACE +a\{1 bC EBRACE +a{1a C EBRACE +a\{1a bC EBRACE +a{1a} C BADBR +a\{1a\} bC BADBR +a{,2} - a{,2} a{,2} +a\{,2\} bC BADBR +a{,} - a{,} a{,} +a\{,\} bC BADBR +a{1,x} C BADBR +a\{1,x\} bC BADBR +a{1,x C EBRACE +a\{1,x bC EBRACE +a{300} C BADBR +a\{300\} bC BADBR +a{1,0} C BADBR +a\{1,0\} bC BADBR +ab{0,0}c - abcac ac +ab\{0,0\}c b abcac ac +ab{0,1}c - abcac abc +ab\{0,1\}c b abcac abc +ab{0,3}c - abbcac abbc +ab\{0,3\}c b abbcac abbc +ab{1,1}c - acabc abc +ab\{1,1\}c b acabc abc +ab{1,3}c - acabc abc +ab\{1,3\}c b acabc abc +ab{2,2}c - abcabbc abbc +ab\{2,2\}c b abcabbc abbc +ab{2,4}c - abcabbc abbc +ab\{2,4\}c b abcabbc abbc +((a{1,10}){1,10}){1,10} - a a a,a diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in new file mode 100644 index 0000000..da97bad --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in @@ -0,0 +1,21 @@ +# multiple repetitions +a** &C BADRPT +a++ C BADRPT +a?? C BADRPT +a*+ C BADRPT +a*? C BADRPT +a+* C BADRPT +a+? C BADRPT +a?* C BADRPT +a?+ C BADRPT +a{1}{1} C BADRPT +a*{1} C BADRPT +a+{1} C BADRPT +a?{1} C BADRPT +a{1}* C BADRPT +a{1}+ C BADRPT +a{1}? C BADRPT +a*{b} - a{b} a{b} +a\{1\}\{1\} bC BADRPT +a*\{1\} bC BADRPT +a\{1\}* bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in new file mode 100644 index 0000000..08bc286 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in @@ -0,0 +1,10 @@ +# ordinary repetitions +ab*c & abc abc +ab+c - abc abc +ab?c - abc abc +a\(*\)b b a*b a*b +a\(**\)b b ab ab +a\(***\)b bC BADRPT +*a b *a *a +**a b a a +***a bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/startend.in b/contrib/netbsd-tests/lib/libc/regex/data/startend.in new file mode 100644 index 0000000..c396e58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/startend.in @@ -0,0 +1,9 @@ +# check out the STARTEND option +[abc] &# a(b)c b +[abc] &# a(d)c +[abc] &# a(bc)d b +[abc] &# a(dc)d c +. &# a()c +b.*c &# b(bc)c bc +b.* &# b(bc)c bc +.*c &# b(bc)c bc diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subexp.in b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in new file mode 100644 index 0000000..c7bcc06 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in @@ -0,0 +1,57 @@ +# subexpressions +a(b)(c)d - abcd abcd b,c +a(((b)))c - abc abc b,b,b +a(b|(c))d - abd abd b,- +a(b*|c|e)d - abbd abbd bb +a(b*|c|e)d - acd acd c +a(b*|c|e)d - ad ad @d +a(b?)c - abc abc b +a(b?)c - ac ac @c +a(b+)c - abc abc b +a(b+)c - abbbc abbbc bbb +a(b*)c - ac ac @c +(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de +# the regression tester only asks for 9 subexpressions +a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j +a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k +a([bc]?)c - abc abc b +a([bc]?)c - ac ac @c +a([bc]+)c - abc abc b +a([bc]+)c - abcc abcc bc +a([bc]+)bc - abcbc abcbc bc +a(bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abbb abbb bb +a(bbb+|bb+|b)bb - abbb abbb b +(.*).* - abcdef abcdef abcdef +(a*)* - bc @b @b + +# do we get the right subexpression when it is used more than once? +a(b|c)*d - ad ad - +a(b|c)*d - abcd abcd c +a(b|c)+d - abd abd b +a(b|c)+d - abcd abcd c +a(b|c?)+d - ad ad @d +a(b|c?)+d - abcd abcd @d +a(b|c){0,0}d - ad ad - +a(b|c){0,1}d - ad ad - +a(b|c){0,1}d - abd abd b +a(b|c){0,2}d - ad ad - +a(b|c){0,2}d - abcd abcd c +a(b|c){0,}d - ad ad - +a(b|c){0,}d - abcd abcd c +a(b|c){1,1}d - abd abd b +a(b|c){1,1}d - acd acd c +a(b|c){1,2}d - abd abd b +a(b|c){1,2}d - abcd abcd c +a(b|c){1,}d - abd abd b +a(b|c){1,}d - abcd abcd c +a(b|c){2,2}d - acbd acbd b +a(b|c){2,2}d - abcd abcd c +a(b|c){2,4}d - abcd abcd c +a(b|c){2,4}d - abcbd abcbd b +a(b|c){2,4}d - abcbcd abcbcd c +a(b|c){2,}d - abcd abcd c +a(b|c){2,}d - abcbd abcbd b +a(b+|((c)*))+d - abd abd @d,@d,- +a(b+|((c)*))+d - abcd abcd @d,@d,- diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subtle.in b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in new file mode 100644 index 0000000..92d68bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in @@ -0,0 +1,21 @@ +# subtleties of matching +abc & xabcy abc +a\(b\)?c\1d b acd +aBc i Abc Abc +a[Bc]*d i abBCcd abBCcd +0[[:upper:]]1 &i 0a1 0a1 +0[[:lower:]]1 &i 0A1 0A1 +a[^b]c &i abc +a[^b]c &i aBc +a[^b]c &i adc adc +[a]b[c] - abc abc +[a]b[a] - aba aba +[abc]b[abc] - abc abc +[abc]b[abd] - abd abd +a(b?c)+d - accd accd +(wee|week)(knights|night) - weeknights weeknights +(we|wee|week|frob)(knights|night|day) - weeknights weeknights +a[bc]d - xyzaaabcaababdacd abd +a[ab]c - aaabc abc +abc s abc abc +a* & b @b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in new file mode 100644 index 0000000..e09a329 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in @@ -0,0 +1,13 @@ +# word boundaries (ick) +[[:<:]]a & a a +[[:<:]]a & ba +[[:<:]]a & -a a +a[[:>:]] & a a +a[[:>:]] & ab +a[[:>:]] & a- a +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc +[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc +[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc +[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_ +[[:<:]]a_b[[:>:]] & x_a_b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/zero.in b/contrib/netbsd-tests/lib/libc/regex/data/zero.in new file mode 100644 index 0000000..2786944 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/zero.in @@ -0,0 +1,7 @@ +# cases involving NULs +aZb & a a +aZb &p a +aZb &p# (aZb) aZb +aZ*b &p# (ab) ab +a.b &# (aZb) aZb +a.* &# (aZb)c aZb diff --git a/contrib/netbsd-tests/lib/libc/regex/debug.c b/contrib/netbsd-tests/lib/libc/regex/debug.c new file mode 100644 index 0000000..f1d2b15 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/debug.c @@ -0,0 +1,278 @@ +/* $NetBSD: debug.c,v 1.2 2011/10/10 04:32:41 christos Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <ctype.h> +#include <limits.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> +#ifdef __FreeBSD__ +#include <wchar.h> +#include <wctype.h> +#endif + +/* Don't sort these! */ +#include "utils.h" +#include "regex2.h" + +#include "test_regex.h" + +static void s_print(struct re_guts *, FILE *); +static char *regchar(int); + +/* + * regprint - print a regexp for debugging + */ +void +regprint(regex_t *r, FILE *d) +{ +#ifdef __NetBSD__ + struct re_guts *g = r->re_g; + int c; + int last; + int nincat[NC]; + + fprintf(d, "%ld states, %zu categories", (long)g->nstates, + g->ncategories); + fprintf(d, ", first %ld last %ld", (long)g->firststate, + (long)g->laststate); + if (g->iflags&USEBOL) + fprintf(d, ", USEBOL"); + if (g->iflags&USEEOL) + fprintf(d, ", USEEOL"); + if (g->iflags&BAD) + fprintf(d, ", BAD"); + if (g->nsub > 0) + fprintf(d, ", nsub=%ld", (long)g->nsub); + if (g->must != NULL) + fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen, + g->must); + if (g->backrefs) + fprintf(d, ", backrefs"); + if (g->nplus > 0) + fprintf(d, ", nplus %ld", (long)g->nplus); + fprintf(d, "\n"); + s_print(g, d); + for (size_t i = 0; i < g->ncategories; i++) { + nincat[i] = 0; + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (g->categories[c] == i) + nincat[i]++; + } + fprintf(d, "cc0#%d", nincat[0]); + for (size_t i = 1; i < g->ncategories; i++) + if (nincat[i] == 1) { + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (g->categories[c] == i) + break; + fprintf(d, ", %zu=%s", i, regchar(c)); + } + fprintf(d, "\n"); + for (size_t i = 1; i < g->ncategories; i++) + if (nincat[i] != 1) { + fprintf(d, "cc%zu\t", i); + last = -1; + for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */ + if (c <= CHAR_MAX && g->categories[c] == i) { + if (last < 0) { + fprintf(d, "%s", regchar(c)); + last = c; + } + } else { + if (last >= 0) { + if (last != c-1) + fprintf(d, "-%s", + regchar(c-1)); + last = -1; + } + } + fprintf(d, "\n"); + } +#endif +} + +/* + * s_print - print the strip for debugging + */ +static void +s_print(struct re_guts *g, FILE *d) +{ + sop *s; + cset *cs; + int done = 0; + sop opnd; + int col = 0; + ssize_t last; + sopno offset = 2; +# define GAP() { if (offset % 5 == 0) { \ + if (col > 40) { \ + fprintf(d, "\n\t"); \ + col = 0; \ + } else { \ + fprintf(d, " "); \ + col++; \ + } \ + } else \ + col++; \ + offset++; \ + } + + if (OP(g->strip[0]) != OEND) + fprintf(d, "missing initial OEND!\n"); + for (s = &g->strip[1]; !done; s++) { + opnd = OPND(*s); + switch (OP(*s)) { + case OEND: + fprintf(d, "\n"); + done = 1; + break; + case OCHAR: + if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) + fprintf(d, "\\%c", (char)opnd); + else + fprintf(d, "%s", regchar((char)opnd)); + break; + case OBOL: + fprintf(d, "^"); + break; + case OEOL: + fprintf(d, "$"); + break; + case OBOW: + fprintf(d, "\\{"); + break; + case OEOW: + fprintf(d, "\\}"); + break; + case OANY: + fprintf(d, "."); + break; + case OANYOF: + fprintf(d, "[(%ld)", (long)opnd); +#ifdef __NetBSD__ + cs = &g->sets[opnd]; + last = -1; + for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */ + if (CHIN(cs, i) && i < g->csetsize) { + if (last < 0) { + fprintf(d, "%s", regchar(i)); + last = i; + } + } else { + if (last >= 0) { + if (last != (ssize_t)i - 1) + fprintf(d, "-%s", + regchar(i - 1)); + last = -1; + } + } +#endif + fprintf(d, "]"); + break; + case OBACK_: + fprintf(d, "(\\<%ld>", (long)opnd); + break; + case O_BACK: + fprintf(d, "<%ld>\\)", (long)opnd); + break; + case OPLUS_: + fprintf(d, "(+"); + if (OP(*(s+opnd)) != O_PLUS) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_PLUS: + if (OP(*(s-opnd)) != OPLUS_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "+)"); + break; + case OQUEST_: + fprintf(d, "(?"); + if (OP(*(s+opnd)) != O_QUEST) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_QUEST: + if (OP(*(s-opnd)) != OQUEST_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "?)"); + break; + case OLPAREN: + fprintf(d, "((<%ld>", (long)opnd); + break; + case ORPAREN: + fprintf(d, "<%ld>))", (long)opnd); + break; + case OCH_: + fprintf(d, "<"); + if (OP(*(s+opnd)) != OOR2) + fprintf(d, "<%ld>", (long)opnd); + break; + case OOR1: + if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "|"); + break; + case OOR2: + fprintf(d, "|"); + if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_CH: + if (OP(*(s-opnd)) != OOR1) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, ">"); + break; + default: +#ifdef __FreeBSD__ + fprintf(d, "!%ld(%ld)!", OP(*s), opnd); +#else + fprintf(d, "!%d(%d)!", OP(*s), opnd); +#endif + break; + } + if (!done) + GAP(); + } +} + +/* + * regchar - make a character printable + */ +static char * /* -> representation */ +regchar(int ch) +{ + static char buf[10]; + + if (isprint(ch) || ch == ' ') + sprintf(buf, "%c", ch); + else + sprintf(buf, "\\%o", ch); + return(buf); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/main.c b/contrib/netbsd-tests/lib/libc/regex/main.c new file mode 100644 index 0000000..eac4e2d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/main.c @@ -0,0 +1,523 @@ +/* $NetBSD: main.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> + +#include "test_regex.h" + +char *progname; +int debug = 0; +int line = 0; +int status = 0; + +int copts = REG_EXTENDED; +int eopts = 0; +regoff_t startoff = 0; +regoff_t endoff = 0; + +static char empty = '\0'; + +static char *eprint(int); +static int efind(char *); + +/* + * main - do the simple case, hand off to regress() for regression + */ +int +main(int argc, char *argv[]) +{ + regex_t re; +# define NS 10 + regmatch_t subs[NS]; + char erbuf[100]; + int err; + size_t len; + int c; + int errflg = 0; + int i; + extern int optind; + extern char *optarg; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "c:e:S:E:x")) != -1) + switch (c) { + case 'c': /* compile options */ + copts = options('c', optarg); + break; + case 'e': /* execute options */ + eopts = options('e', optarg); + break; + case 'S': /* start offset */ + startoff = (regoff_t)atoi(optarg); + break; + case 'E': /* end offset */ + endoff = (regoff_t)atoi(optarg); + break; + case 'x': /* Debugging. */ + debug++; + break; + case '?': + default: + errflg++; + break; + } + if (errflg) { + fprintf(stderr, "usage: %s ", progname); + fprintf(stderr, "[-c copt][-C][-d] [re]\n"); + exit(2); + } + + if (optind >= argc) { + regress(stdin); + exit(status); + } + + err = regcomp(&re, argv[optind++], copts); + if (err) { + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "error %s, %zd/%zd `%s'\n", + eprint(err), len, (size_t)sizeof(erbuf), erbuf); + exit(status); + } + regprint(&re, stdout); + + if (optind >= argc) { + regfree(&re); + exit(status); + } + + if (eopts®_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..0670e51 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c @@ -0,0 +1,224 @@ +/* $NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $"); + +#include <stdio.h> +#include <regex.h> +#include <string.h> +#include <stdlib.h> +#include <err.h> +#include <atf-c.h> +#ifdef __FreeBSD__ +#include <sys/resource.h> +#endif + +#ifndef REGEX_MAXSIZE +#define REGEX_MAXSIZE 9999 +#endif + +static char * +mkstr(const char *str, size_t len) +{ + size_t slen = strlen(str); + char *p = malloc(slen * len + 1); + ATF_REQUIRE(p != NULL); + for (size_t i = 0; i < len; i++) + strcpy(&p[i * slen], str); + return p; +} + +static char * +concat(const char *d, const char *s) +{ + size_t dlen = strlen(d); + size_t slen = strlen(s); + char *p = malloc(dlen + slen + 1); + + ATF_REQUIRE(p != NULL); + strcpy(p, d); + strcpy(p + dlen, s); + return p; +} + +static char * +p0(size_t len) +{ + char *d, *s1, *s2; + s1 = mkstr("\\(", len); + s2 = concat(s1, ")"); + free(s1); + d = concat("(", s2); + free(s2); + return d; +} + +static char * +p1(size_t len) +{ + char *d, *s1, *s2, *s3; + s1 = mkstr("\\(", 60); + s2 = mkstr("(.*)", len); + s3 = concat(s1, s2); + free(s2); + free(s1); + s1 = concat(s3, ")"); + free(s3); + d = concat("(", s1); + free(s1); + return d; +} + +static char * +ps(const char *m, const char *s, size_t len) +{ + char *d, *s1, *s2, *s3; + s1 = mkstr(m, len); + s2 = mkstr(s, len); + s3 = concat(s1, s2); + free(s2); + free(s1); + d = concat("(.?)", s3); + free(s3); + return d; +} + +static char * +p2(size_t len) +{ + return ps("((.*){0,255}", ")", len); +} + +static char * +p3(size_t len) +{ + return ps("(.\\{0,}", ")", len); +} + +static char * +p4(size_t len) +{ + return ps("((.*){1,255}", ")", len); +} + +static char * +p5(size_t len) +{ + return ps("(", "){1,100}", len); +} + +static char * +p6(size_t len) +{ + char *d, *s1, *s2; + s1 = mkstr("(?:(.*)|", len); + s2 = concat(s1, "(.*)"); + free(s1); + s1 = mkstr(")", len); + d = concat(s2, s1); + free(s1); + free(s2); + return d; +} + +static const struct { + char *(*pattern)(size_t); + int type; +} tests[] = { + { p0, REG_EXTENDED }, + { p1, REG_EXTENDED }, + { p2, REG_EXTENDED }, + { p3, REG_EXTENDED }, + { p4, REG_EXTENDED }, + { p5, REG_EXTENDED }, + { p6, REG_BASIC }, +}; + +ATF_TC(regcomp_too_big); + +ATF_TC_HEAD(regcomp_too_big, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that large patterns don't" + " crash, but return a proper error code"); + // libtre needs it. + atf_tc_set_md_var(tc, "timeout", "600"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.memory", "64M"); +#else + atf_tc_set_md_var(tc, "require.memory", "120M"); +#endif +} + +ATF_TC_BODY(regcomp_too_big, tc) +{ + regex_t re; +#ifdef __FreeBSD__ + struct rlimit limit; +#endif + int e; + +#ifdef __FreeBSD__ + limit.rlim_cur = limit.rlim_max = 64 * 1024 * 1024; + ATF_REQUIRE(setrlimit(RLIMIT_VMEM, &limit) != -1); +#endif + for (size_t i = 0; i < __arraycount(tests); i++) { + char *d = (*tests[i].pattern)(REGEX_MAXSIZE); + e = regcomp(&re, d, tests[i].type); + if (e) { + char ebuf[1024]; + (void)regerror(e, &re, ebuf, sizeof(ebuf)); + ATF_REQUIRE_MSG(e == REG_ESPACE, + "regcomp returned %d (%s) for pattern %zu [%s]", e, ebuf, + i, d); + free(d); + continue; + } + free(d); + (void)regexec(&re, "aaaaaaaaaaa", 0, NULL, 0); + regfree(&re); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, regcomp_too_big); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex.sh b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh new file mode 100755 index 0000000..bef3ac9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh @@ -0,0 +1,73 @@ +# $NetBSD: t_regex.sh,v 1.1 2012/08/24 20:24:40 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +check() +{ + local dataname="${1}"; shift + + prog="$(atf_get_srcdir)/h_regex" + data="$(atf_get_srcdir)/data/${dataname}.in" + + atf_check -x "${prog} <${data}" + atf_check -x "${prog} -el <${data}" + atf_check -x "${prog} -er <${data}" +} + +create_tc() +{ + local name="${1}"; shift + local descr="${1}"; shift + + atf_test_case "${name}" + eval "${name}_head() { atf_set 'descr' '${descr}'; }" + eval "${name}_body() { check '${name}'; }" + + atf_add_test_case "${name}" +} + +atf_init_test_cases() +{ + create_tc basic "Checks basic functionality" + create_tc paren "Checks parentheses" + create_tc anchor "Checks anchors and REG_NEWLINE" + create_tc error "Checks syntax errors and non-errors" + create_tc meta "Checks metacharacters and backslashes" + create_tc backref "Checks back references" + create_tc repet_ordinary "Checks ordinary repetitions" + create_tc repet_bounded "Checks bounded repetitions" + create_tc repet_multi "Checks multiple repetitions" + create_tc bracket "Checks brackets" + create_tc complex "Checks various complex examples" + create_tc subtle "Checks various subtle examples" + create_tc c_comments "Checks matching C comments" + create_tc subexp "Checks subexpressions" + create_tc startend "Checks STARTEND option" + create_tc nospec "Checks NOSPEC option" + create_tc zero "Checks NULs" + create_tc word_bound "Checks word boundaries" + create_tc regress "Checks various past problems and suspected problems" +} diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c new file mode 100644 index 0000000..0ca44b4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c @@ -0,0 +1,639 @@ +/* $NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $"); + +#include <sys/param.h> + +#include <stdio.h> +#include <regex.h> +#include <string.h> +#include <stdlib.h> +#include <vis.h> +#include <ctype.h> +#include <atf-c.h> +#ifdef __FreeBSD__ +#include <libutil.h> +#endif + +static const char sep[] = "\r\n\t"; +static const char delim[3] = "\\\\\0"; + + +static void +fail(const char *pattern, const char *input, size_t lineno) { + fprintf(stderr, + "skipping failed test at line %zu (pattern=%s, input=%s)\n", + lineno, pattern, input); +} + +static int +bug(const char *pattern, const char *input, size_t lineno) { + static const struct { + const char *p; + const char *i; + } b[] = { +#if defined(REGEX_SPENCER) + /* + * The default libc implementation by Henry Spencer + */ + { "a[-]?c", "ac" }, // basic.dat + { "(a*)*", "a" }, // categorization.dat + { "(aba|a*b)*", "ababa" }, // categorization.dat + { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat + { "(a*)*", "aaaaaa" }, // nullsubexpression.dat + { "(a*)*", "aaaaaax" }, // nullsubexpression.dat + { "(a*)+", "a" }, // nullsubexpression.dat + { "(a*)+", "aaaaaa" }, // nullsubexpression.dat + { "(a*)+", "aaaaaax" }, // nullsubexpression.dat + { "([a]*)*", "a" }, // nullsubexpression.dat + { "([a]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([a]*)*", "aaaaaax" }, // nullsubexpression.dat + { "([a]*)+", "a" }, // nullsubexpression.dat + { "([a]*)+", "aaaaaa" }, // nullsubexpression.dat + { "([a]*)+", "aaaaaax" }, // nullsubexpression.dat + { "([^b]*)*", "a" }, // nullsubexpression.dat + { "([^b]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([^b]*)*", "aaaaaab" }, // nullsubexpression.dat + { "([ab]*)*", "a" }, // nullsubexpression.dat + { "([ab]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([ab]*)*", "ababab" }, // nullsubexpression.dat + { "([ab]*)*", "bababa" }, // nullsubexpression.dat + { "([ab]*)*", "b" }, // nullsubexpression.dat + { "([ab]*)*", "bbbbbb" }, // nullsubexpression.dat + { "([ab]*)*", "aaaabcde" }, // nullsubexpression.dat + { "([^a]*)*", "b" }, // nullsubexpression.dat + { "([^a]*)*", "bbbbbb" }, // nullsubexpression.dat + { "([^ab]*)*", "ccccxx" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)", "ax" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)", "axa" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)", "x" }, // nullsubexpression.dat +/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // nullsubexpression.dat +/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // "" + { "(a*)*(x)", "ax" }, // nullsubexpression.dat + { "(a*)*(x)", "axa" }, // nullsubexpression.dat + { "(a*)+(x)", "ax" }, // nullsubexpression.dat + { "(a*)+(x)", "axa" }, // nullsubexpression.dat + { "((a|ab)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat + { "((a|ab)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat + { "((ab|a)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat + { "((ab|a)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat + { "((a*)(b|abc))(c*)", "abc" }, // forcedassoc.dat + { "((a*)(abc|b))(c*)", "abc" }, // forcedassoc.dat + { "((..)|(.)){2}", "aaa" }, // repetition.dat + { "((..)|(.)){3}", "aaa" }, // repetition.dat + { "((..)|(.)){3}", "aaaa" }, // repetition.dat + { "((..)|(.)){3}", "aaaaa" }, // repetition.dat + { "X(.?){0,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){1,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){2,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){3,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){4,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){5,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){6,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){0,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){1,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){2,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){3,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){4,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){5,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){6,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){7,8}Y", "X1234567Y" }, // repetition.dat + { "(a|ab|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd)*(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd)+(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd)*(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd)+(d*)", "ababcd" }, // repetition.dat +#elif defined(REGEX_TRE) + { "a[-]?c", "ac" }, // basic.dat + { "a\\(b\\)*\\1", "a" }, // categorization.dat + { "a\\(b\\)*\\1", "abab" }, // categorization.dat + { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // categorization.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // "" + { "((..)|(.))*", "aa" }, // repetition.dat + { "((..)|(.))*", "aaa" }, // repetition.dat + { "((..)|(.))*", "aaaaa" }, // repetition.dat + { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat +#else + { "", "" } +#endif + }; + + for (size_t i = 0; i < __arraycount(b); i++) { + if (strcmp(pattern, b[i].p) == 0 && + strcmp(input, b[i].i) == 0) { + fail(pattern, input, lineno); + return 1; + } + } + return 0; +} + +#ifdef REGEX_SPENCER +#define HAVE_BRACES 1 +#define HAVE_MINIMAL 0 +#endif +#ifndef HAVE_BRACES +#define HAVE_BRACES 1 +#endif +#ifndef HAVE_MINIMAL +#define HAVE_MINIMAL 1 +#endif + +static int +optional(const char *s) +{ + static const struct{ + const char *n; + int v; + } nv[]= { + { "[[<element>]] not supported", HAVE_BRACES }, + { "no *? +? mimimal match ops", HAVE_MINIMAL }, + }; + + for (size_t i = 0; i < __arraycount(nv); i++) + if (strcmp(nv[i].n, s) == 0) { + if (nv[i].v) + return 0; + fprintf(stderr, "skipping unsupported [%s] tests\n", s); + return 1; + } + + ATF_REQUIRE_MSG(0, "Unknown feature: %s", s); + return 0; +} + +static int +unsupported(const char *s) +{ + static const char *we[] = { +#if defined(REGEX_SPENCER) + "ASSOCIATIVITY=left", // have right associativity + "SUBEXPRESSION=precedence", // have grouping subexpression + "REPEAT_LONGEST=last", // have first repeat longest + "BUG=alternation-order", // don't have it + "BUG=first-match", // don't have it + "BUG=nomatch-match", // don't have it + "BUG=repeat-any", // don't have it + "BUG=range-null", // don't have it + "BUG=repeat-null-unknown", // don't have it + "BUG=repeat-null", // don't have it + "BUG=repeat-artifact", // don't have it + "BUG=subexpression-first", // don't have it +#elif defined(REGEX_TRE) + "ASSOCIATIVITY=right", // have left associativity + "SUBEXPRESSION=grouping", // have precedence subexpression + "REPEAT_LONGEST=first", // have last repeat longest + "LENGTH=first", // have last length + "BUG=alternation-order", // don't have it + "BUG=first-match", // don't have it + "BUG=range-null", // don't have it + "BUG=repeat-null", // don't have it + "BUG=repeat-artifact", // don't have it + "BUG=subexpression-first", // don't have it + "BUG=repeat-short", // don't have it +#endif + }; + + if (s == NULL) + return 0; + + while (*s == '#' || isspace((unsigned char)*s)) + s++; + + for (size_t i = 0; i < __arraycount(we); i++) + if (strcmp(we[i], s) == 0) + return 1; + return 0; +} + +static void +geterror(const char *s, int *comp, int *exec) +{ + static const struct { + const char *n; + int v; + int ce; + } nv[] = { +#define COMP 1 +#define EXEC 2 + { "OK", 0, COMP|EXEC }, +#define _DO(a, b) { # a, REG_ ## a, b }, + _DO(NOMATCH, EXEC) + _DO(BADPAT, COMP) + _DO(ECOLLATE, COMP) + _DO(ECTYPE, COMP) + _DO(EESCAPE, COMP) + _DO(ESUBREG, COMP) + _DO(EBRACK, COMP) + _DO(EPAREN, COMP) + _DO(EBRACE, COMP) + _DO(BADBR, COMP) + _DO(ERANGE, COMP) + _DO(ESPACE, EXEC) + _DO(BADRPT, COMP) + _DO(EMPTY, COMP) + _DO(ASSERT, COMP) + _DO(INVARG, COMP) + _DO(ENOSYS, COMP) +#undef _DO + }; + *comp = 0; + *exec = 0; + for (size_t i = 0; i < __arraycount(nv); i++) + if (strcmp(s, nv[i].n) == 0) { + if (nv[i].ce & COMP) + *comp = nv[i].v; + if (nv[i].ce & EXEC) + *exec = nv[i].v; + return; + } + ATF_REQUIRE_MSG(0, "Unknown error %s", s); + return; +} + +static int +getflags(char *s) +{ + int flags = 0; + + for (;; s++) + switch (*s) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *s = '\0'; + break; + case '\0': + return flags; + case 'B': + case 'E': + case 'F': + case 'L': + break; + case 'i': + flags |= REG_ICASE; + *s = '\0'; + break; + case '$': + *s = '\0'; + break; + case 'n': + *s = '\0'; + break; + default: + ATF_REQUIRE_MSG(0, "Unknown char %c", *s); + break; + } +} + +static size_t +getmatches(const char *s) +{ + size_t i; + char *q; + for (i = 0; (q = strchr(s, '(')) != NULL; i++, s = q + 1) + continue; + ATF_REQUIRE_MSG(i != 0, "No parentheses found"); + return i; +} + +static void +checkcomment(const char *s, size_t lineno) +{ + if (s && strstr(s, "BUG") != NULL) + fprintf(stderr, "Expected %s at line %zu\n", s, lineno); +} + +static void +checkmatches(const char *matches, size_t nm, const regmatch_t *pm, + size_t lineno) +{ + if (nm == 0) + return; + + char *res; + size_t len = strlen(matches) + 1, off = 0; + + ATF_REQUIRE((res = strdup(matches)) != NULL); + for (size_t i = 0; i < nm; i++) { + int l; + if (pm[i].rm_so == -1 && pm[i].rm_eo == -1) + l = snprintf(res + off, len - off, "(?,?)"); + else + l = snprintf(res + off, len - off, "(%lld,%lld)", + (long long)pm[i].rm_so, (long long)pm[i].rm_eo); + ATF_REQUIRE_MSG((size_t) l < len - off, "String too long %s" + " cur=%d, max=%zu", res, l, len - off); + off += l; + } +#ifdef __FreeBSD__ + ATF_CHECK_STREQ_MSG(res, matches, " at line %zu", lineno); +#else + ATF_REQUIRE_STREQ_MSG(res, matches, " at line %zu", lineno); +#endif + free(res); +} + +static void +att_test(const struct atf_tc *tc, const char *data_name) +{ + regex_t re; + char *line, *lastpattern = NULL, data_path[MAXPATHLEN]; + size_t len, lineno = 0; + int skipping = 0; + FILE *input_file; + + snprintf(data_path, sizeof(data_path), "%s/data/%s.dat", + atf_tc_get_config_var(tc, "srcdir"), data_name); + + input_file = fopen(data_path, "r"); + if (input_file == NULL) + atf_tc_fail("Failed to open input file %s", data_path); + + for (; (line = fparseln(input_file, &len, &lineno, delim, 0)) + != NULL; free(line)) { + char *name, *pattern, *input, *matches, *comment; + regmatch_t *pm; + size_t nm; +#ifdef DEBUG + fprintf(stderr, "[%s]\n", line); +#endif + if ((name = strtok(line, sep)) == NULL) + continue; + + /* + * We check these early so that we skip the lines quickly + * in order to do more strict testing on the other arguments + * The same characters are also tested in the switch below + */ + if (*name == '}') { + skipping = 0; + continue; + } + if (skipping) + continue; + if (*name == ';' || *name == '#' || strcmp(name, "NOTE") == 0) + continue; + if (*name == ':') { + /* Skip ":HA#???:" prefix */ + while (*++name && *name != ':') + continue; + if (*name) + name++; + } + + ATF_REQUIRE_MSG((pattern = strtok(NULL, sep)) != NULL, + "Missing pattern at line %zu", lineno); + ATF_REQUIRE_MSG((input = strtok(NULL, sep)) != NULL, + "Missing input at line %zu", lineno); + + if (strchr(name, '$')) { + ATF_REQUIRE(strunvis(pattern, pattern) != -1); + ATF_REQUIRE(strunvis(input, input) != -1); + } + + + if (strcmp(input, "NULL") == 0) + *input = '\0'; + + if (strcmp(pattern, "SAME") == 0) { + ATF_REQUIRE(lastpattern != NULL); + pattern = lastpattern; + } else { + free(lastpattern); + ATF_REQUIRE((lastpattern = strdup(pattern)) != NULL); + } + + ATF_REQUIRE_MSG((matches = strtok(NULL, sep)) != NULL, + "Missing matches at line %zu", lineno); + + comment = strtok(NULL, sep); + switch (*name) { + case '{': /* Begin optional implementation */ + if (optional(comment)) { + skipping++; + continue; + } + name++; /* We have it, so ignore */ + break; + case '}': /* End optional implementation */ + skipping = 0; + continue; + case '?': /* Optional */ + case '|': /* Alternative */ + if (unsupported(comment)) + continue; + name++; /* We have it, so ignore */ + break; + case '#': /* Comment */ + case ';': /* Skip */ + continue; + default: + break; + } + + /* XXX: Our bug */ + if (bug(pattern, input, lineno)) + continue; + + int comp, exec; + if (*matches != '(') { + geterror(matches, &comp, &exec); + pm = NULL; + nm = 0; + } else { + comp = exec = 0; + nm = getmatches(matches); + ATF_REQUIRE((pm = calloc(nm, sizeof(*pm))) != NULL); + } + + + + int iflags = getflags(name); + for (; *name; name++) { + int flags; + switch (*name) { + case 'B': + flags = REG_BASIC; + break; + case 'E': + flags = REG_EXTENDED; + break; + case 'L': + flags = REG_NOSPEC; + break; + default: + ATF_REQUIRE_MSG(0, "Bad name %c", *name); + continue; + } + int c = regcomp(&re, pattern, flags | iflags); + ATF_REQUIRE_MSG(c == comp, + "regcomp returned %d for pattern %s at line %zu", + c, pattern, lineno); + if (c) + continue; + int e = regexec(&re, input, nm, pm, 0); + ATF_REQUIRE_MSG(e == exec, "Expected error %d," + " got %d at line %zu", exec, e, lineno); + checkmatches(matches, nm, pm, lineno); + checkcomment(comment, lineno); + regfree(&re); + } + free(pm); + } + + fclose(input_file); +} + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests basic functionality"); +} +ATF_TC_BODY(basic, tc) +{ + att_test(tc, "basic"); +} + +ATF_TC(categorization); +ATF_TC_HEAD(categorization, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests implementation categorization"); +} +ATF_TC_BODY(categorization, tc) +{ + att_test(tc, "categorization"); +} + +ATF_TC(nullsubexpr); +ATF_TC_HEAD(nullsubexpr, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests (...)*"); +} +ATF_TC_BODY(nullsubexpr, tc) +{ + att_test(tc, "nullsubexpr"); +} + +ATF_TC(leftassoc); +ATF_TC_HEAD(leftassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests left-associative " + "implementations"); +} +ATF_TC_BODY(leftassoc, tc) +{ +#if SKIP_LEFTASSOC + /* jmmv: I converted the original shell-based tests to C and they + * disabled this test in a very unconventional way without giving + * any explation. Mark as broken here, but I don't know why. */ + atf_tc_expect_fail("Reason for breakage unknown"); +#endif +#ifdef __FreeBSD__ + atf_tc_expect_fail("The expected and matched groups are mismatched on FreeBSD"); +#endif + att_test(tc, "leftassoc"); +} + +ATF_TC(rightassoc); +ATF_TC_HEAD(rightassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests right-associative " + "implementations"); +} +ATF_TC_BODY(rightassoc, tc) +{ +#if SKIP_RIGHTASSOC + /* jmmv: I converted the original shell-based tests to C and they + * disabled this test in a very unconventional way without giving + * any explation. Mark as broken here, but I don't know why. */ + atf_tc_expect_fail("Reason for breakage unknown"); +#endif + att_test(tc, "rightassoc"); +} + +ATF_TC(forcedassoc); +ATF_TC_HEAD(forcedassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests subexpression grouping to " + "force association"); +} +ATF_TC_BODY(forcedassoc, tc) +{ + att_test(tc, "forcedassoc"); +} + +ATF_TC(repetition); +ATF_TC_HEAD(repetition, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests implicit vs. explicit " + "repetition"); +} +ATF_TC_BODY(repetition, tc) +{ + att_test(tc, "repetition"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, categorization); + ATF_TP_ADD_TC(tp, nullsubexpr); + ATF_TP_ADD_TC(tp, leftassoc); + ATF_TP_ADD_TC(tp, rightassoc); + ATF_TP_ADD_TC(tp, forcedassoc); + ATF_TP_ADD_TC(tp, repetition); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/test_regex.h b/contrib/netbsd-tests/lib/libc/regex/test_regex.h new file mode 100644 index 0000000..1d9f59d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/test_regex.h @@ -0,0 +1,44 @@ +/* $NetBSD: test_regex.h,v 1.1 2011/01/08 18:10:31 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* from main.c */ +void regress(FILE *); +void try(char *, char *, char *, char *, char *, int); +int options(int, char *); +int opt(int, char *); +void fixstr(char *); +char *check(char *, regmatch_t, char *); + +/* from split.c */ +int split(char *string, char *fields[], int nfields, const char *sep); + +/* from debug.c */ +void regprint(regex_t *r, FILE *d); diff --git a/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x new file mode 100644 index 0000000..cbddfcc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x @@ -0,0 +1,21 @@ +/* $NetBSD: h_testbits.x,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */ + +enum smallenum { + SE_ONE = 1, + SE_TWO = 2 +}; + +enum medenum { + ME_NEG = -1234, + ME_ONE = 1, + ME_TWO = 2, + ME_MANY = 1234 +}; + +enum bigenum { + BE_ONE = 1, + BE_TWO = 2, + BE_MANY = 1234, + BE_LOTS = 1234567 +}; + diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c new file mode 100644 index 0000000..67bc8c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c @@ -0,0 +1,161 @@ +/* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $"); + +#include <sys/types.h> +#include <sys/socket.h> +#include <rpc/rpc.h> +#include <stdlib.h> +#include <err.h> +#include <netdb.h> +#include <stdio.h> +#include <unistd.h> + + +#ifndef TEST +#include <atf-c.h> + +#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) + +#define SKIPX(ev, msg, ...) do { \ + atf_tc_skip(msg, __VA_ARGS__); \ + return; \ +} while(/*CONSTCOND*/0) + +#else +#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) +#define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) +#endif + + +#define RPCBPROC_NULL 0 + +static int +reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) +{ + char host[NI_MAXHOST]; + struct sockaddr *sock = raddrp->buf; + int error; + + + error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0); + if (error) + warnx("Cannot resolve address (%s)", gai_strerror(error)); + else + printf("response from: %s\n", host); + return 0; +} + +#ifdef __FreeBSD__ +#define __rpc_control rpc_control +#endif + +extern bool __rpc_control(int, void *); + +static void +onehost(const char *host, const char *transp) +{ + CLIENT *clnt; + struct netbuf addr; + struct timeval tv; + + /* + * Magic! + */ + tv.tv_sec = 0; + tv.tv_usec = 500000; +#define CLCR_SET_RPCB_TIMEOUT 2 + __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv); + + if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL) + SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror("")); + + tv.tv_sec = 1; + tv.tv_usec = 0; + if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) + != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); + clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); + reply(NULL, &addr, NULL); +} + +#ifdef TEST +static void +allhosts(void) +{ + enum clnt_stat clnt_stat; + + clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, + (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, + NULL, (resultproc_t)reply, transp); + if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) + ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); +} + +int +main(int argc, char *argv[]) +{ + int ch; + const char *transp = "udp"; + + + while ((ch = getopt(argc, argv, "ut")) != -1) + switch (ch) { + case 't': + transp = "tcp"; + break; + case 'u': + transp = "udp"; + break; + default: + fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n", + getprogname()); + return EXIT_FAILURE; + } + + if (argc == optind) + allhosts(); + else + for (; optind < argc; optind++) + onehost(argv[optind], transp); + + return EXIT_SUCCESS; +} + +#else + +ATF_TC(get_svc_addr_tcp); +ATF_TC_HEAD(get_svc_addr_tcp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp"); + +} + +ATF_TC_BODY(get_svc_addr_tcp, tc) +{ + onehost("localhost", "tcp"); + +} + +ATF_TC(get_svc_addr_udp); +ATF_TC_HEAD(get_svc_addr_udp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp"); +} + +ATF_TC_BODY(get_svc_addr_udp, tc) +{ + onehost("localhost", "udp"); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, get_svc_addr_udp); + ATF_TP_ADD_TC(tp, get_svc_addr_tcp); + + return atf_no_error(); +} + +#endif diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c new file mode 100644 index 0000000..2a68eb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c @@ -0,0 +1,129 @@ +/* $NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Ben Harris. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 2001 Ben Harris + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $"); + +#include <rpc/types.h> +#include <rpc/xdr.h> + +#include <string.h> + +#include <atf-c.h> + +#include "h_testbits.h" + +char xdrdata[] = { + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* double 1.0 */ + 0x00, 0x00, 0x00, 0x01, /* enum smallenum SE_ONE */ + 0xff, 0xff, 0xfb, 0x2e, /* enum medenum ME_NEG */ + 0x00, 0x12, 0xd6, 0x87, /* enum bigenum BE_LOTS */ +}; + +ATF_TC(xdr); +ATF_TC_HEAD(xdr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks encoding/decoding of doubles and enumerations"); +} +ATF_TC_BODY(xdr, tc) +{ + XDR x; + double d; + smallenum s; + medenum m; + bigenum b; + char newdata[sizeof(xdrdata)]; + + xdrmem_create(&x, xdrdata, sizeof(xdrdata), XDR_DECODE); + + ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double DECODE failed"); + ATF_REQUIRE_EQ_MSG(d, 1.0, "double 1.0 decoded as %g", d); + + ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(s, SE_ONE, "SE_ONE decoded as %d", s); + + ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(m, ME_NEG, "ME_NEG decoded as %d", m); + + ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(b, BE_LOTS, "BE_LOTS decoded as %d", b); + + xdr_destroy(&x); + + + xdrmem_create(&x, newdata, sizeof(newdata), XDR_ENCODE); + + ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double ENCODE failed"); + ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum ENCODE failed"); + ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum ENCODE failed"); + ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum ENCODE failed"); + ATF_REQUIRE_MSG(memcmp(newdata, xdrdata, sizeof(xdrdata)) == 0, + "xdr ENCODE result differs"); + + xdr_destroy(&x); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, xdr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c new file mode 100644 index 0000000..4d2a93b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c @@ -0,0 +1,196 @@ +/* $NetBSD: t_setjmp.c,v 1.1 2010/12/27 19:35:31 pgoyette Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1994 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_setjmp.c,v 1.1 2010/12/27 19:35:31 pgoyette Exp $"); + +#include <sys/types.h> + +#include <errno.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +#define TEST_SETJMP 0 +#define TEST_U_SETJMP 1 +#define TEST_SIGSETJMP_SAVE 2 +#define TEST_SIGSETJMP_NOSAVE 3 + +static int expectsignal; + +static void +aborthandler(int signo) +{ + ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); + atf_tc_pass(); +} + +static void +h_check(int test) +{ + struct sigaction sa; + jmp_buf jb; + sigjmp_buf sjb; + sigset_t ss; + int i, x; + + i = getpid(); + + if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) + expectsignal = 0; + else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) + expectsignal = 1; + else + atf_tc_fail("unknown test"); + + sa.sa_handler = aborthandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); + REQUIRE_ERRNO(sigemptyset(&ss) != -1); + REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); + REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + x = setjmp(jb); + else if (test == TEST_U_SETJMP) + x = _setjmp(jb); + else + x = sigsetjmp(sjb, !expectsignal); + + if (x != 0) { + ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); + kill(i, SIGABRT); + ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); + atf_tc_pass(); + } + + REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + longjmp(jb, i); + else if (test == TEST_U_SETJMP) + _longjmp(jb, i); + else + siglongjmp(sjb, i); + + atf_tc_fail("jmp failed"); +} + +ATF_TC(setjmp); +ATF_TC_HEAD(setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks setjmp(3)"); +} +ATF_TC_BODY(setjmp, tc) +{ + h_check(TEST_SETJMP); +} + +ATF_TC(_setjmp); +ATF_TC_HEAD(_setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks _setjmp(3)"); +} +ATF_TC_BODY(_setjmp, tc) +{ + h_check(TEST_U_SETJMP); +} + +ATF_TC(sigsetjmp_save); +ATF_TC_HEAD(sigsetjmp_save, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask enabled"); +} +ATF_TC_BODY(sigsetjmp_save, tc) +{ + h_check(TEST_SIGSETJMP_SAVE); +} + +ATF_TC(sigsetjmp_nosave); +ATF_TC_HEAD(sigsetjmp_nosave, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask disabled"); +} +ATF_TC_BODY(sigsetjmp_nosave, tc) +{ + h_check(TEST_SIGSETJMP_NOSAVE); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, setjmp); + ATF_TP_ADD_TC(tp, _setjmp); + ATF_TP_ADD_TC(tp, sigsetjmp_save); + ATF_TP_ADD_TC(tp, sigsetjmp_nosave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c new file mode 100644 index 0000000..4437c92 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c @@ -0,0 +1,218 @@ +/* $NetBSD: t_threadjmp.c,v 1.1 2011/04/21 18:58:20 martin Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1994 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_threadjmp.c,v 1.1 2011/04/21 18:58:20 martin Exp $"); + +#include <sys/types.h> + +#include <errno.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <pthread.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +#define TEST_SETJMP 0 +#define TEST_U_SETJMP 1 +#define TEST_SIGSETJMP_SAVE 2 +#define TEST_SIGSETJMP_NOSAVE 3 + +static pthread_t myself = NULL; + +static int expectsignal; + +static void +aborthandler(int signo) +{ + ATF_REQUIRE(myself == pthread_self()); + ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); + atf_tc_pass(); +} + +static void +h_check(int test) +{ + struct sigaction sa; + jmp_buf jb; + sigjmp_buf sjb; + sigset_t ss; + int i, x; + + myself = pthread_self(); + i = getpid(); + + if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) + expectsignal = 0; + else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) + expectsignal = 1; + else + atf_tc_fail("unknown test"); + + sa.sa_handler = aborthandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); + REQUIRE_ERRNO(sigemptyset(&ss) != -1); + REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); + REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); + ATF_REQUIRE(myself == pthread_self()); + + if (test == TEST_SETJMP) + x = setjmp(jb); + else if (test == TEST_U_SETJMP) + x = _setjmp(jb); + else + x = sigsetjmp(sjb, !expectsignal); + + if (x != 0) { + ATF_REQUIRE(myself == pthread_self()); + ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); + kill(i, SIGABRT); + ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); + ATF_REQUIRE(myself == pthread_self()); + atf_tc_pass(); + } + + ATF_REQUIRE(myself == pthread_self()); + REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + longjmp(jb, i); + else if (test == TEST_U_SETJMP) + _longjmp(jb, i); + else + siglongjmp(sjb, i); + + atf_tc_fail("jmp failed"); +} + +ATF_TC(setjmp); +ATF_TC_HEAD(setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and setjmp(3)"); +} +ATF_TC_BODY(setjmp, tc) +{ + h_check(TEST_SETJMP); +} + +ATF_TC(_setjmp); +ATF_TC_HEAD(_setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and _setjmp(3)"); +} +ATF_TC_BODY(_setjmp, tc) +{ + h_check(TEST_U_SETJMP); +} + +ATF_TC(sigsetjmp_save); +ATF_TC_HEAD(sigsetjmp_save, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and sigsetjmp(3) with savemask enabled"); +} +ATF_TC_BODY(sigsetjmp_save, tc) +{ + h_check(TEST_SIGSETJMP_SAVE); +} + +ATF_TC(sigsetjmp_nosave); +ATF_TC_HEAD(sigsetjmp_nosave, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and sigsetjmp(3) with savemask disabled"); +} +ATF_TC_BODY(sigsetjmp_nosave, tc) +{ + h_check(TEST_SIGSETJMP_NOSAVE); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * These test cases try to verify setjmp and friends in a program + * linked with pthreads, and verify that pthread_self() stays + * consistent throughout the program. A setcontext() call invoked + * by *setjmp() might clobber the TLS special register used to + * implement pthread_self(). + */ + ATF_TP_ADD_TC(tp, setjmp); + ATF_TP_ADD_TC(tp, _setjmp); + ATF_TP_ADD_TC(tp, sigsetjmp_save); + ATF_TP_ADD_TC(tp, sigsetjmp_nosave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c new file mode 100644 index 0000000..ad9376a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c @@ -0,0 +1,46 @@ +/* $NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)fgets(b, len, stdin); + (void)printf("%s\n", b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c new file mode 100644 index 0000000..68e3a6f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <sys/param.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + (void)getcwd(b, len); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_gets.c b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c new file mode 100644 index 0000000..8c601b0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c @@ -0,0 +1,43 @@ +/* $NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)gets(b); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c new file mode 100644 index 0000000..1950f73 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + + (void)memcpy(b, "1020202020202", len); + (void)printf("%*.*s\n", len, len, b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c new file mode 100644 index 0000000..0ebfd29 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + + (void)memmove(b, "1020202020202", len); + (void)printf("%*.*s\n", len, len, b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memset.c b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c new file mode 100644 index 0000000..c5ab607 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c @@ -0,0 +1,49 @@ +/* $NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + size_t len = atoi(argv[1]); + (void)memset(b, 0, len); +#ifdef __FreeBSD__ + return b[0]; /* keeps optimizer from zapping the call to memset() */ +#else + return 0; +#endif +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_raw.c b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c new file mode 100644 index 0000000..a232481 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c @@ -0,0 +1,57 @@ +/* $NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $"); + +#include <stdio.h> +#include <stdlib.h> + +void poke(int *, size_t); + +void +poke(int *b, size_t index) +{ + size_t i; + volatile int sum = 0; + + b[index] = 42; + for (i = 0; i < 10; i++) + sum += b[i]; +} + +int +main(int argc, char *argv[]) +{ + int b[10]; + + poke(b, atoi(argv[1])); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_read.c b/contrib/netbsd-tests/lib/libc/ssp/h_read.c new file mode 100644 index 0000000..1197b6c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_read.c @@ -0,0 +1,65 @@ +/* $NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <sys/param.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +#ifdef __FreeBSD__ +#include <fcntl.h> + +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + int fd, n; + size_t len = atoi(argv[1]); + + fd = open("/dev/zero", O_RDONLY); + if ((n = read(fd, b, len)) == -1) + abort(); + (void)printf("%s\n", b); + return (0); +} +#else +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + + (void)printf("%s\n", b); + return 0; +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c new file mode 100644 index 0000000..7e8bff6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c @@ -0,0 +1,66 @@ +/* $NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <sys/param.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +#ifdef __FreeBSD__ +#include <err.h> +#include <string.h> +#endif + +int +main(int argc, char *argv[]) +{ +#ifdef __FreeBSD__ + char b[512], *sl; + int n; + size_t len = atoi(argv[1]); + sl = malloc(len); + memset(sl, 'a', len); + sl[len - 1] = 0; + unlink("symlink"); + if (symlink(sl, "symlink") == -1) + err(1, "symlink()"); + n = readlink("symlink", b, len); + unlink("symlink"); +#else + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + (void)readlink("/", b, len); +#endif + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c new file mode 100644 index 0000000..7576788 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c @@ -0,0 +1,51 @@ +/* $NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + size_t len = atoi(argv[1]); +#ifdef __FreeBSD__ + char c[] = "01234567890123456789"; + c[len] = 0; + (void)snprintf(b, len, "%s", c); +#else + (void)snprintf(b, len, "%s", "0123456789"); +#endif + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c new file mode 100644 index 0000000..0f6d0cb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c @@ -0,0 +1,43 @@ +/* $NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)sprintf(b, "%s", argv[1]); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c new file mode 100644 index 0000000..c8dfbb7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c @@ -0,0 +1,49 @@ +/* $NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + char *q = stpcpy(b, argv[1]); + + if ((size_t)(q - b) != strlen(argv[1])) + abort(); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c new file mode 100644 index 0000000..c03d2a8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c @@ -0,0 +1,56 @@ +/* $NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $"); + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); +#if __GNUC_PREREQ__(4, 8) + char *q = stpncpy(b, "1020202020202", len); + + if (q - b != len) + abort(); +#else + // gcc-4.5 lacks __builtin___stpncpy_chk, lose. + (void)strncpy(b, "1020202020202", len); +#endif + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c new file mode 100644 index 0000000..687acf7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c @@ -0,0 +1,46 @@ +/* $NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)strcpy(b, "1"); + (void)strcat(b, argv[1]); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c new file mode 100644 index 0000000..2a7f1f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c @@ -0,0 +1,45 @@ +/* $NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)strcpy(b, argv[1]); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c new file mode 100644 index 0000000..0d66c7b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)strcpy(b, "1"); + (void)strncat(b, "1020202020202", len); + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c new file mode 100644 index 0000000..fddf67b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)strncpy(b, "1020202020202", len); + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c new file mode 100644 index 0000000..0f6af85 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c @@ -0,0 +1,57 @@ +/* $NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +static void wrap(size_t, const char *, ...) __printflike(2, 3); + +void +wrap(size_t len, const char *fmt, ...) +{ + char b[10]; + va_list ap; + va_start(ap, fmt); + (void)vsnprintf(b, len, fmt, ap); + (void)printf("%s\n", b); + va_end(ap); +} + +int +main(int argc, char *argv[]) +{ + size_t len = atoi(argv[1]); + wrap(len, "%s", "012345678901234567890"); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c new file mode 100644 index 0000000..c7fc780 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c @@ -0,0 +1,55 @@ +/* $NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $"); + +#include <stdio.h> +#include <stdarg.h> + +static void wrap(const char *, ...) __printflike(1, 2); + +static void +wrap(const char *fmt, ...) +{ + char b[10]; + va_list ap; + va_start(ap, fmt); + (void)vsprintf(b, fmt, ap); + (void)printf("%s\n", b); + va_end(ap); +} + +int +main(int argc, char *argv[]) +{ + wrap("%s", argv[1]); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh new file mode 100755 index 0000000..04adc67 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh @@ -0,0 +1,459 @@ +# $NetBSD: t_ssp.sh,v 1.7 2014/04/06 19:28:59 christos Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +h_pass() +{ + echo "Executing command [ $2$1 ]" + eval $2 atf_check -s exit:0 -o ignore -e ignore $1 +} + +h_fail() +{ + echo "Executing command [ $2$1 ]" + # Begin FreeBSD + if true; then + eval $2 atf_check -s signal -o ignore -e ignore $1 + else + # End FreeBSD + eval $2 atf_check -s signal:6 -o ignore -e ignore $1 + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case sprintf +sprintf_head() +{ + atf_set "descr" "Checks sprintf(3)" +} +sprintf_body() +{ + prog="$(atf_get_srcdir)/h_sprintf" + + h_pass "$prog ok" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case vsprintf +vsprintf_head() +{ + atf_set "descr" "Checks vsprintf(3)" +} +vsprintf_body() +{ + prog="$(atf_get_srcdir)/h_vsprintf" + + h_pass "$prog ok" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case snprintf +snprintf_head() +{ + atf_set "descr" "Checks snprintf(3)" +} +snprintf_body() +{ + prog="$(atf_get_srcdir)/h_snprintf" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case vsnprintf +vsnprintf_head() +{ + atf_set "descr" "Checks vsnprintf(3)" +} +vsnprintf_body() +{ + prog="$(atf_get_srcdir)/h_vsnprintf" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case gets +gets_head() +{ + atf_set "descr" "Checks gets(3)" +} +gets_body() +{ + prog="$(atf_get_srcdir)/h_gets" + + h_pass "$prog" "echo ok |" + # Begin FreeBSD + if true; then + h_fail "$prog" "echo 0123456789ab |" + else + # End FreeBSD + h_fail "$prog" "echo 0123456789 |" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case fgets +fgets_head() +{ + atf_set "descr" "Checks fgets(3)" +} +fgets_body() +{ + prog="$(atf_get_srcdir)/h_fgets" + + h_pass "$prog 10" "echo ok |" + # Begin FreeBSD + if true; then + h_fail "$prog 13" "echo 0123456789abc |" + else + # End FreeBSD + h_fail "$prog 11" "echo busted |" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case memcpy +memcpy_head() +{ + atf_set "descr" "Checks memcpy(3)" +} +memcpy_body() +{ + prog="$(atf_get_srcdir)/h_memcpy" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case memmove +memmove_head() +{ + atf_set "descr" "Checks memmove(3)" +} +memmove_body() +{ + prog="$(atf_get_srcdir)/h_memmove" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case memset +memset_head() +{ + atf_set "descr" "Checks memset(3)" +} +memset_body() +{ + prog="$(atf_get_srcdir)/h_memset" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case strcpy +strcpy_head() +{ + atf_set "descr" "Checks strcpy(3)" +} +strcpy_body() +{ + prog="$(atf_get_srcdir)/h_strcpy" + + h_pass "$prog 0123456" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case stpcpy +stpcpy_head() +{ + atf_set "descr" "Checks stpcpy(3)" +} +stpcpy_body() +{ + prog="$(atf_get_srcdir)/h_stpcpy" + + h_pass "$prog 0123456" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case strcat +strcat_head() +{ + atf_set "descr" "Checks strcat(3)" +} +strcat_body() +{ + prog="$(atf_get_srcdir)/h_strcat" + + h_pass "$prog 0123456" + h_fail "$prog 0123456789ABCDEF" +} + +atf_test_case strncpy +strncpy_head() +{ + atf_set "descr" "Checks strncpy(3)" +} +strncpy_body() +{ + prog="$(atf_get_srcdir)/h_strncpy" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case stpncpy +stpncpy_head() +{ + atf_set "descr" "Checks stpncpy(3)" +} +stpncpy_body() +{ + prog="$(atf_get_srcdir)/h_stpncpy" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case strncat +strncat_head() +{ + atf_set "descr" "Checks strncat(3)" +} +strncat_body() +{ + prog="$(atf_get_srcdir)/h_strncat" + + # Begin FreeBSD + h_pass "$prog 8" + if true; then + h_fail "$prog 11" + else + # End FreeBSD + h_fail "$prog 9" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case raw +raw_head() +{ + atf_set "descr" "Checks raw array overflow" +} +raw_body() +{ + prog="$(atf_get_srcdir)/h_raw" + + h_pass "$prog 9" + # Begin FreeBSD + if true; then + h_fail "$prog 12" + else + # End FreeBSD + h_fail "$prog 10" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case read +read_head() +{ + atf_set "descr" "Checks read(2)" +} +read_body() +{ + prog="$(atf_get_srcdir)/h_read" + + h_pass "$prog 1024" "echo foo |" + # Begin FreeBSD + if true; then + h_fail "$prog 1027" "echo bar |" + else + # End FreeBSD + h_fail "$prog 1025" "echo bar |" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case readlink +readlink_head() +{ + atf_set "descr" "Checks readlink(2)" +} +readlink_body() +{ + prog="$(atf_get_srcdir)/h_readlink" + + # Begin FreeBSD + if true; then + h_pass "$prog 512" + h_fail "$prog 523" + else + # End FreeBSD + h_pass "$prog 1024" + h_fail "$prog 1025" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case getcwd +getcwd_head() +{ + atf_set "descr" "Checks getcwd(3)" +} +getcwd_body() +{ + prog="$(atf_get_srcdir)/h_getcwd" + + h_pass "$prog 1024" + # Begin FreeBSD + if false; then + # End FreeBSD + h_fail "$prog 1025" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_init_test_cases() +{ + atf_add_test_case sprintf + atf_add_test_case vsprintf + atf_add_test_case snprintf + atf_add_test_case vsnprintf + atf_add_test_case gets + atf_add_test_case fgets + atf_add_test_case memcpy + atf_add_test_case memmove + atf_add_test_case memset + atf_add_test_case stpcpy + atf_add_test_case stpncpy + atf_add_test_case strcat + atf_add_test_case strcpy + atf_add_test_case strncat + atf_add_test_case strncpy + atf_add_test_case raw + atf_add_test_case read + atf_add_test_case readlink + atf_add_test_case getcwd +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c new file mode 100644 index 0000000..251804e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $ */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> + +static const char path[] = "/etc/passwd"; + +ATF_TC(clearerr_basic); +ATF_TC_HEAD(clearerr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of clearerr(3)"); +} + +ATF_TC_BODY(clearerr_basic, tc) +{ + char buf[2048]; + FILE *fp; + + fp = fopen(path, "r"); + ATF_REQUIRE(fp != NULL); + + while (feof(fp) == 0) + (void)fread(buf, sizeof(buf), 1, fp); + + ATF_REQUIRE(feof(fp) != 0); + + errno = 0; + clearerr(fp); + + ATF_REQUIRE(errno == 0); + ATF_REQUIRE(feof(fp) == 0); + ATF_REQUIRE(fclose(fp) != EOF); +} + +ATF_TC(clearerr_err); +ATF_TC_HEAD(clearerr_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that clearerr(3) does not fail"); +} + +ATF_TC_BODY(clearerr_err, tc) +{ + FILE *fp; + + fp = fopen(path, "r"); + + ATF_REQUIRE(fp != NULL); + ATF_REQUIRE(fclose(fp) == 0); + + errno = 0; + clearerr(fp); + + ATF_REQUIRE(errno == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clearerr_basic); + ATF_TP_ADD_TC(tp, clearerr_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c new file mode 100644 index 0000000..70498c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c @@ -0,0 +1,175 @@ +/* $NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <unistd.h> + +static const char *path = "fflush"; + +ATF_TC_WITH_CLEANUP(fflush_err); +ATF_TC_HEAD(fflush_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fflush(3)"); +} + +ATF_TC_BODY(fflush_err, tc) +{ + FILE *f; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("the EOF invariant fails on FreeBSD; this is new"); +#endif + + f = fopen(path, "w"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fflush(NULL) == 0); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + ATF_REQUIRE(f != NULL); + + /* + * In NetBSD the call should fail if the supplied + * parameteris not an open stream or the stream is + * not open for writing. + */ + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF); + + ATF_REQUIRE(fclose(f) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fflush_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fflush_seek); +ATF_TC_HEAD(fflush_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test file offsets with fflush(3)"); +} + +ATF_TC_BODY(fflush_seek, tc) +{ + char buf[12]; + int fd = -1; + FILE *f; + + /* + * IEEE Std 1003.1-2008: + * + * "For a stream open for reading, if the file + * is not already at EOF, and the file is one + * capable of seeking, the file offset of the + * underlying open file description shall be + * adjusted so that the next operation on the + * open file description deals with the byte + * after the last one read from or written to + * the stream being flushed." + */ + f = fopen(path, "w"); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r+"); + ATF_REQUIRE(f != NULL); + + fd = fileno(f); + ATF_REQUIRE(fd != -1); + + ATF_REQUIRE(fread(buf, 1, 3, f) == 3); + ATF_REQUIRE(fflush(f) == 0); + ATF_REQUIRE(fseek(f, 0, SEEK_CUR) == 0); + + /* + * Verify that the offsets are right and that + * a read operation resumes at the correct location. + */ + ATF_REQUIRE(ftell(f) == 3); + ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == 3); + ATF_REQUIRE(fgetc(f) == 'b'); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fflush_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fpurge_err); +ATF_TC_HEAD(fpurge_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fpurge(3)"); +} + +ATF_TC_BODY(fpurge_err, tc) +{ + FILE *f; + + f = fopen(path, "w"); + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fpurge(f) == EOF); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fpurge_err, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fflush_err); + ATF_TP_ADD_TC(tp, fflush_seek); + ATF_TP_ADD_TC(tp, fpurge_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c new file mode 100644 index 0000000..31b76d0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c @@ -0,0 +1,1181 @@ +/* $NetBSD: t_fmemopen.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */ + +/*- + * Copyright (c)2010 Takehiko NOZAKI, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include <atf-c.h> +#else +#if defined(__linux__) +#define _GNU_SOURCE +#include <features.h> +#endif +#include <assert.h> +#include <stdio.h> +#define ATF_TC(arg0) static void arg0##_head(void) +#define ATF_TC_HEAD(arg0, arg1) static void arg0##_head() +#define atf_tc_set_md_var(arg0, arg1, ...) do { \ + printf(__VA_ARGS__); \ + puts(""); \ +} while (/*CONSTCOND*/0) +#define ATF_TC_BODY(arg0, arg1) static void arg0##_body() +#define ATF_CHECK(arg0) assert(arg0) +#define ATF_TP_ADD_TCS(arg0) int main(void) +#define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body() +#define atf_no_error() 0 +#endif + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +const char *mode_rwa[] = { + "r", "rb", "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + "a", "ab", "a+", "ab+", "a+b", + NULL +}; + +const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL }; +const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL }; +const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL }; + +struct testcase { + const char *s; + off_t n; +} testcases[] = { +#define TESTSTR(s) { s, sizeof(s)-1 } + TESTSTR("\0he quick brown fox jumps over the lazy dog"), + TESTSTR("T\0e quick brown fox jumps over the lazy dog"), + TESTSTR("Th\0 quick brown fox jumps over the lazy dog"), + TESTSTR("The\0quick brown fox jumps over the lazy dog"), + TESTSTR("The \0uick brown fox jumps over the lazy dog"), + TESTSTR("The q\0ick brown fox jumps over the lazy dog"), + TESTSTR("The qu\0ck brown fox jumps over the lazy dog"), + TESTSTR("The qui\0k brown fox jumps over the lazy dog"), + TESTSTR("The quic\0 brown fox jumps over the lazy dog"), + TESTSTR("The quick\0brown fox jumps over the lazy dog"), + TESTSTR("The quick \0rown fox jumps over the lazy dog"), + TESTSTR("The quick b\0own fox jumps over the lazy dog"), + TESTSTR("The quick br\0wn fox jumps over the lazy dog"), + TESTSTR("The quick bro\0n fox jumps over the lazy dog"), + TESTSTR("The quick brow\0 fox jumps over the lazy dog"), + TESTSTR("The quick brown\0fox jumps over the lazy dog"), + TESTSTR("The quick brown \0ox jumps over the lazy dog"), + TESTSTR("The quick brown f\0x jumps over the lazy dog"), + TESTSTR("The quick brown fo\0 jumps over the lazy dog"), + TESTSTR("The quick brown fox\0jumps over the lazy dog"), + TESTSTR("The quick brown fox \0umps over the lazy dog"), + TESTSTR("The quick brown fox j\0mps over the lazy dog"), + TESTSTR("The quick brown fox ju\0ps over the lazy dog"), + TESTSTR("The quick brown fox jum\0s over the lazy dog"), + TESTSTR("The quick brown fox jump\0 over the lazy dog"), + TESTSTR("The quick brown fox jumps\0over the lazy dog"), + TESTSTR("The quick brown fox jumps \0ver the lazy dog"), + TESTSTR("The quick brown fox jumps o\0er the lazy dog"), + TESTSTR("The quick brown fox jumps ov\0r the lazy dog"), + TESTSTR("The quick brown fox jumps ove\0 the lazy dog"), + TESTSTR("The quick brown fox jumps over\0the lazy dog"), + TESTSTR("The quick brown fox jumps over \0he lazy dog"), + TESTSTR("The quick brown fox jumps over t\0e lazy dog"), + TESTSTR("The quick brown fox jumps over th\0 lazy dog"), + TESTSTR("The quick brown fox jumps over the\0lazy dog"), + TESTSTR("The quick brown fox jumps over the \0azy dog"), + TESTSTR("The quick brown fox jumps over the l\0zy dog"), + TESTSTR("The quick brown fox jumps over the la\0y dog"), + TESTSTR("The quick brown fox jumps over the laz\0 dog"), + TESTSTR("The quick brown fox jumps over the lazy\0dog"), + TESTSTR("The quick brown fox jumps over the lazy \0og"), + TESTSTR("The quick brown fox jumps over the lazy d\0g"), + TESTSTR("The quick brown fox jumps over the lazy do\0"), + TESTSTR("The quick brown fox jumps over the lazy dog"), + { NULL, 0 }, +}; + +ATF_TC(test00); +ATF_TC_HEAD(test00, tc) +{ + atf_tc_set_md_var(tc, "descr", "test00"); +} +ATF_TC_BODY(test00, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_rwa[0]; *p != NULL; ++p) { + fp = fmemopen(&buf[0], sizeof(buf), *p); +/* + * Upon successful completion, fmemopen() shall return a pointer to the + * object controlling the stream. + */ + ATF_CHECK(fp != NULL); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test01); +ATF_TC_HEAD(test01, tc) +{ + atf_tc_set_md_var(tc, "descr", "test01"); +} +ATF_TC_BODY(test01, tc) +{ + const char **p; + const char *mode[] = { + "r+", "rb+", "r+b", + "w+", "wb+", "w+b", + "a+", "ab+", "a+b", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * If a null pointer is specified as the buf argument, fmemopen() shall + * allocate size bytes of memory as if by a call to malloc(). + */ + fp = fmemopen(NULL, BUFSIZ, *p); + ATF_CHECK(fp != NULL); + +/* + * If buf is a null pointer, the initial position shall always be set + * to the beginning of the buffer. + */ + ATF_CHECK(ftello(fp) == (off_t)0); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test02); +ATF_TC_HEAD(test02, tc) +{ + atf_tc_set_md_var(tc, "descr", "test02"); +} +ATF_TC_BODY(test02, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_r[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + +/* + * This position is initially set to either the beginning of the buffer + * (for r and w modes) + */ + ATF_CHECK((unsigned char)buf[0] == 0x1); + ATF_CHECK(ftello(fp) == (off_t)0); + +/* + * The stream also maintains the size of the current buffer contents. + * For modes r and r+ the size is set to the value given by the size argument. + */ +#if !defined(__GLIBC__) + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test03); +ATF_TC_HEAD(test03, tc) +{ + atf_tc_set_md_var(tc, "descr", "test03"); +} +ATF_TC_BODY(test03, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_w[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + +/* + * This position is initially set to either the beginning of the buffer + * (for r and w modes) + */ + ATF_CHECK(buf[0] == '\0'); + ATF_CHECK(ftello(fp) == (off_t)0); + +/* + * For modes w and w+ the initial size is zero + */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test04); +ATF_TC_HEAD(test04, tc) +{ + atf_tc_set_md_var(tc, "descr", "test04"); +} +ATF_TC_BODY(test04, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + +/* + * or to the first null byte in the buffer (for a modes) + */ + for (p = &mode_a[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + + ATF_CHECK((unsigned char)buf[0] == 0x1); + +/* If no null byte is found in append mode, + * the initial position is set to one byte after the end of the buffer. + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + +/* + * and for modes a and a+ the initial size is either the position of the + * first null byte in the buffer or the value of the size argument + * if no null byte is found. + */ +#if !defined(__GLIBC__) + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test05); +ATF_TC_HEAD(test05, tc) +{ + atf_tc_set_md_var(tc, "descr", "test05"); +} +ATF_TC_BODY(test05, tc) +{ + const char **p; + FILE *fp; + char buf[BUFSIZ]; + + for (p = &mode_rwa[0]; *p != NULL; ++p) { +/* + * Otherwise, a null pointer shall be returned, and errno shall be set + * to indicate the error. + */ + errno = 0; + fp = fmemopen(NULL, (size_t)0, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + + errno = 0; + fp = fmemopen((void *)&buf[0], 0, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +} + +ATF_TC(test06); +ATF_TC_HEAD(test06, tc) +{ + atf_tc_set_md_var(tc, "descr", "test06"); +} +ATF_TC_BODY(test06, tc) +{ + const char **p; + const char *mode[] = { "", " ", "???", NULL }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * The value of the mode argument is not valid. + */ + fp = fmemopen(NULL, 1, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +} + +ATF_TC(test07); +ATF_TC_HEAD(test07, tc) +{ + atf_tc_set_md_var(tc, "descr", "test07"); +} +ATF_TC_BODY(test07, tc) +{ +#if !defined(__GLIBC__) + const char **p; + const char *mode[] = { + "r", "rb", + "w", "wb", + "a", "ab", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * Because this feature is only useful when the stream is opened for updating + * (because there is no way to get a pointer to the buffer) the fmemopen() + * call may fail if the mode argument does not include a '+' . + */ + errno = 0; + fp = fmemopen(NULL, 1, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +#endif +} + +ATF_TC(test08); +ATF_TC_HEAD(test08, tc) +{ + atf_tc_set_md_var(tc, "descr", "test08"); +} +ATF_TC_BODY(test08, tc) +{ +#if !defined(__GLIBC__) + const char **p; + const char *mode[] = { + "r+", "rb+", "r+b", + "w+", "wb+", "w+b", + "a+", "ab+", "a+b", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * The buf argument is a null pointer and the allocation of a buffer of + * length size has failed. + */ + fp = fmemopen(NULL, SIZE_MAX, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == ENOMEM); + } +#endif +} + +/* + * test09 - test14: + * An attempt to seek a memory buffer stream to a negative position or to a + * position larger than the buffer size given in the size argument shall fail. + */ + +ATF_TC(test09); +ATF_TC_HEAD(test09, tc) +{ + atf_tc_set_md_var(tc, "descr", "test09"); +} +ATF_TC_BODY(test09, tc) +{ + struct testcase *t; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + off_t i; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rwa[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_SET) + */ + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_SET) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive */ + for (i = (off_t)1; i <= (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_SET) == 0); + ATF_CHECK(ftello(fp) == i); + } + /* positive + OOB */ + ATF_CHECK(fseeko(fp, t->n + 1, SEEK_SET) == -1); + ATF_CHECK(ftello(fp) == t->n); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_SET) == -1); + ATF_CHECK(ftello(fp) == t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_rw[] = { + "r", "rb", "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + NULL +}; + +ATF_TC(test10); +ATF_TC_HEAD(test10, tc) +{ + atf_tc_set_md_var(tc, "descr", "test10"); +} +ATF_TC_BODY(test10, tc) +{ + struct testcase *t; + off_t i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_CUR) + */ + ATF_CHECK(ftello(fp) == (off_t)0); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* negative & OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive */ + for (i = 0; i < (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == i + 1); + } + + /* positive & OOB */ + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test11); +ATF_TC_HEAD(test11, tc) +{ + atf_tc_set_md_var(tc, "descr", "test11"); +} +ATF_TC_BODY(test11, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_CUR) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = (off_t)t->n - len; + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_CUR) + */ +#if defined(__GLIBC__) + if (i < (off_t)t->n) { +#endif + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == len); + + /* posive */ + for (i = (off_t)1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == len + i); + } + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + /* negative */ + for (i = (off_t)1; i <= (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == (off_t)t->n - i); + } + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +#ifndef __FreeBSD__ +ATF_TC(test12); +ATF_TC_HEAD(test12, tc) +{ + atf_tc_set_md_var(tc, "descr", "test12"); +} +ATF_TC_BODY(test12, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = t->n - len; + for (p = &mode_r[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)0); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* positive */ + for (i = 1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len + i); + } + + /* negative */ + for (i = 1; i < len; ++i) { + ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len - i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} +#endif + +ATF_TC(test13); +ATF_TC_HEAD(test13, tc) +{ + atf_tc_set_md_var(tc, "descr", "test13"); +} +ATF_TC_BODY(test13, tc) +{ + struct testcase *t; +#ifndef __FreeBSD__ + off_t i; +#endif + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_w[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(buf[0] == '\0'); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); +#endif + +#ifndef __FreeBSD__ + /* positive */ + for (i = 1; i <= t->n; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test14); +ATF_TC_HEAD(test14, tc) +{ + atf_tc_set_md_var(tc, "descr", "test14"); +} +ATF_TC_BODY(test14, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = (off_t)t->n - len; + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == len); + + /* zero */ + ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + +#ifndef __FreeBSD__ + /* positive */ + for (i = 1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len + i); + } +#endif + + /* negative */ + for (i = 1; i < len; ++i) { + ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len - i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_rw1[] = { + "r", "rb", "r+", "rb+", "r+b", + "w+", "wb+", + NULL +}; + +#ifndef __FreeBSD__ + +/* test15 - 18: + * When a stream open for writing is flushed or closed, a null byte is written + * at the current position or at the end of the buffer, depending on the size + * of the contents. + */ + +ATF_TC(test15); +ATF_TC_HEAD(test15, tc) +{ + atf_tc_set_md_var(tc, "descr", "test15"); +} +ATF_TC_BODY(test15, tc) +{ + struct testcase *t; + const char **p; + char buf0[BUFSIZ]; + FILE *fp; + int i; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fgetc(3) + */ + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf0[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test16); +ATF_TC_HEAD(test16, tc) +{ + atf_tc_set_md_var(tc, "descr", "test16"); +} +ATF_TC_BODY(test16, tc) +{ + struct testcase *t; + const char **p; + char buf0[BUFSIZ], buf1[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + buf1[t->n] = 0x1; + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fread(4) + */ + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0); + ATF_CHECK((unsigned char)buf1[t->n] == 0x1); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_a1[] = { "a+", "ab+", NULL }; + +ATF_TC(test17); +ATF_TC_HEAD(test17, tc) +{ + atf_tc_set_md_var(tc, "descr", "test17"); +} +ATF_TC_BODY(test17, tc) +{ + struct testcase *t; + size_t len; + int i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a1[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fgetc(3) + */ +#if defined(__GLIBC__) + if (i < t->n) { +#endif + for (i = len; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + rewind(fp); + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test18); +ATF_TC_HEAD(test18, tc) +{ + atf_tc_set_md_var(tc, "descr", "test18"); +} +ATF_TC_BODY(test18, tc) +{ + struct testcase *t; + size_t len; + const char **p; + char buf0[BUFSIZ], buf1[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + buf1[t->n - len] = 0x1; + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fread(3) + */ +#if defined(__GLIBC__) + if (i < t->n) { +#endif + ATF_CHECK(ftello(fp) == (off_t)len); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) + == t->n - len); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len)); + ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1); + rewind(fp); + buf1[t->n] = 0x1; + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) + == (size_t)t->n); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n)); + ATF_CHECK((unsigned char)buf1[t->n] == 0x1); +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +/* + * test19 - test22: + * If a stream open for update is flushed or closed and the last write has + * advanced the current buffer size, a null byte is written at the end of the + * buffer if it fits. + */ + +const char *mode_rw2[] = { + "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + NULL +}; + +ATF_TC(test19); +ATF_TC_HEAD(test19, tc) +{ + atf_tc_set_md_var(tc, "descr", "test19"); +} +ATF_TC_BODY(test19, tc) +{ + struct testcase *t; + int i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw2[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + buf[t->n] = 0x1; + fp = fmemopen(&buf[0], t->n + 1, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fputc(3) + */ + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fputc(t->s[i], fp) == t->s[i]); + ATF_CHECK(buf[i] == t->s[i]); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + ATF_CHECK(buf[i] == t->s[i]); +#if !defined(__GLIBC__) + ATF_CHECK(buf[i + 1] == '\0'); +#endif + } + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(fputc(0x1, fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(feof(fp) == 0); + +/* accept nul character at end of buffer */ + ATF_CHECK(fputc('\0', fp) == '\0'); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + ATF_CHECK(feof(fp) == 0); + +/* reach EOF */ + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + + /* compare */ + ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); + ATF_CHECK(buf[t->n] == '\0'); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test20); +ATF_TC_HEAD(test20, tc) +{ + atf_tc_set_md_var(tc, "descr", "test20"); +} +ATF_TC_BODY(test20, tc) +{ + struct testcase *t; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw2[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + buf[t->n] = 0x1; + fp = fmemopen(&buf[0], t->n + 1, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); + ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n); +/* + * test fmemopen_write + fwrite(3) + */ +#if !defined(__GLIBC__) + ATF_CHECK(buf[t->n] == '\0'); + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(feof(fp) == 0); +#endif + +/* accept nul character at end of buffer */ + ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + ATF_CHECK(feof(fp) == 0); + +/* reach EOF */ + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + +/* compare */ + ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); + ATF_CHECK(buf[t->n] == '\0'); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test21); +ATF_TC_HEAD(test21, tc) +{ + atf_tc_set_md_var(tc, "descr", "test21"); +} +ATF_TC_BODY(test21, tc) +{ + struct testcase *t; + int len, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a[0]; *p != NULL; ++p) { + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fputc(3) + */ + if (len < t->n) { + for (i = len; i < t->n - 1; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fputc(t->s[i - len], fp) + == t->s[i - len]); + ATF_CHECK(buf[i] == t->s[i - len]); + ATF_CHECK(ftello(fp) == (off_t)i + 1); +#if !defined(__GLIBC__) + ATF_CHECK(buf[i + 1] == '\0'); +#endif + } + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + ATF_CHECK(fputc(0x1, fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + +/* accept nul character at end of buffer */ + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + ATF_CHECK(fputc('\0', fp) == '\0'); + ATF_CHECK(ftello(fp) == (off_t)t->n); + } + +/* reach EOF */ + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test22); +ATF_TC_HEAD(test22, tc) +{ + atf_tc_set_md_var(tc, "descr", "test22"); +} +ATF_TC_BODY(test22, tc) +{ + struct testcase *t0, *t1; + size_t len0, len1, nleft; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t0 = &testcases[0]; t0->s != NULL; ++t0) { + len0 = strnlen(t0->s, t0->n); + for (t1 = &testcases[0]; t1->s != NULL; ++t1) { + len1 = strnlen(t1->s, t1->n); + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t0->s, t0->n); + fp = fmemopen(&buf[0], t0->n, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fwrite(3) + */ + nleft = t0->n - len0; +#if !defined(__GLIBC__) + if (nleft == 0 || len1 == nleft - 1) { + ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) + == nleft); + ATF_CHECK(ftell(fp) == t1->n); + } else { + ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) + == nleft - 1); + ATF_CHECK(ftell(fp) == t1->n - 1); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } + } +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, test00); + ATF_TP_ADD_TC(tp, test01); + ATF_TP_ADD_TC(tp, test02); + ATF_TP_ADD_TC(tp, test03); + ATF_TP_ADD_TC(tp, test04); + ATF_TP_ADD_TC(tp, test05); + ATF_TP_ADD_TC(tp, test06); + ATF_TP_ADD_TC(tp, test07); + ATF_TP_ADD_TC(tp, test08); + ATF_TP_ADD_TC(tp, test09); + ATF_TP_ADD_TC(tp, test10); + ATF_TP_ADD_TC(tp, test11); +#ifndef __FreeBSD__ + ATF_TP_ADD_TC(tp, test12); +#endif + ATF_TP_ADD_TC(tp, test13); + ATF_TP_ADD_TC(tp, test14); +#ifndef __FreeBSD__ + ATF_TP_ADD_TC(tp, test15); + ATF_TP_ADD_TC(tp, test16); + ATF_TP_ADD_TC(tp, test17); + ATF_TP_ADD_TC(tp, test18); + ATF_TP_ADD_TC(tp, test19); + ATF_TP_ADD_TC(tp, test20); + ATF_TP_ADD_TC(tp, test21); + ATF_TP_ADD_TC(tp, test22); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c new file mode 100644 index 0000000..d9e2dd6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c @@ -0,0 +1,444 @@ +/* $NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static const char *path = "fopen"; + +ATF_TC_WITH_CLEANUP(fdopen_close); +ATF_TC_HEAD(fdopen_close, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that descriptors are closed"); +} + +ATF_TC_BODY(fdopen_close, tc) +{ + FILE *f; + int fd; + + /* + * Check that the file descriptor + * used to fdopen(3) a stream is + * closed once the stream is closed. + */ + fd = open(path, O_RDWR | O_CREAT); + + ATF_REQUIRE(fd >= 0); + + f = fdopen(fd, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(close(fd) == -1); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fdopen_close, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fdopen_err); +ATF_TC_HEAD(fdopen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fdopen(3)"); +} + +ATF_TC_BODY(fdopen_err, tc) +{ + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "w") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "a") == NULL); + + ATF_REQUIRE(close(fd) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fdopen(fd, "r") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fdopen(-1, "w+") == NULL); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fdopen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fdopen_seek); +ATF_TC_HEAD(fdopen_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stream position with fdopen(3)"); +} + +ATF_TC_BODY(fdopen_seek, tc) +{ + FILE *f; + int fd; + + /* + * Verify that the file position associated + * with the stream corresponds with the offset + * set earlier for the file descriptor. + */ + fd = open(path, O_RDWR | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(write(fd, "garbage", 7) == 7); + ATF_REQUIRE(lseek(fd, 3, SEEK_SET) == 3); + + f = fdopen(fd, "r+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftell(f) == 3); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fdopen_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_err); +ATF_TC_HEAD(fopen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fopen(3)"); +} + +ATF_TC_BODY(fopen_err, tc) +{ + static const char *mode[] = { + "x", "xr", "xr", "+r+", "R", "W+", " aXX", "Xr", " r+", "" }; + + char buf[PATH_MAX + 1]; + size_t i; + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + /* + * Note that also "invalid" characters + * may follow the mode-string whenever + * the first character is valid. + */ + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + f = fopen(path, mode[i]); + + if (f == NULL && errno == EINVAL) + continue; + + if (f != NULL) + (void)fclose(f); + + atf_tc_fail_nonfatal("opened file as '%s'", mode[i]); + } + + (void)unlink(path); + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EISDIR, fopen("/usr/bin", "w") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, fopen("/a/b/c/d/e/f", "r") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, fopen(buf, "r+") == NULL); +} + +ATF_TC_CLEANUP(fopen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_append); +ATF_TC_HEAD(fopen_append, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that append-mode works"); +} + +ATF_TC_BODY(fopen_append, tc) +{ + char buf[15]; + FILE *f; + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "a"); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + + ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); + ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fopen_append, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_mode); +ATF_TC_HEAD(fopen_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fopen(3) modes"); +} + +ATF_TC_BODY(fopen_mode, tc) +{ + size_t i; + FILE *f; + + static const char *mode[] = { + "r", "r+", "w", "w+", "a", "a+", + "rb", "r+b", "wb", "w+b", "ab", "a+b" + "re", "r+e", "we", "w+e", "ae", "a+e" + "rf", "r+f", "wf", "w+f", "af", "a+f" + }; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + /* + * Verify that various modes work. + */ + for (i = 0; i < __arraycount(mode); i++) { + + f = fopen(path, mode[i]); + + if (f != NULL) { + ATF_REQUIRE(fclose(f) == 0); + continue; + } + + atf_tc_fail_nonfatal("failed to open file as %s", mode[i]); + } + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fopen_mode, tc) +{ + (void)unlink(path); +} + +ATF_TC(fopen_perm); +ATF_TC_HEAD(fopen_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with fopen(3)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(fopen_perm, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "a+") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "w+") == NULL); +} + +ATF_TC(fopen_regular); +ATF_TC_HEAD(fopen_regular, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fopen(3) with 'f' mode"); +} + +ATF_TC_BODY(fopen_regular, tc) +{ + static const char *mode[] = { "rf", "r+f", "wf", "w+f", "af", "a+f" }; + static const char *devs[] = { _PATH_DEVNULL }; + + size_t i, j; + FILE *f; + + for (i = 0; i < __arraycount(devs); i++) { + + for (j = 0; j < __arraycount(mode); j++) { + + errno = 0; + f = fopen(devs[i], mode[j]); + + if (f == NULL && errno == EFTYPE) + continue; + + if (f != NULL) + (void)fclose(f); + + atf_tc_fail_nonfatal("opened %s as %s", + devs[i], mode[j]); + } + } +} + +ATF_TC_WITH_CLEANUP(fopen_seek); +ATF_TC_HEAD(fopen_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test initial stream position"); +} + +ATF_TC_BODY(fopen_seek, tc) +{ + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + /* + * The position of the stream should be + * at the start, except for append-mode. + */ + f = fopen(path, "r"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftello(f) == 0); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "a"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftello(f) == 7); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fopen_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(freopen_std); +ATF_TC_HEAD(freopen_std, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of freopen(3)"); +} + +ATF_TC_BODY(freopen_std, tc) +{ + FILE *std[2] = { stdin, stdout }; + char buf[15]; + size_t i; + FILE *f; + + /* + * Associate a standard stream with a custom stream. + * Then write to the standard stream and verify that + * the result now appears in the custom stream. + */ + for (i = 0; i < __arraycount(std); i++) { + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + ATF_REQUIRE(f != NULL); + + f = freopen(path, "w+", std[i]); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fprintf(std[i], "garbage") == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); + ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); + + ATF_REQUIRE(fclose(f) == 0); + } + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(freopen_std, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fdopen_close); + ATF_TP_ADD_TC(tp, fdopen_err); + ATF_TP_ADD_TC(tp, fdopen_seek); + ATF_TP_ADD_TC(tp, fopen_append); + ATF_TP_ADD_TC(tp, fopen_err); + ATF_TP_ADD_TC(tp, fopen_mode); + ATF_TP_ADD_TC(tp, fopen_perm); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, fopen_regular); +#endif + ATF_TP_ADD_TC(tp, fopen_seek); + ATF_TP_ADD_TC(tp, freopen_std); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c new file mode 100644 index 0000000..ed7c0dc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static const char *path = "fputc"; +static void puterr(int (*)(int, FILE *)); +static void putstr(int (*)(int, FILE *)); + +static void +puterr(int (*func)(int, FILE *)) +{ + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(func('x', f) == EOF); +} + +static void +putstr(int (*func)(int, FILE *)) +{ + const char *str = "1234567890x"; + unsigned short i = 0; + char buf[10]; + FILE *f; + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + ATF_REQUIRE(f != NULL); + + while (str[i] != 'x') { + ATF_REQUIRE(func(str[i], f) == str[i]); + i++; + } + + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fread(buf, 1, 10, f) == 10); + ATF_REQUIRE(strncmp(buf, str, 10) == 0); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_WITH_CLEANUP(fputc_basic); +ATF_TC_HEAD(fputc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fputc(3)"); +} + +ATF_TC_BODY(fputc_basic, tc) +{ + putstr(fputc); +} + +ATF_TC_CLEANUP(fputc_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fputc_err); +ATF_TC_HEAD(fputc_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fputc(3)"); +} + +ATF_TC_BODY(fputc_err, tc) +{ + puterr(fputc); +} + +ATF_TC_CLEANUP(fputc_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_basic); +ATF_TC_HEAD(putc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of putc(3)"); +} + +ATF_TC_BODY(putc_basic, tc) +{ + putstr(putc); +} + +ATF_TC_CLEANUP(putc_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_err); +ATF_TC_HEAD(putc_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from putc(3)"); +} + +ATF_TC_BODY(putc_err, tc) +{ + puterr(putc); +} + +ATF_TC_CLEANUP(putc_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_unlocked_basic); +ATF_TC_HEAD(putc_unlocked_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of putc_unlocked(3)"); +} + +ATF_TC_BODY(putc_unlocked_basic, tc) +{ + putstr(putc_unlocked); +} + +ATF_TC_CLEANUP(putc_unlocked_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_unlocked_err); +ATF_TC_HEAD(putc_unlocked_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from putc_unlocked(3)"); +} + +ATF_TC_BODY(putc_unlocked_err, tc) +{ + puterr(putc_unlocked); +} + +ATF_TC_CLEANUP(putc_unlocked_err, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fputc_basic); + ATF_TP_ADD_TC(tp, fputc_err); + ATF_TP_ADD_TC(tp, putc_basic); + ATF_TP_ADD_TC(tp, putc_err); + ATF_TP_ADD_TC(tp, putc_unlocked_basic); + ATF_TP_ADD_TC(tp, putc_unlocked_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c new file mode 100644 index 0000000..e423060 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c @@ -0,0 +1,54 @@ +/* $NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $"); + +#include <atf-c.h> +#include <stdlib.h> + +ATF_TC(mktemp_not_exist); +ATF_TC_HEAD(mktemp_not_exist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that mktemp does not fail on" + " a path that does not exist"); +} + +ATF_TC_BODY(mktemp_not_exist, tc) +{ + char template[] = "I will barf/XXXXXX"; + ATF_REQUIRE(mktemp(template) != NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mktemp_not_exist); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_popen.c b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c new file mode 100644 index 0000000..699498c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1999\ + The NetBSD Foundation, Inc. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +__RCSID("$NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $"); +#endif /* not lint */ + +#include <atf-c.h> + +#include <sys/param.h> + +#include <errno.h> +#include <err.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +#define _PATH_CAT "/bin/cat" +#define BUFSIZE (640*1024) + /* 640KB ought to be enough for everyone. */ +#define DATAFILE "popen.data" + +#define TEST_ERROR(a) \ + do \ + { \ + warn(a); \ + atf_tc_fail("Check stderr for error details."); \ + } while ( /*CONSTCOND*/ 0 ) + +ATF_TC_WITH_CLEANUP(popen_zeropad); +ATF_TC_HEAD(popen_zeropad, tc) +{ + + atf_tc_set_md_var(tc, "descr", "output format zero padding"); +} + +ATF_TC_BODY(popen_zeropad, tc) +{ + char *buffer, command[MAXPATHLEN]; + int idx, in; + FILE *my_pipe; + + if ((buffer = malloc(BUFSIZE)) == NULL) + atf_tc_skip("Unable to allocate buffer."); + + srand ((unsigned int)time(NULL)); + + for (idx = 0; idx < BUFSIZE; idx++) + buffer[idx]=(char)rand(); + + (void)snprintf(command, sizeof(command), "%s >%s", + _PATH_CAT, DATAFILE); + + if ((my_pipe = popen(command, "w")) == NULL) + TEST_ERROR("popen write"); + + if (fwrite(buffer, sizeof(char), BUFSIZE, my_pipe) != BUFSIZE) + TEST_ERROR("fwrite"); + + if (pclose(my_pipe) == -1) + TEST_ERROR("pclose"); + + (void)snprintf(command, sizeof(command), "%s %s", _PATH_CAT, DATAFILE); + + if ((my_pipe = popen(command, "r")) == NULL) + TEST_ERROR("popen read"); + + idx = 0; + while ((in = fgetc(my_pipe)) != EOF) + if (idx == BUFSIZE) { + errno = EFBIG; + TEST_ERROR("read"); + } + else if ((char)in != buffer[idx++]) { + errno = EINVAL; + TEST_ERROR("read"); + } + + if (idx < BUFSIZE) { + errno = EIO; + TEST_ERROR("read"); + } + + if (pclose(my_pipe) == -1) + TEST_ERROR("pclose"); +} + +ATF_TC_CLEANUP(popen_zeropad, tc) +{ + (void)unlink(DATAFILE); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, popen_zeropad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c new file mode 100644 index 0000000..5ef58f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c @@ -0,0 +1,204 @@ +/* $NetBSD: t_printf.c,v 1.8 2012/04/11 16:21:42 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/resource.h> +#include <atf-c.h> +#include <math.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <time.h> +#include <stdlib.h> + +#ifndef __NetBSD__ +#include <signal.h> +#endif + +ATF_TC(snprintf_c99); +ATF_TC_HEAD(snprintf_c99, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Test printf(3) C99 conformance (PR lib/22019)"); +} + +ATF_TC_BODY(snprintf_c99, tc) +{ + char s[4]; + + (void)memset(s, '\0', sizeof(s)); + (void)snprintf(s, sizeof(s), "%#.o", 0); + (void)printf("printf = %#.o\n", 0); + (void)fprintf(stderr, "snprintf = %s", s); + + ATF_REQUIRE(strlen(s) == 1); + ATF_REQUIRE(s[0] == '0'); +} + +ATF_TC(snprintf_dotzero); +ATF_TC_HEAD(snprintf_dotzero, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "PR lib/32951: %%.0f formats (0.0,0.5] to \"0.\""); +} + +ATF_TC_BODY(snprintf_dotzero, tc) +{ + char s[4]; + + ATF_CHECK(snprintf(s, sizeof(s), "%.0f", 0.1) == 1); + ATF_REQUIRE_STREQ(s, "0"); +} + +ATF_TC(snprintf_posarg); +ATF_TC_HEAD(snprintf_posarg, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments"); +} + +ATF_TC_BODY(snprintf_posarg, tc) +{ + char s[16]; + + ATF_CHECK(snprintf(s, sizeof(s), "%1$d", -23) == 3); + ATF_REQUIRE_STREQ(s, "-23"); +} + +ATF_TC(snprintf_posarg_width); +ATF_TC_HEAD(snprintf_posarg_width, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments with " + "field width"); +} + +ATF_TC_BODY(snprintf_posarg_width, tc) +{ + char s[16]; + + ATF_CHECK(snprintf(s, sizeof(s), "%1$*2$d", -23, 4) == 4); + ATF_REQUIRE_STREQ(s, " -23"); +} + +ATF_TC(snprintf_posarg_error); +ATF_TC_HEAD(snprintf_posarg_error, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments out " + "of bounds"); +} + +ATF_TC_BODY(snprintf_posarg_error, tc) +{ + char s[16], fmt[32]; + +#ifndef __NetBSD__ + atf_tc_expect_signal(SIGSEGV, + "some non-NetBSD platforms including FreeBSD don't validate " + "negative size; testcase blows up with SIGSEGV"); +#endif + + snprintf(fmt, sizeof(fmt), "%%%zu$d", SIZE_MAX / sizeof(size_t)); + + ATF_CHECK(snprintf(s, sizeof(s), fmt, -23) == -1); +} + +ATF_TC(snprintf_float); +ATF_TC_HEAD(snprintf_float, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test that floating conversions don't" + " leak memory"); +} + +ATF_TC_BODY(snprintf_float, tc) +{ + union { + double d; + uint64_t bits; + } u; + uint32_t ul, uh; + time_t now; + char buf[1000]; + struct rlimit rl; + + rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_AS, &rl) != -1); + rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_DATA, &rl) != -1); + + time(&now); + srand(now); + for (size_t i = 0; i < 10000; i++) { + ul = rand(); + uh = rand(); + u.bits = (uint64_t)uh << 32 | ul; + ATF_CHECK(snprintf(buf, sizeof buf, " %.2f", u.d) != -1); + } +} + +ATF_TC(sprintf_zeropad); +ATF_TC_HEAD(sprintf_zeropad, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test output format zero padding (PR lib/44113)"); +} + +ATF_TC_BODY(sprintf_zeropad, tc) +{ + char str[1024]; + + ATF_CHECK(sprintf(str, "%010f", 0.0) == 10); + ATF_REQUIRE_STREQ(str, "000.000000"); + + /* ieeefp */ +#ifndef __vax__ + /* printf(3) should ignore zero padding for nan/inf */ + ATF_CHECK(sprintf(str, "%010f", NAN) == 10); + ATF_REQUIRE_STREQ(str, " nan"); + ATF_CHECK(sprintf(str, "%010f", INFINITY) == 10); + ATF_REQUIRE_STREQ(str, " inf"); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, snprintf_c99); + ATF_TP_ADD_TC(tp, snprintf_dotzero); + ATF_TP_ADD_TC(tp, snprintf_posarg); + ATF_TP_ADD_TC(tp, snprintf_posarg_width); + ATF_TP_ADD_TC(tp, snprintf_posarg_error); + ATF_TP_ADD_TC(tp, snprintf_float); + ATF_TP_ADD_TC(tp, sprintf_zeropad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c new file mode 100644 index 0000000..194cd17 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c @@ -0,0 +1,85 @@ +/* $NetBSD: t_scanf.c,v 1.3 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <math.h> +#include <stdio.h> +#include <string.h> + +#define NUM -0x1234 +#define STRNUM ___STRING(NUM) + +ATF_TC(sscanf_neghex); +ATF_TC_HEAD(sscanf_neghex, tc) +{ + atf_tc_set_md_var(tc, "descr", + "PR lib/21691: %%i and %%x fail with negative hex numbers"); +} + +ATF_TC_BODY(sscanf_neghex, tc) +{ + int i; + + sscanf(STRNUM, "%i", &i); + ATF_REQUIRE(i == NUM); + + sscanf(STRNUM, "%x", &i); + ATF_REQUIRE(i == NUM); +} + +ATF_TC(sscanf_whitespace); +ATF_TC_HEAD(sscanf_whitespace, tc) +{ + + atf_tc_set_md_var(tc, "descr", "verify sscanf skips all whitespace"); +} + +ATF_TC_BODY(sscanf_whitespace, tc) +{ + const char str[] = "\f\n\r\t\v%z"; + char c; + +#ifndef __NetBSD__ + atf_tc_expect_fail("fails on FreeBSD and some variants of Linux"); +#endif + + /* set of "white space" symbols from isspace(3) */ + c = 0; + (void)sscanf(str, "%%%c", &c); + ATF_REQUIRE(c == 'z'); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sscanf_neghex); + ATF_TP_ADD_TC(tp, sscanf_whitespace); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c new file mode 100644 index 0000000..c0641db --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c @@ -0,0 +1,212 @@ +/* $NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +extern int __cxa_atexit(void (*func)(void *), void *, void *); +extern void __cxa_finalize(void *); + +#ifdef __FreeBSD__ +/* + * On shared object unload, in __cxa_finalize, call and clear all installed + * atexit and __cxa_atexit handlers that are either installed by unloaded + * dso, or points to the functions provided by the dso. + * + * The reason of the change is to ensure that there is no lingering pointers + * to the unloaded code after the dlclose(3). It is known reason for infinite + * stream of the crash reports for many programs which use loadable modules + * and fail to properly clean on module unload. Examples are apache, php, + * perl etc. + * + * You pass the &dso_handle_1 and &dso_handle_2, which points inside the + * main binary, to the registration function. The code from r211706, + * correctly detects that they are for the main binary, and on the first + * call to __cxa_finalize(), which also pass pointer to main binary, all + * registered functions from the main binary are executed. + */ + +static void *dso_handle_1 = (void *)1; +static void *dso_handle_2 = (void *)2; +static void *dso_handle_3 = (void *)3; +#else +static int dso_handle_1; +static int dso_handle_2; +static int dso_handle_3; +#endif + +static int arg_1; +static int arg_2; +static int arg_3; + +static int exiting_state; + +#define ASSERT(expr) \ +do { \ + if ((expr) == 0) { \ + write(STDERR_FILENO, __func__, strlen(__func__)); \ + write(STDERR_FILENO, ": ", 2); \ + write(STDERR_FILENO, __STRING(expr), \ + strlen(__STRING(expr))); \ + write(STDERR_FILENO, "\n", 1); \ + my_abort(); \ + } \ +} while (/*CONSTCOND*/0) + +#define SUCCESS() \ +do { \ + write(STDOUT_FILENO, __func__, strlen(__func__)); \ + write(STDOUT_FILENO, "\n", 1); \ +} while (/*CONSTCOND*/0) + +static void +my_abort(void) +{ + + kill(getpid(), SIGABRT); + /* NOTREACHED */ +} + +static void +cxa_handler_5(void *arg) +{ + static int cxa_handler_5_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_5_called == 0); + ASSERT(exiting_state == 5); + + exiting_state--; + cxa_handler_5_called = 1; + SUCCESS(); +} + +static void +cxa_handler_4(void *arg) +{ + static int cxa_handler_4_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_4_called == 0); + ASSERT(exiting_state == 4); + + exiting_state--; + cxa_handler_4_called = 1; + SUCCESS(); +} + +static void +cxa_handler_3(void *arg) +{ + static int cxa_handler_3_called; + + ASSERT(arg == (void *)&arg_2); + ASSERT(cxa_handler_3_called == 0); + ASSERT(exiting_state == 3); + + exiting_state--; + cxa_handler_3_called = 1; + SUCCESS(); +} + +static void +cxa_handler_2(void *arg) +{ + static int cxa_handler_2_called; + + ASSERT(arg == (void *)&arg_3); + ASSERT(cxa_handler_2_called == 0); + ASSERT(exiting_state == 2); + + exiting_state--; + cxa_handler_2_called = 1; + SUCCESS(); +} + +static void +normal_handler_1(void) +{ + static int normal_handler_1_called; + + ASSERT(normal_handler_1_called == 0); + ASSERT(exiting_state == 1); + + exiting_state--; + normal_handler_1_called = 1; + SUCCESS(); +} + +static void +normal_handler_0(void) +{ + static int normal_handler_0_called; + + ASSERT(normal_handler_0_called == 0); + ASSERT(exiting_state == 0); + + normal_handler_0_called = 1; + SUCCESS(); +} + +int +main(int argc, char *argv[]) +{ + + exiting_state = 5; + + ASSERT(0 == atexit(normal_handler_0)); + ASSERT(0 == atexit(normal_handler_1)); +#ifdef __FreeBSD__ + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3)); + + __cxa_finalize(dso_handle_1); + __cxa_finalize(dso_handle_2); +#else + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3)); + + __cxa_finalize(&dso_handle_1); + __cxa_finalize(&dso_handle_2); +#endif + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c new file mode 100644 index 0000000..ec2b9bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c @@ -0,0 +1,130 @@ +/* $NetBSD: h_getopt.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> +#ifdef __FreeBSD__ +#include <libutil.h> +#endif + +#define WS "\t\n " +#define debug 0 + +int +main(int argc, char *argv[]) +{ + size_t len, lineno = 0; + char *line, *ptr, *optstring = NULL, *result = NULL; + char buf[1024]; + char *args[100]; + char arg[100]; + int nargs = -1; + int c; + + while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) { + if (strncmp(line, "load:", 5) == 0) { + if (optstring) + free(optstring); + optstring = strtok(&line[6], WS); + if (optstring == NULL) + errx(1, "missing optstring at line %ld", + (unsigned long)lineno); + optstring = strdup(optstring); + if (debug) + fprintf(stderr, "optstring = %s\n", optstring); + } else if (strncmp(line, "args:", 5) == 0) { + for (; nargs >= 0; nargs--) { + if (args[nargs] != NULL) + free(args[nargs]); + } + args[nargs = 0] = strtok(&line[6], WS); + if (args[nargs] == NULL) + errx(1, "missing args at line %ld", + (unsigned long)lineno); + + args[nargs] = strdup(args[nargs]); + while ((args[++nargs] = strtok(NULL, WS)) != NULL) + args[nargs] = strdup(args[nargs]); + if (debug) { + int i = 0; + for (i = 0; i < nargs; i++) + fprintf(stderr, "argv[%d] = %s\n", i, + args[i]); + } + } else if (strncmp(line, "result:", 7) == 0) { + buf[0] = '\0'; + optind = optreset = 1; + if (result) + free(result); + result = strtok(&line[8], WS); + if (result == NULL) + errx(1, "missing result at line %ld", + (unsigned long)lineno); + result = strdup(result); + if (nargs == -1) + errx(1, "result: without args:"); + if (debug) + fprintf(stderr, "result = %s\n", result); + while ((c = getopt(nargs, args, optstring)) != -1) { + if (c == ':') + err(1, "`:' found as argument char"); + if ((ptr = strchr(optstring, c)) == NULL) { + snprintf(arg, sizeof(arg), "!%c,", c); + strcat(buf, arg); + continue; + } + if (ptr[1] != ':') + snprintf(arg, sizeof(arg), "%c,", c); + else + snprintf(arg, sizeof(arg), "%c=%s,", + c, optarg); + strcat(buf, arg); + } + len = strlen(buf); + if (len > 0) { + buf[len - 1] = '|'; + buf[len] = '\0'; + } else { + buf[0] = '|'; + buf[1] = '\0'; + } + snprintf(arg, sizeof(arg), "%d", nargs - optind); + strcat(buf, arg); + if (strcmp(buf, result) != 0) + errx(1, "`%s' != `%s'", buf, result); + } + free(line); + } + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c new file mode 100644 index 0000000..2293e2c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c @@ -0,0 +1,242 @@ +/* $NetBSD: h_getopt_long.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <ctype.h> +#include <err.h> +#include <getopt.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef __FreeBSD__ +#include <libutil.h> +#endif + +#define SKIPWS(p) while (isspace((int)(*p))) p++ +#define WS "\t\n " + +int +main(int argc, char *argv[]) +{ + size_t len, lineno = 0; + char *line, *eptr, *longopt, *ptr, *optstring = NULL, *result = NULL; + char buf[1024]; + char *args[128]; + char arg[256]; + int nargs = -1; + int c; + int nlongopts = 0; + int maxnlongopts = 0; + int *longopt_flags = NULL; + struct option *longopts = NULL; + + while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) { + if (strncmp(line, "optstring:", 10) == 0) { + if (optstring) + free(optstring); + optstring = strtok(&line[11], WS); + if (optstring == NULL) + errx(1, "missing optstring at line %ld", + (unsigned long)lineno); + optstring = strdup(optstring); + } else if (strncmp(line, "longopts:", 9) == 0) { + if (longopts) { + int i; + for (i = 0; i < nlongopts; i++) + if (longopts[i].name != NULL) + free(__UNCONST(longopts[i].name)); + free(longopts); + } + if (longopt_flags) + free(longopt_flags); + nlongopts = 0; + ptr = strtok(&line[10], WS); + if (ptr == NULL) + errx(1, "missing longopts at line %ld", + (unsigned long)lineno); + maxnlongopts = strtoul(ptr, &eptr, 10); + if (*eptr != '\0') + warnx("garbage in longopts at line %ld", + (unsigned long)lineno); + maxnlongopts++; /* space for trailer */ + longopts = + (struct option *)calloc(sizeof(struct option), + maxnlongopts); + if (longopts == NULL) + err(1, "calloc"); + longopt_flags = (int *)calloc(sizeof(int), maxnlongopts); + if (longopt_flags == NULL) + err(1, "calloc"); + } else if (strncmp(line, "longopt:", 8) == 0) { + if (longopts == NULL) + errx(1, "longopt: without longopts at line %ld", + (unsigned long)lineno); + if (nlongopts >= maxnlongopts) + errx(1, "longopt: too many options at line %ld", + (unsigned long)lineno); + /* name */ + ptr = &line[9]; + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (longopt == NULL) + errx(1, "missing longopt at line %ld", + (unsigned long)lineno); + longopts[nlongopts].name = strdup(longopt); + /* has_arg */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt != '\0') { + if (strncmp(longopt, "0", 1) == 0 || + strncmp(longopt, "no_argument", 2) == 0) + longopts[nlongopts].has_arg = no_argument; + else if (strncmp(longopt, "1", 1) == 0 || + strncmp(longopt, "required_argument", 8) == 0) + longopts[nlongopts].has_arg = required_argument; + else if (strncmp(longopt, "2", 1) == 0 || + strncmp(longopt, "optional_argument", 8) == 0) + longopts[nlongopts].has_arg = optional_argument; + else + errx(1, "unknown has_arg %s at line %ld", + longopt, (unsigned long)lineno); + } + /* flag */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt != '\0' && + strncmp(longopt, "NULL", 4) != 0) + longopts[nlongopts].flag = &longopt_flags[nlongopts]; + /* val */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt == '\0') + errx(1, "missing val at line %ld", + (unsigned long)lineno); + if (*longopt != '\'') { + longopts[nlongopts].val = + (int)strtoul(longopt, &eptr, 10); + if (*eptr != '\0') + errx(1, "invalid val at line %ld", + (unsigned long)lineno); + } else + longopts[nlongopts].val = (int)longopt[1]; + nlongopts++; + } else if (strncmp(line, "args:", 5) == 0) { + for (; nargs >= 0; nargs--) { + if (args[nargs] != NULL) + free(args[nargs]); + } + args[nargs = 0] = strtok(&line[6], WS); + if (args[nargs] == NULL) + errx(1, "Missing args"); + + args[nargs] = strdup(args[nargs]); + while ((args[++nargs] = strtok(NULL, WS)) != NULL) + args[nargs] = strdup(args[nargs]); + } else if (strncmp(line, "result:", 7) == 0) { + int li; + buf[0] = '\0'; + optind = optreset = 1; + if (result) + free(result); + result = strtok(&line[8], WS); + if (result == NULL) + errx(1, "missing result at line %ld", + (unsigned long)lineno); + if (optstring == NULL) + errx(1, "result: without optstring"); + if (longopts == NULL || nlongopts == 0) + errx(1, "result: without longopts"); + result = strdup(result); + if (nargs == -1) + errx(1, "result: without args"); + li = -2; + while ((c = getopt_long(nargs, args, optstring, + longopts, &li)) != -1) { + if (c == ':') + errx(1, "`:' found as argument char"); + if (li == -2) { + ptr = strchr(optstring, c); + if (ptr == NULL) { + snprintf(arg, sizeof(arg), + "!%c,", c); + strcat(buf, arg); + continue; + } + if (ptr[1] != ':') + snprintf(arg, sizeof(arg), + "%c,", c); + else + snprintf(arg, sizeof(arg), + "%c=%s,", c, optarg); + } else { + switch (longopts[li].has_arg) { + case no_argument: + snprintf(arg, sizeof(arg), "-%s,", + longopts[li].name); + break; + case required_argument: + snprintf(arg, sizeof(arg), + "-%s=%s,", + longopts[li].name, optarg); + break; + case optional_argument: + snprintf(arg, sizeof(arg), + "-%s%s%s,", + longopts[li].name, + (optarg)? "=" : "", + (optarg)? optarg : ""); + break; + default: + errx(1, "internal error"); + } + } + strcat(buf, arg); + li = -2; + } + len = strlen(buf); + if (len > 0) { + buf[len - 1] = '|'; + buf[len] = '\0'; + } else { + buf[0] = '|'; + buf[1] = '\0'; + } + snprintf(arg, sizeof(arg), "%d", nargs - optind); + strcat(buf, arg); + if (strcmp(buf, result) != 0) + errx(1, "`%s' != `%s'", buf, result); + } else + errx(1, "unknown directive at line %ld", + (unsigned long)lineno); + free(line); + } + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c new file mode 100644 index 0000000..282a125 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c @@ -0,0 +1,154 @@ +/* $NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $"); + +#include <atf-c.h> +#include <inttypes.h> +#include <limits.h> +#include <stdlib.h> + +ATF_TC(abs_basic); +ATF_TC_HEAD(abs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that abs(3) works"); +} + +ATF_TC_BODY(abs_basic, tc) +{ + static const struct { + int val; + int res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -0x1010, 0x1010 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(abs(table[i].val) == table[i].res); +} + +ATF_TC(imaxabs_basic); +ATF_TC_HEAD(imaxabs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that imaxabs(3) works"); +} + +ATF_TC_BODY(imaxabs_basic, tc) +{ + static const struct { + intmax_t val; + intmax_t res; + } table[] = { + { 0, 0 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { LLONG_MAX, LLONG_MAX }, + { -LLONG_MAX, LLONG_MAX }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(imaxabs(table[i].val) == table[i].res); +} + +ATF_TC(labs_basic); +ATF_TC_HEAD(labs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that labs(3) works"); +} + +ATF_TC_BODY(labs_basic, tc) +{ + static const struct { + long val; + long res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -1, 1 }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(labs(table[i].val) == table[i].res); +} + +ATF_TC(llabs_basic); +ATF_TC_HEAD(llabs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that llabs(3) works"); +} + +ATF_TC_BODY(llabs_basic, tc) +{ + static const struct { + long long val; + long long res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -1, 1 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { LLONG_MAX, LLONG_MAX }, + { -LLONG_MAX, LLONG_MAX }, + { -0x100000000LL, 0x100000000LL }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(llabs(table[i].val) == table[i].res); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, abs_basic); + ATF_TP_ADD_TC(tp, imaxabs_basic); + ATF_TP_ADD_TC(tp, labs_basic); + ATF_TP_ADD_TC(tp, llabs_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh new file mode 100755 index 0000000..d11268b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh @@ -0,0 +1,54 @@ +# $NetBSD: t_atexit.sh,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +atf_test_case atexit +atexit_head() +{ + atf_set "descr" "Checks atexit(3) and __cxa_atexit()/__cxa_finalize()" +} +atexit_body() +{ + $(atf_get_srcdir)/h_atexit >out \ + || atf_fail "h_exit failed, see output of the test for details" + + cat >exp <<EOF +cxa_handler_5 +cxa_handler_4 +cxa_handler_3 +cxa_handler_2 +normal_handler_1 +normal_handler_0 +EOF + + diff -Nru exp out \ + || atf_fail "h_exit failed, see output of the test for details" +} + +atf_init_test_cases() +{ + atf_add_test_case atexit +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c b/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c new file mode 100644 index 0000000..3e0c35f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c @@ -0,0 +1,121 @@ +/* $NetBSD: t_atoi.c,v 1.2 2012/03/29 05:56:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_atoi.c,v 1.2 2012/03/29 05:56:36 jruoho Exp $"); + +#include <atf-c.h> +#include <float.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(atof_strtod); +ATF_TC_HEAD(atof_strtod, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atof(3) matches the corresponding strtod(3) call"); +} + +ATF_TC_BODY(atof_strtod, tc) +{ + char buf[128]; + + (void)snprintf(buf, sizeof(buf), "%f\n", DBL_MAX); + + ATF_REQUIRE(atof("0") == strtod("0", NULL)); + ATF_REQUIRE(atof("-1") == strtod("-1", NULL)); + ATF_REQUIRE(atof(buf) == strtod(buf, NULL)); +} + +ATF_TC(atoi_strtol); +ATF_TC_HEAD(atoi_strtol, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atoi(3) matches the corresponding strtol(3) call"); +} + +ATF_TC_BODY(atoi_strtol, tc) +{ + char buf[64]; + + (void)snprintf(buf, sizeof(buf), "%d\n", INT_MAX); + + ATF_REQUIRE(atoi("0") == strtol("0", NULL, 10)); + ATF_REQUIRE(atoi("-1") == strtol("-1", NULL, 10)); + ATF_REQUIRE(atoi(buf) == strtol(buf, NULL, 10)); +} + +ATF_TC(atol_strtol); +ATF_TC_HEAD(atol_strtol, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atol(3) matches the corresponding strtol(3) call"); +} + +ATF_TC_BODY(atol_strtol, tc) +{ + char buf[64]; + + (void)snprintf(buf, sizeof(buf), "%ld\n", LONG_MAX); + + ATF_REQUIRE(atol("0") == strtol("0", NULL, 10)); + ATF_REQUIRE(atol("-1") == strtol("-1", NULL, 10)); + ATF_REQUIRE(atol(buf) == strtol(buf, NULL, 10)); +} + +ATF_TC(atoll_strtoll); +ATF_TC_HEAD(atoll_strtoll, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atoll(3) matches the corresponding strtoll(3) call"); +} + +ATF_TC_BODY(atoll_strtoll, tc) +{ + char buf[128]; + + (void)snprintf(buf, sizeof(buf), "%lld\n", LLONG_MAX); + + ATF_REQUIRE(atoll("0") == strtoll("0", NULL, 10)); + ATF_REQUIRE(atoll("-1") == strtoll("-1", NULL, 10)); + ATF_REQUIRE(atoll(buf) == strtoll(buf, NULL, 10)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, atof_strtod); + ATF_TP_ADD_TC(tp, atoi_strtol); + ATF_TP_ADD_TC(tp, atol_strtol); + ATF_TP_ADD_TC(tp, atoll_strtoll); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_div.c b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c new file mode 100644 index 0000000..376f357 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_div.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> + +#define NUM 1999236 +#define DENOM 1000000 +#define QUOT 1 +#define REM 999236 + +ATF_TC(div_basic); +ATF_TC_HEAD(div_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test div(3) for correctness"); +} + +ATF_TC_BODY(div_basic, tc) +{ + div_t d; + + d = div(NUM, DENOM); + + ATF_CHECK(d.quot == QUOT); + ATF_CHECK(d.rem == REM); +} + +ATF_TC(ldiv_basic); +ATF_TC_HEAD(ldiv_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test ldiv(3) for correctness"); +} + +ATF_TC_BODY(ldiv_basic, tc) +{ + ldiv_t ld; + + ld = ldiv(NUM, DENOM); + + ATF_CHECK(ld.quot == QUOT); + ATF_CHECK(ld.rem == REM); +} + +ATF_TC(lldiv_basic); +ATF_TC_HEAD(lldiv_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test lllldiv(3) for correctness"); +} + +ATF_TC_BODY(lldiv_basic, tc) +{ + lldiv_t lld; + + lld = lldiv(NUM, DENOM); + + ATF_CHECK(lld.quot == QUOT); + ATF_CHECK(lld.rem == REM); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, div_basic); + ATF_TP_ADD_TC(tp, ldiv_basic); + ATF_TP_ADD_TC(tp, lldiv_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c new file mode 100644 index 0000000..067cb51 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c @@ -0,0 +1,186 @@ +/* $NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static bool fail; +static void func(void); + +static void +func(void) +{ + fail = false; +} + +ATF_TC(exit_atexit); +ATF_TC_HEAD(exit_atexit, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of atexit(3)"); +} + +ATF_TC_BODY(exit_atexit, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (atexit(func) != 0) + _exit(EXIT_FAILURE); + + fail = true; + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("atexit(3) failed"); + + if (fail != false) + atf_tc_fail("atexit(3) was not called"); +} + +ATF_TC(exit_basic); +ATF_TC_HEAD(exit_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of exit(3)"); +} + +ATF_TC_BODY(exit_basic, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("exit(3) did not exit successfully"); +} + +ATF_TC(exit_status); +ATF_TC_HEAD(exit_status, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exit(3) status"); +} + +ATF_TC_BODY(exit_status, tc) +{ + const int n = 10; + int i, sta; + pid_t pid; + + for (i = 0; i < n; i++) { + + pid = fork(); + + if (pid < 0) + exit(EXIT_FAILURE); + + if (pid == 0) + exit(i); + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != i) + atf_tc_fail("invalid exit(3) status"); + } +} + +ATF_TC(exit_tmpfile); +ATF_TC_HEAD(exit_tmpfile, tc) +{ + atf_tc_set_md_var(tc, "descr", "Temporary files are unlinked?"); +} + +ATF_TC_BODY(exit_tmpfile, tc) +{ + int sta, fd = -1; + char buf[12]; + pid_t pid; + FILE *f; + + (void)strlcpy(buf, "exit.XXXXXX", sizeof(buf)); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + fd = mkstemp(buf); + + if (fd < 0) + exit(EXIT_FAILURE); + + exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create temporary file"); + + f = fdopen(fd, "r"); + + if (f != NULL) + atf_tc_fail("exit(3) did not clear temporary file"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, exit_atexit); + ATF_TP_ADD_TC(tp, exit_basic); + ATF_TP_ADD_TC(tp, exit_status); + ATF_TP_ADD_TC(tp, exit_tmpfile); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c new file mode 100644 index 0000000..5a8fa28 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c @@ -0,0 +1,211 @@ +/* $NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef __FreeBSD__ +#include <signal.h> +#endif + +extern char **environ; + +ATF_TC(clearenv_basic); +ATF_TC_HEAD(clearenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test user clearing environment directly"); +} + +ATF_TC_BODY(clearenv_basic, tc) +{ + char name[1024], value[1024]; + + for (size_t i = 0; i < 1024; i++) { + snprintf(name, sizeof(name), "crap%zu", i); + snprintf(value, sizeof(value), "%zu", i); + ATF_CHECK(setenv(name, value, 1) != -1); + } + + *environ = NULL; + + for (size_t i = 0; i < 1; i++) { + snprintf(name, sizeof(name), "crap%zu", i); + snprintf(value, sizeof(value), "%zu", i); + ATF_CHECK(setenv(name, value, 1) != -1); + } + + ATF_CHECK_STREQ(getenv("crap0"), "0"); + ATF_CHECK(getenv("crap1") == NULL); + ATF_CHECK(getenv("crap2") == NULL); +} + +ATF_TC(getenv_basic); +ATF_TC_HEAD(getenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test setenv(3), getenv(3)"); +} + +ATF_TC_BODY(getenv_basic, tc) +{ + ATF_CHECK(setenv("EVIL", "very=bad", 1) != -1); + ATF_CHECK_STREQ(getenv("EVIL"), "very=bad"); + ATF_CHECK(getenv("EVIL=very") == NULL); + ATF_CHECK(unsetenv("EVIL") != -1); +} + +ATF_TC(putenv_basic); +ATF_TC_HEAD(putenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test putenv(3), getenv(3), unsetenv(3)"); +} + + +ATF_TC_BODY(putenv_basic, tc) +{ + char string[1024]; + + snprintf(string, sizeof(string), "crap=true"); + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("crap"), "true"); + string[1] = 'l'; + ATF_CHECK_STREQ(getenv("clap"), "true"); + ATF_CHECK(getenv("crap") == NULL); + string[1] = 'r'; + ATF_CHECK(unsetenv("crap") != -1); + ATF_CHECK(getenv("crap") == NULL); + + ATF_CHECK_ERRNO(EINVAL, putenv(NULL) == -1); + ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("val")) == -1); + ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("=val")) == -1); +} + +ATF_TC(setenv_basic); +ATF_TC_HEAD(setenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test setenv(3), getenv(3), unsetenv(3)"); + atf_tc_set_md_var(tc, "timeout", "300"); +} + +ATF_TC_BODY(setenv_basic, tc) +{ + const size_t numvars = 8192; + size_t i, offset; + char name[1024]; + char value[1024]; + + offset = lrand48(); + for (i = 0; i < numvars; i++) { + (void)snprintf(name, sizeof(name), "var%zu", + (i * 7 + offset) % numvars); + (void)snprintf(value, sizeof(value), "value%ld", lrand48()); + ATF_CHECK(setenv(name, value, 1) != -1); + ATF_CHECK(setenv(name, "foo", 0) != -1); + ATF_CHECK_STREQ(getenv(name), value); + } + + offset = lrand48(); + for (i = 0; i < numvars; i++) { + (void)snprintf(name, sizeof(name), "var%zu", + (i * 11 + offset) % numvars); + ATF_CHECK(unsetenv(name) != -1); + ATF_CHECK(getenv(name) == NULL); + ATF_CHECK(unsetenv(name) != -1); + } + + ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1); +#ifdef __FreeBSD__ + /* + Both FreeBSD and OS/X does not validate the second + argument to setenv(3) + */ + atf_tc_expect_signal(SIGSEGV, "FreeBSD does not validate the second " + "argument to setenv(3); see bin/189805"); +#endif + + ATF_CHECK_ERRNO(EINVAL, setenv("var", NULL, 1) == -1); + + ATF_CHECK(setenv("var", "=val", 1) == 0); + ATF_CHECK_STREQ(getenv("var"), "=val"); +} + +ATF_TC(setenv_mixed); +ATF_TC_HEAD(setenv_mixed, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mixing setenv(3), unsetenv(3) and putenv(3)"); +} + +ATF_TC_BODY(setenv_mixed, tc) +{ + char string[32]; + + (void)strcpy(string, "mixedcrap=putenv"); + + ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); + ATF_CHECK(unsetenv("mixedcrap") != -1); + ATF_CHECK(getenv("mixedcrap") == NULL); + + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); + ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); + ATF_CHECK(unsetenv("mixedcrap") != -1); + ATF_CHECK(getenv("mixedcrap") == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clearenv_basic); + ATF_TP_ADD_TC(tp, getenv_basic); + ATF_TP_ADD_TC(tp, putenv_basic); + ATF_TP_ADD_TC(tp, setenv_basic); + ATF_TP_ADD_TC(tp, setenv_mixed); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c new file mode 100644 index 0000000..d935629 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c @@ -0,0 +1,250 @@ +/* $NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define THREADED_NUM_THREADS 8 +#define THREADED_NUM_VARS 16 +#define THREADED_VAR_NAME "THREADED%zu" +#define THREADED_RUN_TIME 10 + +static void *thread_getenv_r(void *); +static void *thread_putenv(void *); +static void *thread_setenv(void *); +static void *thread_unsetenv(void *); + +static void * +thread_getenv_r(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32], value[128]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + + if (getenv_r(name, value, sizeof(value)) == -1) { + ATF_CHECK(errno == ENOENT); + } + } while (time(NULL) < endtime); + + return NULL; +} + + +static void * +thread_putenv(void *arg) +{ + time_t endtime; + size_t i; + static char vars[THREADED_NUM_VARS][128]; + + for (i = 0; i < THREADED_NUM_VARS; i++) { + (void)snprintf(vars[i], sizeof(vars[i]), + THREADED_VAR_NAME "=putenv %ld", i, lrand48()); + } + + endtime = *(time_t *)arg; + do { + char name[128]; + + i = lrand48() % THREADED_NUM_VARS; + (void)strlcpy(name, vars[i], sizeof(name)); + *strchr(name, '=') = '\0'; + + ATF_CHECK(unsetenv(name) != -1); + ATF_CHECK(putenv(vars[i]) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +static void * +thread_setenv(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32], value[64]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + (void)snprintf(value, sizeof(value), "setenv %ld", lrand48()); + + ATF_CHECK(setenv(name, value, 1) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +static void * +thread_unsetenv(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + + ATF_CHECK(unsetenv(name) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +ATF_TC(getenv_r_thread); +ATF_TC_HEAD(getenv_r_thread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test getenv_r(3) with threads"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(getenv_r_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_getenv_r, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(putenv_thread); +ATF_TC_HEAD(putenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test concurrent access by putenv(3)"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(putenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_putenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(setenv_thread); +ATF_TC_HEAD(setenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test concurrent access by setenv(3)"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(setenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_setenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(unsetenv_thread); +ATF_TC_HEAD(unsetenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unsetenv(3) with threads"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(unsetenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_unsetenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getenv_r_thread); + ATF_TP_ADD_TC(tp, putenv_thread); + ATF_TP_ADD_TC(tp, setenv_thread); + ATF_TP_ADD_TC(tp, unsetenv_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh new file mode 100755 index 0000000..cc10f65 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh @@ -0,0 +1,123 @@ +# $NetBSD: t_getopt.sh,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +h_getopt() +{ + atf_check -e save:stderr -x "$(atf_get_srcdir)/h_getopt" <<EOF +load: $1 +args: $2 +result: $3 +EOF + cat stderr + rm -f stderr +} + +h_getopt_long() +{ + atf_check -e save:stderr -x "$(atf_get_srcdir)/h_getopt_long" <<EOF +$1 +args: $2 +result: $3 +EOF + cat stderr + rm -f stderr +} + +atf_test_case getopt +getopt_head() +{ + atf_set "descr" "Checks getopt(3)" +} +getopt_body() +{ + load="c:d" + + h_getopt "${load}" "foo -c 1 -d foo" "c=1,d|1" + h_getopt "${load}" "foo -d foo bar" "d|2" + h_getopt "${load}" "foo -c 2 foo bar" "c=2|2" + h_getopt "${load}" "foo -e 1 foo bar" "!?|3" + h_getopt "${load}" "foo -d -- -c 1" "d|2" + h_getopt "${load}" "foo -c- 1" "c=-|1" + h_getopt "${load}" "foo -d - 1" "d|2" +} + +atf_test_case getopt_long +getopt_long_head() +{ + atf_set "descr" "Checks getopt_long(3)" +} +getopt_long_body() +{ + # GNU libc tests with these + load="optstring: abc: +longopts: 5 +longopt: required, required_argument, , 'r' +longopt: optional, optional_argument, , 'o' +longopt: none, no_argument, , 'n' +longopt: color, no_argument, , 'C' +longopt: colour, no_argument, , 'C'" + + h_getopt_long "${load}" "foo --req foobar" "-required=foobar|0" + h_getopt_long "${load}" "foo --opt=bazbug" "-optional=bazbug|0" + + # This is problematic + # + # GNU libc 2.1.3 this fails with ambiguous result + # h_getopt_long "${load}" "foo --col" "!?|0" + # + # GNU libc 2.2 >= this works + h_getopt_long "${load}" "foo --col" "-color|0" + + h_getopt_long "${load}" "foo --colour" "-colour|0" + + # This is the real GNU libc test! + args="foo -a -b -cfoobar --required foobar --optional=bazbug --none random --col --color --colour" + # GNU libc 2.1.3 this fails with ambiguous + #result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,!?,-color,-colour|1" + # + # GNU libc 2.2 >= this works + result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,-color,-color,-colour|1" + h_getopt_long "${load}" "${args}" "${result}" + + # + # The order of long options in the long option array should not matter. + # An exact match should never be treated as ambiguous. + # + load="optstring: fgl +longopts: 3 +longopt: list-foobar, no_argument, lopt, 'f' +longopt: list-goobar, no_argument, lopt, 'g' +longopt: list, no_argument, lopt, 'l'" + h_getopt_long "${load}" "foo --list" "-list|0" +} + + +atf_init_test_cases() +{ + atf_add_test_case getopt + atf_add_test_case getopt_long +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c new file mode 100644 index 0000000..a0e77d3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c @@ -0,0 +1,411 @@ +/* $NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2001 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $"); + +#include <errno.h> +#include <search.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +#ifdef __NetBSD__ +ATF_TC(hsearch_basic); +ATF_TC_HEAD(hsearch_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); +} + +ATF_TC_BODY(hsearch_basic, tc) +{ + ENTRY e, *ep; + char ch[2]; + int i; + + REQUIRE_ERRNO(hcreate(16) != 0); + + /* ch[1] should be constant from here on down. */ + ch[1] = '\0'; + + /* Basic insertions. Check enough that there'll be collisions. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + e.key = strdup(ch); /* ptr to provided key is kept! */ + ATF_REQUIRE(e.key != NULL); + e.data = (void *)(intptr_t)i; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + /* e.key should be constant from here on down. */ + e.key = ch; + + /* Basic lookups. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + + ep = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + hdestroy1(free, NULL); +} +#endif + +ATF_TC(hsearch_duplicate); +ATF_TC_HEAD(hsearch_duplicate, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " + "doesn't overwrite existing data"); +} + +ATF_TC_BODY(hsearch_duplicate, tc) +{ + ENTRY e, *ep; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("a"); + e.data = (void *)(intptr_t) 0; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.data = (void *)(intptr_t)12345; + + ep = hsearch(e, ENTER); + ep = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + hdestroy(); +} + +ATF_TC(hsearch_nonexistent); +ATF_TC_HEAD(hsearch_nonexistent, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks searching for non-existent entry"); +} + +ATF_TC_BODY(hsearch_nonexistent, tc) +{ + ENTRY e, *ep; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("A"); + ep = hsearch(e, FIND); + ATF_REQUIRE_EQ(ep, NULL); + + hdestroy(); +} + +ATF_TC(hsearch_two); +ATF_TC_HEAD(hsearch_two, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that searching doesn't overwrite previous search results"); +} + +ATF_TC_BODY(hsearch_two, tc) +{ + ENTRY e, *ep, *ep2; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("a"); + e.data = (void*)(intptr_t)0; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.key = __UNCONST("b"); + e.data = (void*)(intptr_t)1; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 1); + + e.key = __UNCONST("a"); + ep = hsearch(e, FIND); + + e.key = __UNCONST("b"); + ep2 = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + ATF_REQUIRE(ep2 != NULL); + ATF_REQUIRE_STREQ(ep2->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); + + hdestroy(); +} + +#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version +#ifdef __NetBSD__ +ATF_TC(hsearch_r_basic); +ATF_TC_HEAD(hsearch_r_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); +} + +ATF_TC_BODY(hsearch_r_basic, tc) +{ + ENTRY e, *ep; + char ch[2]; + int i; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t) != 0); + + /* ch[1] should be constant from here on down. */ + ch[1] = '\0'; + + /* Basic insertions. Check enough that there'll be collisions. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + e.key = strdup(ch); /* ptr to provided key is kept! */ + ATF_REQUIRE(e.key != NULL); + e.data = (void *)(intptr_t)i; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + /* e.key should be constant from here on down. */ + e.key = ch; + + /* Basic lookups. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + hdestroy1_r(&t, free, NULL); +} +#endif + +ATF_TC(hsearch_r_duplicate); +ATF_TC_HEAD(hsearch_r_duplicate, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " + "doesn't overwrite existing data"); +} + +ATF_TC_BODY(hsearch_r_duplicate, tc) +{ + ENTRY e, *ep; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("a"); + e.data = (void *)(intptr_t) 0; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.data = (void *)(intptr_t)12345; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + hdestroy_r(&t); +} + +ATF_TC(hsearch_r_nonexistent); +ATF_TC_HEAD(hsearch_r_nonexistent, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks searching for non-existent entry"); +} + +ATF_TC_BODY(hsearch_r_nonexistent, tc) +{ + ENTRY e, *ep; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("A"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + ATF_REQUIRE_EQ(ep, NULL); + + hdestroy_r(&t); +} + +ATF_TC(hsearch_r_two); +ATF_TC_HEAD(hsearch_r_two, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that searching doesn't overwrite previous search results"); +} + +ATF_TC_BODY(hsearch_r_two, tc) +{ + ENTRY e, *ep, *ep2; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("a"); + e.data = (void*)(intptr_t)0; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.key = __UNCONST("b"); + e.data = (void*)(intptr_t)1; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 1); + + e.key = __UNCONST("a"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + + e.key = __UNCONST("b"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep2, &t) == 1); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + ATF_REQUIRE(ep2 != NULL); + ATF_REQUIRE_STREQ(ep2->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); + + hdestroy_r(&t); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, hsearch_basic); +#endif + ATF_TP_ADD_TC(tp, hsearch_duplicate); + ATF_TP_ADD_TC(tp, hsearch_nonexistent); + ATF_TP_ADD_TC(tp, hsearch_two); + +#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, hsearch_r_basic); +#endif + ATF_TP_ADD_TC(tp, hsearch_r_duplicate); + ATF_TP_ADD_TC(tp, hsearch_r_nonexistent); + ATF_TP_ADD_TC(tp, hsearch_r_two); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c new file mode 100644 index 0000000..77d6443 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $ */ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $"); + +#include <atf-c.h> +#include <stdlib.h> +#include <string.h> + +ATF_TC(mi_vector_hash_basic); +ATF_TC_HEAD(mi_vector_hash_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mi_vector_hash_vector_hash for consistent results"); +} + +static const struct testvector { + const char *vector; + uint32_t hashes[3]; +} testv[] = { + { "hello, world", { 0xd38f7f21, 0xbf6be9ab, 0x37a0e989 } }, + { "", { 0x9b2ec03d, 0xdb2b69ae, 0xbd49d10d } }, + { "a", { 0x9454baa3, 0xb711c708, 0x29eec818 } }, + { "ab", { 0x9a5dca90, 0xdd212644, 0x9879ac41 } }, + { "abc", { 0x0b91c470, 0x4770cdf5, 0x251e4793 } }, + { "abcd", { 0x5f128df3, 0xf5a667a6, 0x5ae61fa5 } }, + { "abcde", { 0x4cbae281, 0x799c0ed5, 0x03a96866 } }, + { "abcdef", { 0x507a54c8, 0xb6bd06f4, 0xde922732 } }, + { "abcdefg", { 0xae2bca5d, 0x61e960ef, 0xb9e6762c } }, + { "abcdefgh", { 0xd1021264, 0x87f6988f, 0x053f775e } }, + { "abcdefghi", { 0xe380defc, 0xfc35a811, 0x3a7b0a5f } }, + { "abcdefghij", { 0x9a504408, 0x70d2e89d, 0xc9cac242 } }, + { "abcdefghijk", { 0x376117d0, 0x89f434d4, 0xe52b8e4c } }, + { "abcdefghijkl", { 0x92253599, 0x7b6ff99e, 0x0b1b3ea5 } }, + { "abcdefghijklm", { 0x92ee6a52, 0x55587d47, 0x3122b031 } }, + { "abcdefghijklmn", { 0x827baf08, 0x1d0ada73, 0xfec330e0 } }, + { "abcdefghijklmno", { 0x06ab787d, 0xc1ad17c2, 0x11dccf31 } }, + { "abcdefghijklmnop", { 0x2cf18103, 0x638c9268, 0xfa1ecf51 } }, +}; + +ATF_TC_BODY(mi_vector_hash_basic, tc) +{ + size_t i, j, len; + uint32_t hashes[3]; + char buf[256]; + + for (j = 0; j < 8; ++j) { + for (i = 0; i < sizeof(testv) / sizeof(testv[0]); ++i) { + len = strlen(testv[i].vector); + strcpy(buf + j, testv[i].vector); + mi_vector_hash(buf + j, len, 0, hashes); + ATF_CHECK_EQ(hashes[0], testv[i].hashes[0]); + ATF_CHECK_EQ(hashes[1], testv[i].hashes[1]); + ATF_CHECK_EQ(hashes[2], testv[i].hashes[2]); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mi_vector_hash_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c new file mode 100644 index 0000000..47afb84 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c @@ -0,0 +1,88 @@ +/* $NetBSD: t_posix_memalign.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_posix_memalign.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $"); + +#include <atf-c.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +ATF_TC(posix_memalign_basic); +ATF_TC_HEAD(posix_memalign_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_memalign(3)"); +} +ATF_TC_BODY(posix_memalign_basic, tc) +{ + size_t size[] = { + 1, 2, 3, 4, 10, 100, 16384, 32768, 65536 + }; + size_t align[] = { + 512, 1024, 16, 32, 64, 4, 2048, 16, 2 + }; + + size_t i; + void *p; + + for (i = 0; i < __arraycount(size); i++) { + int ret; + p = (void*)0x1; + + (void)printf("Checking posix_memalign(&p, %zd, %zd)...\n", + align[i], size[i]); + ret = posix_memalign(&p, align[i], size[i]); + + if ( align[i] < sizeof(void *)) + ATF_REQUIRE_EQ_MSG(ret, EINVAL, + "posix_memalign: %s", strerror(ret)); + else { + ATF_REQUIRE_EQ_MSG(ret, 0, + "posix_memalign: %s", strerror(ret)); + ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0, + "p = %p", p); + free(p); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, posix_memalign_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_random.c b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c new file mode 100644 index 0000000..9a6d21e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c @@ -0,0 +1,82 @@ +/* $NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> + +/* + * TODO: Add some general RNG tests (cf. the famous "diehard" tests?). + */ + +ATF_TC(random_same); +ATF_TC_HEAD(random_same, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that random(3) does not always return the same " + "value when the seed is initialized to zero"); +} + +#define MAX_ITER 10 + +ATF_TC_BODY(random_same, tc) +{ + long buf[MAX_ITER]; + size_t i, j; + + /* + * See CVE-2012-1577. + */ + srandom(0); + + for (i = 0; i < __arraycount(buf); i++) { + + buf[i] = random(); + + for (j = 0; j < i; j++) { + + (void)fprintf(stderr, "i = %zu, j = %zu: " + "%ld vs. %ld\n", i, j, buf[i], buf[j]); + + ATF_CHECK(buf[i] != buf[j]); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, random_same); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c new file mode 100644 index 0000000..8f0f899 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c @@ -0,0 +1,342 @@ +/* $NetBSD: t_strtod.c,v 1.32 2014/11/04 00:20:19 justin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Public domain, Otto Moerbeek <otto@drijf.net>, 2006. */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strtod.c,v 1.32 2014/11/04 00:20:19 justin Exp $"); + +#include <errno.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <atf-c.h> + +#if defined(__i386__) || defined(__amd64__) || defined(__sparc__) +#include <fenv.h> +#endif + +#if !defined(__vax__) +static const char * const inf_strings[] = + { "Inf", "INF", "-Inf", "-INF", "Infinity", "+Infinity", + "INFINITY", "-INFINITY", "InFiNiTy", "+InFiNiTy" }; +const char *nan_string = "NaN(x)y"; +#endif + +#ifdef __FreeBSD__ +#define __HAVE_LONG_DOUBLE +#endif + +ATF_TC(strtod_basic); +ATF_TC_HEAD(strtod_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strtod(3)"); +} + +ATF_TC_BODY(strtod_basic, tc) +{ + static const size_t n = 1024 * 1000; + + for (size_t i = 1; i < n; i = i + 1024) { + char buf[512]; + (void)snprintf(buf, sizeof(buf), "%zu.%zu", i, i + 1); + + errno = 0; + double d = strtod(buf, NULL); + + ATF_REQUIRE(d > 0.0); + ATF_REQUIRE(errno == 0); + } +} + +ATF_TC(strtod_hex); +ATF_TC_HEAD(strtod_hex, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with hexadecimals"); +} + +#ifdef __vax__ +#define SMALL_NUM 1.0e-38 +#else +#define SMALL_NUM 1.0e-40 +#endif + +ATF_TC_BODY(strtod_hex, tc) +{ + const char *str; + char *end; + volatile double d; + + str = "-0x0"; + d = strtod(str, &end); /* -0.0 */ + + ATF_REQUIRE(end == str + 4); + ATF_REQUIRE(signbit(d) != 0); + ATF_REQUIRE(fabs(d) < SMALL_NUM); + + str = "-0x"; + d = strtod(str, &end); /* -0.0 */ + + ATF_REQUIRE(end == str + 2); + ATF_REQUIRE(signbit(d) != 0); + ATF_REQUIRE(fabs(d) < SMALL_NUM); +} + +ATF_TC(strtod_inf); +ATF_TC_HEAD(strtod_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtod_inf, tc) +{ +#ifndef __vax__ + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile double d = strtod(inf_strings[i], NULL); + ATF_REQUIRE(isinf(d) != 0); + } +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtof_inf); +ATF_TC_HEAD(strtof_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtof(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtof_inf, tc) +{ +#ifndef __vax__ + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile float f = strtof(inf_strings[i], NULL); + ATF_REQUIRE(isinf(f) != 0); + } +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtold_inf); +ATF_TC_HEAD(strtold_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtold(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtold_inf, tc) +{ +#ifndef __vax__ +# ifdef __HAVE_LONG_DOUBLE + + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile long double ld = strtold(inf_strings[i], NULL); + ATF_REQUIRE(isinf(ld) != 0); + } +# else + atf_tc_skip("Requires long double support"); +# endif +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtod_nan); +ATF_TC_HEAD(strtod_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with NaN"); +} + +ATF_TC_BODY(strtod_nan, tc) +{ +#ifndef __vax__ + char *end; + + volatile double d = strtod(nan_string, &end); + ATF_REQUIRE(isnan(d) != 0); + ATF_REQUIRE(strcmp(end, "y") == 0); +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtof_nan); +ATF_TC_HEAD(strtof_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtof(3) with NaN"); +} + +ATF_TC_BODY(strtof_nan, tc) +{ +#ifndef __vax__ + char *end; + + volatile float f = strtof(nan_string, &end); + ATF_REQUIRE(isnanf(f) != 0); + ATF_REQUIRE(strcmp(end, "y") == 0); +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtold_nan); +ATF_TC_HEAD(strtold_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtold(3) with NaN (PR lib/45020)"); +} + +ATF_TC_BODY(strtold_nan, tc) +{ +#ifndef __vax__ +# ifdef __HAVE_LONG_DOUBLE + + char *end; + + volatile long double ld = strtold(nan_string, &end); + ATF_REQUIRE(isnan(ld) != 0); +#ifdef __FreeBSD__ + ATF_REQUIRE(strcmp(end, "y") == 0); +#else + ATF_REQUIRE(__isnanl(ld) != 0); +#endif + ATF_REQUIRE(strcmp(end, "y") == 0); +# else + atf_tc_skip("Requires long double support"); +# endif +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtod_round); +ATF_TC_HEAD(strtod_round, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test rouding in strtod(3)"); +} + +ATF_TC_BODY(strtod_round, tc) +{ +#if defined(__i386__) || defined(__amd64__) || defined(__sparc__) + + /* + * Test that strtod(3) honors the current rounding mode. + * The used value is somewhere near 1 + DBL_EPSILON + FLT_EPSILON. + */ + const char *val = + "1.00000011920928977282585492503130808472633361816406"; + + (void)fesetround(FE_UPWARD); + + volatile double d1 = strtod(val, NULL); + + (void)fesetround(FE_DOWNWARD); + + volatile double d2 = strtod(val, NULL); + + if (fabs(d1 - d2) > 0.0) + return; + else { + atf_tc_expect_fail("PR misc/44767"); + atf_tc_fail("strtod(3) did not honor fesetround(3)"); + } +#else + atf_tc_skip("Requires one of i386, amd64 or sparc"); +#endif +} + +ATF_TC(strtod_underflow); +ATF_TC_HEAD(strtod_underflow, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test underflow in strtod(3)"); +} + +ATF_TC_BODY(strtod_underflow, tc) +{ + + const char *tmp = + "0.0000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000002"; + + errno = 0; + volatile double d = strtod(tmp, NULL); + + if (d != 0 || errno != ERANGE) + atf_tc_fail("strtod(3) did not detect underflow"); +} + +/* + * Bug found by Geza Herman. + * See + * http://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/ + */ +ATF_TC(strtod_gherman_bug); +ATF_TC_HEAD(strtod_gherman_bug, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test a bug found by Geza Herman"); +} + +ATF_TC_BODY(strtod_gherman_bug, tc) +{ + + const char *str = + "1.8254370818746402660437411213933955878019332885742187"; + + errno = 0; + volatile double d = strtod(str, NULL); + + ATF_CHECK(d == 0x1.d34fd8378ea83p+0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strtod_basic); + ATF_TP_ADD_TC(tp, strtod_hex); + ATF_TP_ADD_TC(tp, strtod_inf); + ATF_TP_ADD_TC(tp, strtof_inf); + ATF_TP_ADD_TC(tp, strtold_inf); + ATF_TP_ADD_TC(tp, strtod_nan); + ATF_TP_ADD_TC(tp, strtof_nan); + ATF_TP_ADD_TC(tp, strtold_nan); + ATF_TP_ADD_TC(tp, strtod_round); + ATF_TP_ADD_TC(tp, strtod_underflow); + ATF_TP_ADD_TC(tp, strtod_gherman_bug); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c new file mode 100644 index 0000000..5a0c6d0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c @@ -0,0 +1,234 @@ +/* $NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +struct test { + const char *str; + int64_t res; + int base; + const char *end; +}; + +static void check(struct test *, long int, long long int, char *); + +static void +check(struct test *t, long int li, long long int lli, char *end) +{ + + if (li != -1 && li != t->res) + atf_tc_fail_nonfatal("strtol(%s, &end, %d) failed " + "(rv = %ld)", t->str, t->base, li); + + if (lli != -1 && lli != t->res) + atf_tc_fail_nonfatal("strtoll(%s, NULL, %d) failed " + "(rv = %lld)", t->str, t->base, lli); + + if (t->end != NULL && strcmp(t->end, end) != 0) + atf_tc_fail_nonfatal("invalid end pointer ('%s') from " + "strtol(%s, &end, %d)", end, t->str, t->base); +} + +ATF_TC(strtol_base); +ATF_TC_HEAD(strtol_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strtol(3) with different bases"); +} + +ATF_TC_BODY(strtol_base, tc) +{ + struct test t[] = { + { "123456789", 123456789, 0, NULL }, + { "111010110111100110100010101", 123456789, 2, NULL }, + { "22121022020212200", 123456789, 3, NULL }, + { "13112330310111", 123456789, 4, NULL }, + { "223101104124", 123456789, 5, NULL }, + { "20130035113", 123456789, 6, NULL }, + { "3026236221", 123456789, 7, NULL }, + { "726746425", 123456789, 8, NULL }, + { "277266780", 123456789, 9, NULL }, + { "123456789", 123456789, 10, NULL }, + { "63762A05", 123456789, 11, NULL }, + { "35418A99", 123456789, 12, NULL }, + { "1C767471", 123456789, 13, NULL }, + { "12579781", 123456789, 14, NULL }, + { "AC89BC9", 123456789, 15, NULL }, + { "75BCD15", 123456789, 16, NULL }, + { "123456789", 342391, 8, NULL }, + { "0123456789", 342391, 0, NULL }, + { "0123456789", 123456789, 10, NULL }, + { "0x75bcd15", 123456789, 0, NULL }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TC(strtol_case); +ATF_TC_HEAD(strtol_case, tc) +{ + atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtol(3)"); +} + +ATF_TC_BODY(strtol_case, tc) +{ + struct test t[] = { + { "abcd", 0xabcd, 16, NULL }, + { " dcba", 0xdcba, 16, NULL }, + { "abcd dcba", 0xabcd, 16, " dcba" }, + { "abc0x123", 0xabc0, 16, NULL }, + { "abcd\0x123", 0xabcd, 16, "\0x123" }, + { "ABCD", 0xabcd, 16, NULL }, + { "aBcD", 0xabcd, 16, NULL }, + { "0xABCD", 0xabcd, 16, NULL }, + { "0xABCDX", 0xabcd, 16, "X" }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TC(strtol_range); +ATF_TC_HEAD(strtol_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtol(3)"); +} + +ATF_TC_BODY(strtol_range, tc) +{ + +#if LONG_MAX == 0x7fffffff /* XXX: Is this portable? */ + + struct test t[] = { + { "20000000000", 2147483647, 8, NULL }, + { "2147483648", 2147483647, 10, NULL }, + { "80000000", 2147483647, 16, NULL }, + }; +#else + struct test t[] = { + { "1000000000000000000000", 9223372036854775807, 8, NULL }, + { "9223372036854775808", 9223372036854775807, 10, NULL }, + { "8000000000000000", 9223372036854775807, 16, NULL }, + }; +#endif + + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + errno = 0; + li = strtol(t[i].str, &end, t[i].base); + + if (errno != ERANGE) + atf_tc_fail("strtol(3) did not catch ERANGE"); + + check(&t[i], li, -1, end); + } +} + +ATF_TC(strtol_signed); +ATF_TC_HEAD(strtol_signed, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strtol(3)"); +} + +ATF_TC_BODY(strtol_signed, tc) +{ + struct test t[] = { + { "1", 1, 0, NULL }, + { " 2", 2, 0, NULL }, + { " 3", 3, 0, NULL }, + { " -3", -3, 0, NULL }, + { "--1", 0, 0, "--1" }, + { "+-2", 0, 0, "+-2" }, + { "++3", 0, 0, "++3" }, + { "+9", 9, 0, NULL }, + { "+123", 123, 0, NULL }, + { "-1 3", -1, 0, " 3" }, + { "-1.3", -1, 0, ".3" }, + { "- 3", 0, 0, "- 3" }, + { "+33.", 33, 0, "." }, + { "30x0", 30, 0, "x0" }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strtol_base); + ATF_TP_ADD_TC(tp, strtol_case); + ATF_TP_ADD_TC(tp, strtol_range); + ATF_TP_ADD_TC(tp, strtol_signed); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_system.c b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c new file mode 100644 index 0000000..235005b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c @@ -0,0 +1,83 @@ +/* $NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $"); + +#include <atf-c.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const char *path = "system"; + +ATF_TC_WITH_CLEANUP(system_basic); +ATF_TC_HEAD(system_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of system(3)"); +} + +ATF_TC_BODY(system_basic, tc) +{ + char buf[23]; + int fd, i = 2; + + ATF_REQUIRE(system("/bin/echo -n > system") == 0); + + while (i >= 0) { + ATF_REQUIRE(system("/bin/echo -n garbage >> system") == 0); + i--; + } + + fd = open(path, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, '\0', sizeof(buf)); + + ATF_REQUIRE(read(fd, buf, 21) == 21); + ATF_REQUIRE(strcmp(buf, "garbagegarbagegarbage") == 0); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(system_basic, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, system_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_bm.c b/contrib/netbsd-tests/lib/libc/string/t_bm.c new file mode 100644 index 0000000..5ec4022 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_bm.c @@ -0,0 +1,102 @@ +/* $Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $ */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Mateusz Kocielski. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <sys/types.h> +#include <bm.h> +#include <string.h> +#include <stdlib.h> + +ATF_TC(bm); +ATF_TC_HEAD(bm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bm(3)"); +} + +typedef struct { + const char *pattern; + const char *text; + const char *freq; + ssize_t match; +} t_testcase; + +const t_testcase testcases[] = { + {"test", "test", NULL, 0}, + {"test", "ttest", NULL, 1}, + {"test", "tes", NULL, -1}, + {"test", "testtesttest", NULL, 0}, + {"test", "testtesttesttesttesttest", NULL, 0}, + {"test", "------------------------", NULL, -1}, + {"a", "a", NULL, 0}, + {"a", "ba", NULL, 1}, + {"a", "bba", NULL, 2}, + {"bla", "bl", NULL, -1}, + {"a", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", NULL, -1}, + {"test", "qfwiofjqeiwofjioqewfjeiqwjfiqewjfioqewfjioewqjfioewqjfioewqjoi", + NULL, -1}, + {"needle", "haystack", NULL, -1}, + {"netbsd", "freebsd netbsd openbsd", NULL, 8}, +}; + +ATF_TC_BODY(bm, tc) +{ + size_t ts; + u_char *off; + char *text; + bm_pat *pattern; + + for (ts = 0; ts < sizeof(testcases)/sizeof(t_testcase); ts++) { + ATF_CHECK(pattern = bm_comp((const u_char *)testcases[ts].pattern, + strlen(testcases[ts].pattern), (const u_char *)testcases[ts].freq)); + + ATF_REQUIRE(text = strdup(testcases[ts].text)); + off = bm_exec(pattern, (u_char *)text, strlen(text)); + + if (testcases[ts].match == -1) + ATF_CHECK_EQ(off, NULL); + else + ATF_CHECK_EQ(testcases[ts].match, + (off-(u_char *)text)); + + bm_free(pattern); + free(text); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bm); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memchr.c b/contrib/netbsd-tests/lib/libc/string/t_memchr.c new file mode 100644 index 0000000..296f1f8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memchr.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_memchr.c,v 1.3 2012/04/06 07:53:10 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(memchr_basic); +ATF_TC_HEAD(memchr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #1"); +} + +ATF_TC_BODY(memchr_basic, tc) +{ + /* try to trick the compiler */ + void * (*f)(const void *, int, size_t) = memchr; + + unsigned int a, t; + void *off, *off2; + char buf[32]; + + struct tab { + const char *val; + size_t len; + char match; + ssize_t off; + }; + + const struct tab tab[] = { + { "", 0, 0, 0 }, + + { "/", 0, 0, 0 }, + { "/", 1, 1, 0 }, + { "/a", 2, 1, 0 }, + { "/ab", 3, 1, 0 }, + { "/abc", 4, 1, 0 }, + { "/abcd", 5, 1, 0 }, + { "/abcde", 6, 1, 0 }, + { "/abcdef", 7, 1, 0 }, + { "/abcdefg", 8, 1, 0 }, + + { "a/", 1, 0, 0 }, + { "a/", 2, 1, 1 }, + { "a/b", 3, 1, 1 }, + { "a/bc", 4, 1, 1 }, + { "a/bcd", 5, 1, 1 }, + { "a/bcde", 6, 1, 1 }, + { "a/bcdef", 7, 1, 1 }, + { "a/bcdefg", 8, 1, 1 }, + + { "ab/", 2, 0, 0 }, + { "ab/", 3, 1, 2 }, + { "ab/c", 4, 1, 2 }, + { "ab/cd", 5, 1, 2 }, + { "ab/cde", 6, 1, 2 }, + { "ab/cdef", 7, 1, 2 }, + { "ab/cdefg", 8, 1, 2 }, + + { "abc/", 3, 0, 0 }, + { "abc/", 4, 1, 3 }, + { "abc/d", 5, 1, 3 }, + { "abc/de", 6, 1, 3 }, + { "abc/def", 7, 1, 3 }, + { "abc/defg", 8, 1, 3 }, + + { "abcd/", 4, 0, 0 }, + { "abcd/", 5, 1, 4 }, + { "abcd/e", 6, 1, 4 }, + { "abcd/ef", 7, 1, 4 }, + { "abcd/efg", 8, 1, 4 }, + + { "abcde/", 5, 0, 0 }, + { "abcde/", 6, 1, 5 }, + { "abcde/f", 7, 1, 5 }, + { "abcde/fg", 8, 1, 5 }, + + { "abcdef/", 6, 0, 0 }, + { "abcdef/", 7, 1, 6 }, + { "abcdef/g", 8, 1, 6 }, + + { "abcdefg/", 7, 0, 0 }, + { "abcdefg/", 8, 1, 7 }, + + { "\xff\xff\xff\xff" "efg/", 8, 1, 7 }, + { "a" "\xff\xff\xff\xff" "fg/", 8, 1, 7 }, + { "ab" "\xff\xff\xff\xff" "g/", 8, 1, 7 }, + { "abc" "\xff\xff\xff\xff" "/", 8, 1, 7 }, + }; + + for (a = 1; a < 1 + sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + buf[a-1] = '/'; + strcpy(&buf[a], tab[t].val); + + off = f(&buf[a], '/', tab[t].len); + if (tab[t].match == 0) { + if (off != 0) { + fprintf(stderr, "a = %d, t = %d\n", + a, t); + atf_tc_fail("should not have found " + " char past len"); + } + } else if (tab[t].match == 1) { + if (tab[t].off != ((char*)off - &buf[a])) { + fprintf(stderr, "a = %d, t = %d\n", + a, t); + atf_tc_fail("char not found at " + "correct offset"); + } + } else { + fprintf(stderr, "a = %d, t = %d\n", a, t); + atf_tc_fail("Corrupt test case data"); + } + + /* check zero extension of char arg */ + off2 = f(&buf[a], 0xffffff00 | '/', tab[t].len); + if (off2 != off) + atf_tc_fail("zero extension of char arg " + "failed"); + } + } +} + +ATF_TC(memchr_simple); +ATF_TC_HEAD(memchr_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #2"); +} + +ATF_TC_BODY(memchr_simple, tc) +{ + char buf[] = "abcdefg"; + short i = 7; + + ATF_CHECK(memchr(buf, 'a', 0) == NULL); + ATF_CHECK(memchr(buf, 'g', 0) == NULL); + ATF_CHECK(memchr(buf, 'x', 7) == NULL); + + ATF_CHECK(memchr("\0", 'x', 0) == NULL); + ATF_CHECK(memchr("\0", 'x', 1) == NULL); + + while (i <= 14) { + + ATF_CHECK(memchr(buf, 'a', i) == buf + 0); + ATF_CHECK(memchr(buf, 'b', i) == buf + 1); + ATF_CHECK(memchr(buf, 'c', i) == buf + 2); + ATF_CHECK(memchr(buf, 'd', i) == buf + 3); + ATF_CHECK(memchr(buf, 'e', i) == buf + 4); + ATF_CHECK(memchr(buf, 'f', i) == buf + 5); + ATF_CHECK(memchr(buf, 'g', i) == buf + 6); + + i *= 2; + } +} + +ATF_TC(memrchr_simple); +ATF_TC_HEAD(memrchr_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memrchr(3) results"); +} + +ATF_TC_BODY(memrchr_simple, tc) +{ + char buf[] = "abcdabcd"; + + ATF_CHECK(memrchr(buf, 'a', 0) == NULL); + ATF_CHECK(memrchr(buf, 'g', 0) == NULL); + ATF_CHECK(memrchr(buf, 'x', 8) == NULL); + + ATF_CHECK(memrchr("\0", 'x', 0) == NULL); + ATF_CHECK(memrchr("\0", 'x', 1) == NULL); + + ATF_CHECK(memrchr(buf, 'a', 8) == buf + 4); + ATF_CHECK(memrchr(buf, 'b', 8) == buf + 5); + ATF_CHECK(memrchr(buf, 'c', 8) == buf + 6); + ATF_CHECK(memrchr(buf, 'd', 8) == buf + 7); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memchr_basic); + ATF_TP_ADD_TC(tp, memchr_simple); + ATF_TP_ADD_TC(tp, memrchr_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memcpy.c b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c new file mode 100644 index 0000000..192a4e8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c @@ -0,0 +1,162 @@ +/* $NetBSD: t_memcpy.c,v 1.5 2013/03/17 02:23:31 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <md5.h> + +#include <sys/types.h> + +#define ALIGNMENTS 16 +#define LENGTHS 4 +#define BLOCKTYPES 4 + +MD5_CTX mc[1]; + +typedef unsigned char testBlock_t[ALIGNMENTS * LENGTHS]; + +testBlock_t bss1, bss2; + +unsigned char *start[BLOCKTYPES] = { + bss1, bss2 +}; + +char result[100]; +#ifdef __NetBSD__ +const char goodResult[] = "7b405d24bc03195474c70ddae9e1f8fb"; +#else +const char goodResult[] = "217b4fbe456916bf62a2f85df752e4ab"; +#endif + +static void +runTest(unsigned char *b1, unsigned char *b2) +{ + int i, j, k, m; + size_t n; + + for (i = 0; i < ALIGNMENTS; ++i) { + for (j = 0; j < ALIGNMENTS; ++j) { + k = sizeof(testBlock_t) - (i > j ? i : j); + for (m = 0; m < k; ++m) { + for (n = 0; n < sizeof(testBlock_t); ++n) { + b1[n] = (unsigned char)random(); + b2[n] = (unsigned char)random(); + } + memcpy(b1 + i, b2 + j, m); + MD5Update(mc, b1, sizeof(testBlock_t)); + MD5Update(mc, b2, sizeof(testBlock_t)); + } + } + } +} + +ATF_TC(memcpy_basic); +ATF_TC_HEAD(memcpy_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memcpy results"); +} + +ATF_TC_BODY(memcpy_basic, tc) +{ + int i, j; + testBlock_t auto1, auto2; + + start[2] = auto1; + start[3] = auto2; + +#ifdef __NetBSD__ + srandom(0L); +#else + /* + * random() shall produce by default a sequence of numbers that can be + * duplicated by calling srandom() with 1 as the seed. + */ + srandom(1); +#endif + MD5Init(mc); + for (i = 0; i < BLOCKTYPES; ++i) + for (j = 0; j < BLOCKTYPES; ++j) + if (i != j) + runTest(start[i], start[j]); + MD5End(mc, result); + ATF_REQUIRE_EQ(strcmp(result, goodResult), 0); +} + +ATF_TC(memccpy_simple); +ATF_TC_HEAD(memccpy_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memccpy(3) results"); +} + +ATF_TC_BODY(memccpy_simple, tc) +{ + char buf[100]; + char c = ' '; + + (void)memset(buf, c, sizeof(buf)); + + ATF_CHECK(memccpy(buf, "foo bar", c, sizeof(buf)) != NULL); + ATF_CHECK(buf[4] == c); + + ATF_CHECK(memccpy(buf, "foo bar", '\0', sizeof(buf) - 1) != NULL); + ATF_CHECK(buf[8] == c); + + ATF_CHECK(memccpy(buf, "foo bar", 'x', 7) == NULL); + ATF_CHECK(strncmp(buf, "foo bar", 7) == 0); + + ATF_CHECK(memccpy(buf, "xxxxxxx", 'r', 7) == NULL); + ATF_CHECK(strncmp(buf, "xxxxxxx", 7) == 0); +} + +ATF_TC(memcpy_return); +ATF_TC_HEAD(memcpy_return, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memcpy(3) return value"); +} + +ATF_TC_BODY(memcpy_return, tc) +{ + char *b = (char *)0x1; + char c[2]; + ATF_REQUIRE_EQ(memcpy(b, b, 0), b); + ATF_REQUIRE_EQ(memcpy(c, "ab", sizeof(c)), c); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memcpy_basic); + ATF_TP_ADD_TC(tp, memcpy_return); + ATF_TP_ADD_TC(tp, memccpy_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memmem.c b/contrib/netbsd-tests/lib/libc/string/t_memmem.c new file mode 100644 index 0000000..8734bc3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memmem.c @@ -0,0 +1,105 @@ +/* $NetBSD: t_memmem.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char p0[] = ""; +int lp0 = 0; +char p1[] = "0123"; +int lp1 = 4; +char p2[] = "456"; +int lp2 = 3; +char p3[] = "789"; +int lp3 = 3; +char p4[] = "abc"; +int lp4 = 3; +char p5[] = "0"; +int lp5 = 1; +char p6[] = "9"; +int lp6 = 1; +char p7[] = "654"; +int lp7 = 3; + +char b0[] = ""; +int lb0 = 0; +char b1[] = "0"; +int lb1 = 1; +char b2[] = "0123456789"; +int lb2 = 10; + +#define expect(b) \ + if (!(b)) { \ + fprintf(stderr, "failed on line %d\n", __LINE__); \ + atf_tc_fail("Check stderr for test id/line"); \ + } + +ATF_TC(memmem_basic); +ATF_TC_HEAD(memmem_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test memmem results"); +} + +ATF_TC_BODY(memmem_basic, tc) +{ + +#if defined(__darwin__) || defined(__FreeBSD__) + expect(memmem(b2, lb2, p0, lp0) == NULL); + expect(memmem(b0, lb0, p0, lp0) == NULL); +#else + expect(memmem(b2, lb2, p0, lp0) == b2); + expect(memmem(b0, lb0, p0, lp0) == b0); +#endif + expect(memmem(b0, lb0, p1, lp1) == NULL); + expect(memmem(b1, lb1, p1, lp1) == NULL); + + expect(memmem(b2, lb2, p1, lp1) == b2); + expect(memmem(b2, lb2, p2, lp2) == (b2 + 4)); + expect(memmem(b2, lb2, p3, lp3) == (b2 + 7)); + + expect(memmem(b2, lb2, p5, lp5) == b2); + expect(memmem(b2, lb2, p6, lp6) == (b2 + 9)); + + expect(memmem(b2, lb2, p4, lp4) == NULL); + expect(memmem(b2, lb2, p7, lp7) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memmem_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memset.c b/contrib/netbsd-tests/lib/libc/string/t_memset.c new file mode 100644 index 0000000..c1fb385 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memset.c @@ -0,0 +1,207 @@ +/* $NetBSD: t_memset.c,v 1.3 2013/03/17 02:23:31 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_memset.c,v 1.3 2013/03/17 02:23:31 christos Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static long page = 0; +static void fill(char *, size_t, char); +static bool check(char *, size_t, char); + +ATF_TC(memset_array); +ATF_TC_HEAD(memset_array, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with arrays"); +} + +ATF_TC_BODY(memset_array, tc) +{ + char buf[1024]; + + (void)memset(buf, 0, sizeof(buf)); + + if (check(buf, sizeof(buf), 0) != true) + atf_tc_fail("memset(3) did not fill a static buffer"); + + (void)memset(buf, 'x', sizeof(buf)); + + if (check(buf, sizeof(buf), 'x') != true) + atf_tc_fail("memset(3) did not fill a static buffer"); +} + +ATF_TC(memset_return); +ATF_TC_HEAD(memset_return, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) return value"); +} + +ATF_TC_BODY(memset_return, tc) +{ + char *b = (char *)0x1; + char c[2]; + ATF_REQUIRE_EQ(memset(b, 0, 0), b); + ATF_REQUIRE_EQ(memset(c, 2, sizeof(c)), c); +} + +ATF_TC(memset_basic); +ATF_TC_HEAD(memset_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of memset(3)"); +} + +ATF_TC_BODY(memset_basic, tc) +{ + char *buf, *ret; + + buf = malloc(page); + ret = malloc(page); + + ATF_REQUIRE(buf != NULL); + ATF_REQUIRE(ret != NULL); + + fill(ret, page, 0); + memset(buf, 0, page); + + ATF_REQUIRE(memcmp(ret, buf, page) == 0); + + fill(ret, page, 'x'); + memset(buf, 'x', page); + + ATF_REQUIRE(memcmp(ret, buf, page) == 0); + + free(buf); + free(ret); +} + +ATF_TC(memset_nonzero); +ATF_TC_HEAD(memset_nonzero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with non-zero params"); +} + +ATF_TC_BODY(memset_nonzero, tc) +{ + const size_t n = 0x7f; + char *buf; + size_t i; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + for (i = 0x21; i < n; i++) { + + (void)memset(buf, i, page); + + if (check(buf, page, i) != true) + atf_tc_fail("memset(3) did not fill properly"); + } + + free(buf); +} + +ATF_TC(memset_struct); +ATF_TC_HEAD(memset_struct, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with a structure"); +} + +ATF_TC_BODY(memset_struct, tc) +{ + struct stat st; + + st.st_dev = 0; + st.st_ino = 1; + st.st_mode = 2; + st.st_nlink = 3; + st.st_uid = 4; + st.st_gid = 5; + st.st_rdev = 6; + st.st_size = 7; + st.st_atime = 8; + st.st_mtime = 9; + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_CHECK(st.st_dev == 0); + ATF_CHECK(st.st_ino == 0); + ATF_CHECK(st.st_mode == 0); + ATF_CHECK(st.st_nlink == 0); + ATF_CHECK(st.st_uid == 0); + ATF_CHECK(st.st_gid == 0); + ATF_CHECK(st.st_rdev == 0); + ATF_CHECK(st.st_size == 0); + ATF_CHECK(st.st_atime == 0); + ATF_CHECK(st.st_mtime == 0); +} + +static void +fill(char *buf, size_t len, char x) +{ + size_t i; + + for (i = 0; i < len; i++) + buf[i] = x; +} + +static bool +check(char *buf, size_t len, char x) +{ + size_t i; + + for (i = 0; i < len; i++) { + + if (buf[i] != x) + return false; + } + + return true; +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, memset_array); + ATF_TP_ADD_TC(tp, memset_basic); + ATF_TP_ADD_TC(tp, memset_nonzero); + ATF_TP_ADD_TC(tp, memset_struct); + ATF_TP_ADD_TC(tp, memset_return); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_popcount.c b/contrib/netbsd-tests/lib/libc/string/t_popcount.c new file mode 100644 index 0000000..2bae52f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_popcount.c @@ -0,0 +1,198 @@ +/* $NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $ */ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $"); + +#include <atf-c.h> +#include <strings.h> + +static unsigned int byte_count[256]; + +static void +popcount_init(const char *cfg_var) +{ + unsigned int i, j; + + if (strcasecmp(cfg_var, "YES") == 0 || + strcasecmp(cfg_var, "Y") == 0 || + strcasecmp(cfg_var, "1") == 0 || + strcasecmp(cfg_var, "T") == 0 || + strcasecmp(cfg_var, "TRUE") == 0) { + for (i = 0; i < 256; ++i) { + byte_count[i] = 0; + for (j = i; j != 0; j >>= 1) { + if (j & 1) + ++byte_count[i]; + } + } + return; + } + + atf_tc_skip("config variable \"run_popcount\" not set to YES/TRUE"); +} + +unsigned int test_parts[256] = { + 0x318e53e6U, 0x11710316U, 0x62608ffaU, 0x67e0f562U, + 0xe432e82cU, 0x9862e8b2U, 0x7d96a627U, 0x3f74ad31U, + 0x3cecf906U, 0xcdc0dcb4U, 0x241dab64U, 0x31e6133eU, + 0x23086ad4U, 0x721d5a91U, 0xc483da53U, 0x6a62af52U, + 0xf3f5c386U, 0xe0de3f77U, 0x65afe528U, 0xf4816485U, + 0x40ccbf08U, 0x25df49c1U, 0xae5a6ee0U, 0xab36ccadU, + 0x87e1ec29U, 0x60ca2407U, 0x49d62e47U, 0xa09f2df5U, + 0xaf4c1c68U, 0x8ef08d50U, 0x624cfd2fU, 0xa6a36f20U, + 0x68aaf879U, 0x0fe9deabU, 0x5c9a4060U, 0x215d8f08U, + 0x55e84712U, 0xea1f1681U, 0x3a10b8a1U, 0x08e06632U, + 0xcbc875e2U, 0x31e53258U, 0xcd3807a4U, 0xb9d17516U, + 0x8fbfd9abU, 0x6651b555U, 0x550fb381U, 0x05061b9dU, + 0x35aef3f2U, 0x9175078cU, 0xae0f14daU, 0x92a2d5f8U, + 0x70d968feU, 0xe86f41c5U, 0x5cfaf39fU, 0x8499b18dU, + 0xb33f879aU, 0x0a68ad3dU, 0x9323ecc1U, 0x060037ddU, + 0xb91a5051U, 0xa0dbebf6U, 0x3e6aa6f1U, 0x7b422b5bU, + 0x599e811eU, 0x199f7594U, 0xca453365U, 0x1cda6f48U, + 0xe9c75d2cU, 0x6a873217U, 0x79c45d72U, 0x143b8e37U, + 0xa11df26eU, 0xaf31f80aU, 0x311bf759U, 0x2378563cU, + 0x9ab95fa5U, 0xfcf4d47cU, 0x1f7db268U, 0xd64b09e1U, + 0xad7936daU, 0x7a59005cU, 0x45b173d3U, 0xc1a71b32U, + 0x7d9f0de2U, 0xa9ac3792U, 0x9e7f9966U, 0x7f0b8080U, + 0xece6c06fU, 0x78d92a3cU, 0x6d5f8f6cU, 0xc50ca544U, + 0x5d8ded27U, 0xd27a8462U, 0x4bcd13ccU, 0xd49075f2U, + 0xa8d52acfU, 0x41915d97U, 0x564f7062U, 0xefb046e2U, + 0xe296277aU, 0x605b0ea3U, 0x10b2c3a1U, 0x4e8e5c66U, + 0x4bd8ec04U, 0x29935be9U, 0x381839f3U, 0x555d8824U, + 0xd6befddbU, 0x5d8d6d6eU, 0xb2fdb7b4U, 0xb471c8fcU, + 0xc2fd325bU, 0x932d2487U, 0xbdbbadefU, 0x66c8895dU, + 0x5d77857aU, 0x259f1cc0U, 0x302037faU, 0xda9aa7a8U, + 0xb112c6aaU, 0x78f74192U, 0xfd4da741U, 0xfa5765c1U, + 0x6ea1bc5cU, 0xd283f39cU, 0x268ae67dU, 0xdedcd134U, + 0xbbf92410U, 0x6b45fb55U, 0x2f75ac71U, 0x64bf2ca5U, + 0x8b99675aU, 0x3f4923b6U, 0x7e610550U, 0x04b1c06dU, + 0x8f92e7c6U, 0x45cb608bU, 0x2d06d1f2U, 0x79cf387aU, + 0xfd3ed225U, 0x243eee20U, 0x2cbefc6fU, 0x8286cbaaU, + 0x70d4c182U, 0x054e3cc6U, 0xb66c5362U, 0x0c73fa5dU, + 0x539948feU, 0xec638563U, 0x0cf04ab6U, 0xec7b52f4U, + 0x58eeffceU, 0x6fe8049aU, 0xb3b33332U, 0x2e33bfdbU, + 0xcc817567U, 0x71ac57c8U, 0x4bab3ac7U, 0x327c558bU, + 0x82a6d279U, 0x5adf71daU, 0x1074a656U, 0x3c533c1fU, + 0x82fdbe69U, 0x21b4f6afU, 0xd59580e8U, 0x0de824ebU, + 0xa510941bU, 0x7cd91144U, 0xa8c10631U, 0x4c839267U, + 0x5d503c2fU, 0xe1567d55U, 0x23910cc7U, 0xdb1bdc34U, + 0x2a866704U, 0x33e21f0cU, 0x5c7681b4U, 0x818651caU, + 0xb1d18162U, 0x225ad014U, 0xadf7d6baU, 0xac548d9bU, + 0xe94736e5U, 0x2279c5f1U, 0x33215d2cU, 0xdc8ab90eU, + 0xf5e3d7f2U, 0xedcb15cfU, 0xc9a43c4cU, 0xfc678fc6U, + 0x43796b95U, 0x3f8b700cU, 0x867bbc72U, 0x81f71fecU, + 0xd00cad7dU, 0x302c458fU, 0x8ae21accU, 0x05850ce8U, + 0x7764d8e8U, 0x8a36cd68U, 0x40b44bd7U, 0x1cffaeb7U, + 0x2b248f34U, 0x1eefdbafU, 0x574d7437U, 0xe86cd935U, + 0xf53dd1c8U, 0x1b022513U, 0xef2d249bU, 0x94fb2b08U, + 0x15d3eff8U, 0x14245e1bU, 0x82aa8425U, 0x53959028U, + 0x9c5f9b80U, 0x325e0c82U, 0x3e236c24U, 0x74e1dd36U, + 0x9890df3fU, 0xaf9701a2U, 0x023b3413U, 0x7634c67eU, + 0x55cf5e45U, 0x56d2a95bU, 0xb6db869bU, 0xac19e260U, + 0xdd310740U, 0x26d68f84U, 0x45bebf17U, 0xe4a7728fU, + 0xf082e66eU, 0xb2fe3c10U, 0x2db1fa2cU, 0x4b3dfcfaU, + 0xc7b3a672U, 0xaeadc67bU, 0x6cce6f2bU, 0x8263dbbfU, + 0xd9724d5bU, 0xbcc767b5U, 0x8d563798U, 0x2db764b4U, + 0x76e0cee7U, 0xd34f9a67U, 0x035c810aU, 0x3f56bdc1U, + 0x5b3f2c84U, 0x0baca8c0U, 0xfe979a77U, 0x484ca775U, + 0xbdc7f104U, 0xc06c3efbU, 0xdbc5f32cU, 0x44b017e7U, +}; + +ATF_TC(popcount_basic); +ATF_TC_HEAD(popcount_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test popcount results"); + atf_tc_set_md_var(tc, "timeout", "0"); +} + +ATF_TC_BODY(popcount_basic, tc) +{ + unsigned int i, r; + + popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO")); + + for (i = 0; i < 0xffffffff; ++i) { + r = byte_count[i & 255] + byte_count[(i >> 8) & 255] + + byte_count[(i >> 16) & 255] + + byte_count[(i >> 24) & 255]; + + ATF_CHECK_EQ(r, popcount(i)); + } + ATF_CHECK_EQ(popcount(0xffffffff), 32); +} + +ATF_TC(popcountll_basic); +ATF_TC_HEAD(popcountll_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test popcountll results"); + atf_tc_set_md_var(tc, "timeout", "0"); +} + +ATF_TC_BODY(popcountll_basic, tc) +{ + unsigned int i, j, r, r2, p; + unsigned long long v; + + popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO")); + + for (j = 0; j < 256; ++j) { + p = test_parts[j]; + r2 = byte_count[p & 255] + byte_count[(p >> 8) & 255] + + byte_count[(p >> 16) & 255] + + byte_count[(p >> 24) & 255]; + + for (i = 0; i < 0xffffffff; ++i) { + r = byte_count[i & 255] + byte_count[(i >> 8) & 255] + + byte_count[(i >> 16) & 255] + + byte_count[(i >> 24) & 255] + r2; + + v = (((unsigned long long)i) << 32) + p; + ATF_CHECK_EQ(r, popcountll(v)); + v = (((unsigned long long)p) << 32) + i; + ATF_CHECK_EQ(r, popcountll(v)); + } + } + + ATF_CHECK_EQ(popcountll(0xffffffffffffffffULL), 64); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, popcount_basic); + ATF_TP_ADD_TC(tp, popcountll_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcat.c b/contrib/netbsd-tests/lib/libc/string/t_strcat.c new file mode 100644 index 0000000..bd98691 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcat.c @@ -0,0 +1,153 @@ +/* $NetBSD: t_strcat.c,v 1.2 2011/07/14 05:46:04 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strcat_basic); +ATF_TC_HEAD(strcat_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcat(3) results"); +} + +ATF_TC_BODY(strcat_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(char *, const char *s) = strcat; + + unsigned int a0, a1, t0, t1; + char buf0[64]; + char buf1[64]; + char *ret; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t0 = 0; t0 < __arraycount(tab); ++t0) { + for (t1 = 0; t1 < __arraycount(tab); ++t1) { + + memcpy(&buf0[a0], tab[t0].val, + tab[t0].len + 1); + memcpy(&buf1[a1], tab[t1].val, + tab[t1].len + 1); + + ret = f(&buf0[a0], &buf1[a1]); + + /* + * verify strcat returns address + * of first parameter + */ + if (&buf0[a0] != ret) { + fprintf(stderr, "a0 %d, a1 %d, " + "t0 %d, t1 %d\n", + a0, a1, t0, t1); + atf_tc_fail("strcat did not " + "return its first arg"); + } + + /* verify string copied correctly */ + if (memcmp(&buf0[a0] + tab[t0].len, + &buf1[a1], + tab[t1].len + 1) != 0) { + fprintf(stderr, "a0 %d, a1 %d, " + "t0 %d, t1 %d\n", + a0, a1, t0, t1); + atf_tc_fail("string not copied " + "correctly"); + } + } + } + } + } +} + +ATF_TC(strncat_simple); +ATF_TC_HEAD(strncat_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strncat(3) results"); +} + +ATF_TC_BODY(strncat_simple, tc) +{ + char buf[100] = "abcdefg"; + + ATF_CHECK(strncat(buf, "xxx", 0) == buf); + ATF_CHECK(strcmp(buf, "abcdefg") == 0); + ATF_CHECK(strncat(buf, "xxx", 1) == buf); + ATF_CHECK(strcmp(buf, "abcdefgx") == 0); + ATF_CHECK(strncat(buf, "xxx", 2) == buf); + ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0); + ATF_CHECK(strncat(buf, "\0", 1) == buf); + ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcat_basic); + ATF_TP_ADD_TC(tp, strncat_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strchr.c b/contrib/netbsd-tests/lib/libc/string/t_strchr.c new file mode 100644 index 0000000..958b186 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strchr.c @@ -0,0 +1,292 @@ +/* $NetBSD: t_strchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> + +static char *slow_strchr(char *, int); +static void verify_strchr(char *, int, unsigned int, unsigned int); + +char * (*volatile strchr_fn)(const char *, int); + +static char * +slow_strchr(char *buf, int ch) +{ + unsigned char c = 1; + + ch &= 0xff; + + for (; c != 0; buf++) { + c = *buf; + if (c == ch) + return buf; + } + return 0; +} + +static void +verify_strchr(char *buf, int ch, unsigned int t, unsigned int a) +{ + const char *off, *ok_off; + + off = strchr_fn(buf, ch); + ok_off = slow_strchr(buf, ch); + if (off == ok_off) + return; + + fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, " + "alignment %d)\n", + buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a); + + atf_tc_fail("Check stderr for details"); +} + +ATF_TC(strchr_basic); +ATF_TC_HEAD(strchr_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test strchr(3) results"); +} + +ATF_TC_BODY(strchr_basic, tc) +{ + unsigned int t, a; + char *off; + char buf[32]; + + const char *tab[] = { + "", + "a", + "aa", + "abc", + "abcd", + "abcde", + "abcdef", + "abcdefg", + "abcdefgh", + + "/", + "//", + "/a", + "/a/", + "/ab", + "/ab/", + "/abc", + "/abc/", + "/abcd", + "/abcd/", + "/abcde", + "/abcde/", + "/abcdef", + "/abcdef/", + "/abcdefg", + "/abcdefg/", + "/abcdefgh", + "/abcdefgh/", + + "a/", + "a//", + "a/a", + "a/a/", + "a/ab", + "a/ab/", + "a/abc", + "a/abc/", + "a/abcd", + "a/abcd/", + "a/abcde", + "a/abcde/", + "a/abcdef", + "a/abcdef/", + "a/abcdefg", + "a/abcdefg/", + "a/abcdefgh", + "a/abcdefgh/", + + "ab/", + "ab//", + "ab/a", + "ab/a/", + "ab/ab", + "ab/ab/", + "ab/abc", + "ab/abc/", + "ab/abcd", + "ab/abcd/", + "ab/abcde", + "ab/abcde/", + "ab/abcdef", + "ab/abcdef/", + "ab/abcdefg", + "ab/abcdefg/", + "ab/abcdefgh", + "ab/abcdefgh/", + + "abc/", + "abc//", + "abc/a", + "abc/a/", + "abc/ab", + "abc/ab/", + "abc/abc", + "abc/abc/", + "abc/abcd", + "abc/abcd/", + "abc/abcde", + "abc/abcde/", + "abc/abcdef", + "abc/abcdef/", + "abc/abcdefg", + "abc/abcdefg/", + "abc/abcdefgh", + "abc/abcdefgh/", + + "abcd/", + "abcd//", + "abcd/a", + "abcd/a/", + "abcd/ab", + "abcd/ab/", + "abcd/abc", + "abcd/abc/", + "abcd/abcd", + "abcd/abcd/", + "abcd/abcde", + "abcd/abcde/", + "abcd/abcdef", + "abcd/abcdef/", + "abcd/abcdefg", + "abcd/abcdefg/", + "abcd/abcdefgh", + "abcd/abcdefgh/", + + "abcde/", + "abcde//", + "abcde/a", + "abcde/a/", + "abcde/ab", + "abcde/ab/", + "abcde/abc", + "abcde/abc/", + "abcde/abcd", + "abcde/abcd/", + "abcde/abcde", + "abcde/abcde/", + "abcde/abcdef", + "abcde/abcdef/", + "abcde/abcdefg", + "abcde/abcdefg/", + "abcde/abcdefgh", + "abcde/abcdefgh/", + + "abcdef/", + "abcdef//", + "abcdef/a", + "abcdef/a/", + "abcdef/ab", + "abcdef/ab/", + "abcdef/abc", + "abcdef/abc/", + "abcdef/abcd", + "abcdef/abcd/", + "abcdef/abcde", + "abcdef/abcde/", + "abcdef/abcdef", + "abcdef/abcdef/", + "abcdef/abcdefg", + "abcdef/abcdefg/", + "abcdef/abcdefgh", + "abcdef/abcdefgh/", + + "abcdefg/", + "abcdefg//", + "abcdefg/a", + "abcdefg/a/", + "abcdefg/ab", + "abcdefg/ab/", + "abcdefg/abc", + "abcdefg/abc/", + "abcdefg/abcd", + "abcdefg/abcd/", + "abcdefg/abcde", + "abcdefg/abcde/", + "abcdefg/abcdef", + "abcdefg/abcdef/", + "abcdefg/abcdefg", + "abcdefg/abcdefg/", + "abcdefg/abcdefgh", + "abcdefg/abcdefgh/", + + "abcdefgh/", + "abcdefgh//", + "abcdefgh/a", + "abcdefgh/a/", + "abcdefgh/ab", + "abcdefgh/ab/", + "abcdefgh/abc", + "abcdefgh/abc/", + "abcdefgh/abcd", + "abcdefgh/abcd/", + "abcdefgh/abcde", + "abcdefgh/abcde/", + "abcdefgh/abcdef", + "abcdefgh/abcdef/", + "abcdefgh/abcdefg", + "abcdefgh/abcdefg/", + "abcdefgh/abcdefgh", + "abcdefgh/abcdefgh/", + }; + + + strchr_fn = dlsym(dlopen(0, RTLD_LAZY), "test_strchr"); + if (!strchr_fn) + strchr_fn = strchr; + + for (a = 3; a < 3 + sizeof(long); ++a) { + /* Put char and a \0 before the buffer */ + buf[a-1] = '/'; + buf[a-2] = '0'; + buf[a-3] = 0xff; + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + int len = strlen(tab[t]) + 1; + memcpy(&buf[a], tab[t], len); + + /* Put the char we are looking for after the \0 */ + buf[a + len] = '/'; + + /* Check search for NUL at end of string */ + verify_strchr(buf + a, 0, t, a); + + /* Then for the '/' in the strings */ + verify_strchr(buf + a, '/', t, a); + + /* check zero extension of char arg */ + verify_strchr(buf + a, 0xffffff00 | '/', t, a); + + /* Replace all the '/' with 0xff */ + while ((off = slow_strchr(buf + a, '/')) != NULL) + *off = 0xff; + + buf[a + len] = 0xff; + + /* Check we can search for 0xff as well as '/' */ + verify_strchr(buf + a, 0xff, t, a); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strchr_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcmp.c b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c new file mode 100644 index 0000000..14e2e9c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_strcmp.c,v 1.4 2012/03/25 08:17:54 joerg Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strcmp_basic); +ATF_TC_HEAD(strcmp_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #1"); +} + +ATF_TC_BODY(strcmp_basic, tc) +{ + /* try to trick the compiler */ + int (*f)(const char *, const char *s) = strcmp; + + unsigned int a0, a1, t; + char buf0[64]; + char buf1[64]; + int ret; + + struct tab { + const char* val0; + const char* val1; + int ret; + }; + + const struct tab tab[] = { + { "", "", 0 }, + + { "a", "a", 0 }, + { "a", "b", -1 }, + { "b", "a", +1 }, + { "", "a", -1 }, + { "a", "", +1 }, + + { "aa", "aa", 0 }, + { "aa", "ab", -1 }, + { "ab", "aa", +1 }, + { "a", "aa", -1 }, + { "aa", "a", +1 }, + + { "aaa", "aaa", 0 }, + { "aaa", "aab", -1 }, + { "aab", "aaa", +1 }, + { "aa", "aaa", -1 }, + { "aaa", "aa", +1 }, + + { "aaaa", "aaaa", 0 }, + { "aaaa", "aaab", -1 }, + { "aaab", "aaaa", +1 }, + { "aaa", "aaaa", -1 }, + { "aaaa", "aaa", +1 }, + + { "aaaaa", "aaaaa", 0 }, + { "aaaaa", "aaaab", -1 }, + { "aaaab", "aaaaa", +1 }, + { "aaaa", "aaaaa", -1 }, + { "aaaaa", "aaaa", +1 }, + + { "aaaaaa", "aaaaaa", 0 }, + { "aaaaaa", "aaaaab", -1 }, + { "aaaaab", "aaaaaa", +1 }, + { "aaaaa", "aaaaaa", -1 }, + { "aaaaaa", "aaaaa", +1 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t = 0; t < __arraycount(tab); ++t) { + memcpy(&buf0[a0], tab[t].val0, + strlen(tab[t].val0) + 1); + memcpy(&buf1[a1], tab[t].val1, + strlen(tab[t].val1) + 1); + + ret = f(&buf0[a0], &buf1[a1]); + + if ((ret == 0 && tab[t].ret != 0) || + (ret < 0 && tab[t].ret >= 0) || + (ret > 0 && tab[t].ret <= 0)) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + fprintf(stderr, "\"%s\" \"%s\" %d\n", + &buf0[a0], &buf1[a1], ret); + atf_tc_fail("Check stderr for details"); + } + } + } + } +} + +ATF_TC(strcmp_simple); +ATF_TC_HEAD(strcmp_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #2"); +} + +ATF_TC_BODY(strcmp_simple, tc) +{ + char buf1[10] = "xxx"; + char buf2[10] = "xxy"; + + ATF_CHECK(strcmp(buf1, buf1) == 0); + ATF_CHECK(strcmp(buf2, buf2) == 0); + + ATF_CHECK(strcmp("x\xf6x", "xox") > 0); + ATF_CHECK(strcmp("xxx", "xxxyyy") < 0); + ATF_CHECK(strcmp("xxxyyy", "xxx") > 0); + + ATF_CHECK(strcmp(buf1 + 0, buf2 + 0) < 0); + ATF_CHECK(strcmp(buf1 + 1, buf2 + 1) < 0); + ATF_CHECK(strcmp(buf1 + 2, buf2 + 2) < 0); + ATF_CHECK(strcmp(buf1 + 3, buf2 + 3) == 0); + + ATF_CHECK(strcmp(buf2 + 0, buf1 + 0) > 0); + ATF_CHECK(strcmp(buf2 + 1, buf1 + 1) > 0); + ATF_CHECK(strcmp(buf2 + 2, buf1 + 2) > 0); + ATF_CHECK(strcmp(buf2 + 3, buf1 + 3) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcmp_basic); + ATF_TP_ADD_TC(tp, strcmp_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcpy.c b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c new file mode 100644 index 0000000..285371e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c @@ -0,0 +1,124 @@ +/* $NetBSD: t_strcpy.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strcpy_basic); +ATF_TC_HEAD(strcpy_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcpy(3) results"); +} + +ATF_TC_BODY(strcpy_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(char *, const char *s) = strcpy; + + unsigned int a0, a1, t; + char buf0[64]; + char buf1[64]; + char *ret; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + + memcpy(&buf1[a1], tab[t].val, tab[t].len + 1); + ret = f(&buf0[a0], &buf1[a1]); + + /* + * verify strcpy returns address of + * first parameter + */ + if (&buf0[a0] != ret) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + atf_tc_fail("strcpy did not return " + "its first arg"); + } + + /* + * verify string was copied correctly + */ + if (memcmp(&buf0[a0], &buf1[a1], + tab[t].len + 1) != 0) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + atf_tc_fail("not correctly copied"); + } + } + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcpy_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcspn.c b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c new file mode 100644 index 0000000..d38cdb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <string.h> + +ATF_TC(strcspn); +ATF_TC_HEAD(strcspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcspn(3)"); +} + +ATF_TC_BODY(strcspn, tc) +{ + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", ""), 16); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "a"), 0); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "b"), 1); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "cd"), 2); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "qrstuvwxyz"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strerror.c b/contrib/netbsd-tests/lib/libc/string/t_strerror.c new file mode 100644 index 0000000..888a826 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strerror.c @@ -0,0 +1,139 @@ +/* $NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <locale.h> +#include <string.h> + +#ifdef __FreeBSD__ +#include <stdio.h> +#endif + +ATF_TC(strerror_basic); +ATF_TC_HEAD(strerror_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strerror(3)"); +} + +ATF_TC_BODY(strerror_basic, tc) +{ + int i; + + for (i = 1; i < sys_nerr; i++) + ATF_REQUIRE(strstr(strerror(i), "Unknown error:") == NULL); + + for (; i < sys_nerr + 10; i++) + ATF_REQUIRE(strstr(strerror(i), "Unknown error:") != NULL); +} + +ATF_TC(strerror_err); +ATF_TC_HEAD(strerror_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from strerror(3)"); +} + +ATF_TC_BODY(strerror_err, tc) +{ + + errno = 0; + + ATF_REQUIRE(strstr(strerror(INT_MAX), "Unknown error:") != NULL); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(strstr(strerror(INT_MIN), "Unknown error:") != NULL); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(strerror_r_basic); +ATF_TC_HEAD(strerror_r_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strerror_r(3)"); +} + +ATF_TC_BODY(strerror_r_basic, tc) +{ + char buf[512]; + int i; + + for (i = 1; i < sys_nerr; i++) { + ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == 0); + ATF_REQUIRE(strstr(buf, "Unknown error:") == NULL); + } + + for (; i < sys_nerr + 10; i++) { + ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); + } +} + +ATF_TC(strerror_r_err); +ATF_TC_HEAD(strerror_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from strerror_r(3)"); +} + +ATF_TC_BODY(strerror_r_err, tc) +{ + char buf[512]; + int rv; + + rv = strerror_r(EPERM, buf, 1); + ATF_REQUIRE(rv == ERANGE); + + rv = strerror_r(INT_MAX, buf, sizeof(buf)); + + ATF_REQUIRE(rv == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); + + rv = strerror_r(INT_MIN, buf, sizeof(buf)); + + ATF_REQUIRE(rv == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)setlocale(LC_ALL, "C"); + + ATF_TP_ADD_TC(tp, strerror_basic); + ATF_TP_ADD_TC(tp, strerror_err); + ATF_TP_ADD_TC(tp, strerror_r_basic); + ATF_TP_ADD_TC(tp, strerror_r_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_stresep.c b/contrib/netbsd-tests/lib/libc/string/t_stresep.c new file mode 100644 index 0000000..4678e55 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_stresep.c @@ -0,0 +1,72 @@ +/* $NetBSD: t_stresep.c,v 1.3 2013/02/15 23:56:32 christos Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define expect(a) \ + if ((p = stresep(&q, " ", '\\')) == NULL || strcmp(p, a)) { \ + fprintf(stderr, "failed on line %d: %s != %s\n", \ + __LINE__, p, a); \ + atf_tc_fail("Check stderr for test id/line"); \ + } + +ATF_TC(stresep_basic); +ATF_TC_HEAD(stresep_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test stresep results"); +} + +ATF_TC_BODY(stresep_basic, tc) +{ + char brkstr[] = "foo\\ \\ bar baz bar\\ foo\\ bar\\ \\ foo \\ \\ \\ " + "baz bar\\ \\ "; + char *p, *q = brkstr; + + expect("foo bar"); + expect("baz"); + expect("bar foo "); + expect("bar foo"); + expect(" baz"); + expect("bar "); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, stresep_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strlen.c b/contrib/netbsd-tests/lib/libc/string/t_strlen.c new file mode 100644 index 0000000..66158fd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strlen.c @@ -0,0 +1,199 @@ +/* $NetBSD: t_strlen.c,v 1.5 2011/07/14 07:33:20 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> +#include <unistd.h> + +static void write_num(int); + +static void +write_num(int val) +{ + char buf[20]; + int i; + + for (i = sizeof buf; --i >= 0;) { + buf[i] = '0' + val % 10; + val /= 10; + if (val == 0) { + write(2, buf + i, sizeof buf - i); + return; + } + } + write(2, "overflow", 8); +} + +ATF_TC(strlen_basic); +ATF_TC_HEAD(strlen_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strlen(3) results"); +} + +ATF_TC_BODY(strlen_basic, tc) +{ + /* try to trick the compiler */ + size_t (*strlen_fn)(const char *); + + unsigned int a, t; + size_t len; + char buf[64]; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + /* + * During testing it is useful have the rest of the program + * use a known good version! + */ + strlen_fn = dlsym(dlopen(NULL, RTLD_LAZY), "test_strlen"); + if (!strlen_fn) + strlen_fn = strlen; + + for (a = 0; a < sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + + memcpy(&buf[a], tab[t].val, tab[t].len + 1); + len = strlen_fn(&buf[a]); + + if (len != tab[t].len) { + /* Write error without using printf / strlen */ + write(2, "alignment ", 10); + write_num(a); + write(2, ", test ", 7); + write_num(t); + write(2, ", got len ", 10); + write_num(len); + write(2, ", not ", 6); + write_num(tab[t].len); + write(2, ", for '", 7); + write(2, tab[t].val, tab[t].len); + write(2, "'\n", 2); + atf_tc_fail("See stderr for details"); + } + } + } +} + +ATF_TC(strlen_huge); +ATF_TC_HEAD(strlen_huge, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings"); +} + +ATF_TC_BODY(strlen_huge, tc) +{ + long page; + char *str; + size_t i; + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + for (i = 1; i < 1000; i = i + 100) { + + str = malloc(i * page + 1); + + if (str == NULL) + continue; + + (void)memset(str, 'x', i * page); + str[i * page] = '\0'; + + ATF_REQUIRE(strlen(str) == i * page); + free(str); + } +} + +ATF_TC(strnlen_basic); +ATF_TC_HEAD(strnlen_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)"); +} + +ATF_TC_BODY(strnlen_basic, tc) +{ + char buf[1]; + + buf[0] = '\0'; + + ATF_CHECK(strnlen(buf, 000) == 0); + ATF_CHECK(strnlen(buf, 111) == 0); + + ATF_CHECK(strnlen("xxx", 0) == 0); + ATF_CHECK(strnlen("xxx", 1) == 1); + ATF_CHECK(strnlen("xxx", 2) == 2); + ATF_CHECK(strnlen("xxx", 3) == 3); + ATF_CHECK(strnlen("xxx", 9) == 3); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strlen_basic); + ATF_TP_ADD_TC(tp, strlen_huge); + ATF_TP_ADD_TC(tp, strnlen_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c new file mode 100644 index 0000000..d0f2d9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c @@ -0,0 +1,62 @@ +/* $NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <string.h> + +ATF_TC(strpbrk); +ATF_TC_HEAD(strpbrk, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strpbrk(3)"); +} + +ATF_TC_BODY(strpbrk, tc) +{ + static const char s[] = "abcdefghijklmnop"; + + ATF_CHECK_EQ(strpbrk(s, ""), NULL); + ATF_CHECK_EQ(strpbrk(s, "qrst"), NULL); + ATF_CHECK_EQ(strpbrk(s, "a"), s); + ATF_CHECK_EQ(strpbrk(s, "b"), s + 1); + ATF_CHECK_EQ(strpbrk(s, "ab"), s); + ATF_CHECK_EQ(strpbrk(s, "cdef"), s + 2); + ATF_CHECK_EQ(strpbrk(s, "fedc"), s + 2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strpbrk); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strrchr.c b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c new file mode 100644 index 0000000..038daff --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c @@ -0,0 +1,257 @@ +/* $NetBSD: t_strrchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin <jtc@acorntoolworks.com> + * Public domain. + */ + +#include <atf-c.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +ATF_TC(strrchr_basic); +ATF_TC_HEAD(strrchr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strrchr(3) results"); +} + +ATF_TC_BODY(strrchr_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(const char *, int) = strrchr; + + unsigned int a, t; + char *off, *off2; + char buf[32]; + + struct tab { + const char* val; + char match; + ssize_t f_off; /* offset of first match */ + ssize_t l_off; /* offset of last match */ + }; + + const struct tab tab[] = { + { "", 0, 0, 0 }, + { "a", 0, 0, 0 }, + { "aa", 0, 0, 0 }, + { "abc", 0, 0, 0 }, + { "abcd", 0, 0, 0 }, + { "abcde", 0, 0, 0 }, + { "abcdef", 0, 0, 0 }, + { "abcdefg", 0, 0, 0 }, + { "abcdefgh", 0, 0, 0 }, + + { "/", 1, 0, 0 }, + { "//", 1, 0, 1 }, + { "/a", 1, 0, 0 }, + { "/a/", 1, 0, 2 }, + { "/ab", 1, 0, 0 }, + { "/ab/", 1, 0, 3 }, + { "/abc", 1, 0, 0 }, + { "/abc/", 1, 0, 4 }, + { "/abcd", 1, 0, 0 }, + { "/abcd/", 1, 0, 5 }, + { "/abcde", 1, 0, 0 }, + { "/abcde/", 1, 0, 6 }, + { "/abcdef", 1, 0, 0 }, + { "/abcdef/", 1, 0, 7 }, + { "/abcdefg", 1, 0, 0 }, + { "/abcdefg/", 1, 0, 8 }, + { "/abcdefgh", 1, 0, 0 }, + { "/abcdefgh/", 1, 0, 9 }, + + { "a/", 1, 1, 1 }, + { "a//", 1, 1, 2 }, + { "a/a", 1, 1, 1 }, + { "a/a/", 1, 1, 3 }, + { "a/ab", 1, 1, 1 }, + { "a/ab/", 1, 1, 4 }, + { "a/abc", 1, 1, 1 }, + { "a/abc/", 1, 1, 5 }, + { "a/abcd", 1, 1, 1 }, + { "a/abcd/", 1, 1, 6 }, + { "a/abcde", 1, 1, 1 }, + { "a/abcde/", 1, 1, 7 }, + { "a/abcdef", 1, 1, 1 }, + { "a/abcdef/", 1, 1, 8 }, + { "a/abcdefg", 1, 1, 1 }, + { "a/abcdefg/", 1, 1, 9 }, + { "a/abcdefgh", 1, 1, 1 }, + { "a/abcdefgh/", 1, 1, 10 }, + + { "ab/", 1, 2, 2 }, + { "ab//", 1, 2, 3 }, + { "ab/a", 1, 2, 2 }, + { "ab/a/", 1, 2, 4 }, + { "ab/ab", 1, 2, 2 }, + { "ab/ab/", 1, 2, 5 }, + { "ab/abc", 1, 2, 2 }, + { "ab/abc/", 1, 2, 6 }, + { "ab/abcd", 1, 2, 2 }, + { "ab/abcd/", 1, 2, 7 }, + { "ab/abcde", 1, 2, 2 }, + { "ab/abcde/", 1, 2, 8 }, + { "ab/abcdef", 1, 2, 2 }, + { "ab/abcdef/", 1, 2, 9 }, + { "ab/abcdefg", 1, 2, 2 }, + { "ab/abcdefg/", 1, 2, 10 }, + { "ab/abcdefgh", 1, 2, 2 }, + { "ab/abcdefgh/", 1, 2, 11 }, + + { "abc/", 1, 3, 3 }, + { "abc//", 1, 3, 4 }, + { "abc/a", 1, 3, 3 }, + { "abc/a/", 1, 3, 5 }, + { "abc/ab", 1, 3, 3 }, + { "abc/ab/", 1, 3, 6 }, + { "abc/abc", 1, 3, 3 }, + { "abc/abc/", 1, 3, 7 }, + { "abc/abcd", 1, 3, 3 }, + { "abc/abcd/", 1, 3, 8 }, + { "abc/abcde", 1, 3, 3 }, + { "abc/abcde/", 1, 3, 9 }, + { "abc/abcdef", 1, 3, 3 }, + { "abc/abcdef/", 1, 3, 10 }, + { "abc/abcdefg", 1, 3, 3 }, + { "abc/abcdefg/", 1, 3, 11 }, + { "abc/abcdefgh", 1, 3, 3 }, + { "abc/abcdefgh/", 1, 3, 12 }, + + { "abcd/", 1, 4, 4 }, + { "abcd//", 1, 4, 5 }, + { "abcd/a", 1, 4, 4 }, + { "abcd/a/", 1, 4, 6 }, + { "abcd/ab", 1, 4, 4 }, + { "abcd/ab/", 1, 4, 7 }, + { "abcd/abc", 1, 4, 4 }, + { "abcd/abc/", 1, 4, 8 }, + { "abcd/abcd", 1, 4, 4 }, + { "abcd/abcd/", 1, 4, 9 }, + { "abcd/abcde", 1, 4, 4 }, + { "abcd/abcde/", 1, 4, 10 }, + { "abcd/abcdef", 1, 4, 4 }, + { "abcd/abcdef/", 1, 4, 11 }, + { "abcd/abcdefg", 1, 4, 4 }, + { "abcd/abcdefg/", 1, 4, 12 }, + { "abcd/abcdefgh", 1, 4, 4 }, + { "abcd/abcdefgh/", 1, 4, 13 }, + + { "abcde/", 1, 5, 5 }, + { "abcde//", 1, 5, 6 }, + { "abcde/a", 1, 5, 5 }, + { "abcde/a/", 1, 5, 7 }, + { "abcde/ab", 1, 5, 5 }, + { "abcde/ab/", 1, 5, 8 }, + { "abcde/abc", 1, 5, 5 }, + { "abcde/abc/", 1, 5, 9 }, + { "abcde/abcd", 1, 5, 5 }, + { "abcde/abcd/", 1, 5, 10 }, + { "abcde/abcde", 1, 5, 5 }, + { "abcde/abcde/", 1, 5, 11 }, + { "abcde/abcdef", 1, 5, 5 }, + { "abcde/abcdef/", 1, 5, 12 }, + { "abcde/abcdefg", 1, 5, 5 }, + { "abcde/abcdefg/", 1, 5, 13 }, + { "abcde/abcdefgh", 1, 5, 5 }, + { "abcde/abcdefgh/", 1, 5, 14 }, + + { "abcdef/", 1, 6, 6 }, + { "abcdef//", 1, 6, 7 }, + { "abcdef/a", 1, 6, 6 }, + { "abcdef/a/", 1, 6, 8 }, + { "abcdef/ab", 1, 6, 6 }, + { "abcdef/ab/", 1, 6, 9 }, + { "abcdef/abc", 1, 6, 6 }, + { "abcdef/abc/", 1, 6, 10 }, + { "abcdef/abcd", 1, 6, 6 }, + { "abcdef/abcd/", 1, 6, 11 }, + { "abcdef/abcde", 1, 6, 6 }, + { "abcdef/abcde/", 1, 6, 12 }, + { "abcdef/abcdef", 1, 6, 6 }, + { "abcdef/abcdef/", 1, 6, 13 }, + { "abcdef/abcdefg", 1, 6, 6 }, + { "abcdef/abcdefg/", 1, 6, 14 }, + { "abcdef/abcdefgh", 1, 6, 6 }, + { "abcdef/abcdefgh/", 1, 6, 15 }, + + { "abcdefg/", 1, 7, 7 }, + { "abcdefg//", 1, 7, 8 }, + { "abcdefg/a", 1, 7, 7 }, + { "abcdefg/a/", 1, 7, 9 }, + { "abcdefg/ab", 1, 7, 7 }, + { "abcdefg/ab/", 1, 7, 10 }, + { "abcdefg/abc", 1, 7, 7 }, + { "abcdefg/abc/", 1, 7, 11 }, + { "abcdefg/abcd", 1, 7, 7 }, + { "abcdefg/abcd/", 1, 7, 12 }, + { "abcdefg/abcde", 1, 7, 7 }, + { "abcdefg/abcde/", 1, 7, 13 }, + { "abcdefg/abcdef", 1, 7, 7 }, + { "abcdefg/abcdef/", 1, 7, 14 }, + { "abcdefg/abcdefg", 1, 7, 7 }, + { "abcdefg/abcdefg/", 1, 7, 15 }, + { "abcdefg/abcdefgh", 1, 7, 7 }, + { "abcdefg/abcdefgh/", 1, 7, 16 }, + + { "abcdefgh/", 1, 8, 8 }, + { "abcdefgh//", 1, 8, 9 }, + { "abcdefgh/a", 1, 8, 8 }, + { "abcdefgh/a/", 1, 8, 10 }, + { "abcdefgh/ab", 1, 8, 8 }, + { "abcdefgh/ab/", 1, 8, 11 }, + { "abcdefgh/abc", 1, 8, 8 }, + { "abcdefgh/abc/", 1, 8, 12 }, + { "abcdefgh/abcd", 1, 8, 8 }, + { "abcdefgh/abcd/", 1, 8, 13 }, + { "abcdefgh/abcde", 1, 8, 8 }, + { "abcdefgh/abcde/", 1, 8, 14 }, + { "abcdefgh/abcdef", 1, 8, 8 }, + { "abcdefgh/abcdef/", 1, 8, 15 }, + { "abcdefgh/abcdefg", 1, 8, 8 }, + { "abcdefgh/abcdefg/", 1, 8, 16 }, + { "abcdefgh/abcdefgh", 1, 8, 8 }, + { "abcdefgh/abcdefgh/", 1, 8, 17 }, + }; + + for (a = 0; a < sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + strcpy(&buf[a], tab[t].val); + + off = f(&buf[a], '/'); + if (tab[t].match == 0) { + if (off != 0) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("strrchr should not have " + "found the character"); + } + } else if (tab[t].match == 1) { + if (tab[t].l_off != (off - &buf[a])) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("strrchr returns wrong " + "offset"); + } + } else { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("bad test case data"); + } + + /* check zero extension of char arg */ + off2 = f(&buf[a], 0xffffff00 | '/'); + if (off != off2) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("zero extension of char arg fails"); + } + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strrchr_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strspn.c b/contrib/netbsd-tests/lib/libc/string/t_strspn.c new file mode 100644 index 0000000..6782181 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strspn.c @@ -0,0 +1,60 @@ +/* $NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include <atf-c.h> +#include <string.h> + +ATF_TC(strspn); +ATF_TC_HEAD(strspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strspn(3)"); +} + +ATF_TC_BODY(strspn, tc) +{ + ATF_CHECK_EQ(strspn("abcdefghijklmnop", ""), 0); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "a"), 1); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "b"), 0); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "ab"), 2); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abc"), 3); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abce"), 3); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abcdefghijklmnop"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_swab.c b/contrib/netbsd-tests/lib/libc/string/t_swab.c new file mode 100644 index 0000000..797397a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_swab.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_swab.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <err.h> + +#define MAXCHK 100 + +static void +build(char *a, char *b, size_t n) { + size_t i; + + n >>= 1; + for (i = 0; i < n; i += 2) { + b[i+1] = a[i] = (char)i; + b[i] = a[i+1] = (char)(i+1); + } + for (n <<= 1; n < MAXCHK; n++) + a[n] = b[n] = (char)~0; +} + +static void +dump(const char *f, char *b, size_t l) +{ + + printf("%s ", f); + while (l--) + printf("%.2x ", (unsigned char)*b++); + printf("\n"); +} + +ATF_TC(swab_basic); +ATF_TC_HEAD(swab_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test swab results"); +} + +ATF_TC_BODY(swab_basic, tc) +{ + char a[MAXCHK], b[MAXCHK], r[MAXCHK]; + size_t i; + + for (i = 0; i < MAXCHK; i += 2) { + build(a, b, i); + (void)memset(r, ~0, MAXCHK); + swab(a, r, i); + if (memcmp(b, r, MAXCHK) != 0) { + fprintf(stderr, "pattern mismatch at %lu bytes", + (unsigned long)i); + dump("expect:", b, MAXCHK); + dump("result:", r, MAXCHK); + atf_tc_fail("Check stderr for details"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swab_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c new file mode 100644 index 0000000..0f2068a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c @@ -0,0 +1,168 @@ +/* $NetBSD: all_sync_ops_linkable.c,v 1.4 2014/02/21 10:26:25 martin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is a simple link-time test to verify all builtin atomic sync + * operations are available. Depending on the exact cpu/arch code generator + * options, some of these need support functions (which on NetBSD we + * typically provide in src/common/lib/libc/atomic). + * + * The list of operations has been extracted from sync-builtins.def file + * in the gcc distribution (as of gcc 4.8.2). + */ + +#include <machine/types.h> +#include <sys/inttypes.h> + +volatile uint8_t u8 = 0; +volatile uint16_t u16 = 0; +volatile uint32_t u32 = 0; + +#ifdef __HAVE_ATOMIC64_OPS +volatile uint64_t u64 = 0; +#endif + +int +main(int argc, char **argv) +{ + __sync_synchronize(); + __sync_add_and_fetch(&u8, 1); + __sync_add_and_fetch_1(&u8, 1); + __sync_add_and_fetch_2(&u16, 1); + __sync_add_and_fetch_4(&u32, 1); +#ifdef __HAVE_ATOMIC64_OPS + __sync_add_and_fetch_8(&u64, 1); +#endif + __sync_bool_compare_and_swap(&u8, 1, 2); + __sync_bool_compare_and_swap_1(&u8, 1, 2); + __sync_bool_compare_and_swap_2(&u16, 1, 2); + __sync_bool_compare_and_swap_4(&u32, 1, 2); +#ifdef __HAVE_ATOMIC64_OPS + __sync_bool_compare_and_swap_8(&u64, 1, 2); +#endif + __sync_fetch_and_add(&u8, 1); + __sync_fetch_and_add_1(&u8, 1); + __sync_fetch_and_add_2(&u16, 1); + __sync_fetch_and_add_4(&u32, 1); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_add_8(&u64, 1); +#endif + __sync_fetch_and_and(&u8, 0x80); + __sync_fetch_and_and_1(&u8, 0x80); + __sync_fetch_and_and_2(&u16, 0x80); + __sync_fetch_and_and_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_and_8(&u64, 0x80); +#endif +#ifndef __clang__ + __sync_fetch_and_nand(&u8, 0x80); + __sync_fetch_and_nand_1(&u8, 0x80); + __sync_fetch_and_nand_2(&u16, 0x80); + __sync_fetch_and_nand_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_nand_8(&u64, 0x80); +#endif +#endif + __sync_fetch_and_or(&u8, 0x80); + __sync_fetch_and_or_1(&u8, 0x80); + __sync_fetch_and_or_2(&u16, 0x80); + __sync_fetch_and_or_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_or_8(&u64, 0x80); +#endif + __sync_fetch_and_sub(&u8, 0x80); + __sync_fetch_and_sub_1(&u8, 0x80); + __sync_fetch_and_sub_2(&u16, 0x80); + __sync_fetch_and_sub_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_sub_8(&u64, 0x80); +#endif + __sync_fetch_and_xor(&u8, 0x80); + __sync_fetch_and_xor_1(&u8, 0x80); + __sync_fetch_and_xor_2(&u16, 0x80); + __sync_fetch_and_xor_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_xor_8(&u64, 0x80); +#endif + __sync_lock_release(&u8); + __sync_lock_release_1(&u8); + __sync_lock_release_2(&u16); + __sync_lock_release_4(&u32); +#ifdef __HAVE_ATOMIC64_OPS + __sync_lock_release_8(&u64); +#endif + __sync_lock_test_and_set(&u8, 5); + __sync_lock_test_and_set_1(&u8, 5); + __sync_lock_test_and_set_2(&u16, 5); + __sync_lock_test_and_set_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_lock_test_and_set_8(&u64, 5); +#endif +#ifndef __clang__ + __sync_nand_and_fetch(&u8, 5); + __sync_nand_and_fetch_1(&u8, 5); + __sync_nand_and_fetch_2(&u16, 5); + __sync_nand_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_nand_and_fetch_8(&u64, 5); +#endif +#endif + __sync_or_and_fetch(&u8, 5); + __sync_or_and_fetch_1(&u8, 5); + __sync_or_and_fetch_2(&u16, 5); + __sync_or_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_or_and_fetch_8(&u64, 5); +#endif + __sync_sub_and_fetch(&u8, 5); + __sync_sub_and_fetch_1(&u8, 5); + __sync_sub_and_fetch_2(&u16, 5); + __sync_sub_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_sub_and_fetch_8(&u64, 5); +#endif + __sync_val_compare_and_swap(&u8, 5, 9); + __sync_val_compare_and_swap_1(&u8, 5, 9); + __sync_val_compare_and_swap_2(&u16, 5, 9); + __sync_val_compare_and_swap_4(&u32, 5, 9); +#ifdef __HAVE_ATOMIC64_OPS + __sync_val_compare_and_swap_8(&u64, 5, 9); +#endif + __sync_xor_and_fetch(&u8, 5); + __sync_xor_and_fetch_1(&u8, 5); + __sync_xor_and_fetch_2(&u16, 5); + __sync_xor_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_xor_and_fetch_8(&u64, 5); +#endif + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_access.c b/contrib/netbsd-tests/lib/libc/sys/t_access.c new file mode 100644 index 0000000..69d2df2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c @@ -0,0 +1,219 @@ +/* $NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#ifdef __FreeBSD__ +#include <sys/param.h> +#include <sys/stat.h> +#endif + +static const char path[] = "access"; +static const int mode[4] = { R_OK, W_OK, X_OK, F_OK }; + +ATF_TC_WITH_CLEANUP(access_access); +ATF_TC_HEAD(access_access, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(access_access, tc) +{ + const int perm[3] = { 0200, 0400, 0000 }; + size_t i; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + + if (fd < 0) + return; + + for (i = 0; i < __arraycount(mode) - 1; i++) { + + ATF_REQUIRE(fchmod(fd, perm[i]) == 0); + + errno = 0; + + ATF_REQUIRE(access(path, mode[i]) != 0); + ATF_REQUIRE(errno == EACCES); + } + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(access_access, tc) +{ + (void)unlink(path); +} + +ATF_TC(access_fault); +ATF_TC_HEAD(access_fault, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT"); +} + +ATF_TC_BODY(access_fault, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access(NULL, mode[i]) != 0); + ATF_REQUIRE(errno == EFAULT); + + errno = 0; + + ATF_REQUIRE(access((char *)-1, mode[i]) != 0); + ATF_REQUIRE(errno == EFAULT); + } +} + +ATF_TC(access_inval); +ATF_TC_HEAD(access_inval, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL"); +} + +ATF_TC_BODY(access_inval, tc) +{ + +#if defined(__FreeBSD__) && __FreeBSD_version < 1100033 + atf_tc_expect_fail("arguments to access aren't validated; see " + "bug # 181155 for more details"); +#endif + errno = 0; + + ATF_REQUIRE(access("/usr", -1) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(access_notdir); +ATF_TC_HEAD(access_notdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR"); +} + +ATF_TC_BODY(access_notdir, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + /* + * IEEE Std 1003.1-2008 about ENOTDIR: + * + * "A component of the path prefix is not a directory, + * or the path argument contains at least one non-<slash> + * character and ends with one or more trailing <slash> + * characters and the last pathname component names an + * existing file that is neither a directory nor a symbolic + * link to a directory." + */ + ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0); + ATF_REQUIRE(errno == ENOTDIR); + } +} + +ATF_TC(access_notexist); +ATF_TC_HEAD(access_notexist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT"); +} + +ATF_TC_BODY(access_notexist, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access("", mode[i]) != 0); + ATF_REQUIRE(errno == ENOENT); + } +} + +ATF_TC(access_toolong); +ATF_TC_HEAD(access_toolong, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG"); +} + +ATF_TC_BODY(access_toolong, tc) +{ + char *buf; + size_t i; + + buf = malloc(PATH_MAX); + + if (buf == NULL) + return; + + for (i = 0; i < PATH_MAX; i++) + buf[i] = 'x'; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access(buf, mode[i]) != 0); + ATF_REQUIRE(errno == ENAMETOOLONG); + } + + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, access_access); + ATF_TP_ADD_TC(tp, access_fault); + ATF_TP_ADD_TC(tp, access_inval); + ATF_TP_ADD_TC(tp, access_notdir); + ATF_TP_ADD_TC(tp, access_notexist); + ATF_TP_ADD_TC(tp, access_toolong); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_chroot.c b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c new file mode 100644 index 0000000..651dc10 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c @@ -0,0 +1,321 @@ +/* $NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <pwd.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#include <sys/stat.h> +#endif + +ATF_TC(chroot_basic); +ATF_TC_HEAD(chroot_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(chroot_basic, tc) +{ + char buf[PATH_MAX]; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + (void)getcwd(buf, sizeof(buf)); + (void)strlcat(buf, "/dir", sizeof(buf)); + + ATF_REQUIRE(mkdir(buf, 0500) == 0); + ATF_REQUIRE(chdir(buf) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (chroot(buf) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (chroot("/root") != -1) + _exit(EXIT_FAILURE); + + if (errno != ENOENT) + _exit(EXIT_FAILURE); + + fd = open("file", O_RDONLY | O_CREAT, 0600); + + if (fd < 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("chroot(2) failed"); + + (void)chdir("/"); + (void)strlcat(buf, "/file", sizeof(buf)); + + fd = open(buf, O_RDONLY); + + if (fd < 0) + atf_tc_fail("chroot(2) did not change the root directory"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(buf) == 0); +} + +ATF_TC(chroot_err); +ATF_TC_HEAD(chroot_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(chroot_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, chroot(buf) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, chroot((void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, chroot("/a/b/c/d/e/f/g/h/i/j") == -1); +} + +ATF_TC(chroot_perm); +ATF_TC_HEAD(chroot_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(chroot_perm, tc) +{ + static char buf[LINE_MAX]; + pid_t pid; + int sta; + + (void)memset(buf, '\0', sizeof(buf)); + ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + + if (chroot(buf) != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("chroot(2) succeeded as unprivileged user"); +} + +#ifdef __NetBSD__ +ATF_TC(fchroot_basic); +ATF_TC_HEAD(fchroot_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_basic, tc) +{ + char buf[PATH_MAX]; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + (void)getcwd(buf, sizeof(buf)); + (void)strlcat(buf, "/dir", sizeof(buf)); + + ATF_REQUIRE(mkdir(buf, 0500) == 0); + ATF_REQUIRE(chdir(buf) == 0); + + fd = open(buf, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (fchroot(fd) != 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + fd = open("file", O_RDONLY | O_CREAT, 0600); + + if (fd < 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("fchroot(2) failed"); + + (void)chdir("/"); + (void)strlcat(buf, "/file", sizeof(buf)); + + fd = open(buf, O_RDONLY); + + if (fd < 0) + atf_tc_fail("fchroot(2) did not change the root directory"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(buf) == 0); +} + +ATF_TC(fchroot_err); +ATF_TC_HEAD(fchroot_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fchroot(-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOTDIR, fchroot(fd) == -1); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(fchroot_perm); +ATF_TC_HEAD(fchroot_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_perm, tc) +{ + static char buf[LINE_MAX]; + struct passwd *pw; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL); + + pw = getpwnam("nobody"); + fd = open(buf, O_RDONLY); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pw != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setuid(pw->pw_uid); + + errno = 0; + + if (fchroot(fd) != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("fchroot(2) succeeded as unprivileged user"); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, chroot_basic); + ATF_TP_ADD_TC(tp, chroot_err); + ATF_TP_ADD_TC(tp, chroot_perm); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, fchroot_basic); + ATF_TP_ADD_TC(tp, fchroot_err); + ATF_TP_ADD_TC(tp, fchroot_perm); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c new file mode 100644 index 0000000..229c343 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c @@ -0,0 +1,220 @@ +/* $NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Frank Kardel. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 2006 Frank Kardel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/sysctl.h> + +#ifdef __NetBSD__ +#include <machine/int_limits.h> +#endif + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#ifdef __NetBSD__ +#include "../../../h_macros.h" +#else +#include <limits.h> +#include <stdint.h> +#include "h_macros.h" +#endif + +#define MINPOSDIFF 15000000 /* 15 ms for now */ +#define TIMEOUT 5 + +#define TC_HARDWARE "kern.timecounter.hardware" +#define TC_CHOICE "kern.timecounter.choice" + +static void +check_timecounter(void) +{ + struct timespec tsa, tsb, tsl, res; + long long mindiff = INTMAX_MAX; + time_t endlimit; + +#define CL(x) \ + do { \ + if ((x) != -1) \ + break; \ + atf_tc_fail_nonfatal("%s: %s", #x, strerror(errno)); \ + return; \ + } while (0) + + CL(clock_gettime(CLOCK_REALTIME, &tsa)); + tsl = tsa; + + CL(time(&endlimit)); + endlimit += TIMEOUT + 1; + + while ((time_t)tsa.tv_sec < endlimit) { + long long diff; + + CL(clock_gettime(CLOCK_REALTIME, &tsb)); + diff = 1000000000LL * (tsb.tv_sec - tsa.tv_sec) + + tsb.tv_nsec - tsa.tv_nsec; + + if (diff > 0 && mindiff > diff) + mindiff = diff; + + if (diff < 0 || diff > MINPOSDIFF) { + long long elapsed; + (void)printf("%stime TSA: 0x%jx.%08jx, TSB: 0x%jx.%08jx, " + "diff = %lld nsec, ", (diff < 0) ? "BAD " : "", + (uintmax_t)tsa.tv_sec, (uintmax_t)tsa.tv_nsec, + (uintmax_t)tsb.tv_sec, (uintmax_t)tsb.tv_nsec, diff); + + elapsed = 1000000000LL * (tsb.tv_sec - tsl.tv_sec) + + tsb.tv_nsec - tsl.tv_nsec; + + + (void)printf("%lld nsec\n", elapsed); + tsl = tsb; + + ATF_CHECK(diff >= 0); + if (diff < 0) + return; + } + + tsa.tv_sec = tsb.tv_sec; + tsa.tv_nsec = tsb.tv_nsec; + } + + if (clock_getres(CLOCK_REALTIME, &res) == 0) { + long long r = res.tv_sec * 1000000000 + res.tv_nsec; + + (void)printf("Claimed resolution: %lld nsec (%f Hz) or " + "better\n", r, 1.0 / r * 1e9); + (void)printf("Observed minimum non zero delta: %lld " + "nsec\n", mindiff); + } + +#undef CL +} + +ATF_TC(clock_gettime_real); +ATF_TC_HEAD(clock_gettime_real, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Checks the monotonicity of the CLOCK_REALTIME implementation"); + atf_tc_set_md_var(tc, "timeout", "300"); +} + +ATF_TC_BODY(clock_gettime_real, tc) +{ + char name[128], cbuf[512], ctrbuf[10240]; + size_t cbufsiz = sizeof(cbuf); + size_t ctrbufsiz = sizeof(ctrbuf); + const char *p; + char *save; + int quality, n; + + if (sysctlbyname(TC_HARDWARE, cbuf, &cbufsiz, NULL, 0) != 0) { + (void)printf("\nChecking legacy time implementation " + "for %d seconds\n", TIMEOUT); + check_timecounter(); + return; + /* NOTREACHED */ + } + (void)printf("%s = %s\n", TC_HARDWARE, cbuf); + REQUIRE_LIBC(save = strdup(cbuf), NULL); + + RL(sysctlbyname(TC_CHOICE, ctrbuf, &ctrbufsiz, NULL, 0)); + (void)printf("%s = %s\n", TC_CHOICE, ctrbuf); + + for (p = ctrbuf, n = 0; sscanf(p, "%127[^(](q=%d, f=%*u Hz)%*[ ]%n", + name, &quality, &n) == 2; p += n) { + struct timespec ts; + int ret; + + if (quality < 0) + continue; + + (void)printf("\nChecking %s for %d seconds\n", name, TIMEOUT); + CHECK_LIBC(ret = sysctlbyname(TC_HARDWARE, NULL, 0, + name, strlen(name)), -1); + if (ret == -1) + continue; + + /* wait a bit to select new counter in clockinterrupt */ + ts.tv_sec = 0; + ts.tv_nsec = 100000000; + (void)nanosleep(&ts, NULL); + + check_timecounter(); + } + + RL(sysctlbyname(TC_HARDWARE, NULL, 0, save, strlen(save))); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clock_gettime_real); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clone.c b/contrib/netbsd-tests/lib/libc/sys/t_clone.c new file mode 100644 index 0000000..ea33f32 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clone.c @@ -0,0 +1,252 @@ +/* $NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $"); + +#include <sys/mman.h> +#include <sys/resource.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <errno.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#define STACKSIZE (8 * 1024) +#define FROBVAL 41973 +#define CHILDEXIT 0xa5 + +static int +dummy(void *arg) +{ + + return 0; +} + +static int +clone_func(void *arg) +{ + long *frobp = arg, diff; + + printf("child: stack ~= %p, frobme = %p\n", &frobp, frobp); + fflush(stdout); + + if (frobp[0] != getppid()) + return 1; + + if (frobp[0] == getpid()) + return 2; + + diff = labs(frobp[1] - (long) &frobp); + + if (diff > 1024) + return 3; + + frobp[1] = FROBVAL; + + return (CHILDEXIT); +} + +ATF_TC(clone_basic); +ATF_TC_HEAD(clone_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks clone(2)"); +} + +ATF_TC_BODY(clone_basic, tc) +{ + sigset_t mask; + void *allocstack, *stack; + pid_t pid; + volatile long frobme[2]; + int stat; + + allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANON, -1, (off_t) 0); + + ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED); + + stack = allocstack; +#ifndef __MACHINE_STACK_GROWS_UP + stack = (char *)stack + STACKSIZE; +#endif + + printf("parent: stack = %p, frobme = %p\n", stack, frobme); + fflush(stdout); + + frobme[0] = (long)getpid(); + frobme[1] = (long)stack; + + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + + ATF_REQUIRE_ERRNO(errno, sigprocmask(SIG_BLOCK, &mask, NULL) != -1); + + switch (pid = __clone(clone_func, stack, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGUSR1, + __UNVOLATILE(frobme))) { + case 0: + atf_tc_fail("clone() returned 0"); + /*NOTREACHED*/ + case -1: + atf_tc_fail("clone() failed: %s", strerror(errno)); + /*NOTREACHED*/ + default: + while (waitpid(pid, &stat, __WCLONE) != pid) + continue; + } + + ATF_REQUIRE_MSG(WIFEXITED(stat) != 0, "child didn't exit"); + + printf("parent: childexit = 0x%x, frobme = %ld\n", + WEXITSTATUS(stat), frobme[1]); + + switch (WEXITSTATUS(stat)) { + case CHILDEXIT: + ATF_REQUIRE_EQ(frobme[1], FROBVAL); + break; + case 1: + atf_tc_fail("child: argument does not contain parent's pid"); + /*NOTREACHED*/ + case 2: + atf_tc_fail("child: called in parent's pid"); + /*NOTREACHED*/ + case 3: + atf_tc_fail("child: called with bad stack"); + /*NOTREACHED*/ + default: + atf_tc_fail("child returned unknown code: %d", + WEXITSTATUS(stat)); + /*NOTREACHED*/ + } + + ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1); +} + +ATF_TC(clone_null_stack); +ATF_TC_HEAD(clone_null_stack, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when stack pointer is NULL"); +} + +ATF_TC_BODY(clone_null_stack, tc) +{ + int rv; + + rv = __clone(dummy, NULL, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EINVAL); +} + +ATF_TC(clone_null_func); +ATF_TC_HEAD(clone_null_func, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when function pointer is NULL"); +} + +ATF_TC_BODY(clone_null_func, tc) +{ + void *allocstack, *stack; + int rv; + + allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANON, -1, (off_t) 0); + ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED); + stack = allocstack; +#ifndef __MACHINE_STACK_GROWS_UP + stack = (char *)stack + STACKSIZE; +#endif + + errno = 0; + rv = __clone(0, stack, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EINVAL); + + ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1); +} + +ATF_TC(clone_out_of_proc); +ATF_TC_HEAD(clone_out_of_proc, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when running out of processes"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(clone_out_of_proc, tc) +{ + struct rlimit rl; + int rv; + + ATF_REQUIRE_ERRNO(errno, getrlimit(RLIMIT_NPROC, &rl) != -1); + + rl.rlim_cur = 0; + rl.rlim_max = 0; + + ATF_REQUIRE_ERRNO(errno, setrlimit(RLIMIT_NPROC, &rl) != -1); + + errno = 0; + rv = __clone(dummy, malloc(10240), + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, (void *)&rl); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EAGAIN); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clone_basic); + ATF_TP_ADD_TC(tp, clone_null_stack); + ATF_TP_ADD_TC(tp, clone_null_func); + ATF_TP_ADD_TC(tp, clone_out_of_proc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_connect.c b/contrib/netbsd-tests/lib/libc/sys/t_connect.c new file mode 100644 index 0000000..e492206 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_connect.c @@ -0,0 +1,103 @@ +/* $NetBSD: t_connect.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */ +/* + * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <err.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include <atf-c.h> + +#ifdef __FreeBSD__ +#include <sys/socket.h> +#endif + +ATF_TC(connect_low_port); +ATF_TC_HEAD(connect_low_port, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that low-port allocation " + "works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(connect_low_port, tc) +{ + struct sockaddr_in sin, sinlist; + int sd, val, slist; + socklen_t slen; + + slist = socket(AF_INET, SOCK_STREAM, 0); + sd = socket(AF_INET, SOCK_STREAM, 0); + + /* bind listening socket */ + memset(&sinlist, 0, sizeof(sinlist)); + sinlist.sin_family = AF_INET; + sinlist.sin_port = htons(31522); + sinlist.sin_addr.s_addr = inet_addr("127.0.0.1"); + + ATF_REQUIRE_EQ(bind(slist, + (struct sockaddr *)&sinlist, sizeof(sinlist)), 0); + ATF_REQUIRE_EQ(listen(slist, 1), 0); + + val = IP_PORTRANGE_LOW; + if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val, + sizeof(val)) == -1) + atf_tc_fail("setsockopt failed: %s", strerror(errno)); + + memset(&sin, 0, sizeof(sin)); + + sin.sin_port = htons(31522); + sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + sin.sin_family = AF_INET; + + if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + int serrno = errno; + atf_tc_fail("connect failed: %s%s", + strerror(serrno), + serrno != EACCES ? "" : + " (see http://mail-index.netbsd.org/" + "source-changes/2007/12/16/0011.html)"); + } + + slen = sizeof(sin); + ATF_REQUIRE_EQ(getsockname(sd, (struct sockaddr *)&sin, &slen), 0); + ATF_REQUIRE_EQ(slen, sizeof(sin)); + ATF_REQUIRE(ntohs(sin.sin_port) <= IPPORT_RESERVEDMAX); + + close(sd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, connect_low_port); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_dup.c b/contrib/netbsd-tests/lib/libc/sys/t_dup.c new file mode 100644 index 0000000..d8125ab --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_dup.c @@ -0,0 +1,405 @@ +/* $NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); + +#include <sys/resource.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sysexits.h> + +#ifdef __FreeBSD__ +#include <stdbool.h> +#endif + +static char path[] = "dup"; +#ifdef __NetBSD__ +static void check_mode(bool, bool, bool); +#endif + +static void +check_mode(bool _dup, bool _dup2, bool _dup3) +{ + int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR }; + int perm[5] = { 0700, 0400, 0600, 0444, 0666 }; + struct stat st, st1; + int fd, fd1, fd2; + size_t i, j; + + /* + * Check that a duplicated descriptor + * retains the mode of the original file. + */ + for (i = 0; i < __arraycount(mode); i++) { + + for (j = 0; j < __arraycount(perm); j++) { + + fd1 = open(path, mode[i] | O_CREAT, perm[j]); + fd2 = open("/etc/passwd", O_RDONLY); + + ATF_REQUIRE(fd1 >= 0); + ATF_REQUIRE(fd2 >= 0); + + if (_dup != false) + fd = dup(fd1); + else if (_dup2 != false) + fd = dup2(fd1, fd2); + else if (_dup3 != false) + fd = dup3(fd1, fd2, O_CLOEXEC); + else { + fd = -1; + } + + ATF_REQUIRE(fd >= 0); + + (void)memset(&st, 0, sizeof(struct stat)); + (void)memset(&st1, 0, sizeof(struct stat)); + + ATF_REQUIRE(fstat(fd, &st) == 0); + ATF_REQUIRE(fstat(fd1, &st1) == 0); + + if (st.st_mode != st1.st_mode) + atf_tc_fail("invalid mode"); + + (void)close(fd); + (void)close(fd1); + (void)close(fd2); + (void)unlink(path); + } + } +} + +ATF_TC(dup2_basic); +ATF_TC_HEAD(dup2_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); +} + +ATF_TC_BODY(dup2_basic, tc) +{ + int fd, fd1, fd2; + + fd1 = open("/etc/passwd", O_RDONLY); + fd2 = open("/etc/passwd", O_RDONLY); + + ATF_REQUIRE(fd1 >= 0); + ATF_REQUIRE(fd2 >= 0); + + fd = dup2(fd1, fd2); + ATF_REQUIRE(fd >= 0); + + if (fd != fd2) + atf_tc_fail("invalid descriptor"); + + (void)close(fd); + (void)close(fd1); + + ATF_REQUIRE(close(fd2) != 0); +} + +ATF_TC(dup2_err); +ATF_TC_HEAD(dup2_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)"); +} + +ATF_TC_BODY(dup2_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1); + + /* + * Note that this should not fail with EINVAL. + */ + ATF_REQUIRE(dup2(fd, fd) != -1); + + (void)close(fd); +} + +ATF_TC(dup2_max); +ATF_TC_HEAD(dup2_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup2(2) against limits"); +} + +ATF_TC_BODY(dup2_max, tc) +{ + struct rlimit res; + + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(STDERR_FILENO, res.rlim_cur + 1) == -1); +} + +ATF_TC_WITH_CLEANUP(dup2_mode); +ATF_TC_HEAD(dup2_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); +} + +ATF_TC_BODY(dup2_mode, tc) +{ + check_mode(false, true, false); +} + +ATF_TC_CLEANUP(dup2_mode, tc) +{ + (void)unlink(path); +} + + +ATF_TC(dup3_err); +ATF_TC_HEAD(dup3_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of dup3(2) (PR lib/45148)"); +} + +ATF_TC_BODY(dup3_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; +#if defined(__FreeBSD__) || defined(__linux__) + /* + * FreeBSD and linux return EINVAL, because... + * + * [EINVAL] The oldd argument is equal to the newd argument. + */ + ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) == -1); +#else + ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1); +#endif + + errno = 0; +#if defined(__FreeBSD__) || defined(__linux__) + ATF_REQUIRE_ERRNO(EINVAL, dup3(-1, -1, O_CLOEXEC) == -1); + ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1); +#else + ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1); + + (void)close(fd); +} + +ATF_TC(dup3_max); +ATF_TC_HEAD(dup3_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup3(2) against limits"); +} + +ATF_TC_BODY(dup3_max, tc) +{ + struct rlimit res; + + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(STDERR_FILENO, + res.rlim_cur + 1, O_CLOEXEC) == -1); +} + +ATF_TC_WITH_CLEANUP(dup3_mode); +ATF_TC_HEAD(dup3_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)"); +} + +ATF_TC_BODY(dup3_mode, tc) +{ + check_mode(false, false, true); +} + +ATF_TC_CLEANUP(dup3_mode, tc) +{ + (void)unlink(path); +} + +ATF_TC(dup_err); +ATF_TC_HEAD(dup_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of dup(2)"); +} + +ATF_TC_BODY(dup_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1); +} + +ATF_TC_WITH_CLEANUP(dup_max); +ATF_TC_HEAD(dup_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup(2) against limits"); +} + +ATF_TC_BODY(dup_max, tc) +{ + struct rlimit res; + int *buf, fd, sta; + size_t i, n; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Open a temporary file until the + * maximum number of open files is + * reached. Ater that dup(2) family + * should fail with EMFILE. + */ + (void)closefrom(0); + (void)memset(&res, 0, sizeof(struct rlimit)); + + n = 10; + res.rlim_cur = res.rlim_max = n; + if (setrlimit(RLIMIT_NOFILE, &res) != 0) + _exit(EX_OSERR); + + buf = calloc(n, sizeof(int)); + + if (buf == NULL) + _exit(EX_OSERR); + + buf[0] = mkstemp(path); + + if (buf[0] < 0) + _exit(EX_OSERR); + + for (i = 1; i < n; i++) { + + buf[i] = open(path, O_RDONLY); + + if (buf[i] < 0) + _exit(EX_OSERR); + } + + errno = 0; + fd = dup(buf[0]); + + if (fd != -1 || errno != EMFILE) + _exit(EX_DATAERR); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EX_OSERR) + atf_tc_fail("system call error"); + + if (WEXITSTATUS(sta) == EX_DATAERR) + atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE"); + + atf_tc_fail("unknown error"); + } + + (void)unlink(path); +} + +ATF_TC_CLEANUP(dup_max, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(dup_mode); +ATF_TC_HEAD(dup_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup(2)"); +} + +ATF_TC_BODY(dup_mode, tc) +{ + check_mode(true, false, false); +} + +ATF_TC_CLEANUP(dup_mode, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, dup2_basic); + ATF_TP_ADD_TC(tp, dup2_err); + ATF_TP_ADD_TC(tp, dup2_max); + ATF_TP_ADD_TC(tp, dup2_mode); + ATF_TP_ADD_TC(tp, dup3_err); + ATF_TP_ADD_TC(tp, dup3_max); + ATF_TP_ADD_TC(tp, dup3_mode); + ATF_TP_ADD_TC(tp, dup_err); + ATF_TP_ADD_TC(tp, dup_max); + ATF_TP_ADD_TC(tp, dup_mode); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_fsync.c b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c new file mode 100644 index 0000000..e61ea7e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $"); + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(fsync_err); +ATF_TC_HEAD(fsync_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of fsync(2) (PR kern/30)"); +} + +ATF_TC_BODY(fsync_err, tc) +{ + int i, fd[2]; + + /* + * The fsync(2) call should fail with EBADF + * when the 'fd' is not a valid descriptor. + */ + for (i = 1; i < 1024; i = i + 128) { + + errno = 0; + + ATF_REQUIRE(fsync(-i) == -1); + ATF_REQUIRE(errno == EBADF); + } + + /* + * On the other hand, EINVAL should follow + * if the operation is not possible with + * the file descriptor. + */ + ATF_REQUIRE(pipe(fd) == 0); + + errno = 0; + + ATF_REQUIRE(fsync(fd[0]) == -1); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(fsync(fd[1]) == -1); + ATF_REQUIRE(errno == EINVAL); + + ATF_REQUIRE(close(fd[0]) == 0); + ATF_REQUIRE(close(fd[1]) == 0); +} + +ATF_TC(fsync_sync); +ATF_TC_HEAD(fsync_sync, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fsync(2)"); +} + +ATF_TC_BODY(fsync_sync, tc) +{ + char buf[128]; + int fd, i; + + for (i = 0; i < 10; i++) { + + (void)snprintf(buf, sizeof(buf), "t_fsync-%d", i); + + fd = mkstemp(buf); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(write(fd, "0", 1) == 1); + ATF_REQUIRE(fsync(fd) == 0); + + ATF_REQUIRE(unlink(buf) == 0); + ATF_REQUIRE(close(fd) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fsync_err); + ATF_TP_ADD_TC(tp, fsync_sync); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c new file mode 100644 index 0000000..46c0ff1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c @@ -0,0 +1,139 @@ +/* $NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <stdarg.h> +#include <stdlib.h> +#include <ucontext.h> + +#define STACKSZ (10*1024) +#define DEPTH 3 + +static int calls; + +static void +run(int n, ...) +{ + va_list va; + int i, ia; + + ATF_REQUIRE_EQ(n, DEPTH - calls - 1); + + va_start(va, n); +#if defined(__FreeBSD__) && defined(__amd64__) + for (i = 0; i < 5; i++) { +#else + for (i = 0; i < 9; i++) { +#endif + ia = va_arg(va, int); + ATF_REQUIRE_EQ(i, ia); + } + va_end(va); + + calls++; +} + +ATF_TC(getcontext_err); +ATF_TC_HEAD(getcontext_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getcontext(2)"); +} + +ATF_TC_BODY(getcontext_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, getcontext((void *)-1) == -1); +} + +ATF_TC(setcontext_err); +ATF_TC_HEAD(setcontext_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setcontext(2)"); +} + +ATF_TC_BODY(setcontext_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, setcontext((void *)-1) == -1); +} + +ATF_TC(setcontext_link); +ATF_TC_HEAD(setcontext_link, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks get/make/setcontext(), context linking via uc_link(), " + "and argument passing to the new context"); +} + +ATF_TC_BODY(setcontext_link, tc) +{ + ucontext_t uc[DEPTH]; + ucontext_t save; + volatile int i = 0; /* avoid longjmp clobbering */ + + for (i = 0; i < DEPTH; ++i) { + ATF_REQUIRE_EQ(getcontext(&uc[i]), 0); + + uc[i].uc_stack.ss_sp = malloc(STACKSZ); + uc[i].uc_stack.ss_size = STACKSZ; + uc[i].uc_link = (i > 0) ? &uc[i - 1] : &save; + +#if defined(__FreeBSD__) && defined(__amd64__) + /* FreeBSD/amd64 only permits up to 6 arguments. */ + makecontext(&uc[i], (void *)run, 6, i, + 0, 1, 2, 3, 4); +#else + makecontext(&uc[i], (void *)run, 10, i, + 0, 1, 2, 3, 4, 5, 6, 7, 8); +#endif + } + + ATF_REQUIRE_EQ(getcontext(&save), 0); + + if (calls == 0) + ATF_REQUIRE_EQ(setcontext(&uc[DEPTH-1]), 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getcontext_err); + ATF_TP_ADD_TC(tp, setcontext_err); + ATF_TP_ADD_TC(tp, setcontext_link); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c new file mode 100644 index 0000000..7dedca4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(getgroups_err); +ATF_TC_HEAD(getgroups_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in getgroups(2)"); +} + +ATF_TC_BODY(getgroups_err, tc) +{ + gid_t gidset[NGROUPS_MAX]; + + errno = 0; + + ATF_REQUIRE(getgroups(10, (gid_t *)-1) == -1); + ATF_REQUIRE(errno == EFAULT); + + errno = 0; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("Reported as kern/189941"); +#endif + ATF_REQUIRE(getgroups(-1, gidset) == -1); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(getgroups_getgid); +ATF_TC_HEAD(getgroups_getgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getgid(2) from getgroups(2)"); +} + +ATF_TC_BODY(getgroups_getgid, tc) +{ + gid_t gidset[NGROUPS_MAX]; + gid_t gid = getgid(); + int i, n; + + /* + * Check that getgid(2) is found from + * the GIDs returned by getgroups(2). + */ + n = getgroups(NGROUPS_MAX, gidset); + + for (i = 0; i < n; i++) { + + if (gidset[i] == gid) + return; + } + + atf_tc_fail("getgid(2) not found from getgroups(2)"); +} + +ATF_TC(getgroups_setgid); +ATF_TC_HEAD(getgroups_setgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setgid(2) from getgroups(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(getgroups_setgid, tc) +{ + gid_t gidset[NGROUPS_MAX]; + int i, n, rv, sta; + pid_t pid; + + /* + * Check that we can setgid(2) + * to the returned group IDs. + */ + n = getgroups(NGROUPS_MAX, gidset); + ATF_REQUIRE(n >= 0); + + for (i = 0; i < n; i++) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = setgid(gidset[i]); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("getgroups(2) is inconsistent"); + } +} + +ATF_TC(getgroups_zero); +ATF_TC_HEAD(getgroups_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getgroups(2) with zero param"); +} + +ATF_TC_BODY(getgroups_zero, tc) +{ + const gid_t val = 123456789; + gid_t gidset[NGROUPS_MAX]; + size_t i; + + /* + * If the first parameter is zero, the number + * of groups should be returned but the supplied + * buffer should remain intact. + */ + for (i = 0; i < __arraycount(gidset); i++) + gidset[i] = val; + + ATF_REQUIRE(getgroups(0, gidset) >= 0); + + for (i = 0; i < __arraycount(gidset); i++) { + + if (gidset[i] != val) + atf_tc_fail("getgroups(2) modified the buffer"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgroups_err); + ATF_TP_ADD_TC(tp, getgroups_getgid); + ATF_TP_ADD_TC(tp, getgroups_setgid); + ATF_TP_ADD_TC(tp, getgroups_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c new file mode 100644 index 0000000..0e4e7b6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c @@ -0,0 +1,216 @@ +/* $NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $"); + +#include <sys/time.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +static bool fail; +static void sighandler(int); + +static void +sighandler(int signo) +{ + + if (signo == SIGALRM || signo == SIGVTALRM) + fail = false; +} + +ATF_TC(getitimer_empty); +ATF_TC_HEAD(getitimer_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "getitimer(2) before setitimer(2)"); +} + +ATF_TC_BODY(getitimer_empty, tc) +{ + struct itimerval it; + + /* + * Verify that the passed structure remains + * empty after calling getitimer(2) but before + * actually arming the timer with setitimer(2). + */ + (void)memset(&it, 0, sizeof(struct itimerval)); + + ATF_REQUIRE(getitimer(ITIMER_REAL, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + ATF_REQUIRE(getitimer(ITIMER_VIRTUAL, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + ATF_REQUIRE(getitimer(ITIMER_PROF, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + return; + +fail: + atf_tc_fail("getitimer(2) modfied the timer before it was armed"); +} + +ATF_TC(getitimer_err); +ATF_TC_HEAD(getitimer_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getitimer(2)"); +} + +ATF_TC_BODY(getitimer_err, tc) +{ + struct itimerval it; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, getitimer(-1, &it) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, getitimer(INT_MAX, &it) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, getitimer(ITIMER_REAL, (void *)-1) == -1); +} + +ATF_TC(setitimer_basic); +ATF_TC_HEAD(setitimer_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setitimer(2)"); +} + +ATF_TC_BODY(setitimer_basic, tc) +{ + struct itimerval it; + + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 100; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + fail = true; + + ATF_REQUIRE(signal(SIGALRM, sighandler) != SIG_ERR); + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0); + + /* + * Although the interaction between + * setitimer(2) and sleep(3) can be + * unspecified, it is assumed that one + * second suspension will be enough for + * the timer to fire. + */ + (void)sleep(1); + + if (fail != false) + atf_tc_fail("timer did not fire"); +} + +ATF_TC(setitimer_err); +ATF_TC_HEAD(setitimer_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setitimer(2)" + " (PR standards/44927)"); +} + +ATF_TC_BODY(setitimer_err, tc) +{ + struct itimerval it, ot; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, setitimer(-1, &it, &ot) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, setitimer(INT_MAX, &it, &ot) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, setitimer(ITIMER_REAL,(void*)-1, &ot) == -1); +} + +ATF_TC(setitimer_old); +ATF_TC_HEAD(setitimer_old, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test old values from setitimer(2)"); +} + +ATF_TC_BODY(setitimer_old, tc) +{ + struct itimerval it, ot; + + /* + * Make two calls; the second one + * should store the old values. + */ + it.it_value.tv_sec = 4; + it.it_value.tv_usec = 3; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0); + + it.it_value.tv_sec = 2; + it.it_value.tv_usec = 1; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0); + +#ifdef __FreeBSD__ + if (ot.it_value.tv_sec == 4 && ot.it_value.tv_usec == 3) + atf_tc_fail("setitimer(2) did not return remaining time"); +#else + if (ot.it_value.tv_sec != 4 || ot.it_value.tv_usec != 3) + atf_tc_fail("setitimer(2) did not store old values"); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getitimer_empty); + ATF_TP_ADD_TC(tp, getitimer_err); + ATF_TP_ADD_TC(tp, setitimer_basic); + ATF_TP_ADD_TC(tp, setitimer_err); + ATF_TP_ADD_TC(tp, setitimer_old); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c new file mode 100644 index 0000000..8c2b199 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c @@ -0,0 +1,237 @@ +/* $NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(getlogin_r_err); +ATF_TC_HEAD(getlogin_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getlogin_r(2)"); +} + +ATF_TC_BODY(getlogin_r_err, tc) +{ + char small[0]; + + ATF_REQUIRE(getlogin_r(small, sizeof(small)) == ERANGE); +} + +ATF_TC(getlogin_same); +ATF_TC_HEAD(getlogin_same, tc) +{ + atf_tc_set_md_var(tc, "descr", "getlogin(2) vs. getlogin_r(2)"); +} + +ATF_TC_BODY(getlogin_same, tc) +{ + char buf[MAXLOGNAME]; + char *str; + + str = getlogin(); + + if (str == NULL) + return; + + ATF_REQUIRE(getlogin_r(buf, sizeof(buf)) == 0); + + if (strcmp(str, buf) != 0) + atf_tc_fail("getlogin(2) and getlogin_r(2) differ"); +} + +ATF_TC(setlogin_basic); +ATF_TC_HEAD(setlogin_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that setlogin(2) works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setlogin_basic, tc) +{ + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setsid(); + + if (setlogin("foobar") != 0) + _exit(EXIT_FAILURE); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("setlogin(2) failed to set login name"); +} + +ATF_TC(setlogin_err); +ATF_TC_HEAD(setlogin_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setlogin(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setlogin_err, tc) +{ + char buf[MAXLOGNAME + 1]; + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + + if (pid == 0) { + + (void)setsid(); + + errno = 0; + + if (setlogin(buf) != -1) + _exit(EINVAL); + + if (errno != EINVAL) + _exit(EINVAL); + + errno = 0; + + if (setlogin((void *)-1) != -1) + _exit(EFAULT); + + if (errno != EFAULT) + _exit(EFAULT); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EFAULT) + atf_tc_fail("expected EFAULT, but the call succeeded"); + + if (WEXITSTATUS(sta) == EINVAL) + atf_tc_fail("expected EINVAL, but the call succeeded"); + + atf_tc_fail("setlogin(2) failed, but login name was set"); + } +} + +ATF_TC(setlogin_perm); +ATF_TC_HEAD(setlogin_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setlogin(2) as normal user"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setlogin_perm, tc) +{ + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setsid(); + + errno = 0; + + if (setlogin("foobar") != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("login name was set as an unprivileged user"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getlogin_r_err); + ATF_TP_ADD_TC(tp, getlogin_same); + ATF_TP_ADD_TC(tp, setlogin_basic); + ATF_TP_ADD_TC(tp, setlogin_err); + ATF_TP_ADD_TC(tp, setlogin_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getpid.c b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c new file mode 100644 index 0000000..b3ed393 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c @@ -0,0 +1,134 @@ +/* $NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <stdlib.h> +#include <pthread.h> +#include <unistd.h> + +#include <atf-c.h> + +static int maxiter = 10; +static void *threadfunc(void *); + +static void * +threadfunc(void *arg) +{ + *(pid_t *)arg = getpid(); + + return NULL; +} + +ATF_TC(getpid_process); +ATF_TC_HEAD(getpid_process, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getpid(2) with processes"); +} + +ATF_TC_BODY(getpid_process, tc) +{ + pid_t ppid, fpid, cpid, tpid, wpid; + int i, sta; + + for (i = 0; i < maxiter; i++) { + + tpid = getpid(); + fpid = fork(); + + ATF_REQUIRE(fpid >= 0); + + if (fpid == 0) { + + cpid = getpid(); + ppid = getppid(); + + if (tpid != ppid) + _exit(EXIT_FAILURE); + + if (cpid == ppid) + _exit(EXIT_FAILURE); + + if (tpid == fpid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + wpid = wait(&sta); + + if (wpid != fpid) + atf_tc_fail("PID mismatch"); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + + if (WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("PID mismatch"); + } +} + +ATF_TC(getpid_thread); +ATF_TC_HEAD(getpid_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getpid(2) with threads"); +} + +ATF_TC_BODY(getpid_thread, tc) +{ + pid_t pid, tpid; + pthread_t tid; + int i, rv; + + for (i = 0; i < maxiter; i++) { + + pid = getpid(); + + rv = pthread_create(&tid, NULL, threadfunc, &tpid); + ATF_REQUIRE(rv == 0); + + rv = pthread_join(tid, NULL); + ATF_REQUIRE(rv == 0); + + if (pid != tpid) + atf_tc_fail("Unequal PIDs"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getpid_process); + ATF_TP_ADD_TC(tp, getpid_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c new file mode 100644 index 0000000..85eeac6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c @@ -0,0 +1,210 @@ +/* $NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $"); + +#include <sys/resource.h> +#include <sys/time.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <stdint.h> +#include <string.h> + +static void work(void); +static void sighandler(int); + +static const size_t maxiter = 2000; + +static void +#ifdef __FreeBSD__ +sighandler(int signo __unused) +#else +sighandler(int signo) +#endif +{ + /* Nothing. */ +} + +static void +work(void) +{ + size_t n = UINT16_MAX * 10; + + while (n > 0) { +#ifdef __or1k__ + asm volatile("l.nop"); /* Do something. */ +#else + asm volatile("nop"); /* Do something. */ +#endif + n--; + } +} + +ATF_TC(getrusage_err); +ATF_TC_HEAD(getrusage_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions"); +} + +ATF_TC_BODY(getrusage_err, tc) +{ + struct rusage ru; + + errno = 0; + + ATF_REQUIRE(getrusage(INT_MAX, &ru) != 0); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(getrusage(RUSAGE_SELF, (void *)0) != 0); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TC(getrusage_sig); +ATF_TC_HEAD(getrusage_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test signal count with getrusage(2)"); +} + +ATF_TC_BODY(getrusage_sig, tc) +{ + struct rusage ru; + const long n = 5; + int i; + + /* + * Test that signals are recorded. + */ + ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR); + + for (i = 0; i < n; i++) + ATF_REQUIRE(raise(SIGUSR1) == 0); + + (void)memset(&ru, 0, sizeof(struct rusage)); + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); + + if (n != ru.ru_nsignals) + atf_tc_fail("getrusage(2) did not record signals"); +} + +ATF_TC(getrusage_utime_back); +ATF_TC_HEAD(getrusage_utime_back, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bogus values from getrusage(2)"); +} + +ATF_TC_BODY(getrusage_utime_back, tc) +{ + struct rusage ru1, ru2; + size_t i; + + /* + * Test that two consecutive calls are sane. + */ +#ifdef __NetBSD__ + atf_tc_expect_fail("PR kern/30115"); +#endif + + for (i = 0; i < maxiter; i++) { + + (void)memset(&ru1, 0, sizeof(struct rusage)); + (void)memset(&ru2, 0, sizeof(struct rusage)); + + work(); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru1) == 0); + + work(); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru2) == 0); + + if (timercmp(&ru2.ru_utime, &ru1.ru_utime, <) != 0) + atf_tc_fail("user time went backwards"); + } + +#ifdef __NetBSD__ + atf_tc_fail("anticipated error did not occur"); +#endif +} + +ATF_TC(getrusage_utime_zero); +ATF_TC_HEAD(getrusage_utime_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test zero utime from getrusage(2)"); +} + +ATF_TC_BODY(getrusage_utime_zero, tc) +{ + struct rusage ru; + size_t i; + +#ifdef __FreeBSD__ + atf_tc_skip("this testcase passes/fails sporadically on FreeBSD/i386 " + "@ r273153 (at least)"); +#endif + + /* + * Test that getrusage(2) does not return + * zero user time for the calling process. + * + * See also (duplicate) PR port-amd64/41734. + */ + atf_tc_expect_fail("PR kern/30115"); + + for (i = 0; i < maxiter; i++) { + + work(); + + (void)memset(&ru, 0, sizeof(struct rusage)); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); + + if (ru.ru_utime.tv_sec == 0 && ru.ru_utime.tv_usec == 0) + atf_tc_fail("zero user time from getrusage(2)"); + } + + atf_tc_fail("anticipated error did not occur"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getrusage_err); + ATF_TP_ADD_TC(tp, getrusage_sig); + ATF_TP_ADD_TC(tp, getrusage_utime_back); + ATF_TP_ADD_TC(tp, getrusage_utime_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getsid.c b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c new file mode 100644 index 0000000..76b54ab --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c @@ -0,0 +1,119 @@ +/* $NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(getsid_current); +ATF_TC_HEAD(getsid_current, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getsid(0)"); +} + +ATF_TC_BODY(getsid_current, tc) +{ + pid_t sid; + + sid = getsid(0); + ATF_REQUIRE(sid != -1); + + if (sid != getsid(getpid())) + atf_tc_fail("getsid(0) did not match the calling process"); +} + +ATF_TC(getsid_err); +ATF_TC_HEAD(getsid_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in getsid(2)"); +} + +ATF_TC_BODY(getsid_err, tc) +{ + + errno = 0; + + ATF_REQUIRE(getsid(-1) == -1); + ATF_REQUIRE(errno == ESRCH); +} + +ATF_TC(getsid_process); +ATF_TC_HEAD(getsid_process, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getsid(2) with processes"); +} + +ATF_TC_BODY(getsid_process, tc) +{ + pid_t csid, pid, ppid, sid; + int sta; + + sid = getsid(0); + pid = fork(); + + ATF_REQUIRE(pid >= 0); + ATF_REQUIRE(sid != -1); + + if (pid == 0) { + + csid = getsid(0); + ppid = getppid(); + + if (sid != csid) + _exit(EXIT_FAILURE); + + if (getsid(ppid) != csid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("invalid session ID"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getsid_current); + ATF_TP_ADD_TC(tp, getsid_err); + ATF_TP_ADD_TC(tp, getsid_process); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c new file mode 100644 index 0000000..1cf303b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c @@ -0,0 +1,86 @@ +/* $NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/time.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> + +ATF_TC(gettimeofday_err); +ATF_TC_HEAD(gettimeofday_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from gettimeofday(2)"); +} + +ATF_TC_BODY(gettimeofday_err, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, gettimeofday((void *)-1, NULL) != 0); +} + +ATF_TC(gettimeofday_mono); +ATF_TC_HEAD(gettimeofday_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test monotonicity of gettimeofday(2)"); +} + +ATF_TC_BODY(gettimeofday_mono, tc) +{ + static const size_t maxiter = 100; + struct timeval tv1, tv2; + size_t i; + + for (i = 0; i < maxiter; i++) { + + (void)memset(&tv1, 0, sizeof(struct timeval)); + (void)memset(&tv2, 0, sizeof(struct timeval)); + + ATF_REQUIRE(gettimeofday(&tv1, NULL) == 0); + ATF_REQUIRE(gettimeofday(&tv2, NULL) == 0); + + if (timercmp(&tv2, &tv1, <) != 0) + atf_tc_fail("time went backwards"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, gettimeofday_err); + ATF_TP_ADD_TC(tp, gettimeofday_mono); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c new file mode 100644 index 0000000..b76ba39 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdlib.h> +#include <unistd.h> + +static bool check(int (*fuid)(uid_t), int (*fgid)(gid_t)); + +static bool +check(int (*fuid)(uid_t), int (*fgid)(gid_t)) +{ + struct passwd *pw; + pid_t pid; + int sta; + + pw = getpwnam("nobody"); + + if (pw == NULL) + return false; + + pid = fork(); + + if (pid < 0) + return false; + + if (pid == 0) { + + if (fuid != NULL && (*fuid)(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + if (fgid != NULL && (*fgid)(pw->pw_gid) != 0) + _exit(EXIT_FAILURE); + + if (issetugid() != 1) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + return false; + + return true; +} + +ATF_TC(issetugid_egid); +ATF_TC_HEAD(issetugid_egid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. GID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_egid, tc) +{ + + if (check(NULL, setegid) != true) + atf_tc_fail("issetugid(2) failed with effective GID"); +} + +ATF_TC(issetugid_euid); +ATF_TC_HEAD(issetugid_euid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. UID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_euid, tc) +{ + + if (check(seteuid, NULL) != true) + atf_tc_fail("issetugid(2) failed with effective UID"); +} + +ATF_TC(issetugid_rgid); +ATF_TC_HEAD(issetugid_rgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real GID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_rgid, tc) +{ + + if (check(NULL, setgid) != true) + atf_tc_fail("issetugid(2) failed with real GID"); +} + +ATF_TC(issetugid_ruid); +ATF_TC_HEAD(issetugid_ruid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real UID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_ruid, tc) +{ + + if (check(setuid, NULL) != true) + atf_tc_fail("issetugid(2) failed with real UID"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, issetugid_egid); + ATF_TP_ADD_TC(tp, issetugid_euid); + ATF_TP_ADD_TC(tp, issetugid_rgid); + ATF_TP_ADD_TC(tp, issetugid_ruid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c new file mode 100644 index 0000000..fe298c5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c @@ -0,0 +1,206 @@ +/* $NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundatiom + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $"); + +#include <sys/types.h> +#include <sys/event.h> + +#include <atf-c.h> +#include <errno.h> +#include <time.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <err.h> +#ifdef __NetBSD__ +#include <sys/drvctlio.h> +#endif +#include <sys/event.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/wait.h> + +#ifdef __FreeBSD__ +#define DRVCTLDEV "/nonexistent" +#endif + +ATF_TC(kevent_zerotimer); +ATF_TC_HEAD(kevent_zerotimer, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that kevent with a 0 timer " + "does not crash the system (PR lib/45618)"); +} + +ATF_TC_BODY(kevent_zerotimer, tc) +{ + struct kevent ev; + int kq; + + ATF_REQUIRE((kq = kqueue()) != -1); + EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0); + ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, &ev, 1, NULL) == 1); +} + +ATF_TC(kqueue_desc_passing); +ATF_TC_HEAD(kqueue_desc_passing, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that passing a kqueue to " + "another process does not crash the kernel (PR 46463)"); +} + +ATF_TC_BODY(kqueue_desc_passing, tc) +{ + pid_t child; + int s[2], storage, status, kq; + struct cmsghdr *msg; + struct iovec iov; + struct msghdr m; + struct kevent ev; + + ATF_REQUIRE((kq = kqueue()) != -1); + + // atf_tc_skip("crashes kernel (PR 46463)"); + + ATF_REQUIRE(socketpair(AF_LOCAL, SOCK_STREAM, 0, s) != -1); + msg = malloc(CMSG_SPACE(sizeof(int))); + m.msg_iov = &iov; + m.msg_iovlen = 1; + m.msg_name = NULL; + m.msg_namelen = 0; + m.msg_control = msg; + m.msg_controllen = CMSG_SPACE(sizeof(int)); + + child = fork(); + if (child == 0) { + close(s[0]); + + iov.iov_base = &storage; + iov.iov_len = sizeof(int); + m.msg_iov = &iov; + m.msg_iovlen = 1; + + if (recvmsg(s[1], &m, 0) == -1) + err(1, "child: could not recvmsg"); + +#ifdef __FreeBSD__ + bcopy(CMSG_DATA(msg), &kq, sizeof(kq)); + printf("child (pid %d): received kq fd %d\n", getpid(), kq); + _exit(0); +#else + kq = *(int *)CMSG_DATA(msg); + printf("child (pid %d): received kq fd %d\n", getpid(), kq); + exit(0); +#endif + } + + close(s[1]); + + iov.iov_base = &storage; + iov.iov_len = sizeof(int); + + msg->cmsg_level = SOL_SOCKET; + msg->cmsg_type = SCM_RIGHTS; + msg->cmsg_len = CMSG_LEN(sizeof(int)); + +#ifdef __FreeBSD__ + /* + * What is should have been + * bcopy(&s[0], CMSG_DATA(msg), sizeof(kq)); + */ + bcopy(&kq, CMSG_DATA(msg), sizeof(kq)); +#else + *(int *)CMSG_DATA(msg) = kq; +#endif + + EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0); + ATF_CHECK(kevent(kq, &ev, 1, NULL, 0, NULL) != -1); + + printf("parent (pid %d): sending kq fd %d\n", getpid(), kq); + if (sendmsg(s[0], &m, 0) == -1) { +#ifdef __NetBSD__ + ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno); + atf_tc_skip("PR kern/46523"); +#endif +#ifdef __FreeBSD__ + ATF_REQUIRE_EQ_MSG(errno, EOPNOTSUPP, "errno is %d", errno); + close(s[0]); +#endif + } + + close(kq); + + waitpid(child, &status, 0); + ATF_CHECK(WIFEXITED(status) && WEXITSTATUS(status)==0); +} + +ATF_TC(kqueue_unsupported_fd); +ATF_TC_HEAD(kqueue_unsupported_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that watching an fd whose" + " type is not supported does not crash the kernel"); +} + +ATF_TC_BODY(kqueue_unsupported_fd, tc) +{ + /* mqueue and semaphore use fnullop_kqueue also */ + int fd, kq; + struct kevent ev; + + fd = open(DRVCTLDEV, O_RDONLY); + if (fd == -1 && errno == ENOENT) + atf_tc_skip("no " DRVCTLDEV " available for testing"); + ATF_REQUIRE(fd != -1); + ATF_REQUIRE((kq = kqueue()) != -1); + + EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK| + NOTE_RENAME|NOTE_REVOKE, 0, 0); + + ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == -1); + ATF_REQUIRE_ERRNO(EOPNOTSUPP, true); + + (void)close(fd); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, kevent_zerotimer); + ATF_TP_ADD_TC(tp, kqueue_desc_passing); + ATF_TP_ADD_TC(tp, kqueue_unsupported_fd); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kill.c b/contrib/netbsd-tests/lib/libc/sys/t_kill.c new file mode 100644 index 0000000..2f42862 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_kill.c @@ -0,0 +1,312 @@ +/* $NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include <sys/wait.h> + +#include <errno.h> +#include <limits.h> +#include <pwd.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(kill_basic); +ATF_TC_HEAD(kill_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that kill(2) works"); +} + +ATF_TC_BODY(kill_basic, tc) +{ + const int sig[] = { SIGHUP, SIGINT, SIGKILL, SIGTERM }; + pid_t pid; + size_t i; + int sta; + + for (i = 0; i < __arraycount(sig); i++) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + switch (pid) { + + case 0: + pause(); + break; + + default: + ATF_REQUIRE(kill(pid, sig[i]) == 0); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != sig[i]) + atf_tc_fail("kill(2) failed to kill child"); + } +} + +ATF_TC(kill_err); +ATF_TC_HEAD(kill_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of kill(2)"); +} + +ATF_TC_BODY(kill_err, tc) +{ + int rv, sta; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + rv = kill(getpid(), -1); + + if (rv == 0 || errno != EINVAL) + _exit(EINVAL); + + errno = 0; + rv = kill(INT_MAX, SIGUSR1); + + if (rv == 0 || errno != ESRCH) + _exit(ESRCH); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EINVAL) + atf_tc_fail("expected EINVAL, but kill(2) succeeded"); + + if (WEXITSTATUS(sta) == ESRCH) + atf_tc_fail("expected ESRCH, but kill(2) succeeded"); + + atf_tc_fail("unknown error from kill(2)"); + } +} + +ATF_TC(kill_perm); +ATF_TC_HEAD(kill_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) permissions"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(kill_perm, tc) +{ + struct passwd *pw; + pid_t cpid, ppid; + uid_t cuid = 0; + uid_t puid = 0; + int sta; + + /* + * Test that kill(2) fails when called + * for a PID owned by another user. + */ + pw = getpwnam("operator"); + + if (pw != NULL) + cuid = pw->pw_uid; + + pw = getpwnam("nobody"); + + if (pw != NULL) + puid = pw->pw_uid; + + if (cuid == 0 || puid == 0 || cuid == puid) + atf_tc_fail("getpwnam(3) failed"); + + ppid = fork(); + + if (ppid < 0) + _exit(EXIT_FAILURE); + + if (ppid == 0) { + + cpid = fork(); + + if (cpid < 0) + _exit(EXIT_FAILURE); + + if (cpid == 0) { + + if (setuid(cuid) < 0) + _exit(EXIT_FAILURE); + else { + (void)sleep(1); + } + + _exit(EXIT_SUCCESS); + } + + /* + * Try to kill the child after having + * set the real and effective UID. + */ + if (setuid(puid) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (kill(cpid, SIGKILL) == 0) + _exit(EPERM); + + if (errno != EPERM) + _exit(EPERM); + + (void)waitpid(cpid, &sta, 0); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) == EPERM) + atf_tc_fail("killed a process of another user"); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("unknown error from kill(2)"); +} + +ATF_TC(kill_pgrp_neg); +ATF_TC_HEAD(kill_pgrp_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #2"); +} + +ATF_TC_BODY(kill_pgrp_neg, tc) +{ + const int maxiter = 3; + pid_t cpid, ppid; + int i, sta; + + ppid = fork(); + ATF_REQUIRE(ppid >= 0); + + if (ppid == 0) { + + ATF_REQUIRE(setpgid(0, 0) == 0); + + for (i = 0; i < maxiter; i++) { + + cpid = fork(); + ATF_REQUIRE(cpid >= 0); + + if (cpid == 0) + pause(); + } + + /* + * Test the variant of killpg(3); if the process number + * is negative but not -1, the signal should be sent to + * all processes whose process group ID is equal to the + * absolute value of the process number. + */ + ATF_REQUIRE(kill(-getpgrp(), SIGKILL) == 0); + + (void)sleep(1); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("failed to kill(2) a process group"); +} + +ATF_TC(kill_pgrp_zero); +ATF_TC_HEAD(kill_pgrp_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #1"); +} + +ATF_TC_BODY(kill_pgrp_zero, tc) +{ + const int maxiter = 3; + pid_t cpid, ppid; + int i, sta; + + ppid = fork(); + ATF_REQUIRE(ppid >= 0); + + if (ppid == 0) { + + ATF_REQUIRE(setpgid(0, 0) == 0); + + for (i = 0; i < maxiter; i++) { + + cpid = fork(); + ATF_REQUIRE(cpid >= 0); + + if (cpid == 0) + pause(); + } + + /* + * If the supplied process number is zero, + * the signal should be sent to all processes + * under the current process group. + */ + ATF_REQUIRE(kill(0, SIGKILL) == 0); + + (void)sleep(1); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("failed to kill(2) a process group"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, kill_basic); + ATF_TP_ADD_TC(tp, kill_err); + ATF_TP_ADD_TC(tp, kill_perm); + ATF_TP_ADD_TC(tp, kill_pgrp_neg); + ATF_TP_ADD_TC(tp, kill_pgrp_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_link.c b/contrib/netbsd-tests/lib/libc/sys/t_link.c new file mode 100644 index 0000000..b8dcacc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_link.c @@ -0,0 +1,233 @@ +/* $NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $"); + +#include <sys/param.h> +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#include <limits.h> +#endif + +static const char *getpath(void); +static char path[] = "link"; +static const char *pathl; + +static const char * +getpath(void) +{ + static char buf[LINE_MAX]; + + (void)memset(buf, '\0', sizeof(buf)); + + if (getcwd(buf, sizeof(buf)) == NULL) + return NULL; + + (void)strlcat(buf, path, sizeof(buf)); + (void)strlcat(buf, ".link", sizeof(buf)); + + return buf; +} + +ATF_TC_WITH_CLEANUP(link_count); +ATF_TC_HEAD(link_count, tc) +{ + atf_tc_set_md_var(tc, "descr", "link(2) counts are incremented?"); +} + +ATF_TC_BODY(link_count, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (sa.st_nlink != sb.st_nlink - 1) + atf_tc_fail("incorrect link(2) count"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_count, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TC_WITH_CLEANUP(link_err); +ATF_TC_HEAD(link_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of link(2)"); +} + +ATF_TC_BODY(link_err, tc) +{ + char buf[MAXPATHLEN + 1]; + int fd; + + (void)memset(buf, 'x', sizeof(buf)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + errno = 0; + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE_ERRNO(EEXIST, link(path, pathl) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, link(buf, "xxx") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link(path, "/d/c/b/a") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", path) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", "/d/c/b/a") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, link(path, (const char *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, link((const char *)-1, "xxx") == -1); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_err, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TC(link_perm); +ATF_TC_HEAD(link_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with link(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(link_perm, tc) +{ + int rv; + + errno = 0; + rv = link("/root", "/root.link"); + ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM), + "link to a directory did not fail with EPERM or EACCESS; link() " + "returned %d, errno %d", rv, errno); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, + link("/root/.profile", "/root/.profile.link") == -1); +} + +ATF_TC_WITH_CLEANUP(link_stat); +ATF_TC_HEAD(link_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check stat(2) of a linked file"); +} + +ATF_TC_BODY(link_stat, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(lstat(pathl, &sb) == 0); + + if (sa.st_uid != sb.st_uid) + atf_tc_fail("unequal UIDs"); + + if (sa.st_mode != sb.st_mode) + atf_tc_fail("unequal modes"); + + if (sa.st_ino != sb.st_ino) + atf_tc_fail("unequal inodes"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_stat, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, link_count); + ATF_TP_ADD_TC(tp, link_err); + ATF_TP_ADD_TC(tp, link_perm); + ATF_TP_ADD_TC(tp, link_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_listen.c b/contrib/netbsd-tests/lib/libc/sys/t_listen.c new file mode 100644 index 0000000..d7c7d9e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_listen.c @@ -0,0 +1,138 @@ +/* $NetBSD: t_listen.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */ +/* + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#ifdef __FreeBSD__ +#include <sys/socket.h> +#endif + +static const char *path = "listen"; + +ATF_TC_WITH_CLEANUP(listen_err); +ATF_TC_HEAD(listen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks errors from listen(2) (PR standards/46150)"); +} + +ATF_TC_BODY(listen_err, tc) +{ + static const size_t siz = sizeof(struct sockaddr_in); + struct sockaddr_in sina, sinb; + int fda, fdb, fdc; + + (void)memset(&sina, 0, sizeof(struct sockaddr_in)); + (void)memset(&sinb, 0, sizeof(struct sockaddr_in)); + + sina.sin_family = AF_INET; + sina.sin_port = htons(31522); + sina.sin_addr.s_addr = inet_addr("127.0.0.1"); + + sinb.sin_family = AF_INET; + sinb.sin_port = htons(31522); + sinb.sin_addr.s_addr = inet_addr("127.0.0.1"); + + fda = socket(AF_INET, SOCK_STREAM, 0); + fdb = socket(AF_INET, SOCK_STREAM, 0); + fdc = open("listen", O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fda >= 0 && fdb >= 0 && fdc >= 0); + ATF_REQUIRE_ERRNO(ENOTSOCK, listen(fdc, 1) == -1); + + (void)close(fdc); + (void)unlink(path); + + ATF_REQUIRE(bind(fda, (struct sockaddr *)&sina, siz) == 0); + ATF_REQUIRE(listen(fda, 1) == 0); + + /* + * According to IEEE Std 1003.1-2008: if the socket is + * already connected, the call should fail with EINVAL. + */ + ATF_REQUIRE(connect(fdb, (struct sockaddr *)&sinb, siz) == 0); + ATF_REQUIRE_ERRNO(EINVAL, listen(fdb, 1) == -1); + + (void)close(fda); + (void)close(fdb); + + ATF_REQUIRE_ERRNO(EBADF, connect(fdb, + (struct sockaddr *)&sinb, siz) == -1); +} + +ATF_TC_CLEANUP(listen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC(listen_low_port); +ATF_TC_HEAD(listen_low_port, tc) +{ + atf_tc_set_md_var(tc, "descr", "Does low-port allocation work?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(listen_low_port, tc) +{ + int sd, val; + + sd = socket(AF_INET, SOCK_STREAM, 0); + + val = IP_PORTRANGE_LOW; + if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val, + sizeof(val)) == -1) + atf_tc_fail("setsockopt failed: %s", strerror(errno)); + + if (listen(sd, 5) == -1) { + int serrno = errno; + atf_tc_fail("listen failed: %s%s", + strerror(serrno), + serrno != EACCES ? "" : + " (see http://mail-index.netbsd.org/" + "source-changes/2007/12/16/0011.html)"); + } + + close(sd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, listen_err); + ATF_TP_ADD_TC(tp, listen_low_port); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c new file mode 100644 index 0000000..02545fe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c @@ -0,0 +1,247 @@ +/* $NetBSD: t_lwp_create.c,v 1.2 2012/05/22 09:23:39 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This code is partly based on code by Joel Sing <joel at sing.id.au> + */ + +#include <atf-c.h> +#include <lwp.h> +#include <stdio.h> +#include <stdlib.h> +#include <ucontext.h> +#include <inttypes.h> +#include <errno.h> + +#ifdef __alpha__ +#include <machine/alpha_cpu.h> +#endif +#ifdef __amd64__ +#include <machine/vmparam.h> +#include <machine/psl.h> +#endif +#ifdef __hppa__ +#include <machine/psl.h> +#endif +#ifdef __i386__ +#include <machine/segments.h> +#include <machine/psl.h> +#endif +#if defined(__m68k__) || defined(__sh3__) || defined __vax__ +#include <machine/psl.h> +#endif + +volatile lwpid_t the_lwp_id = 0; + +static void lwp_main_func(void* arg) +{ + the_lwp_id = _lwp_self(); + _lwp_exit(); +} + +/* + * Hard to document - see usage examples below. + */ +#define INVALID_UCONTEXT(ARCH,NAME,DESC) \ +static void ARCH##_##NAME(ucontext_t *); \ +ATF_TC(lwp_create_##ARCH##_fail_##NAME); \ +ATF_TC_HEAD(lwp_create_##ARCH##_fail_##NAME, tc) \ +{ \ + atf_tc_set_md_var(tc, "descr", "verify rejection of invalid ucontext " \ + "on " #ARCH " due to " DESC); \ +} \ + \ +ATF_TC_BODY(lwp_create_##ARCH##_fail_##NAME, tc) \ +{ \ + ucontext_t uc; \ + lwpid_t lid; \ + int error; \ + \ + getcontext(&uc); \ + uc.uc_flags = _UC_CPU; \ + ARCH##_##NAME(&uc); \ + \ + error = _lwp_create(&uc, 0, &lid); \ + ATF_REQUIRE(error != 0 && errno == EINVAL); \ +} \ +static void ARCH##_##NAME(ucontext_t *uc) \ +{ + + +ATF_TC(lwp_create_works); +ATF_TC_HEAD(lwp_create_works, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify creation of a lwp and waiting" + " for it to finish"); +} + +ATF_TC_BODY(lwp_create_works, tc) +{ + ucontext_t uc; + lwpid_t lid; + int error; + void *stack; + static const size_t ssize = 16*1024; + + stack = malloc(ssize); + _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); + + error = _lwp_create(&uc, 0, &lid); + ATF_REQUIRE(error == 0); + + error = _lwp_wait(lid, NULL); + ATF_REQUIRE(error == 0); + ATF_REQUIRE(lid == the_lwp_id); +} + +INVALID_UCONTEXT(generic, no_uc_cpu, "not setting cpu registers") + uc->uc_flags &= ~_UC_CPU; +} + +#ifdef __alpha__ +INVALID_UCONTEXT(alpha, pslset, "trying to clear the USERMODE flag") + uc->uc_mcontext.__gregs[_REG_PS] &= ~ALPHA_PSL_USERMODE; +} +INVALID_UCONTEXT(alpha, pslclr, "trying to set a 'must be zero' flag") + uc->uc_mcontext.__gregs[_REG_PS] |= ALPHA_PSL_IPL_HIGH; +} +#endif +#ifdef __amd64__ +INVALID_UCONTEXT(amd64, untouchable_rflags, "forbidden rflags changed") + uc->uc_mcontext.__gregs[_REG_RFLAGS] |= PSL_MBZ; +} +/* + * XXX: add invalid GS/DS selector tests + */ +INVALID_UCONTEXT(amd64, pc_too_high, + "instruction pointer outside userland address space") + uc->uc_mcontext.__gregs[_REG_RIP] = VM_MAXUSER_ADDRESS; +} +#endif +#ifdef __arm__ +INVALID_UCONTEXT(arm, invalid_mode, "psr or r15 set to non-user-mode") + uc->uc_mcontext.__gregs[_REG_PC] |= 0x1f /*PSR_SYS32_MODE*/; + uc->uc_mcontext.__gregs[_REG_CPSR] |= 0x03 /*R15_MODE_SVC*/; +} +#endif +#ifdef __hppa__ +INVALID_UCONTEXT(hppa, invalid_1, "set illegal bits in psw") + uc->uc_mcontext.__gregs[_REG_PSW] |= PSW_MBZ; +} +INVALID_UCONTEXT(hppa, invalid_0, "clear illegal bits in psw") + uc->uc_mcontext.__gregs[_REG_PSW] &= ~PSW_MBS; +} +#endif +#ifdef __i386__ +INVALID_UCONTEXT(i386, untouchable_eflags, "changing forbidden eflags") + uc->uc_mcontext.__gregs[_REG_EFL] |= PSL_IOPL; +} +INVALID_UCONTEXT(i386, priv_escalation, "modifying priviledge level") + uc->uc_mcontext.__gregs[_REG_CS] &= ~SEL_RPL; +} +#endif +#ifdef __m68k__ +INVALID_UCONTEXT(m68k, invalid_ps_bits, + "setting forbidden bits in the ps register") + uc->uc_mcontext.__gregs[_REG_PS] |= (PSL_MBZ|PSL_IPL|PSL_S); +} +#endif +#ifdef __sh3__ +INVALID_UCONTEXT(sh3, modify_userstatic, + "modifying illegal bits in the status register") + uc->uc_mcontext.__gregs[_REG_SR] |= PSL_MD; +} +#endif +#ifdef __sparc__ +INVALID_UCONTEXT(sparc, pc_odd, "mis-aligned instruction pointer") + uc->uc_mcontext.__gregs[_REG_PC] = 0x100002; +} +INVALID_UCONTEXT(sparc, npc_odd, "mis-aligned next instruction pointer") + uc->uc_mcontext.__gregs[_REG_nPC] = 0x100002; +} +INVALID_UCONTEXT(sparc, pc_null, "NULL instruction pointer") + uc->uc_mcontext.__gregs[_REG_PC] = 0; +} +INVALID_UCONTEXT(sparc, npc_null, "NULL next instruction pointer") + uc->uc_mcontext.__gregs[_REG_nPC] = 0; +} +#endif +#ifdef __vax__ +INVALID_UCONTEXT(vax, psl_0, "clearing forbidden bits in psl") + uc->uc_mcontext.__gregs[_REG_PSL] &= ~(PSL_U | PSL_PREVU); +} +INVALID_UCONTEXT(vax, psl_1, "setting forbidden bits in psl") + uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_IPL | PSL_IS; +} +INVALID_UCONTEXT(vax, psl_cm, "setting CM bit in psl") + uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_CM; +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lwp_create_works); + ATF_TP_ADD_TC(tp, lwp_create_generic_fail_no_uc_cpu); +#ifdef __alpha__ + ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslset); + ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslclr); +#endif +#ifdef __amd64__ + ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_untouchable_rflags); + ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_pc_too_high); +#endif +#ifdef __arm__ + ATF_TP_ADD_TC(tp, lwp_create_arm_fail_invalid_mode); +#endif +#ifdef __hppa__ + ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_1); + ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_0); +#endif +#ifdef __i386__ + ATF_TP_ADD_TC(tp, lwp_create_i386_fail_untouchable_eflags); + ATF_TP_ADD_TC(tp, lwp_create_i386_fail_priv_escalation); +#endif +#ifdef __m68k__ + ATF_TP_ADD_TC(tp, lwp_create_m68k_fail_invalid_ps_bits); +#endif +#ifdef __sh3__ + ATF_TP_ADD_TC(tp, lwp_create_sh3_fail_modify_userstatic); +#endif +#ifdef __sparc__ + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_odd); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_odd); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_null); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_null); +#endif +#ifdef __vax__ + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_0); + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_1); + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_cm); +#endif + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c new file mode 100644 index 0000000..1b28f75 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c @@ -0,0 +1,74 @@ +/* $NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $"); + +#include <sys/lwpctl.h> + +#include <atf-c.h> +#include <lwp.h> +#include <stdio.h> +#include <time.h> + +ATF_TC(lwpctl_counter); +ATF_TC_HEAD(lwpctl_counter, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks lwpctl preemption counter"); +} + +ATF_TC_BODY(lwpctl_counter, tc) +{ + lwpctl_t *lc; + struct timespec ts; + int ctr1, ctr2; + + ATF_REQUIRE(_lwp_ctl(LWPCTL_FEATURE_PCTR, &lc) == 0); + + /* Ensure that preemption is reported. */ + ctr1 = lc->lc_pctr; + (void)printf("pctr = %d\n", ctr1); + ts.tv_nsec = 10*1000000; + ts.tv_sec = 0; + + ATF_REQUIRE(nanosleep(&ts, 0) != -1); + + ctr2 = lc->lc_pctr; + (void)printf("pctr = %d\n", ctr2); + + ATF_REQUIRE_MSG(ctr1 != ctr2, "counters match"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lwpctl_counter); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mincore.c b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c new file mode 100644 index 0000000..499493f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c @@ -0,0 +1,336 @@ +/* $NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $"); + +#include <sys/mman.h> +#include <sys/shm.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <kvm.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/resource.h> + +#ifdef __FreeBSD__ +#include <sys/stat.h> +#endif + +static long page = 0; +static const char path[] = "mincore"; +static size_t check_residency(void *, size_t); + +static size_t +check_residency(void *addr, size_t npgs) +{ + size_t i, resident; + char *vec; + + vec = malloc(npgs); + + ATF_REQUIRE(vec != NULL); + ATF_REQUIRE(mincore(addr, npgs * page, vec) == 0); + + for (i = resident = 0; i < npgs; i++) { + + if (vec[i] != 0) + resident++; + +#if 0 + (void)fprintf(stderr, "page 0x%p is %sresident\n", + (char *)addr + (i * page), vec[i] ? "" : "not "); +#endif + } + + free(vec); + + return resident; +} + +ATF_TC(mincore_err); +ATF_TC_HEAD(mincore_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from mincore(2)"); +} + +ATF_TC_BODY(mincore_err, tc) +{ + char *map, *vec; + + map = mmap(NULL, page, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + vec = malloc(page); + + ATF_REQUIRE(vec != NULL); + ATF_REQUIRE(map != MAP_FAILED); + +#ifdef __NetBSD__ + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mincore(map, 0, vec) == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mincore(0, page, vec) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mincore(map, page, (void *)-1) == -1); + + free(vec); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TC_WITH_CLEANUP(mincore_resid); +ATF_TC_HEAD(mincore_resid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test page residency with mincore(2)"); +} + +ATF_TC_BODY(mincore_resid, tc) +{ + void *addr, *addr2, *addr3, *buf; + size_t npgs = 0, resident; + struct stat st; + int fd, rv; + struct rlimit rlim; + + ATF_REQUIRE(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0); + rlim.rlim_cur = rlim.rlim_max; + ATF_REQUIRE(setrlimit(RLIMIT_MEMLOCK, &rlim) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + + fd = open(path, O_RDWR | O_CREAT, 0700); + buf = malloc(page * 5); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(buf != NULL); + + rv = write(fd, buf, page * 5); + ATF_REQUIRE(rv >= 0); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + addr = mmap(NULL, (size_t)st.st_size, PROT_READ, + MAP_FILE | MAP_SHARED, fd, (off_t) 0); + + ATF_REQUIRE(addr != MAP_FAILED); + + (void)close(fd); + + npgs = st.st_size / page; + + if (st.st_size % page != 0) + npgs++; + + (void)check_residency(addr, npgs); + + rv = mlock(addr, npgs * page); + if (rv == -1 && errno == EAGAIN) + atf_tc_skip("hit process resource limits"); + ATF_REQUIRE(munmap(addr, st.st_size) == 0); + + npgs = 128; + +#ifdef __FreeBSD__ + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, (off_t)0); +#else + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_WIRED, -1, (off_t)0); +#endif + + if (addr == MAP_FAILED) + atf_tc_skip("could not mmap wired anonymous test area, system " + "might be low on memory"); + +#ifdef __FreeBSD__ + ATF_REQUIRE(mlock(addr, npgs * page) == 0); +#endif + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(munmap(addr, npgs * page) == 0); + + npgs = 128; + + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, (off_t)0); + + ATF_REQUIRE(addr != MAP_FAILED); + + /* + * Check that the in-core pages match the locked pages. + */ + ATF_REQUIRE(check_residency(addr, npgs) == 0); + + errno = 0; + if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0 && errno != ENOMEM) + atf_tc_fail("mlockall(2) failed"); + if (errno == ENOMEM) + atf_tc_skip("mlockall() exceeded process resource limits"); + + resident = check_residency(addr, npgs); + if (resident < npgs) + atf_tc_fail("mlockall(MCL_FUTURE) succeeded, still only " + "%zu pages of the newly mapped %zu pages are resident", + resident, npgs); + + addr2 = mmap(NULL, npgs * page, PROT_READ, MAP_ANON, -1, (off_t)0); + addr3 = mmap(NULL, npgs * page, PROT_NONE, MAP_ANON, -1, (off_t)0); + + if (addr2 == MAP_FAILED || addr3 == MAP_FAILED) + atf_tc_skip("could not mmap more anonymous test pages with " + "mlockall(MCL_FUTURE) in effect, system " + "might be low on memory"); + + ATF_REQUIRE(check_residency(addr2, npgs) == npgs); + ATF_REQUIRE(check_residency(addr3, npgs) == 0); + ATF_REQUIRE(mprotect(addr3, npgs * page, PROT_READ) == 0); + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(check_residency(addr2, npgs) == npgs); + + (void)munlockall(); + + ATF_REQUIRE(madvise(addr2, npgs * page, MADV_FREE) == 0); +#ifdef __NetBSD__ + ATF_REQUIRE(check_residency(addr2, npgs) == 0); +#endif + + (void)memset(addr, 0, npgs * page); + + ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0); +#ifdef __NetBSD__ + ATF_REQUIRE(check_residency(addr, npgs) == 0); +#endif + + (void)munmap(addr, npgs * page); + (void)munmap(addr2, npgs * page); + (void)munmap(addr3, npgs * page); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mincore_resid, tc) +{ + (void)unlink(path); +} + +ATF_TC(mincore_shmseg); +ATF_TC_HEAD(mincore_shmseg, tc) +{ + atf_tc_set_md_var(tc, "descr", "residency of shared memory"); +} + +ATF_TC_BODY(mincore_shmseg, tc) +{ + size_t npgs = 128; + void *addr = NULL; + int shmid; + + shmid = shmget(IPC_PRIVATE, npgs * page, + IPC_CREAT | S_IRUSR | S_IWUSR); + + ATF_REQUIRE(shmid != -1); + + addr = shmat(shmid, NULL, 0); + + ATF_REQUIRE(addr != NULL); + ATF_REQUIRE(check_residency(addr, npgs) == 0); + + (void)memset(addr, 0xff, npgs * page); + + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0); + + /* + * NOTE! Even though we have MADV_FREE'd the range, + * there is another reference (the kernel's) to the + * object which owns the pages. In this case, the + * kernel does not simply free the pages, as haphazardly + * freeing pages when there are still references to + * an object can cause data corruption (say, the other + * referencer doesn't expect the pages to be freed, + * and is surprised by the subsequent ZFOD). + * + * Because of this, we simply report the number of + * pages still resident, for information only. + */ + npgs = check_residency(addr, npgs); + + (void)fprintf(stderr, "%zu pages still resident\n", npgs); + + ATF_REQUIRE(shmdt(addr) == 0); + ATF_REQUIRE(shmctl(shmid, IPC_RMID, NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mincore_err); + ATF_TP_ADD_TC(tp, mincore_resid); + ATF_TP_ADD_TC(tp, mincore_shmseg); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_minherit.c b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c new file mode 100644 index 0000000..0bdf6bc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c @@ -0,0 +1,200 @@ +/* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $"); + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +static long page; + +static void * +makemap(int v, int f) { + void *map = mmap(NULL, page, PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + memset(map, v, page); + if (f != 666) + ATF_REQUIRE(minherit(map, page, f) == 0); + else + ATF_REQUIRE(minherit(map, page, f) == -1); + return map; +} + +ATF_TC(minherit_copy); +ATF_TC_HEAD(minherit_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_COPY from minherit(2)"); +} + +ATF_TC_BODY(minherit_copy, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_COPY); + void *map2 = makemap(1, MAP_INHERIT_COPY); + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 0, page); + exit(0); + } +} + +ATF_TC(minherit_share); +ATF_TC_HEAD(minherit_share, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_SHARE from minherit(2)"); +} + +ATF_TC_BODY(minherit_share, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_SHARE); + void *map2 = makemap(1, MAP_INHERIT_SHARE); + + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + memset(map2, 0, page); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 0, page); + exit(0); + } +} + +static void +segv(int n) { + _exit(n); +} + +ATF_TC(minherit_none); +ATF_TC_HEAD(minherit_none, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_NONE from minherit(2)"); +} + +ATF_TC_BODY(minherit_none, tc) +{ + void *map1 = makemap(0, MAP_INHERIT_NONE); + int status; + + switch (fork()) { + default: + ATF_REQUIRE(wait(&status) != -1); + ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR); + memset(map1, 0, page); + exit(0); + } +} + +ATF_TC(minherit_zero); +ATF_TC_HEAD(minherit_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_ZERO from minherit(2)"); +} + +ATF_TC_BODY(minherit_zero, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_ZERO); + void *map2 = makemap(0, MAP_INHERIT_SHARE); + + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + memset(map2, 1, page); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 2, page); + exit(0); + } +} + +ATF_TC(minherit_bad); +ATF_TC_HEAD(minherit_bad, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for bad minherit(2)"); +} + +ATF_TC_BODY(minherit_bad, tc) +{ + (void)makemap(0, 666); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, minherit_copy); + ATF_TP_ADD_TC(tp, minherit_share); + ATF_TP_ADD_TC(tp, minherit_none); + ATF_TP_ADD_TC(tp, minherit_zero); + ATF_TP_ADD_TC(tp, minherit_bad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c new file mode 100644 index 0000000..d97a20b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c @@ -0,0 +1,210 @@ +/* $NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $ */ + +/*- + * Copyright (c) 2008, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe and Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(mkdir_err); +ATF_TC_HEAD(mkdir_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks errors from mkdir(2)"); +} + +ATF_TC_BODY(mkdir_err, tc) +{ + char buf[PATH_MAX + 1]; + int fd; + + (void)memset(buf, 'x', sizeof(buf)); + + fd = open("/etc", O_RDONLY); + + if (fd >= 0) { + + (void)close(fd); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkdir("/etc", 0500) == -1); + } + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mkdir((void *)-1, 0500) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkdir(buf, 0500) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mkdir("/a/b/c/d/e/f/g/h/i/j/k", 0500) == -1); +} + +ATF_TC_WITH_CLEANUP(mkdir_perm); +ATF_TC_HEAD(mkdir_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks permissions with mkdir(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mkdir_perm, tc) +{ + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, mkdir("/usr/__nonexistent__", 0500) == -1); +} + +ATF_TC_CLEANUP(mkdir_perm, tc) +{ + (void)rmdir("/usr/__nonexistent__"); +} + +ATF_TC_WITH_CLEANUP(mkdir_mode); +ATF_TC_HEAD(mkdir_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that UIDs and GIDs are right " + "for a directory created with mkdir(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mkdir_mode, tc) +{ + static const char *path = "/tmp/mkdir"; + struct stat st_a, st_b; + struct passwd *pw; + pid_t pid; + int sta; + + (void)memset(&st_a, 0, sizeof(struct stat)); + (void)memset(&st_b, 0, sizeof(struct stat)); + + pw = getpwnam("nobody"); + + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(stat("/tmp", &st_a) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + if (mkdir(path, 0500) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create '%s'", path); + + ATF_REQUIRE(stat(path, &st_b) == 0); + ATF_REQUIRE(rmdir(path) == 0); + + /* + * The directory's owner ID should be set to the + * effective UID, whereas the group ID should be + * set to that of the parent directory. + */ + if (st_b.st_uid != pw->pw_uid) + atf_tc_fail("invalid UID for '%s'", path); + + if (st_b.st_gid != st_a.st_gid) + atf_tc_fail("GID did not follow the parent directory"); +} + +ATF_TC_CLEANUP(mkdir_mode, tc) +{ + (void)rmdir("/tmp/mkdir"); +} + +ATF_TC(mkdir_trail); +ATF_TC_HEAD(mkdir_trail, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mkdir(2) for trailing slashes"); +} + +ATF_TC_BODY(mkdir_trail, tc) +{ + const char *tests[] = { + /* + * IEEE 1003.1 second ed. 2.2.2.78: + * + * If the pathname refers to a directory, it may also have + * one or more trailing slashes. Multiple successive slashes + * are considered to be the same as one slash. + */ + "dir1/", + "dir2//", + + NULL, + }; + + const char **test; + + for (test = &tests[0]; *test != NULL; ++test) { + + (void)printf("Checking \"%s\"\n", *test); + (void)rmdir(*test); + + ATF_REQUIRE(mkdir(*test, 0777) == 0); + ATF_REQUIRE(rename(*test, "foo") == 0); + ATF_REQUIRE(rename("foo/", *test) == 0); + ATF_REQUIRE(rmdir(*test) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkdir_err); + ATF_TP_ADD_TC(tp, mkdir_perm); + ATF_TP_ADD_TC(tp, mkdir_mode); + ATF_TP_ADD_TC(tp, mkdir_trail); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c new file mode 100644 index 0000000..56bc4c8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c @@ -0,0 +1,276 @@ +/* $NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +static const char path[] = "fifo"; +static void support(void); + +static void +support(void) +{ + + errno = 0; + + if (mkfifo(path, 0600) == 0) { + ATF_REQUIRE(unlink(path) == 0); + return; + } + + if (errno == EOPNOTSUPP) + atf_tc_skip("the kernel does not support FIFOs"); + else { + atf_tc_fail("mkfifo(2) failed"); + } +} + +ATF_TC_WITH_CLEANUP(mkfifo_block); +ATF_TC_HEAD(mkfifo_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that FIFOs block"); +} + +ATF_TC_BODY(mkfifo_block, tc) +{ + int sta, fd = -1; + pid_t pid; + + support(); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * If we open the FIFO as read-only (write-only), + * the call should block until another process + * opens the FIFO for writing (reading). + */ + fd = open(path, O_RDONLY); + + _exit(EXIT_FAILURE); /* NOTREACHED */ + } + + (void)sleep(1); + + ATF_REQUIRE(kill(pid, SIGKILL) == 0); + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("FIFO did not block"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mkfifo_block, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_err); +ATF_TC_HEAD(mkfifo_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erros from mkfifo(2)"); +} + +ATF_TC_BODY(mkfifo_err, tc) +{ + char buf[PATH_MAX + 1]; + + support(); + + (void)memset(buf, 'x', sizeof(buf)); + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mkfifo((char *)-1, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkfifo("/etc/passwd", 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkfifo(path, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkfifo(buf, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mkfifo("/a/b/c/d/e/f/g", 0600) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_nonblock); +ATF_TC_HEAD(mkfifo_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test O_NONBLOCK with FIFOs"); +} + +ATF_TC_BODY(mkfifo_nonblock, tc) +{ + int fd, sta; + pid_t pid; + + support(); + + fd = -1; + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * If we open the FIFO as O_NONBLOCK, the O_RDONLY + * call should return immediately, whereas the call + * for write-only should fail with ENXIO. + */ + fd = open(path, O_RDONLY | O_NONBLOCK); + + if (fd >= 0) + _exit(EXIT_SUCCESS); + + (void)pause(); /* NOTREACHED */ + } + + (void)sleep(1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENXIO, open(path, O_WRONLY | O_NONBLOCK) == -1); + + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL) + atf_tc_fail("FIFO blocked for O_NONBLOCK open(2)"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mkfifo_nonblock, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_perm); +ATF_TC_HEAD(mkfifo_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with mkfifo(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mkfifo_perm, tc) +{ + + support(); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, mkfifo("/root/fifo", 0600) == -1); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + /* + * For some reason this fails with EFTYPE... + */ + errno = 0; + ATF_REQUIRE_ERRNO(EFTYPE, chmod(path, 1777) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_stat); +ATF_TC_HEAD(mkfifo_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mkfifo(2) with stat"); +} + +ATF_TC_BODY(mkfifo_stat, tc) +{ + struct stat st; + + support(); + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISFIFO(st.st_mode) == 0) + atf_tc_fail("invalid mode from mkfifo(2)"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_stat, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkfifo_block); + ATF_TP_ADD_TC(tp, mkfifo_err); + ATF_TP_ADD_TC(tp, mkfifo_nonblock); + ATF_TP_ADD_TC(tp, mkfifo_perm); + ATF_TP_ADD_TC(tp, mkfifo_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mknod.c b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c new file mode 100644 index 0000000..1c5cd9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c @@ -0,0 +1,202 @@ +/* $NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static char path[] = "node"; + +ATF_TC_WITH_CLEANUP(mknod_err); +ATF_TC_HEAD(mknod_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of mknod(2) (PR kern/45111)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + +#ifndef __FreeBSD__ + /* + * As of FreeBSD 6.0 device nodes may be created in regular file systems but + * such nodes cannot be used to access devices. As a result an invalid dev + * argument is unchecked. + */ + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mknod(path, S_IFCHR, -1) == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mknod(buf, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mknod((char *)-1, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mknod("/a/b/c/d/e/f/g", S_IFCHR, 0) == -1); +} + +ATF_TC_CLEANUP(mknod_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_exist); +ATF_TC_HEAD(mknod_exist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EEXIST from mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_exist, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + + (void)close(fd); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, + mknod("/etc/passwd", S_IFCHR, 0) == -1); + } + + ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mknod(path, S_IFCHR, 0) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mknod_exist, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_perm); +ATF_TC_HEAD(mknod_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions of mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mknod_perm, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFBLK, 0) == -1); +} + +ATF_TC_CLEANUP(mknod_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_stat); +ATF_TC_HEAD(mknod_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_stat, tc) +{ + struct stat st; + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISCHR(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFCHR)"); + + ATF_REQUIRE(unlink(path) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mknod(path, S_IFBLK, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISBLK(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFBLK)"); + + ATF_REQUIRE(unlink(path) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + +#ifdef __FreeBSD__ + atf_tc_expect_fail("mknod does not allow S_IFREG"); +#endif + ATF_REQUIRE(mknod(path, S_IFREG, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISREG(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFREG)"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mknod_stat, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mknod_err); + ATF_TP_ADD_TC(tp, mknod_exist); + ATF_TP_ADD_TC(tp, mknod_perm); + ATF_TP_ADD_TC(tp, mknod_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mlock.c b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c new file mode 100644 index 0000000..0397b5c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c @@ -0,0 +1,286 @@ +/* $NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $"); + +#ifdef __FreeBSD__ +#include <sys/types.h> +#endif +#include <sys/mman.h> +#include <sys/resource.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <errno.h> +#include <atf-c.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#define _KMEMUSER +#include <machine/vmparam.h> +#endif + +static long page = 0; + +ATF_TC(mlock_clip); +ATF_TC_HEAD(mlock_clip, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test with mlock(2) that UVM only " + "clips if the clip address is within the entry (PR kern/44788)"); +} + +ATF_TC_BODY(mlock_clip, tc) +{ + void *buf; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + if (page < 1024) + atf_tc_skip("page size too small"); + + for (size_t i = page; i >= 1; i = i - 1024) { + (void)mlock(buf, page - i); + (void)munlock(buf, page - i); + } + + free(buf); +} + +ATF_TC(mlock_err); +ATF_TC_HEAD(mlock_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions in mlock(2) and munlock(2)"); +} + +ATF_TC_BODY(mlock_err, tc) +{ +#ifdef __NetBSD__ + unsigned long vmin = 0; + size_t len = sizeof(vmin); +#endif + void *invalid_ptr; + int null_errno = ENOMEM; /* error expected for NULL */ + +#ifdef __FreeBSD__ +#ifdef VM_MIN_ADDRESS + if ((uintptr_t)VM_MIN_ADDRESS > 0) + null_errno = EINVAL; /* NULL is not inside user VM */ +#endif +#else + if (sysctlbyname("vm.minaddress", &vmin, &len, NULL, 0) != 0) + atf_tc_fail("failed to read vm.minaddress"); + + if (vmin > 0) + null_errno = EINVAL; /* NULL is not inside user VM */ +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, mlock(NULL, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, mlock((char *)0, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, munlock(NULL, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(null_errno, munlock((char *)0, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1); + + /* + * Try to create a pointer to an unmapped page - first after current + * brk will likely do. + */ + invalid_ptr = (void*)(((uintptr_t)sbrk(0)+page) & ~(page-1)); + printf("testing with (hopefully) invalid pointer %p\n", invalid_ptr); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock(invalid_ptr, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock(invalid_ptr, page) == -1); +} + +ATF_TC(mlock_limits); +ATF_TC_HEAD(mlock_limits, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test system limits with mlock(2)"); +} + +ATF_TC_BODY(mlock_limits, tc) +{ + struct rlimit res; + void *buf; + pid_t pid; + int sta; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (ssize_t i = page; i >= 2; i -= 100) { + + res.rlim_cur = i - 1; + res.rlim_max = i - 1; + + (void)fprintf(stderr, "trying to lock %zd bytes " + "with %zu byte limit\n", i, (size_t)res.rlim_cur); + + if (setrlimit(RLIMIT_MEMLOCK, &res) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + +#ifdef __FreeBSD__ + /* + * NetBSD doesn't conform to POSIX with ENOMEM requirement; + * FreeBSD does. + * + * See: NetBSD PR # kern/48962 for more details. + */ + if (mlock(buf, i) != -1 || errno != ENOMEM) { +#else + if (mlock(buf, i) != -1 || errno != EAGAIN) { +#endif + (void)munlock(buf, i); + _exit(EXIT_FAILURE); + } + } + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("mlock(2) locked beyond system limits"); + + free(buf); +} + +ATF_TC(mlock_mmap); +ATF_TC_HEAD(mlock_mmap, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction"); +} + +ATF_TC_BODY(mlock_mmap, tc) +{ +#ifdef __NetBSD__ + static const int flags = MAP_ANON | MAP_PRIVATE | MAP_WIRED; +#else + static const int flags = MAP_ANON | MAP_PRIVATE; +#endif + void *buf; + + /* + * Make a wired RW mapping and check that mlock(2) + * does not fail for the (already locked) mapping. + */ + buf = mmap(NULL, page, PROT_READ | PROT_WRITE, flags, -1, 0); + + ATF_REQUIRE(buf != MAP_FAILED); +#ifdef __FreeBSD__ + /* + * The duplicate mlock call is added to ensure that the call works + * as described above without MAP_WIRED support. + */ + ATF_REQUIRE(mlock(buf, page) == 0); +#endif + ATF_REQUIRE(mlock(buf, page) == 0); + ATF_REQUIRE(munlock(buf, page) == 0); + ATF_REQUIRE(munmap(buf, page) == 0); + ATF_REQUIRE(munlock(buf, page) != 0); + + /* + * But it should be impossible to mlock(2) a PROT_NONE mapping. + */ + buf = mmap(NULL, page, PROT_NONE, flags, -1, 0); + + ATF_REQUIRE(buf != MAP_FAILED); +#ifdef __FreeBSD__ + ATF_REQUIRE_ERRNO(ENOMEM, mlock(buf, page) != 0); +#else + ATF_REQUIRE(mlock(buf, page) != 0); +#endif + ATF_REQUIRE(munmap(buf, page) == 0); +} + +ATF_TC(mlock_nested); +ATF_TC_HEAD(mlock_nested, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that consecutive mlock(2) calls succeed"); +} + +ATF_TC_BODY(mlock_nested, tc) +{ + const size_t maxiter = 100; + void *buf; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + for (size_t i = 0; i < maxiter; i++) + ATF_REQUIRE(mlock(buf, page) == 0); + + ATF_REQUIRE(munlock(buf, page) == 0); + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mlock_clip); + ATF_TP_ADD_TC(tp, mlock_err); + ATF_TP_ADD_TC(tp, mlock_limits); + ATF_TP_ADD_TC(tp, mlock_mmap); + ATF_TP_ADD_TC(tp, mlock_nested); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mmap.c b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c new file mode 100644 index 0000000..5d821ec --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c @@ -0,0 +1,524 @@ +/* $NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $"); + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/socket.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <paths.h> +#ifdef __NetBSD__ +#include <machine/disklabel.h> +#endif + +#ifdef __FreeBSD__ +#include <sys/disklabel.h> +#include <sys/stat.h> +#include <stdint.h> +#endif + +static long page = 0; +static char path[] = "mmap"; +static void map_check(void *, int); +static void map_sighandler(int); +static void testloan(void *, void *, char, int); + +#define BUFSIZE (32 * 1024) /* enough size to trigger sosend_loan */ + +static void +map_check(void *map, int flag) +{ + + if (flag != 0) { + ATF_REQUIRE(map == MAP_FAILED); + return; + } + + ATF_REQUIRE(map != MAP_FAILED); + ATF_REQUIRE(munmap(map, page) == 0); +} + +void +testloan(void *vp, void *vp2, char pat, int docheck) +{ + char buf[BUFSIZE]; + char backup[BUFSIZE]; + ssize_t nwritten; + ssize_t nread; + int fds[2]; + int val; + + val = BUFSIZE; + + if (docheck != 0) + (void)memcpy(backup, vp, BUFSIZE); + + if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds) != 0) + atf_tc_fail("socketpair() failed"); + + val = BUFSIZE; + + if (setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0) + atf_tc_fail("setsockopt() failed, SO_RCVBUF"); + + val = BUFSIZE; + + if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0) + atf_tc_fail("setsockopt() failed, SO_SNDBUF"); + + if (fcntl(fds[0], F_SETFL, O_NONBLOCK) != 0) + atf_tc_fail("fcntl() failed"); + + nwritten = write(fds[0], (char *)vp + page, BUFSIZE - page); + + if (nwritten == -1) + atf_tc_fail("write() failed"); + + /* Break loan. */ + (void)memset(vp2, pat, BUFSIZE); + + nread = read(fds[1], buf + page, BUFSIZE - page); + + if (nread == -1) + atf_tc_fail("read() failed"); + + if (nread != nwritten) + atf_tc_fail("too short read"); + + if (docheck != 0 && memcmp(backup, buf + page, nread) != 0) + atf_tc_fail("data mismatch"); + + ATF_REQUIRE(close(fds[0]) == 0); + ATF_REQUIRE(close(fds[1]) == 0); +} + +static void +map_sighandler(int signo) +{ + _exit(signo); +} + +#ifdef __NetBSD__ +ATF_TC(mmap_block); +ATF_TC_HEAD(mmap_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) with a block device"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mmap_block, tc) +{ + static const int mib[] = { CTL_HW, HW_DISKNAMES }; + static const unsigned int miblen = __arraycount(mib); + char *map, *dk, *drives, dev[PATH_MAX]; + size_t len; + int fd = -1; + + atf_tc_skip("The test case causes a panic (PR kern/38889, kern/46592)"); + + ATF_REQUIRE(sysctl(mib, miblen, NULL, &len, NULL, 0) == 0); + drives = malloc(len); + ATF_REQUIRE(drives != NULL); + ATF_REQUIRE(sysctl(mib, miblen, drives, &len, NULL, 0) == 0); + for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) { + sprintf(dev, _PATH_DEV "%s%c", dk, 'a'+RAW_PART); + fprintf(stderr, "trying: %s\n", dev); + + if ((fd = open(dev, O_RDONLY)) >= 0) { + (void)fprintf(stderr, "using %s\n", dev); + break; + } + } + free(drives); + + if (fd < 0) + atf_tc_skip("failed to find suitable block device"); + + map = mmap(NULL, 4096, PROT_READ, MAP_FILE, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + (void)fprintf(stderr, "first byte %x\n", *map); + ATF_REQUIRE(close(fd) == 0); + (void)fprintf(stderr, "first byte %x\n", *map); + + ATF_REQUIRE(munmap(map, 4096) == 0); +} +#endif + +ATF_TC(mmap_err); +ATF_TC_HEAD(mmap_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of mmap(2)"); +} + +ATF_TC_BODY(mmap_err, tc) +{ + size_t addr = SIZE_MAX; + void *map; + + errno = 0; + map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, -1, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EBADF); + + errno = 0; + map = mmap(&addr, page, PROT_READ, MAP_FIXED|MAP_PRIVATE, -1, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + map = mmap(NULL, page, PROT_READ, MAP_ANON|MAP_PRIVATE, INT_MAX, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC_WITH_CLEANUP(mmap_loan); +ATF_TC_HEAD(mmap_loan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test uvm page loanout with mmap(2)"); +} + +ATF_TC_BODY(mmap_loan, tc) +{ + char buf[BUFSIZE]; + char *vp, *vp2; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + (void)write(fd, buf, sizeof(buf)); + + vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_PRIVATE, fd, 0); + + ATF_REQUIRE(vp != MAP_FAILED); + + vp2 = vp; + + testloan(vp, vp2, 'A', 0); + testloan(vp, vp2, 'B', 1); + + ATF_REQUIRE(munmap(vp, BUFSIZE) == 0); + + vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + + vp2 = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + + ATF_REQUIRE(vp != MAP_FAILED); + ATF_REQUIRE(vp2 != MAP_FAILED); + + testloan(vp, vp2, 'E', 1); + + ATF_REQUIRE(munmap(vp, BUFSIZE) == 0); + ATF_REQUIRE(munmap(vp2, BUFSIZE) == 0); +} + +ATF_TC_CLEANUP(mmap_loan, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mmap_prot_1); +ATF_TC_HEAD(mmap_prot_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #1"); +} + +ATF_TC_BODY(mmap_prot_1, tc) +{ + void *map; + int fd; + + /* + * Open a file write-only and try to + * map it read-only. This should fail. + */ + fd = open(path, O_WRONLY | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "XXX", 3) == 3); + + map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); + map_check(map, 1); + + map = mmap(NULL, 3, PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0); + map_check(map, 0); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_prot_1, tc) +{ + (void)unlink(path); +} + +ATF_TC(mmap_prot_2); +ATF_TC_HEAD(mmap_prot_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #2"); +} + +ATF_TC_BODY(mmap_prot_2, tc) +{ + char buf[2]; + void *map; + pid_t pid; + int sta; + + /* + * Make a PROT_NONE mapping and try to access it. + * If we catch a SIGSEGV, all works as expected. + */ + map = mmap(NULL, page, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TC_WITH_CLEANUP(mmap_prot_3); +ATF_TC_HEAD(mmap_prot_3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #3"); +} + +ATF_TC_BODY(mmap_prot_3, tc) +{ + char buf[2]; + int fd, sta; + void *map; + pid_t pid; + + /* + * Open a file, change the permissions + * to read-only, and try to map it as + * PROT_NONE. This should succeed, but + * the access should generate SIGSEGV. + */ + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "XXX", 3) == 3); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(chmod(path, 0444) == 0); + + fd = open(path, O_RDONLY); + ATF_REQUIRE(fd != -1); + + map = mmap(NULL, 3, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + pid = fork(); + + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, 3) == 0); +} + +ATF_TC_CLEANUP(mmap_prot_3, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mmap_truncate); +ATF_TC_HEAD(mmap_truncate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) and ftruncate(2)"); +} + +ATF_TC_BODY(mmap_truncate, tc) +{ + char *map; + long i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + /* + * See that ftruncate(2) works + * while the file is mapped. + */ + ATF_REQUIRE(ftruncate(fd, page) == 0); + + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE, + fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + for (i = 0; i < page; i++) + map[i] = 'x'; + + ATF_REQUIRE(ftruncate(fd, 0) == 0); + ATF_REQUIRE(ftruncate(fd, page / 8) == 0); + ATF_REQUIRE(ftruncate(fd, page / 4) == 0); + ATF_REQUIRE(ftruncate(fd, page / 2) == 0); + ATF_REQUIRE(ftruncate(fd, page / 12) == 0); + ATF_REQUIRE(ftruncate(fd, page / 64) == 0); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_truncate, tc) +{ + (void)unlink(path); +} + +ATF_TC(mmap_va0); +ATF_TC_HEAD(mmap_va0, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) and vm.user_va0_disable"); +} + +ATF_TC_BODY(mmap_va0, tc) +{ + int flags = MAP_ANON | MAP_FIXED | MAP_PRIVATE; + size_t len = sizeof(int); + void *map; + int val; + + /* + * Make an anonymous fixed mapping at zero address. If the address + * is restricted as noted in security(7), the syscall should fail. + */ +#ifdef __FreeBSD__ + if (sysctlbyname("security.bsd.map_at_zero", &val, &len, NULL, 0) != 0) + atf_tc_fail("failed to read security.bsd.map_at_zero"); + val = !val; /* 1 == enable map at zero */ +#endif +#ifdef __NetBSD__ + if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0) + atf_tc_fail("failed to read vm.user_va0_disable"); +#endif + + map = mmap(NULL, page, PROT_EXEC, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_READ, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_WRITE, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_READ|PROT_WRITE, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_EXEC|PROT_READ|PROT_WRITE, flags, -1, 0); + map_check(map, val); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, mmap_block); +#endif + ATF_TP_ADD_TC(tp, mmap_err); + ATF_TP_ADD_TC(tp, mmap_loan); + ATF_TP_ADD_TC(tp, mmap_prot_1); + ATF_TP_ADD_TC(tp, mmap_prot_2); + ATF_TP_ADD_TC(tp, mmap_prot_3); + ATF_TP_ADD_TC(tp, mmap_truncate); + ATF_TP_ADD_TC(tp, mmap_va0); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c new file mode 100644 index 0000000..ee345aa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c @@ -0,0 +1,365 @@ +/* $NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $"); + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#ifdef __NetBSD__ +#include "../common/exec_prot.h" +#endif + +static long page = 0; +static int pax_global = -1; +static int pax_enabled = -1; +static char path[] = "mmap"; + +static void sighandler(int); +static bool paxinit(void); +static bool paxset(int, int); + +static void +sighandler(int signo) +{ + _exit(signo); +} + +static bool +paxinit(void) +{ + size_t len = sizeof(int); + int rv; + + rv = sysctlbyname("security.pax.mprotect.global", + &pax_global, &len, NULL, 0); + + if (rv != 0) + return false; + + rv = sysctlbyname("security.pax.mprotect.enabled", + &pax_enabled, &len, NULL, 0); + + if (rv != 0) + return false; + + return paxset(1, 1); +} + +static bool +paxset(int global, int enabled) +{ + size_t len = sizeof(int); + int rv; + + rv = sysctlbyname("security.pax.mprotect.global", + NULL, NULL, &global, len); + + if (rv != 0) + return false; + + rv = sysctlbyname("security.pax.mprotect.enabled", + NULL, NULL, &enabled, len); + + if (rv != 0) + return false; + + return true; +} + + +ATF_TC_WITH_CLEANUP(mprotect_access); +ATF_TC_HEAD(mprotect_access, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test for EACCES from mprotect(2)"); +} + +ATF_TC_BODY(mprotect_access, tc) +{ + int prot[2] = { PROT_NONE, PROT_READ }; + void *map; + size_t i; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + /* + * The call should fail with EACCES if we try to mark + * a PROT_NONE or PROT_READ file/section as PROT_WRITE. + */ + for (i = 0; i < __arraycount(prot); i++) { + + map = mmap(NULL, page, prot[i], MAP_SHARED, fd, 0); + + if (map == MAP_FAILED) + continue; + + errno = 0; + + ATF_REQUIRE(mprotect(map, page, PROT_WRITE) != 0); + ATF_REQUIRE(errno == EACCES); + ATF_REQUIRE(munmap(map, page) == 0); + } + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mprotect_access, tc) +{ + (void)unlink(path); +} + +ATF_TC(mprotect_err); +ATF_TC_HEAD(mprotect_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of mprotect(2)"); +} + +ATF_TC_BODY(mprotect_err, tc) +{ + errno = 0; + + ATF_REQUIRE(mprotect((char *)-1, 1, PROT_READ) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +#ifdef __NetBSD__ +ATF_TC(mprotect_exec); +ATF_TC_HEAD(mprotect_exec, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mprotect(2) executable space protections"); +} + +/* + * Trivial function -- should fit into a page + */ +ATF_TC_BODY(mprotect_exec, tc) +{ + pid_t pid; + void *map; + int sta, xp_support; + + xp_support = exec_prot_support(); + + switch (xp_support) { + case NOTIMPL: + atf_tc_skip( + "Execute protection callback check not implemented"); + break; + case NO_XP: + atf_tc_skip( + "Host does not support executable space protection"); + break; + case PARTIAL_XP: case PERPAGE_XP: default: + break; + } + + /* + * Map a page read/write and copy a trivial assembly function inside. + * We will then change the mapping rights: + * - first by setting the execution right, and check that we can + * call the code found in the allocated page. + * - second by removing the execution right. This should generate + * a SIGSEGV on architectures that can enforce --x permissions. + */ + + map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + memcpy(map, (void *)return_one, + (uintptr_t)return_one_end - (uintptr_t)return_one); + + /* give r-x rights then call code in page */ + ATF_REQUIRE(mprotect(map, page, PROT_EXEC|PROT_READ) == 0); + ATF_REQUIRE(((int (*)(void))map)() == 1); + + /* remove --x right */ + ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); + ATF_CHECK(((int (*)(void))map)() == 1); + _exit(0); + } + + (void)wait(&sta); + + ATF_REQUIRE(munmap(map, page) == 0); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + + switch (xp_support) { + case PARTIAL_XP: + /* Partial protection might fail; skip the test when it does */ + if (WEXITSTATUS(sta) != SIGSEGV) { + atf_tc_skip("Host only supports " + "partial executable space protection"); + } + break; + case PERPAGE_XP: default: + /* Per-page --x protection should not fail */ + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + break; + } +} +#endif + +ATF_TC(mprotect_pax); +ATF_TC_HEAD(mprotect_pax, tc) +{ + atf_tc_set_md_var(tc, "descr", "PaX restrictions and mprotect(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mprotect_pax, tc) +{ + const int prot[4] = { PROT_NONE, PROT_READ, PROT_WRITE }; + const char *str = NULL; + void *map; + size_t i; + int rv; + + if (paxinit() != true) + return; + + /* + * As noted in the original PaX documentation [1], + * the following restrictions should apply: + * + * (1) creating executable anonymous mappings + * + * (2) creating executable/writable file mappings + * + * (3) making a non-executable mapping executable + * + * (4) making an executable/read-only file mapping + * writable except for performing relocations + * on an ET_DYN ELF file (non-PIC shared library) + * + * The following will test only the case (3). + * + * [1] http://pax.grsecurity.net/docs/mprotect.txt + * + * (Sun Apr 3 11:06:53 EEST 2011.) + */ + for (i = 0; i < __arraycount(prot); i++) { + + map = mmap(NULL, page, prot[i], MAP_ANON, -1, 0); + + if (map == MAP_FAILED) + continue; + + rv = mprotect(map, 1, prot[i] | PROT_EXEC); + + (void)munmap(map, page); + + if (rv == 0) { + str = "non-executable mapping made executable"; + goto out; + } + } + +out: + if (pax_global != -1 && pax_enabled != -1) + (void)paxset(pax_global, pax_enabled); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(mprotect_write); +ATF_TC_HEAD(mprotect_write, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mprotect(2) write protections"); +} + +ATF_TC_BODY(mprotect_write, tc) +{ + pid_t pid; + void *map; + int sta; + + /* + * Map a page read/write, change the protection + * to read-only with mprotect(2), and try to write + * to the page. This should generate a SIGSEGV. + */ + map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + ATF_REQUIRE(strlcpy(map, "XXX", 3) == 3); + ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(map, "XXX", 3) == 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mprotect_access); + ATF_TP_ADD_TC(tp, mprotect_err); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, mprotect_exec); +#endif + ATF_TP_ADD_TC(tp, mprotect_pax); + ATF_TP_ADD_TC(tp, mprotect_write); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c new file mode 100644 index 0000000..b9b3067 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c @@ -0,0 +1,362 @@ +/* $NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#include <limits.h> +#endif + +#define MSG_KEY 12345689 +#define MSG_MTYPE_1 0x41 + +struct msg { + long mtype; + char buf[3]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgctl_err); +ATF_TC_HEAD(msgctl_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)"); +} + +ATF_TC_BODY(msgctl_err, tc) +{ + const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID }; + struct msqid_ds msgds; + size_t i; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1); + + for (i = 0; i < __arraycount(cmd); i++) { + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_err, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_perm); +ATF_TC_HEAD(msgctl_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgctl_perm, tc) +{ + struct msqid_ds msgds; + struct passwd *pw; + pid_t pid; + int sta; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EX_OSERR); + + msgds.msg_perm.uid = getuid(); + msgds.msg_perm.gid = getgid(); + + errno = 0; + + if (msgctl(id, IPC_SET, &msgds) == 0) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + if (msgctl(id, IPC_STAT, &msgds) != 0) + _exit(EX_OSERR); + + msgds.msg_qbytes = 1; + + if (msgctl(id, IPC_SET, &msgds) == 0) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0) { + + if (WEXITSTATUS(sta) == EX_OSERR) + atf_tc_fail("system call failed"); + + if (WEXITSTATUS(sta) == EXIT_FAILURE) + atf_tc_fail("UID %u manipulated root's " + "message queue", pw->pw_uid); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_perm, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_pid); +ATF_TC_HEAD(msgctl_pid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated"); +} + +ATF_TC_BODY(msgctl_pid, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds msgds; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + if (pid != msgds.msg_lspid) + atf_tc_fail("the PID of last msgsnd(2) was not updated"); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)msgrcv(id, &msg, + sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + if (pid != msgds.msg_lrpid) + atf_tc_fail("the PID of last msgrcv(2) was not updated"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_pid, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_set); +ATF_TC_HEAD(msgctl_set, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgctl_set, tc) +{ + struct msqid_ds msgds; + struct passwd *pw; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + msgds.msg_perm.uid = pw->pw_uid; + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change the UID of message queue"); + + msgds.msg_perm.uid = getuid(); + msgds.msg_perm.gid = pw->pw_gid; + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change the GID of message queue"); + + /* + * Note: setting the qbytes to zero fails even as root. + */ + msgds.msg_qbytes = 1; + msgds.msg_perm.gid = getgid(); + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change qbytes of message queue"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_set, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_time); +ATF_TC_HEAD(msgctl_time, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that access times are updated"); +} + +ATF_TC_BODY(msgctl_time, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds msgds; + time_t t; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + t = time(NULL); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + (void)msgctl(id, IPC_STAT, &msgds); + + if (llabs(t - msgds.msg_stime) > 1) + atf_tc_fail("time of last msgsnd(2) was not updated"); + + if (msgds.msg_rtime != 0) + atf_tc_fail("time of last msgrcv(2) was updated incorrectly"); + + t = time(NULL); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + (void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT); + (void)msgctl(id, IPC_STAT, &msgds); + + if (llabs(t - msgds.msg_rtime) > 1) + atf_tc_fail("time of last msgrcv(2) was not updated"); + + /* + * Note: this is non-zero even after the memset(3). + */ + if (msgds.msg_stime == 0) + atf_tc_fail("time of last msgsnd(2) was updated incorrectly"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_time, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgctl_err); + ATF_TP_ADD_TC(tp, msgctl_perm); + ATF_TP_ADD_TC(tp, msgctl_pid); + ATF_TP_ADD_TC(tp, msgctl_set); + ATF_TP_ADD_TC(tp, msgctl_time); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgget.c b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c new file mode 100644 index 0000000..e26cde2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c @@ -0,0 +1,292 @@ +/* $NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#define MSG_KEY 12345689 + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgget_excl); +ATF_TC_HEAD(msgget_excl, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgget(2) with IPC_EXCL"); +} + +ATF_TC_BODY(msgget_excl, tc) +{ + int id; + + /* + * Create a message queue and re-open it with + * O_CREAT and IPC_EXCL set. This should fail. + */ + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + if (id < 0) + atf_tc_fail("failed to create message queue"); + + errno = 0; + + if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) != -1) + atf_tc_fail("msgget(2) failed for IPC_EXCL"); + + ATF_REQUIRE(errno == EEXIST); + + /* + * However, the same call should succeed + * when IPC_EXCL is not set in the flags. + */ + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + if (id < 0) + atf_tc_fail("msgget(2) failed to re-open"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_excl, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgget_exit); +ATF_TC_HEAD(msgget_exit, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that XSI message queues are " + "not removed when the process exits"); +} + +ATF_TC_BODY(msgget_exit, tc) +{ + int id, sta; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) == -1) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create message queue"); + + id = msgget(MSG_KEY, 0); + + if (id == -1) + atf_tc_fail("message queue was removed on process exit"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_exit, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgget_init); +ATF_TC_HEAD(msgget_init, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that msgget(2) initializes data structures properly"); +} + +ATF_TC_BODY(msgget_init, tc) +{ + const uid_t uid = geteuid(); + const gid_t gid = getegid(); + struct msqid_ds msgds; + time_t t; + int id; + + (void)memset(&msgds, 0x9, sizeof(struct msqid_ds)); + + t = time(NULL); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id !=-1); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + ATF_CHECK(msgds.msg_qnum == 0); + ATF_CHECK(msgds.msg_lspid == 0); + ATF_CHECK(msgds.msg_lrpid == 0); + ATF_CHECK(msgds.msg_rtime == 0); + ATF_CHECK(msgds.msg_stime == 0); + ATF_CHECK(msgds.msg_perm.uid == uid); + ATF_CHECK(msgds.msg_perm.gid == gid); + ATF_CHECK(msgds.msg_perm.cuid == uid); + ATF_CHECK(msgds.msg_perm.cgid == gid); + ATF_CHECK(msgds.msg_perm.mode == 0600); + + if (llabs(t - msgds.msg_ctime) > 5) + atf_tc_fail("msgget(2) initialized current time incorrectly"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_init, tc) +{ + clean(); +} + +ATF_TC(msgget_limit); +ATF_TC_HEAD(msgget_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgget(2) against system limits"); +} + +ATF_TC_BODY(msgget_limit, tc) +{ + size_t len = sizeof(int); + bool fail = false; + int i, lim = 0; + int *buf; + + if (sysctlbyname("kern.ipc.msgmni", &lim, &len, NULL, 0) != 0) + atf_tc_skip("failed to read kern.ipc.msgmni sysctl"); + + buf = calloc(lim + 1, sizeof(*buf)); + ATF_REQUIRE(buf != NULL); + + for (i = 0; i < lim; i++) { + + buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600); + + (void)fprintf(stderr, "key[%d] = %d\n", i, buf[i]); + + /* + * This test only works when there are zero existing + * message queues. Thus, bypass the unit test when + * this precondition is not met, for reason or another. + */ + if (buf[i] == -1) + goto out; + } + + i++; + errno = 0; + + buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600); + + if (buf[i] != -1 || errno != ENOSPC) + fail = true; + +out: /* Remember to clean-up. */ + for (i = 0; i < lim; i++) + (void)msgctl(buf[i], IPC_RMID, 0); + + free(buf); + + if (fail != false) + atf_tc_fail("msgget(2) opened more than %d queues", lim); +} + +ATF_TC_WITH_CLEANUP(msgget_mode); +ATF_TC_HEAD(msgget_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test different modes with msgget(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgget_mode, tc) +{ + static const mode_t mode[] = { + S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, + S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH + }; + + struct msqid_ds msgds; + size_t i; + int id; + + for (i = 0; i < __arraycount(mode); i++) { + + (void)fprintf(stderr, "testing mode %d\n", mode[i]); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + id = msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | (int)mode[i]); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + ATF_REQUIRE(msgds.msg_perm.mode == mode[i]); + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); + } +} + +ATF_TC_CLEANUP(msgget_mode, tc) +{ + clean(); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgget_excl); + ATF_TP_ADD_TC(tp, msgget_exit); + ATF_TP_ADD_TC(tp, msgget_init); + ATF_TP_ADD_TC(tp, msgget_limit); + ATF_TP_ADD_TC(tp, msgget_mode); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c new file mode 100644 index 0000000..70f8906 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c @@ -0,0 +1,346 @@ +/* $NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#include <limits.h> +#endif + +#define MSG_KEY 1234 +#define MSG_MTYPE_1 0x41 +#define MSG_MTYPE_2 0x42 +#define MSG_MTYPE_3 0x43 +#define MSG_LEN 3 + +struct msg { + long mtype; + char buf[MSG_LEN]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgrcv_basic); +ATF_TC_HEAD(msgrcv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_basic, tc) +{ + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msg msg2 = { MSG_MTYPE_1, { 'x', 'y', 'z' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + ATF_CHECK(msg1.buf[2] == msg2.buf[2]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_basic, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_block); +ATF_TC_HEAD(msgrcv_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that msgrcv(2) blocks"); +} + +ATF_TC_BODY(msgrcv_block, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, 0) < 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + /* + * Below msgsnd(2) should unblock the child, + * and hence kill(2) should fail with ESRCH. + */ + (void)sleep(1); + (void)msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT); + (void)sleep(1); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0) + atf_tc_fail("msgrcv(2) did not block"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_block, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_err); +ATF_TC_HEAD(msgrcv_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_err, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, r = 0; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(ENOMSG, msgrcv(id, &msg, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, msgrcv(id, (void *)-1, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg, + SSIZE_MAX, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + + errno = 0; + + ATF_REQUIRE_ERRNO(E2BIG, msgrcv(id, &r, + MSG_LEN - 1, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_err, tc) +{ + clean(); +} + + +ATF_TC_WITH_CLEANUP(msgrcv_mtype); +ATF_TC_HEAD(msgrcv_mtype, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test message types with msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_mtype, tc) +{ + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msg msg2 = { MSG_MTYPE_3, { 'x', 'y', 'z' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_2, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] != msg2.buf[0]); /* Different mtype. */ + ATF_CHECK(msg1.buf[1] != msg2.buf[1]); + ATF_CHECK(msg1.buf[2] != msg2.buf[2]); + + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); /* Same mtype. */ + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + ATF_CHECK(msg1.buf[2] == msg2.buf[2]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_mtype, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_nonblock); +ATF_TC_HEAD(msgrcv_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with IPC_NOWAIT"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgrcv_nonblock, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + const ssize_t n = 10; + int id, sta; + ssize_t i; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + for (i = 0; i < n; i++) { + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + } + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + while (i != 0) { + + if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, + IPC_NOWAIT) == -1) + _exit(EXIT_FAILURE); + + i--; + } + + _exit(EXIT_SUCCESS); + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL) + atf_tc_fail("msgrcv(2) blocked with IPC_NOWAIT"); + + if (WIFEXITED(sta) == 0 && WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("msgrcv(2) failed"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_nonblock, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_truncate); +ATF_TC_HEAD(msgrcv_truncate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with MSG_NOERROR"); +} + +ATF_TC_BODY(msgrcv_truncate, tc) +{ +#define MSG_SMALLLEN 2 + struct msgsmall { + long mtype; + char buf[MSG_SMALLLEN]; + }; + + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msgsmall msg2 = { MSG_MTYPE_1, { 'x', 'y' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_SMALLLEN, + MSG_MTYPE_1, IPC_NOWAIT | MSG_NOERROR); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_truncate, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgrcv_basic); + ATF_TP_ADD_TC(tp, msgrcv_block); + ATF_TP_ADD_TC(tp, msgrcv_err); + ATF_TP_ADD_TC(tp, msgrcv_mtype); + ATF_TP_ADD_TC(tp, msgrcv_nonblock); + ATF_TP_ADD_TC(tp, msgrcv_truncate); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c new file mode 100644 index 0000000..d30cb7b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c @@ -0,0 +1,342 @@ +/* $NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $"); + +#include <sys/msg.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <time.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#include <limits.h> +#endif + +#define MSG_KEY 1234 +#define MSG_MTYPE_1 0x41 +#define MSG_MTYPE_2 0x42 +#define MSG_MTYPE_3 0x43 + +struct msg { + long mtype; + char buf[3]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgsnd_block); +ATF_TC_HEAD(msgsnd_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that msgsnd(2) blocks"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_block, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Enqueue messages until some limit (e.g. the maximum + * number of messages in the queue or the maximum number + * of bytes in the queue) is reached. After this the call + * should block when the IPC_NOWAIT is not set. + */ + for (;;) { + + if (msgsnd(id, &msg, sizeof(struct msg), 0) < 0) + _exit(EXIT_FAILURE); + } + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) != 0 || WIFSIGNALED(sta) == 0) + atf_tc_fail("msgsnd(2) did not block"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_block, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_count); +ATF_TC_HEAD(msgsnd_count, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that msgsnd(2) increments the amount of " + "message in the queue, as given by msgctl(2)"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_count, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds ds; + size_t i = 0; + int id, rv; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + for (;;) { + + errno = 0; + rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + + if (rv == 0) { + i++; + continue; + } + + if (rv == -1 && errno == EAGAIN) + break; + + atf_tc_fail("failed to enqueue a message"); + } + + (void)memset(&ds, 0, sizeof(struct msqid_ds)); + (void)msgctl(id, IPC_STAT, &ds); + + if (ds.msg_qnum != i) + atf_tc_fail("incorrect message count"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_count, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_err); +ATF_TC_HEAD(msgsnd_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgsnd(2)"); +} + +ATF_TC_BODY(msgsnd_err, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, msgsnd(id, (void *)-1, + sizeof(struct msg), IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg, + sizeof(struct msg), IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg, + SSIZE_MAX, IPC_NOWAIT) == -1); + + errno = 0; + msg.mtype = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(id, &msg, + sizeof(struct msg), IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_err, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_nonblock); +ATF_TC_HEAD(msgsnd_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgsnd(2) with IPC_NOWAIT"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_nonblock, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, rv, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (;;) { + + errno = 0; + rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); + + if (rv == -1 && errno == EAGAIN) + _exit(EXIT_SUCCESS); + } + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0) + atf_tc_fail("msgsnd(2) blocked with IPC_NOWAIT"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_nonblock, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_perm); +ATF_TC_HEAD(msgsnd_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with msgsnd(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgsnd_perm, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct passwd *pw; + int id, sta; + pid_t pid; + uid_t uid; + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + + uid = pw->pw_uid; + ATF_REQUIRE(uid != 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Try to enqueue a message to the queue + * created by root as RW for owner only. + */ + if (setuid(uid) != 0) + _exit(EX_OSERR); + + id = msgget(MSG_KEY, 0); + + if (id == -1) + _exit(EX_OSERR); + + errno = 0; + + if (msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT) == 0) + _exit(EXIT_FAILURE); + + if (errno != EACCES) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (errno == EX_OSERR) + atf_tc_fail("system call failed"); + + atf_tc_fail("UID %u enqueued message to root's queue", uid); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_perm, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgsnd_block); + ATF_TP_ADD_TC(tp, msgsnd_count); + ATF_TP_ADD_TC(tp, msgsnd_err); + ATF_TP_ADD_TC(tp, msgsnd_nonblock); + ATF_TP_ADD_TC(tp, msgsnd_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msync.c b/contrib/netbsd-tests/lib/libc/sys/t_msync.c new file mode 100644 index 0000000..70d0ccf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msync.c @@ -0,0 +1,248 @@ +/* $NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $"); + +#include <sys/mman.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static long page = 0; +static const off_t off = 512; +static const char path[] = "msync"; + +static const char *msync_sync(const char *, int); + +static const char * +msync_sync(const char *garbage, int flags) +{ + char *buf, *map = MAP_FAILED; + const char *str = NULL; + size_t i, len; + ssize_t tot; + int fd, rv; + + /* + * Create a temporary file, write + * one page to it, and map the file. + */ + buf = malloc(page); + + if (buf == NULL) + return NULL; + + for (i = 0; i < (size_t)page; i++) + buf[i] = 'x'; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) { + str = "failed to open"; + goto out; + } + + tot = 0; + + while (tot < page) { + + rv = write(fd, buf, sizeof(buf)); + + if (rv < 0) { + str = "failed to write"; + goto out; + } + + tot += rv; + } + + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE, + fd, 0); + + if (map == MAP_FAILED) { + str = "failed to map"; + goto out; + } + + /* + * Seek to an arbitrary offset and + * write garbage to this position. + */ + if (lseek(fd, off, SEEK_SET) != off) { + str = "failed to seek"; + goto out; + } + + len = strlen(garbage); + rv = write(fd, garbage, len); + + if (rv != (ssize_t)len) { + str = "failed to write garbage"; + goto out; + } + + /* + * Synchronize the mapping and verify + * that garbage is at the given offset. + */ + if (msync(map, page, flags) != 0) { + str = "failed to msync"; + goto out; + } + + if (memcmp(map + off, garbage, len) != 0) { + str = "msync did not synchronize"; + goto out; + } + +out: + free(buf); + + (void)close(fd); + (void)unlink(path); + + if (map != MAP_FAILED) + (void)munmap(map, page); + + return str; +} + +ATF_TC(msync_async); +ATF_TC_HEAD(msync_async, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_ASYNC"); +} + +ATF_TC_BODY(msync_async, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_ASYNC); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(msync_err); +ATF_TC_HEAD(msync_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in msync(2)"); +} + +ATF_TC_BODY(msync_err, tc) +{ + + char *map = MAP_FAILED; + + /* + * Test that invalid flags error out. + */ +#ifdef __FreeBSD__ + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", -1) != NULL); + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", INT_MAX) != NULL); +#else + ATF_REQUIRE(msync_sync("error", -1) != NULL); + ATF_REQUIRE(msync_sync("error", INT_MAX) != NULL); +#endif + + errno = 0; + + /* + * Map a page and then unmap to get an unmapped address. + */ + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, + -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + (void)munmap(map, page); + + ATF_REQUIRE(msync(map, page, MS_SYNC) != 0); +#ifdef __FreeBSD__ + ATF_REQUIRE(errno == ENOMEM); +#else + ATF_REQUIRE(errno == EFAULT); +#endif +} + +ATF_TC(msync_invalidate); +ATF_TC_HEAD(msync_invalidate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_INVALIDATE"); +} + +ATF_TC_BODY(msync_invalidate, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_INVALIDATE); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(msync_sync); +ATF_TC_HEAD(msync_sync, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_SYNC"); +} + +ATF_TC_BODY(msync_sync, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_SYNC); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + + ATF_REQUIRE(page >= 0); + ATF_REQUIRE(page > off); + + ATF_TP_ADD_TC(tp, msync_async); + ATF_TP_ADD_TC(tp, msync_err); + ATF_TP_ADD_TC(tp, msync_invalidate); + ATF_TP_ADD_TC(tp, msync_sync); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c new file mode 100644 index 0000000..b4d9f8a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c @@ -0,0 +1,191 @@ +/* $NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $"); + +#include <sys/time.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <time.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> + +static void +#ifdef __FreeBSD__ +handler(int signo __unused) +#else +handler(int signo) +#endif +{ + /* Nothing. */ +} + +ATF_TC(nanosleep_basic); +ATF_TC_HEAD(nanosleep_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that nanosleep(2) works"); +} + +ATF_TC_BODY(nanosleep_basic, tc) +{ + static const size_t maxiter = 10; + struct timespec ts1, ts2, tsn; + size_t i; + + for (i = 1; i < maxiter; i++) { + + tsn.tv_sec = 0; + tsn.tv_nsec = i; + + (void)memset(&ts1, 0, sizeof(struct timespec)); + (void)memset(&ts2, 0, sizeof(struct timespec)); + + ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts1) == 0); + ATF_REQUIRE(nanosleep(&tsn, NULL) == 0); + ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts2) == 0); + + /* + * Verify that we slept at least one nanosecond. + */ + if (timespeccmp(&ts2, &ts1, <=) != 0) { + + (void)fprintf(stderr, + "sleep time:: sec %llu, nsec %lu\n\t\t" + "ts1: sec %llu, nsec %lu\n\t\t" + "ts2: sec %llu, nsec %lu\n", + (unsigned long long)tsn.tv_sec, tsn.tv_nsec, + (unsigned long long)ts1.tv_sec, ts1.tv_nsec, + (unsigned long long)ts2.tv_sec, ts2.tv_nsec); + + atf_tc_fail_nonfatal("inaccuracies in sleep time " + "(resolution = %lu nsec)", tsn.tv_nsec); + } + } +} + +ATF_TC(nanosleep_err); +ATF_TC_HEAD(nanosleep_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test errors from nanosleep(2) (PR bin/14558)"); +} + +ATF_TC_BODY(nanosleep_err, tc) +{ + struct timespec ts; + + ts.tv_sec = 1; + ts.tv_nsec = -1; + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1); + + ts.tv_sec = 1; + ts.tv_nsec = 1000000000; + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1); + + ts.tv_sec = -1; + ts.tv_nsec = 0; + errno = 0; + ATF_REQUIRE_ERRNO(0, nanosleep(&ts, NULL) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, nanosleep((void *)-1, NULL) == -1); +} + +ATF_TC(nanosleep_sig); +ATF_TC_HEAD(nanosleep_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test signal for nanosleep(2)"); +} + +ATF_TC_BODY(nanosleep_sig, tc) +{ + struct timespec tsn, tsr; + pid_t pid; + int sta; + + /* + * Test that a signal interrupts nanosleep(2). + * + * (In which case the return value should be -1 and the + * second parameter should contain the unslept time.) + */ + pid = fork(); + + ATF_REQUIRE(pid >= 0); + ATF_REQUIRE(signal(SIGINT, handler) == 0); + + if (pid == 0) { + + tsn.tv_sec = 10; + tsn.tv_nsec = 0; + + tsr.tv_sec = 0; + tsr.tv_nsec = 0; + + errno = 0; + + if (nanosleep(&tsn, &tsr) != -1) + _exit(EXIT_FAILURE); + + if (errno != EINTR) + _exit(EXIT_FAILURE); + + if (tsr.tv_sec == 0 && tsr.tv_nsec == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)kill(pid, SIGINT); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("signal did not interrupt nanosleep(2)"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nanosleep_basic); + ATF_TP_ADD_TC(tp, nanosleep_err); + ATF_TP_ADD_TC(tp, nanosleep_sig); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c new file mode 100644 index 0000000..b30b94d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_pipe.c,v 1.3 2011/10/31 15:41:31 christos Exp $ */ + +/*- + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pipe.c,v 1.3 2011/10/31 15:41:31 christos Exp $"); + +#include <sys/types.h> +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <poll.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +static pid_t pid; +static int nsiginfo = 0; + +/* + * This is used for both parent and child. Handle parent's SIGALRM, + * the childs SIGINFO doesn't need anything. + */ +static void +sighand(int sig) +{ + if (sig == SIGALRM) { + kill(pid, SIGINFO); + } + if (sig == SIGINFO) { + nsiginfo++; + } +} + +ATF_TC(pipe_restart); +ATF_TC_HEAD(pipe_restart, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that writing to pipe " + "works correctly after being interrupted and restarted " + "(kern/14087)"); +} + +ATF_TC_BODY(pipe_restart, tc) +{ + int pp[2], st; + ssize_t sz, todo, done; + char *f; + sigset_t asigset, osigset, emptysigset; + + /* Initialise signal masks */ + RL(sigemptyset(&emptysigset)); + RL(sigemptyset(&asigset)); + RL(sigaddset(&asigset, SIGINFO)); + + /* Register signal handlers for both read and writer */ + REQUIRE_LIBC(signal(SIGINFO, sighand), SIG_ERR); + REQUIRE_LIBC(signal(SIGALRM, sighand), SIG_ERR); + + todo = 2 * 1024 * 1024; + REQUIRE_LIBC(f = malloc(todo), NULL); + + RL(pipe(pp)); + + RL(pid = fork()); + if (pid == 0) { + /* child */ + RL(close(pp[1])); + + /* Do inital write. This should succeed, make + * the other side do partial write and wait for us to pick + * rest up. + */ + RL(done = read(pp[0], f, 128 * 1024)); + + /* Wait until parent is alarmed and awakens us */ + RL(sigprocmask(SIG_BLOCK, &asigset, &osigset)); + while (nsiginfo == 0) { + if (sigsuspend(&emptysigset) != -1 || errno != EINTR) + atf_tc_fail("sigsuspend(&emptysigset): %s", + strerror(errno)); + } + RL(sigprocmask(SIG_SETMASK, &osigset, NULL)); + + /* Read all what parent wants to give us */ + while((sz = read(pp[0], f, 1024 * 1024)) > 0) + done += sz; + + /* + * Exit with 1 if number of bytes read doesn't match + * number of expected bytes + */ + printf("Read: %#zx\n", (size_t)done); + printf("Expected: %#zx\n", (size_t)todo); + + exit(done != todo); + + /* NOTREACHED */ + } else { + RL(close(pp[0])); + + /* + * Arrange for alarm after two seconds. Since we have + * handler setup for SIGARLM, the write(2) call should + * be restarted internally by kernel. + */ + (void)alarm(2); + + /* We write exactly 'todo' bytes. The very first write(2) + * should partially succeed, block and eventually + * be restarted by kernel + */ + while(todo > 0 && ((sz = write(pp[1], f, todo)) > 0)) + todo -= sz; + + /* Close the pipe, so that child would stop reading */ + RL(close(pp[1])); + + /* And pickup child's exit status */ + RL(waitpid(pid, &st, 0)); + + ATF_REQUIRE_EQ(WEXITSTATUS(st), 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pipe_restart); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c new file mode 100644 index 0000000..8208cf7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c @@ -0,0 +1,210 @@ +/* $NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $"); + +#include <atf-c.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/resource.h> + +static void +run(int flags) +{ + int fd[2], i; + + while ((i = open("/", O_RDONLY)) < 3) + ATF_REQUIRE(i != -1); + +#ifdef __FreeBSD__ + closefrom(3); +#else + ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1); +#endif + + ATF_REQUIRE(pipe2(fd, flags) == 0); + + ATF_REQUIRE(fd[0] == 3); + ATF_REQUIRE(fd[1] == 4); + + if (flags & O_CLOEXEC) { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0); + } + + if (flags & O_NONBLOCK) { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0); + } + +#ifndef __FreeBSD__ + if (flags & O_NOSIGPIPE) { + ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) != 0); + ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) != 0); + } else { + ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) == 0); + ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) == 0); + } +#endif + + ATF_REQUIRE(close(fd[0]) != -1); + ATF_REQUIRE(close(fd[1]) != -1); +} + +ATF_TC(pipe2_basic); +ATF_TC_HEAD(pipe2_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_basic, tc) +{ + run(0); +} + +ATF_TC(pipe2_consume); +ATF_TC_HEAD(pipe2_consume, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that consuming file descriptors " + "with pipe2(2) does not crash the system (PR kern/46457)"); +} + +ATF_TC_BODY(pipe2_consume, tc) +{ + struct rlimit rl; + int err, filedes[2]; +#ifdef __FreeBSD__ + int old; + + closefrom(4); +#else + err = fcntl(4, F_CLOSEM); + ATF_REQUIRE(err == 0); +#endif + + err = getrlimit(RLIMIT_NOFILE, &rl); + ATF_REQUIRE(err == 0); + /* + * The heart of this test is to run against the number of open + * file descriptor limit in the middle of a pipe2() call - i.e. + * before the call only a single descriptor may be openend. + */ +#ifdef __FreeBSD__ + old = rl.rlim_cur; +#endif + rl.rlim_cur = 4; + err = setrlimit(RLIMIT_NOFILE, &rl); + ATF_REQUIRE(err == 0); + + err = pipe2(filedes, O_CLOEXEC); + ATF_REQUIRE(err == -1); +#ifdef __FreeBSD__ + rl.rlim_cur = old; + err = setrlimit(RLIMIT_NOFILE, &rl); +#endif +} + +ATF_TC(pipe2_nonblock); +ATF_TC_HEAD(pipe2_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "A non-blocking test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_nonblock, tc) +{ + run(O_NONBLOCK); +} + +ATF_TC(pipe2_cloexec); +ATF_TC_HEAD(pipe2_cloexec, tc) +{ + atf_tc_set_md_var(tc, "descr", "A close-on-exec test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_cloexec, tc) +{ + run(O_CLOEXEC); +} + +#ifdef __NetBSD__ +ATF_TC(pipe2_nosigpipe); +ATF_TC_HEAD(pipe2_nosigpipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "A no sigpipe test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_nosigpipe, tc) +{ + run(O_NOSIGPIPE); +} +#endif + +ATF_TC(pipe2_einval); +ATF_TC_HEAD(pipe2_einval, tc) +{ + atf_tc_set_md_var(tc, "descr", "A error check of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_einval, tc) +{ + int fd[2]; + ATF_REQUIRE_ERRNO(EINVAL, pipe2(fd, O_ASYNC) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pipe2_basic); + ATF_TP_ADD_TC(tp, pipe2_consume); + ATF_TP_ADD_TC(tp, pipe2_nonblock); + ATF_TP_ADD_TC(tp, pipe2_cloexec); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, pipe2_nosigpipe); +#endif + ATF_TP_ADD_TC(tp, pipe2_einval); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_poll.c b/contrib/netbsd-tests/lib/libc/sys/t_poll.c new file mode 100644 index 0000000..6214486 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_poll.c @@ -0,0 +1,396 @@ +/* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/time.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <poll.h> +#include <stdio.h> +#include <signal.h> +#include <unistd.h> + +static int desc; + +static void +child1(void) +{ + struct pollfd pfd; + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)poll(&pfd, 1, 2000); + (void)printf("child1 exit\n"); +} + +static void +child2(void) +{ + struct pollfd pfd; + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)sleep(1); + (void)poll(&pfd, 1, INFTIM); + (void)printf("child2 exit\n"); +} + +static void +child3(void) +{ + struct pollfd pfd; + + (void)sleep(5); + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)poll(&pfd, 1, INFTIM); + (void)printf("child3 exit\n"); +} + +ATF_TC(poll_3way); +ATF_TC_HEAD(poll_3way, tc) +{ + atf_tc_set_md_var(tc, "timeout", "15"); + atf_tc_set_md_var(tc, "descr", + "Check for 3-way collision for descriptor. First child comes " + "and polls on descriptor, second child comes and polls, first " + "child times out and exits, third child comes and polls. When " + "the wakeup event happens, the two remaining children should " + "both be awaken. (kern/17517)"); +} + +ATF_TC_BODY(poll_3way, tc) +{ + int pf[2]; + int status, i; + pid_t pid; + + pipe(pf); + desc = pf[0]; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child1(); + _exit(0); + /* NOTREACHED */ + } + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child2(); + _exit(0); + /* NOTREACHED */ + } + + pid = fork(); + ATF_REQUIRE( pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child3(); + _exit(0); + /* NOTREACHED */ + } + + (void)sleep(10); + + (void)printf("parent write\n"); + + ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6); + + for(i = 0; i < 3; ++i) + (void)wait(&status); + + (void)printf("parent terminated\n"); +} + +ATF_TC(poll_basic); +ATF_TC_HEAD(poll_basic, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Basis functionality test for poll(2)"); +} + +ATF_TC_BODY(poll_basic, tc) +{ + int fds[2]; + struct pollfd pfds[2]; + int ret; + + ATF_REQUIRE_EQ(pipe(fds), 0); + + pfds[0].fd = fds[0]; + pfds[0].events = POLLIN; + pfds[1].fd = fds[1]; + pfds[1].events = POLLOUT; + + /* + * Check that we get a timeout waiting for data on the read end + * of our pipe. + */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); + + /* Check that the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ + pfds[1].revents); + + /* Check that only the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + /* Write data to our pipe. */ + ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + + /* Check that both ends of our pipe are reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", + pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + ATF_REQUIRE_EQ(close(fds[0]), 0); + ATF_REQUIRE_EQ(close(fds[1]), 0); +} + +ATF_TC(poll_err); +ATF_TC_HEAD(poll_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)"); +} + +ATF_TC_BODY(poll_err, tc) +{ + struct pollfd pfd; + int fd = 0; + + pfd.fd = fd; + pfd.events = POLLIN; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1); +} + +#ifndef __FreeBSD__ +ATF_TC(pollts_basic); +ATF_TC_HEAD(pollts_basic, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Basis functionality test for pollts(2)"); +} + +ATF_TC_BODY(pollts_basic, tc) +{ + int fds[2]; + struct pollfd pfds[2]; + struct timespec timeout; + int ret; + + ATF_REQUIRE_EQ(pipe(fds), 0); + + pfds[0].fd = fds[0]; + pfds[0].events = POLLIN; + pfds[1].fd = fds[1]; + pfds[1].events = POLLOUT; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* + * Check that we get a timeout waiting for data on the read end + * of our pipe. + */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); + + /* Check that the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ + pfds[1].revents); + + /* Check that only the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + /* Write data to our pipe. */ + ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + + /* Check that both ends of our pipe are reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", + pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + ATF_REQUIRE_EQ(close(fds[0]), 0); + ATF_REQUIRE_EQ(close(fds[1]), 0); +} + +ATF_TC(pollts_err); +ATF_TC_HEAD(pollts_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)"); +} + +ATF_TC_BODY(pollts_err, tc) +{ + struct timespec timeout; + struct pollfd pfd; + int fd = 0; + + pfd.fd = fd; + pfd.events = POLLIN; + + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1); + + timeout.tv_sec = -1; + timeout.tv_nsec = -1; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1); +} + +ATF_TC(pollts_sigmask); +ATF_TC_HEAD(pollts_sigmask, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Check that pollts(2) restores the signal mask (PR kern/44986)"); +} + +ATF_TC_BODY(pollts_sigmask, tc) +{ + int fd; + struct pollfd pfd; + struct timespec timeout; + sigset_t mask; + int ret; + + fd = open(_PATH_DEVNULL, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + pfd.fd = fd; + pfd.events = POLLIN; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* Unblock all signals. */ + ATF_REQUIRE_EQ(sigfillset(&mask), 0); + ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0); + + /* + * Check that pollts(2) immediately returns. We block *all* + * signals during pollts(2). + */ + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1, + "got: %d", ret); + + /* Check that signals are now longer blocked. */ + ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0); + ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0, + "signal mask was changed."); + + ATF_REQUIRE_EQ(close(fd), 0); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, poll_3way); + ATF_TP_ADD_TC(tp, poll_basic); + ATF_TP_ADD_TC(tp, poll_err); +#ifndef __FreeBSD__ + ATF_TP_ADD_TC(tp, pollts_basic); + ATF_TP_ADD_TC(tp, pollts_err); + ATF_TP_ADD_TC(tp, pollts_sigmask); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c new file mode 100644 index 0000000..da4e746 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_posix_fadvise.c,v 1.1 2011/10/15 06:10:26 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by YAMAMOTO Takashi. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c)2005 YAMAMOTO Takashi, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_posix_fadvise.c,v 1.1 2011/10/15 06:10:26 jruoho Exp $"); + +#include <sys/fcntl.h> + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +ATF_TC(posix_fadvise); +ATF_TC_HEAD(posix_fadvise, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2)"); +} + +ATF_TC(posix_fadvise_reg); +ATF_TC_HEAD(posix_fadvise_reg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2) " + "for regular files"); +} + +ATF_TC_BODY(posix_fadvise, tc) +{ + int fd; + int pipe_fds[2]; + int badfd = 10; + int ret; + + RL(fd = open("/dev/null", O_RDWR)); + + (void)close(badfd); + RL(pipe(pipe_fds)); + + /* + * it's hard to check if posix_fadvise is working properly. + * only check return values here. + */ + + /* posix_fadvise shouldn't affect errno. */ + +#define CE(x, exp) \ + do { \ + int save = errno; \ + errno = 999; \ + ATF_CHECK_EQ_MSG(ret = (x), exp, "got: %d", ret); \ + ATF_CHECK_EQ_MSG(errno, 999, "got: %s", strerror(errno)); \ + errno = save; \ + } while (0); + + CE(posix_fadvise(fd, 0, 0, -1), EINVAL); + CE(posix_fadvise(pipe_fds[0], 0, 0, POSIX_FADV_NORMAL), ESPIPE); + CE(posix_fadvise(badfd, 0, 0, POSIX_FADV_NORMAL), EBADF); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NORMAL), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE), 0); +} + +ATF_TC_BODY(posix_fadvise_reg, tc) +{ + int rfd, ret; + + rump_init(); + RL(rfd = rump_sys_open("/a_file", O_CREAT, 0666)); + + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NORMAL), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_SEQUENTIAL), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_RANDOM), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_WILLNEED), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NOREUSE), 0); + + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NORMAL), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_SEQUENTIAL), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_RANDOM), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_WILLNEED), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NOREUSE), 0); + + //atf_tc_expect_signal(-1, "http://mail-index.netbsd.org/source-changes-d/2010/11/11/msg002508.html"); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_DONTNEED), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_DONTNEED), 0); +#undef CE +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, posix_fadvise); + ATF_TP_ADD_TC(tp, posix_fadvise_reg); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c new file mode 100644 index 0000000..76bc7dd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c @@ -0,0 +1,161 @@ +/* $NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jared McNeill and Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $"); + +#include <atf-c.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/wait.h> + +#include <string.h> +#include <time.h> +#include <stdint.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sched.h> + +#define BUFSIZE 65536 +#define NPKTS 50 + +#define min(a, b) ((a) < (b) ? (a) : (b)) +static int debug; + + +ATF_TC(recvmmsg_basic); +ATF_TC_HEAD(recvmmsg_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of recvmmsg(2)"); +} + +ATF_TC_BODY(recvmmsg_basic, tc) +{ + int fd[2], error, i, cnt; + uint8_t *buf; + struct mmsghdr *mmsghdr; + struct iovec *iov; + unsigned int mmsgcnt, n; + int status; + off_t off; + uint8_t DGRAM[1316] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, }; + + error = socketpair(AF_UNIX, SOCK_DGRAM, 0, fd); + ATF_REQUIRE_MSG(error != -1, "socketpair failed (%s)", strerror(errno)); + + buf = malloc(BUFSIZE); + ATF_REQUIRE_MSG(buf != NULL, "malloc failed (%s)", strerror(errno)); + + mmsgcnt = BUFSIZE / sizeof(DGRAM); + mmsghdr = malloc(sizeof(*mmsghdr) * mmsgcnt); + ATF_REQUIRE_MSG(mmsghdr != NULL, "malloc failed (%s)", strerror(errno)); + iov = malloc(sizeof(*iov) * mmsgcnt); + ATF_REQUIRE_MSG(iov != NULL, "malloc failed (%s)", strerror(errno)); + + for (off = 0, n = 0; n < mmsgcnt; n++) { + iov[n].iov_base = buf + off; + iov[n].iov_len = sizeof(DGRAM); + off += iov[n].iov_len; + mmsghdr[n].msg_hdr.msg_iov = &iov[n]; + mmsghdr[n].msg_hdr.msg_iovlen = 1; + mmsghdr[n].msg_hdr.msg_name = NULL; + mmsghdr[n].msg_hdr.msg_namelen = 0; + } + + switch (fork()) { + case -1: + ATF_REQUIRE_MSG(0, "fork failed (%s)", strerror(errno)); + break; + + case 0: + n = NPKTS; + if (debug) + printf("waiting for %u messages (max %u per syscall)\n", n, + mmsgcnt); + while (n > 0) { + struct timespec ts = { 1, 0 }; + cnt = recvmmsg(fd[1], mmsghdr, min(mmsgcnt, n), + MSG_WAITALL, &ts); + ATF_REQUIRE_MSG(cnt != -1, "recvmmsg failed (%s)", + strerror(errno)); + ATF_REQUIRE_MSG(cnt != 0, "recvmmsg timeout"); + if (debug) + printf("recvmmsg: got %u messages\n", cnt); + for (i = 0; i < cnt; i++) { + ATF_CHECK_EQ_MSG(mmsghdr[i].msg_len, + sizeof(DGRAM), "packet length"); + ATF_CHECK_EQ_MSG( + ((uint8_t *)iov[i].iov_base)[0], + NPKTS - n + i, "packet contents"); + } + n -= cnt; + } + if (debug) + printf("done!\n"); + exit(0); + /*NOTREACHED*/ + default: + sched_yield(); + + for (n = 0; n < NPKTS; n++) { + if (debug) + printf("sending packet %u/%u...\n", (n+1), + NPKTS); + do { + DGRAM[0] = n; + error = send(fd[0], DGRAM, sizeof(DGRAM), 0); + } while (error == -1 && errno == ENOBUFS); + if (error == -1) + ATF_REQUIRE_MSG(error != -1, "send failed (%s)", + strerror(errno)); + } + error = wait(&status); + ATF_REQUIRE_MSG(error != -1, "wait failed (%s)", + strerror(errno)); + break; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, recvmmsg_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_revoke.c b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c new file mode 100644 index 0000000..926d2740 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c @@ -0,0 +1,195 @@ +/* $NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $"); + +#include <sys/resource.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const char path[] = "revoke"; + +ATF_TC_WITH_CLEANUP(revoke_basic); +ATF_TC_HEAD(revoke_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of revoke(2)"); +} + +ATF_TC_BODY(revoke_basic, tc) +{ + struct rlimit res; + char tmp[10]; + size_t i, n; + int *buf; + +#ifdef __FreeBSD__ + atf_tc_skip("revoke(2) is only implemented for devfs(5)."); +#endif + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + if ((n = res.rlim_cur / 10) == 0) + n = 10; + + buf = calloc(n, sizeof(int)); + ATF_REQUIRE(buf != NULL); + + buf[0] = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(buf[0] >= 0); + + for (i = 1; i < n; i++) { + buf[i] = open(path, O_RDWR); + ATF_REQUIRE(buf[i] >= 0); + } + + ATF_REQUIRE(revoke(path) == 0); + + for (i = 0; i < n; i++) { + + ATF_REQUIRE(read(buf[i], tmp, sizeof(tmp)) == -1); + + (void)close(buf[i]); + } + + free(buf); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(revoke_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(revoke_err); +ATF_TC_HEAD(revoke_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from revoke(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(revoke_err, tc) +{ + char buf[1024 + 1]; /* XXX: From the manual page... */ + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, revoke((char *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, revoke(buf) == -1); + +#ifdef __FreeBSD__ + atf_tc_skip("revoke(2) is only implemented for devfs(5)."); +#endif + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, revoke("/etc/passwd") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, revoke("/etc/xxx/yyy") == -1); +} + +ATF_TC_WITH_CLEANUP(revoke_perm); +ATF_TC_HEAD(revoke_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions revoke(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(revoke_perm, tc) +{ + struct passwd *pw; + int fd, sta; + pid_t pid; + +#ifdef __FreeBSD__ + atf_tc_skip("revoke(2) is only implemented for devfs(5)."); +#endif + pw = getpwnam("nobody"); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(revoke(path) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (revoke(path) == 0) + _exit(EXIT_FAILURE); + + if (errno != EACCES) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("revoke(2) did not obey permissions"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(revoke_perm, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, revoke_basic); + ATF_TP_ADD_TC(tp, revoke_err); + ATF_TP_ADD_TC(tp, revoke_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_select.c b/contrib/netbsd-tests/lib/libc/sys/t_select.c new file mode 100644 index 0000000..7af725a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_select.c @@ -0,0 +1,223 @@ +/* $NetBSD: t_select.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundatiom + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <sys/types.h> +#include <sys/select.h> +#include <sys/wait.h> +#include <err.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + +#include <atf-c.h> + +static sig_atomic_t keep_going = 1; + +static void +#ifdef __FreeBSD__ +sig_handler(int signum __unused) +#else +sig_handler(int signum) +#endif +{ + keep_going = 0; +} + +static void +#ifdef __FreeBSD__ +sigchld(int signum __unused) +#else +sigchld(int signum) +#endif +{ +} + +static char +xtoa(uint8_t n) +{ + static const char xarray[] = "0123456789abcdef"; + assert(n < sizeof(xarray)); + return xarray[n]; +} + +static const char * +prmask(const sigset_t *m, char *buf, size_t len) +{ + size_t j = 2; + assert(len >= 3 + sizeof(*m)); + buf[0] = '0'; + buf[1] = 'x'; +#define N(p, a) (((p) >> ((a) * 4)) & 0xf) + for (size_t i = __arraycount(m->__bits); i > 0; i--) { + uint32_t p = m->__bits[i - 1]; + for (size_t k = sizeof(p); k > 0; k--) + buf[j++] = xtoa(N(p, k - 1)); + } + buf[j] = '\0'; + return buf; +} + +static void +child(const struct timespec *ts) +{ + struct sigaction sa; + sigset_t set, oset, nset; + char obuf[sizeof(oset) + 3], nbuf[sizeof(nset) + 3]; + int fd; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sig_handler; + if ((fd = open("/dev/null", O_RDONLY)) == -1) + err(1, "open"); + + if (sigaction(SIGTERM, &sa, NULL) == -1) + err(1, "sigaction"); + + sigfillset(&set); + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) + err(1, "sigprocmask"); + + if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1) + err(1, "sigprocmask"); + + sigemptyset(&set); + + for (;;) { + fd_set rset; + FD_ZERO(&rset); + FD_SET(fd, &rset); + if (pselect(1, &rset, NULL, NULL, ts, &set) == -1) { + if(errno == EINTR) { + if (!keep_going) + break; + } + } + if (ts) + break; + } + if (sigprocmask(SIG_BLOCK, NULL, &nset) == -1) + err(1, "sigprocmask"); + if (memcmp(&oset, &nset, sizeof(oset)) != 0) + atf_tc_fail("pselect() masks don't match " + "after timeout %s != %s", + prmask(&nset, nbuf, sizeof(nbuf)), + prmask(&oset, obuf, sizeof(obuf))); +} + +ATF_TC(pselect_sigmask); +ATF_TC_HEAD(pselect_sigmask, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask " + "setting when a signal is received (PR lib/43625)"); +} + +ATF_TC_BODY(pselect_sigmask, tc) +{ + pid_t pid; + int status; + + signal(SIGCHLD, sigchld); + + switch (pid = fork()) { + case 0: + child(NULL); + case -1: + err(1, "fork"); + default: + sleep(1); + if (kill(pid, SIGTERM) == -1) + err(1, "kill"); + sleep(1); + switch (waitpid(pid, &status, WNOHANG)) { + case -1: + err(1, "wait"); + case 0: + if (kill(pid, SIGKILL) == -1) + err(1, "kill"); + atf_tc_fail("pselect() did not receive signal"); + break; + default: + break; + } + } +} + +ATF_TC(pselect_timeout); +ATF_TC_HEAD(pselect_timeout, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask " + "setting when a timeout occurs"); +} + +ATF_TC_BODY(pselect_timeout, tc) +{ + pid_t pid; + int status; + static const struct timespec zero = { 0, 0 }; + + signal(SIGCHLD, sigchld); + + switch (pid = fork()) { + case 0: + child(&zero); + break; + case -1: + err(1, "fork"); + default: + sleep(1); + switch (waitpid(pid, &status, WNOHANG)) { + case -1: + err(1, "wait"); + case 0: + if (kill(pid, SIGKILL) == -1) + err(1, "kill"); + atf_tc_fail("pselect() did not receive signal"); + break; + default: + break; + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pselect_sigmask); + ATF_TP_ADD_TC(tp, pselect_timeout); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c new file mode 100644 index 0000000..72175e4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c @@ -0,0 +1,532 @@ +/* $NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $"); + +#include <sys/resource.h> +#include <sys/mman.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#ifdef __NetBSD__ +#include <lwp.h> +#endif +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ucontext.h> +#include <unistd.h> + +static void sighandler(int); +static const char path[] = "setrlimit"; + +static const int rlimit[] = { + RLIMIT_AS, + RLIMIT_CORE, + RLIMIT_CPU, + RLIMIT_DATA, + RLIMIT_FSIZE, + RLIMIT_MEMLOCK, + RLIMIT_NOFILE, + RLIMIT_NPROC, + RLIMIT_RSS, + RLIMIT_SBSIZE, + RLIMIT_STACK +}; + +ATF_TC(setrlimit_basic); +ATF_TC_HEAD(setrlimit_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic soft limit test"); +} + +ATF_TC_BODY(setrlimit_basic, tc) +{ + struct rlimit res; + int *buf, lim; + size_t i; + + buf = calloc(__arraycount(rlimit), sizeof(int)); + + if (buf == NULL) + atf_tc_fail("initialization failed"); + + for (i = lim = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + if (getrlimit(rlimit[i], &res) != 0) + continue; + + if (res.rlim_cur == RLIM_INFINITY || res.rlim_cur == 0) + continue; + + if (res.rlim_cur == res.rlim_max) /* An unprivileged run. */ + continue; + + buf[i] = res.rlim_cur; + res.rlim_cur = res.rlim_cur - 1; + + if (setrlimit(rlimit[i], &res) != 0) { + lim = rlimit[i]; + goto out; + } + } + +out: + for (i = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + if (buf[i] == 0) + continue; + + if (getrlimit(rlimit[i], &res) != 0) + continue; + + res.rlim_cur = buf[i]; + + (void)setrlimit(rlimit[i], &res); + } + + if (lim != 0) + atf_tc_fail("failed to set limit (%d)", lim); +} + +ATF_TC(setrlimit_current); +ATF_TC_HEAD(setrlimit_current, tc) +{ + atf_tc_set_md_var(tc, "descr", "setrlimit(3) with current limits"); +} + +ATF_TC_BODY(setrlimit_current, tc) +{ + struct rlimit res; + size_t i; + + for (i = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0); + ATF_REQUIRE(setrlimit(rlimit[i], &res) == 0); + } +} + +ATF_TC(setrlimit_err); +ATF_TC_HEAD(setrlimit_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions"); +} + +ATF_TC_BODY(setrlimit_err, tc) +{ + struct rlimit res; + size_t i; + + for (i = 0; i < __arraycount(rlimit); i++) { + + errno = 0; + + ATF_REQUIRE(getrlimit(rlimit[i], (void *)0) != 0); + ATF_REQUIRE(errno == EFAULT); + } + + errno = 0; + + ATF_REQUIRE(getrlimit(INT_MAX, &res) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC_WITH_CLEANUP(setrlimit_fsize); +ATF_TC_HEAD(setrlimit_fsize, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_FSIZE"); +} + +ATF_TC_BODY(setrlimit_fsize, tc) +{ + struct rlimit res; + int fd, sta; + pid_t pid; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + atf_tc_fail("initialization failed"); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + res.rlim_cur = 2; + res.rlim_max = 2; + + if (setrlimit(RLIMIT_FSIZE, &res) != 0) + _exit(EXIT_FAILURE); + + if (signal(SIGXFSZ, sighandler) == SIG_ERR) + _exit(EXIT_FAILURE); + + /* + * The third call should generate a SIGXFSZ. + */ + (void)write(fd, "X", 1); + (void)write(fd, "X", 1); + (void)write(fd, "X", 1); + + _exit(EXIT_FAILURE); + } + + (void)close(fd); + (void)wait(&sta); + (void)unlink(path); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_FSIZE not enforced"); +} + +ATF_TC_CLEANUP(setrlimit_fsize, tc) +{ + (void)unlink(path); +} + +static void +sighandler(int signo) +{ + + if (signo != SIGXFSZ) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); +} + +ATF_TC(setrlimit_memlock); +ATF_TC_HEAD(setrlimit_memlock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK"); +} + +ATF_TC_BODY(setrlimit_memlock, tc) +{ + struct rlimit res; + void *buf; + long page; + pid_t pid; + int sta; + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + buf = malloc(page); + pid = fork(); + + if (buf == NULL || pid < 0) + atf_tc_fail("initialization failed"); + + if (pid == 0) { + + /* + * Try to lock a page while + * RLIMIT_MEMLOCK is zero. + */ + if (mlock(buf, page) != 0) + _exit(EXIT_FAILURE); + + if (munlock(buf, page) != 0) + _exit(EXIT_FAILURE); + + res.rlim_cur = 0; + res.rlim_max = 0; + + if (setrlimit(RLIMIT_MEMLOCK, &res) != 0) + _exit(EXIT_FAILURE); + + if (mlock(buf, page) != 0) + _exit(EXIT_SUCCESS); + + (void)munlock(buf, page); + + _exit(EXIT_FAILURE); + } + + free(buf); + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_MEMLOCK not enforced"); +} + +ATF_TC(setrlimit_nofile_1); +ATF_TC_HEAD(setrlimit_nofile_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #1"); +} + +ATF_TC_BODY(setrlimit_nofile_1, tc) +{ + struct rlimit res; + int fd, i, rv, sta; + pid_t pid; + + res.rlim_cur = 0; + res.rlim_max = 0; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Close all descriptors, set RLIMIT_NOFILE + * to zero, and try to open a random file. + * This should fail with EMFILE. + */ + for (i = 0; i < 1024; i++) + (void)close(i); + + rv = setrlimit(RLIMIT_NOFILE, &res); + + if (rv != 0) + _exit(EXIT_FAILURE); + + errno = 0; + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0 || errno != EMFILE) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NOFILE not enforced"); +} + +ATF_TC(setrlimit_nofile_2); +ATF_TC_HEAD(setrlimit_nofile_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #2"); +} + +ATF_TC_BODY(setrlimit_nofile_2, tc) +{ + static const rlim_t lim = 12; + struct rlimit res; + int fd, i, rv, sta; + pid_t pid; + + /* + * See that an arbitrary limit on + * open files is being enforced. + */ + res.rlim_cur = lim; + res.rlim_max = lim; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (i = 0; i < 1024; i++) + (void)close(i); + + rv = setrlimit(RLIMIT_NOFILE, &res); + + if (rv != 0) + _exit(EXIT_FAILURE); + + for (i = 0; i < (int)lim; i++) { + + fd = open("/etc/passwd", O_RDONLY); + + if (fd < 0) + _exit(EXIT_FAILURE); + } + + /* + * After the limit has been reached, + * EMFILE should again follow. + */ + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0 || errno != EMFILE) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NOFILE not enforced"); +} + +ATF_TC(setrlimit_nproc); +ATF_TC_HEAD(setrlimit_nproc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NPROC"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_nproc, tc) +{ + struct rlimit res; + pid_t pid, cpid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Set RLIMIT_NPROC to zero and try to fork. + */ + res.rlim_cur = 0; + res.rlim_max = 0; + + if (setrlimit(RLIMIT_NPROC, &res) != 0) + _exit(EXIT_FAILURE); + + cpid = fork(); + + if (cpid < 0) + _exit(EXIT_SUCCESS); + + _exit(EXIT_FAILURE); + } + + (void)waitpid(pid, &sta, 0); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NPROC not enforced"); +} + +#ifdef __NetBSD__ +ATF_TC(setrlimit_nthr); +ATF_TC_HEAD(setrlimit_nthr, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NTHR"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +static void +func(lwpid_t *id) +{ + printf("thread %d\n", *id); + fflush(stdout); + _lwp_exit(); +} + +ATF_TC_BODY(setrlimit_nthr, tc) +{ + struct rlimit res; + lwpid_t lwpid; + ucontext_t c; + + /* + * Set RLIMIT_NTHR to zero and try to create a thread. + */ + res.rlim_cur = 0; + res.rlim_max = 0; + ATF_REQUIRE(setrlimit(RLIMIT_NTHR, &res) == 0); + ATF_REQUIRE(getcontext(&c) == 0); + c.uc_link = NULL; + sigemptyset(&c.uc_sigmask); + c.uc_stack.ss_flags = 0; + c.uc_stack.ss_size = 4096; + ATF_REQUIRE((c.uc_stack.ss_sp = malloc(c.uc_stack.ss_size)) != NULL); + makecontext(&c, func, 1, &lwpid); + ATF_CHECK_ERRNO(EAGAIN, _lwp_create(&c, 0, &lwpid) == -1); +} +#endif + +ATF_TC(setrlimit_perm); +ATF_TC_HEAD(setrlimit_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2) for EPERM"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_perm, tc) +{ + struct rlimit res; + size_t i; + + /* + * Try to raise the maximum limits as an user. + */ + for (i = 0; i < __arraycount(rlimit); i++) { + + ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0); + +#ifdef __FreeBSD__ + if (res.rlim_max == INT64_MAX) /* Overflow. */ +#else + if (res.rlim_max == UINT64_MAX) /* Overflow. */ +#endif + continue; + + errno = 0; + res.rlim_max = res.rlim_max + 1; + + ATF_CHECK_ERRNO(EPERM, setrlimit(rlimit[i], &res) != 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, setrlimit_basic); + ATF_TP_ADD_TC(tp, setrlimit_current); + ATF_TP_ADD_TC(tp, setrlimit_err); + ATF_TP_ADD_TC(tp, setrlimit_fsize); + ATF_TP_ADD_TC(tp, setrlimit_memlock); + ATF_TP_ADD_TC(tp, setrlimit_nofile_1); + ATF_TP_ADD_TC(tp, setrlimit_nofile_2); + ATF_TP_ADD_TC(tp, setrlimit_nproc); + ATF_TP_ADD_TC(tp, setrlimit_perm); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, setrlimit_nthr); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setuid.c b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c new file mode 100644 index 0000000..d2bf523 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c @@ -0,0 +1,122 @@ +/* $NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <pwd.h> +#include <stdlib.h> +#include <unistd.h> + +ATF_TC(setuid_perm); +ATF_TC_HEAD(setuid_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setuid(0) as normal user"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setuid_perm, tc) +{ + errno = 0; + + ATF_REQUIRE(setuid(0) == -1); + ATF_REQUIRE(errno == EPERM); +} + +ATF_TC(setuid_real); +ATF_TC_HEAD(setuid_real, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setuid(2) with real UID"); +} + +ATF_TC_BODY(setuid_real, tc) +{ + uid_t uid = getuid(); + + ATF_REQUIRE(setuid(uid) == 0); + + ATF_REQUIRE(getuid() == uid); + ATF_REQUIRE(geteuid() == uid); +} + +ATF_TC(setuid_root); +ATF_TC_HEAD(setuid_root, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setuid(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setuid_root, tc) +{ + struct passwd *pw; + int rv, sta; + pid_t pid; + uid_t uid; + + while ((pw = getpwent()) != NULL) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = setuid(pw->pw_uid); + + if (rv != 0) + _exit(EXIT_FAILURE); + + uid = getuid(); + + if (uid != pw->pw_uid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to change UID to %u", pw->pw_uid); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, setuid_perm); + ATF_TP_ADD_TC(tp, setuid_real); + ATF_TP_ADD_TC(tp, setuid_root); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c new file mode 100644 index 0000000..23ca36a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_sigaction.c,v 1.3 2014/11/04 00:20:19 justin Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigaction.c,v 1.3 2014/11/04 00:20:19 justin Exp $"); + +#include <sys/wait.h> + +#include <signal.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#ifdef __NetBSD__ +#include "../../../h_macros.h" +#else +#include "h_macros.h" +#endif + +static bool handler_called = false; + +static void +#ifdef __FreeBSD__ +handler(int signo __unused) +#else +handler(int signo) +#endif +{ + handler_called = true; +} + +static void +sa_resethand_child(const int flags) +{ + struct sigaction sa; + + sa.sa_flags = flags; + sa.sa_handler = &handler; + sigemptyset(&sa.sa_mask); + + sigaction(SIGUSR1, &sa, NULL); + kill(getpid(), SIGUSR1); + exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE); +} + +static void +wait_and_check_child(const pid_t pid, const char *fail_message) +{ + int status; + + (void)waitpid(pid, &status, 0); + + if (WIFEXITED(status)) + ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); + else + atf_tc_fail("%s; raw exit status was %d", fail_message, status); +} + +static void +#ifdef __FreeBSD__ +catch(int sig __unused) +#else +catch(int sig) +#endif +{ + return; +} + +ATF_TC(sigaction_basic); +ATF_TC_HEAD(sigaction_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache" + "synchronization after copying out the trampoline code."); +} + +ATF_TC_BODY(sigaction_basic, tc) +{ + static struct sigaction sa; + + sa.sa_handler = catch; + + sigaction(SIGUSR1, &sa, 0); + kill(getpid(), SIGUSR1); + atf_tc_pass(); +} + +ATF_TC(sigaction_noflags); +ATF_TC_HEAD(sigaction_noflags, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks programming a signal with " + "sigaction(2) but without any flags"); +} + +ATF_TC_BODY(sigaction_noflags, tc) +{ + const pid_t pid = fork(); + if (pid == -1) + atf_tc_fail_errno("fork(2) failed"); + else if (pid == 0) + sa_resethand_child(0); + else + wait_and_check_child(pid, "Child process did not exit cleanly;" + " it failed to process the signal"); +} + +ATF_TC(sigaction_resethand); +ATF_TC_HEAD(sigaction_resethand, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works"); +} + +ATF_TC_BODY(sigaction_resethand, tc) +{ + const pid_t pid = fork(); + if (pid == -1) + atf_tc_fail_errno("fork(2) failed"); + else if (pid == 0) + sa_resethand_child(SA_RESETHAND); + else { + wait_and_check_child(pid, "Child process did not exit cleanly;" + " it either failed to process the signal or SA_RESETHAND" + " is broken"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigaction_basic); + ATF_TP_ADD_TC(tp, sigaction_noflags); + ATF_TP_ADD_TC(tp, sigaction_resethand); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c new file mode 100644 index 0000000..6686f02 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c @@ -0,0 +1,115 @@ +/* $NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $"); + + +#include <atf-c.h> +#include <errno.h> +#include <signal.h> +#include <stdlib.h> +#include <sched.h> +#include <unistd.h> + +static void handler(int, siginfo_t *, void *); + +#define VALUE (int)0xc001dad1 +static int value; + +static void +#ifdef __FreeBSD__ +handler(int signo __unused, siginfo_t *info __unused, void *data __unused) +#else +handler(int signo, siginfo_t *info, void *data) +#endif +{ + value = info->si_value.sival_int; + kill(0, SIGINFO); +} + +ATF_TC(sigqueue_basic); +ATF_TC_HEAD(sigqueue_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigqueue(3) sigval delivery"); +} + +ATF_TC_BODY(sigqueue_basic, tc) +{ + struct sigaction sa; + union sigval sv; + + sa.sa_sigaction = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + if (sigaction(SIGUSR1, &sa, NULL) != 0) + atf_tc_fail("sigaction failed"); + + sv.sival_int = VALUE; + +#ifdef __FreeBSD__ + /* + * From kern_sig.c: + * Specification says sigqueue can only send signal to single process. + */ + if (sigqueue(getpid(), SIGUSR1, sv) != 0) +#else + if (sigqueue(0, SIGUSR1, sv) != 0) +#endif + atf_tc_fail("sigqueue failed"); + + sched_yield(); + ATF_REQUIRE_EQ(sv.sival_int, value); +} + +ATF_TC(sigqueue_err); +ATF_TC_HEAD(sigqueue_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from sigqueue(3)"); +} + +ATF_TC_BODY(sigqueue_err, tc) +{ + union sigval sv; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, sigqueue(getpid(), -1, sv) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigqueue_basic); + ATF_TP_ADD_TC(tp, sigqueue_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c new file mode 100644 index 0000000..64b68d9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c @@ -0,0 +1,126 @@ +/* $NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $"); + +#include <sys/time.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <atf-c.h> + + +ATF_TC(sigtimedwait_all0timeout); + +ATF_TC_HEAD(sigtimedwait_all0timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", "Test for PR kern/47625: sigtimedwait" + " with a timeout value of all zero should return imediately"); +} + +ATF_TC_BODY(sigtimedwait_all0timeout, tc) +{ + sigset_t block; + struct timespec ts, before, after, len; + siginfo_t info; + int r; + + sigemptyset(&block); + ts.tv_sec = 0; + ts.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &before); + r = sigtimedwait(&block, &info, &ts); + clock_gettime(CLOCK_MONOTONIC, &after); + ATF_REQUIRE(r == -1); + ATF_REQUIRE_ERRNO(EAGAIN, errno); + timespecsub(&after, &before, &len); + ATF_REQUIRE(len.tv_sec < 1); +} + +ATF_TC(sigtimedwait_NULL_timeout); + +ATF_TC_HEAD(sigtimedwait_NULL_timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", "Test sigtimedwait() without timeout"); +} + +ATF_TC_BODY(sigtimedwait_NULL_timeout, tc) +{ + sigset_t sig; + siginfo_t info; + struct itimerval it; + int r; + + /* arrange for a SIGALRM signal in a few seconds */ + memset(&it, 0, sizeof it); + it.it_value.tv_sec = 5; + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0); + + /* wait without timeout */ + sigemptyset(&sig); + sigaddset(&sig, SIGALRM); + r = sigtimedwait(&sig, &info, NULL); + ATF_REQUIRE(r == SIGALRM); +} + +ATF_TC(sigtimedwait_small_timeout); + +ATF_TC_HEAD(sigtimedwait_small_timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "15"); + atf_tc_set_md_var(tc, "descr", "Test sigtimedwait with a small " + "timeout"); +} + +ATF_TC_BODY(sigtimedwait_small_timeout, tc) +{ + sigset_t block; + struct timespec ts; + siginfo_t info; + int r; + + sigemptyset(&block); + ts.tv_sec = 5; + ts.tv_nsec = 0; + r = sigtimedwait(&block, &info, &ts); + ATF_REQUIRE(r == -1); + ATF_REQUIRE_ERRNO(EAGAIN, errno); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sigtimedwait_all0timeout); + ATF_TP_ADD_TC(tp, sigtimedwait_NULL_timeout); + ATF_TP_ADD_TC(tp, sigtimedwait_small_timeout); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c new file mode 100644 index 0000000..9da7861 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c @@ -0,0 +1,141 @@ +/* $NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $"); + +#include <atf-c.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <errno.h> + +static void +connected(int fd) +{ + struct sockaddr_un addr; + socklen_t len = (socklen_t)sizeof(addr); + ATF_REQUIRE(getpeername(fd, (struct sockaddr*)(void *)&addr, + &len) == 0); +} + +static void +run(int flags) +{ + int fd[2], i; + + while ((i = open("/", O_RDONLY)) < 3) + ATF_REQUIRE(i != -1); + +#ifdef __FreeBSD__ + closefrom(3); +#else + ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1); +#endif + + ATF_REQUIRE(socketpair(AF_UNIX, SOCK_DGRAM | flags, 0, fd) == 0); + + ATF_REQUIRE(fd[0] == 3); + ATF_REQUIRE(fd[1] == 4); + + connected(fd[0]); + connected(fd[1]); + + if (flags & SOCK_CLOEXEC) { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0); + } + + if (flags & SOCK_NONBLOCK) { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0); + } + + ATF_REQUIRE(close(fd[0]) != -1); + ATF_REQUIRE(close(fd[1]) != -1); +} + +ATF_TC(socketpair_basic); +ATF_TC_HEAD(socketpair_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_basic, tc) +{ + run(0); +} + +ATF_TC(socketpair_nonblock); +ATF_TC_HEAD(socketpair_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "A non-blocking test of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_nonblock, tc) +{ + run(SOCK_NONBLOCK); +} + +ATF_TC(socketpair_cloexec); +ATF_TC_HEAD(socketpair_cloexec, tc) +{ + atf_tc_set_md_var(tc, "descr", "A close-on-exec of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_cloexec, tc) +{ + run(SOCK_CLOEXEC); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, socketpair_basic); + ATF_TP_ADD_TC(tp, socketpair_nonblock); + ATF_TP_ADD_TC(tp, socketpair_cloexec); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_stat.c b/contrib/netbsd-tests/lib/libc/sys/t_stat.c new file mode 100644 index 0000000..5e1d17e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_stat.c @@ -0,0 +1,421 @@ +/* $NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/types.h> + +#include <arpa/inet.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <fts.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +#include <stdio.h> + +#ifdef __FreeBSD__ +#include <netinet/in.h> +#endif + +static const char *path = "stat"; + +ATF_TC_WITH_CLEANUP(stat_chflags); +ATF_TC_HEAD(stat_chflags, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)"); +} + +ATF_TC_BODY(stat_chflags, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(chflags(path, UF_NODUMP) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (sa.st_flags == sb.st_flags) + atf_tc_fail("stat(2) did not detect chflags(2)"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_chflags, tc) +{ + (void)unlink(path); +} + +ATF_TC(stat_dir); +ATF_TC_HEAD(stat_dir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories"); +} + +ATF_TC_BODY(stat_dir, tc) +{ + const short depth = 2; + struct stat sa, sb; + char *argv[2]; + FTSENT *ftse; + FTS *fts; + int ops; + + argv[1] = NULL; + argv[0] = __UNCONST("/"); + + ops = FTS_NOCHDIR; + ops |= FTS_PHYSICAL; + + fts = fts_open(argv, ops, NULL); + ATF_REQUIRE(fts != NULL); + + while ((ftse = fts_read(fts)) != NULL) { + + if (ftse->fts_level < 1) + continue; + + if (ftse->fts_level > depth) { + (void)fts_set(fts, ftse, FTS_SKIP); + continue; + } + + switch(ftse->fts_info) { + + case FTS_DP: + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0); + ATF_REQUIRE(chdir(ftse->fts_path) == 0); + ATF_REQUIRE(stat(".", &sb) == 0); + + /* + * The previous two stat(2) calls + * should be for the same directory. + */ + if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino) + atf_tc_fail("inconsistent stat(2)"); + + /* + * Check that fts(3)'s stat(2) + * call equals the manual one. + */ + if (sb.st_ino != ftse->fts_statp->st_ino) + atf_tc_fail("stat(2) and fts(3) differ"); + + break; + + default: + break; + } + } + + (void)fts_close(fts); +} + +ATF_TC(stat_err); +ATF_TC_HEAD(stat_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family"); +} + +ATF_TC_BODY(stat_err, tc) +{ + char buf[NAME_MAX + 1]; + struct stat st; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); +} + +ATF_TC_WITH_CLEANUP(stat_mtime); +ATF_TC_HEAD(stat_mtime, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)"); +} + +ATF_TC_BODY(stat_mtime, tc) +{ + struct stat sa, sb; + int fd[3]; + size_t i; + + for (i = 0; i < __arraycount(fd); i++) { + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd[i] = open(path, O_WRONLY | O_CREAT); + + ATF_REQUIRE(fd[i] != -1); + ATF_REQUIRE(write(fd[i], "X", 1) == 1); + ATF_REQUIRE(stat(path, &sa) == 0); + + (void)sleep(1); + + ATF_REQUIRE(write(fd[i], "X", 1) == 1); + ATF_REQUIRE(stat(path, &sb) == 0); + + ATF_REQUIRE(close(fd[i]) == 0); + ATF_REQUIRE(unlink(path) == 0); + + if (sa.st_mtime == sb.st_mtime) + atf_tc_fail("mtimes did not change"); + } +} + +ATF_TC_CLEANUP(stat_mtime, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(stat_perm); +ATF_TC_HEAD(stat_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(stat_perm, tc) +{ + struct stat sa, sb; + gid_t gid; + uid_t uid; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + uid = getuid(); + gid = getgid(); + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(fstat(fd, &sa) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (gid != sa.st_gid || sa.st_gid != sb.st_gid) + atf_tc_fail("invalid GID"); + + if (uid != sa.st_uid || sa.st_uid != sb.st_uid) + atf_tc_fail("invalid UID"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(stat_size); +ATF_TC_HEAD(stat_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)"); +} + +ATF_TC_BODY(stat_size, tc) +{ + struct stat sa, sb, sc; + const size_t n = 10; + size_t i; + int fd; + + fd = open(path, O_WRONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < n; i++) { + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + (void)memset(&sc, 0, sizeof(struct stat)); + + ATF_REQUIRE(fstat(fd, &sa) == 0); + ATF_REQUIRE(write(fd, "X", 1) == 1); + ATF_REQUIRE(fstat(fd, &sb) == 0); + ATF_REQUIRE(stat(path, &sc) == 0); + + if (sa.st_size + 1 != sb.st_size) + atf_tc_fail("invalid file size"); + + if (sb.st_size != sc.st_size) + atf_tc_fail("stat(2) and fstat(2) mismatch"); + } + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_size, tc) +{ + (void)unlink(path); +} + +ATF_TC(stat_socket); +ATF_TC_HEAD(stat_socket, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fstat(2) with " + "a socket (PR kern/46077)"); +} + +ATF_TC_BODY(stat_socket, tc) +{ + struct sockaddr_in addr; + struct stat st; + uint32_t iaddr; + int fd, flags; + + (void)memset(&st, 0, sizeof(struct stat)); + (void)memset(&addr, 0, sizeof(struct sockaddr_in)); + + fd = socket(AF_INET, SOCK_STREAM, 0); + ATF_REQUIRE(fd >= 0); + + flags = fcntl(fd, F_GETFL); + + ATF_REQUIRE(flags != -1); + ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1); + ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1); + + addr.sin_port = htons(42); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = iaddr; + + errno = 0; + + ATF_REQUIRE_ERRNO(EINPROGRESS, + connect(fd, (struct sockaddr *)&addr, + sizeof(struct sockaddr_in)) == -1); + + errno = 0; + + if (fstat(fd, &st) != 0 || errno != 0) + atf_tc_fail("fstat(2) failed for a EINPROGRESS socket"); + + (void)close(fd); +} + +ATF_TC_WITH_CLEANUP(stat_symlink); +ATF_TC_HEAD(stat_symlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)"); +} + +ATF_TC_BODY(stat_symlink, tc) +{ + const char *pathlink = "pathlink"; + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd = open(path, O_WRONLY | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(symlink(path, pathlink) == 0); + ATF_REQUIRE(stat(pathlink, &sa) == 0); + ATF_REQUIRE(lstat(pathlink, &sb) == 0); + + if (S_ISLNK(sa.st_mode) != 0) + atf_tc_fail("stat(2) detected symbolic link"); + + if (S_ISLNK(sb.st_mode) == 0) + atf_tc_fail("lstat(2) did not detect symbolic link"); + + if (sa.st_mode == sb.st_mode) + atf_tc_fail("inconsistencies between stat(2) and lstat(2)"); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathlink) == 0); +} + +ATF_TC_CLEANUP(stat_symlink, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, stat_chflags); + ATF_TP_ADD_TC(tp, stat_dir); + ATF_TP_ADD_TC(tp, stat_err); + ATF_TP_ADD_TC(tp, stat_mtime); + ATF_TP_ADD_TC(tp, stat_perm); + ATF_TP_ADD_TC(tp, stat_size); + ATF_TP_ADD_TC(tp, stat_socket); + ATF_TP_ADD_TC(tp, stat_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c new file mode 100644 index 0000000..de36c88 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c @@ -0,0 +1,133 @@ +/* $NetBSD: t_swapcontext.c,v 1.3 2013/05/05 10:28:11 skrll Exp $ */ + +/* + * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD"); + +#include <ucontext.h> +#include <stdio.h> +#include <stdlib.h> +#include <lwp.h> + +#include <atf-c.h> + +#define STACKSIZE 65536 + +char stack[STACKSIZE]; +ucontext_t nctx; +ucontext_t octx; +void *otls; +void *ntls; +int val1, val2; +int alter_tlsbase; + +/* ARGSUSED0 */ +static void +swapfunc(void *arg) +{ + ntls = _lwp_getprivate(); + printf("after swapcontext TLS pointer = %p\n", ntls); + + if (alter_tlsbase) { + ATF_REQUIRE_EQ(ntls, &val1); + printf("TLS pointer modified by swapcontext()\n"); + } else { + ATF_REQUIRE_EQ(ntls, &val2); + printf("TLS pointer left untouched by swapcontext()\n"); + } + + /* Go back in main */ + ATF_REQUIRE(swapcontext(&nctx, &octx)); + + /* NOTREACHED */ + return; +} + +static void +mainfunc(void) +{ + printf("Testing if swapcontext() alters TLS pointer if _UC_TLSBASE " + "is %s\n", (alter_tlsbase) ? "left set" : "cleared"); + + _lwp_setprivate(&val1); + printf("before swapcontext TLS pointer = %p\n", &val1); + + ATF_REQUIRE(getcontext(&nctx) == 0); + + nctx.uc_stack.ss_sp = stack; + nctx.uc_stack.ss_size = sizeof(stack); + +#ifndef _UC_TLSBASE + ATF_REQUIRE_MSG(0, "_UC_TLSBASE is not defined"); +#else /* _UC_TLSBASE */ + ATF_REQUIRE(nctx.uc_flags & _UC_TLSBASE); + if (!alter_tlsbase) + nctx.uc_flags &= ~_UC_TLSBASE; +#endif /* _UC_TLSBASE */ + + makecontext(&nctx, swapfunc, 0); + + _lwp_setprivate(&val2); + otls = _lwp_getprivate(); + printf("before swapcontext TLS pointer = %p\n", otls); + ATF_REQUIRE(swapcontext(&octx, &nctx) == 0); + + printf("Test completed\n"); +} + + +ATF_TC(swapcontext1); +ATF_TC_HEAD(swapcontext1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can let " + "TLS pointer untouched"); +} +ATF_TC_BODY(swapcontext1, tc) +{ + alter_tlsbase = 0; + mainfunc(); +} + +ATF_TC(swapcontext2); +ATF_TC_HEAD(swapcontext2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can " + "modify TLS pointer"); +} +ATF_TC_BODY(swapcontext2, tc) +{ + alter_tlsbase = 1; + mainfunc(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swapcontext1); + ATF_TP_ADD_TC(tp, swapcontext2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c new file mode 100644 index 0000000..cc85307 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c @@ -0,0 +1,211 @@ +/* $NetBSD: t_timer_create.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <errno.h> +#include <stdio.h> +#include <signal.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +static timer_t t; +static bool fail = true; + +static void +#ifdef __FreeBSD__ +timer_signal_handler(int signo, siginfo_t *si, void *osi __unused) +#else +timer_signal_handler(int signo, siginfo_t *si, void *osi) +#endif +{ + timer_t *tp; + + tp = si->si_value.sival_ptr; + + if (*tp == t && signo == SIGALRM) + fail = false; + + (void)fprintf(stderr, "%s: %s\n", __func__, strsignal(signo)); +} + +static void +timer_signal_create(clockid_t cid, bool expire) +{ + struct itimerspec tim; + struct sigaction act; + struct sigevent evt; + sigset_t set; + + t = 0; + fail = true; + + (void)memset(&evt, 0, sizeof(struct sigevent)); + (void)memset(&act, 0, sizeof(struct sigaction)); + (void)memset(&tim, 0, sizeof(struct itimerspec)); + + /* + * Set handler. + */ + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = timer_signal_handler; + + ATF_REQUIRE(sigemptyset(&set) == 0); + ATF_REQUIRE(sigemptyset(&act.sa_mask) == 0); + + /* + * Block SIGALRM while configuring the timer. + */ + ATF_REQUIRE(sigaction(SIGALRM, &act, NULL) == 0); + ATF_REQUIRE(sigaddset(&set, SIGALRM) == 0); + ATF_REQUIRE(sigprocmask(SIG_SETMASK, &set, NULL) == 0); + + /* + * Create the timer (SIGEV_SIGNAL). + */ + evt.sigev_signo = SIGALRM; + evt.sigev_value.sival_ptr = &t; + evt.sigev_notify = SIGEV_SIGNAL; + + ATF_REQUIRE(timer_create(cid, &evt, &t) == 0); + + /* + * Start the timer. After this, unblock the signal. + */ + tim.it_value.tv_sec = expire ? 5 : 1; + tim.it_value.tv_nsec = 0; + + ATF_REQUIRE(timer_settime(t, 0, &tim, NULL) == 0); + + (void)sigprocmask(SIG_UNBLOCK, &set, NULL); + (void)sleep(2); + + if (expire) { + if (!fail) + atf_tc_fail("timer fired too soon"); + } else { + if (fail) + atf_tc_fail("timer failed to fire"); + } + + ATF_REQUIRE(timer_delete(t) == 0); +} + +ATF_TC(timer_create_err); +ATF_TC_HEAD(timer_create_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check errors from timer_create(2) (PR lib/42434"); +} + +ATF_TC_BODY(timer_create_err, tc) +{ + struct sigevent ev; + + (void)memset(&ev, 0, sizeof(struct sigevent)); + + errno = 0; + ev.sigev_signo = -1; + ev.sigev_notify = SIGEV_SIGNAL; + + ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1); + + errno = 0; + ev.sigev_signo = SIGUSR1; + ev.sigev_notify = SIGEV_THREAD + 100; + + ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1); +} + +ATF_TC(timer_create_real); +ATF_TC_HEAD(timer_create_real, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_SIGNAL"); +} + +ATF_TC_BODY(timer_create_real, tc) +{ + timer_signal_create(CLOCK_REALTIME, false); +} + +ATF_TC(timer_create_mono); +ATF_TC_HEAD(timer_create_mono, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_SIGNAL"); +} + +ATF_TC_BODY(timer_create_mono, tc) +{ + timer_signal_create(CLOCK_MONOTONIC, false); +} + +ATF_TC(timer_create_real_expire); +ATF_TC_HEAD(timer_create_real_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_SIGNAL, with expiration"); +} + +ATF_TC_BODY(timer_create_real_expire, tc) +{ + timer_signal_create(CLOCK_REALTIME, true); +} + +ATF_TC(timer_create_mono_expire); +ATF_TC_HEAD(timer_create_mono_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_SIGNAL, with expiration"); +} + +ATF_TC_BODY(timer_create_mono_expire, tc) +{ + timer_signal_create(CLOCK_MONOTONIC, true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, timer_create_err); + ATF_TP_ADD_TC(tp, timer_create_real); + ATF_TP_ADD_TC(tp, timer_create_mono); + ATF_TP_ADD_TC(tp, timer_create_real_expire); + ATF_TP_ADD_TC(tp, timer_create_mono_expire); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_truncate.c b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c new file mode 100644 index 0000000..59193a9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c @@ -0,0 +1,188 @@ +/* $NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#include <limits.h> +#endif + +static const char path[] = "truncate"; +static const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 }; + +ATF_TC_WITH_CLEANUP(ftruncate_basic); +ATF_TC_HEAD(ftruncate_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)"); +} + +ATF_TC_BODY(ftruncate_basic, tc) +{ + struct stat st; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < __arraycount(sizes); i++) { + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); + + if (sizes[i] != (size_t)st.st_size) + atf_tc_fail("ftruncate(2) did not truncate"); + } + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(ftruncate_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(ftruncate_err); +ATF_TC_HEAD(ftruncate_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(ftruncate_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY, 0400); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1); + + (void)close(fd); +} + +ATF_TC_WITH_CLEANUP(truncate_basic); +ATF_TC_HEAD(truncate_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)"); +} + +ATF_TC_BODY(truncate_basic, tc) +{ + struct stat st; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < __arraycount(sizes); i++) { + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(truncate(path, sizes[i]) == 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); + + if (sizes[i] != (size_t)st.st_size) + atf_tc_fail("truncate(2) did not truncate"); + } + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(truncate_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(truncate_err); +ATF_TC_HEAD(truncate_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(truncate_err, tc) +{ +#ifndef __NetBSD__ + char buf[PATH_MAX]; +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EISDIR, truncate("/etc", 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1); + + errno = 0; +#ifdef __NetBSD__ + ATF_REQUIRE_ERRNO(EACCES, truncate("/usr/bin/fpr", 999) == -1); +#else + snprintf(buf, sizeof(buf), "%s/truncate_test.root_owned", + atf_tc_get_config_var(tc, "srcdir")); + ATF_REQUIRE_ERRNO(EACCES, truncate(buf, 999) == -1); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ftruncate_basic); + ATF_TP_ADD_TC(tp, ftruncate_err); + ATF_TP_ADD_TC(tp, truncate_basic); + ATF_TP_ADD_TC(tp, truncate_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c new file mode 100644 index 0000000..27d6740 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c @@ -0,0 +1,76 @@ +/* $NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $"); + +#include <atf-c.h> +#include <stdio.h> +#include <ucontext.h> + +ATF_TC(ucontext_basic); +ATF_TC_HEAD(ucontext_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks {get,set}context(2)"); +} + +ATF_TC_BODY(ucontext_basic, tc) +{ + ucontext_t u, v, w; + volatile int x, y; + + x = 0; + y = 0; + + printf("Start\n"); + + getcontext(&u); + y++; + + printf("x == %d\n", x); + + getcontext(&v); + + if ( x < 20 ) { + x++; + getcontext(&w); + setcontext(&u); + } + + printf("End, y = %d\n", y); + ATF_REQUIRE_EQ(y, 21); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ucontext_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_umask.c b/contrib/netbsd-tests/lib/libc/sys/t_umask.c new file mode 100644 index 0000000..748cbdc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_umask.c @@ -0,0 +1,205 @@ +/* $NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $"); + +#include <sys/stat.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const char path[] = "umask"; +static const mode_t mask[] = { + S_IRWXU, + S_IRUSR, + S_IWUSR, + S_IXUSR, + S_IRWXG, + S_IRGRP, + S_IWGRP, + S_IXGRP, + S_IRWXO, + S_IROTH, + S_IWOTH, + S_IXOTH +}; + +ATF_TC_WITH_CLEANUP(umask_fork); +ATF_TC_HEAD(umask_fork, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that umask(2) is inherited"); +} + +ATF_TC_BODY(umask_fork, tc) +{ + mode_t mode; + pid_t pid; + size_t i; + int sta; + + for (i = 0; i < __arraycount(mask) - 1; i++) { + + (void)umask(mask[i] | mask[i + 1]); + + pid = fork(); + + if (pid < 0) + continue; + + if (pid == 0) { + + mode = umask(mask[i]); + + if (mode != (mask[i] | mask[i + 1])) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + goto fail; + } + + return; + +fail: + (void)umask(S_IWGRP | S_IWOTH); + + atf_tc_fail("umask(2) was not inherited"); +} + +ATF_TC_CLEANUP(umask_fork, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); +} + +ATF_TC_WITH_CLEANUP(umask_open); +ATF_TC_HEAD(umask_open, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of open(2) and umask(2)"); +} + +ATF_TC_BODY(umask_open, tc) +{ + const char *str = NULL; + struct stat st; + size_t i; + int fd; + + for (i = 0; i < __arraycount(mask); i++) { + + (void)umask(mask[i]); + + fd = open(path, O_RDWR | O_CREAT, 0777); + + if (fd < 0) + continue; + + (void)memset(&st, 0, sizeof(struct stat)); + + if (stat(path, &st) != 0) { + str = "failed to stat(2)"; + goto out; + } + + if ((st.st_mode & mask[i]) != 0) { + str = "invalid umask(2)"; + goto out; + } + + if (unlink(path) != 0) { + str = "failed to unlink(2)"; + goto out; + } + + } + +out: + (void)umask(S_IWGRP | S_IWOTH); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC_CLEANUP(umask_open, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(umask_previous); +ATF_TC_HEAD(umask_previous, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test the return value from umask(2)"); +} + +ATF_TC_BODY(umask_previous, tc) +{ + mode_t mode; + size_t i; + + for (i = 0; i < __arraycount(mask); i++) { + + mode = umask(mask[i]); + mode = umask(mask[i]); + + if (mode != mask[i]) + goto fail; + } + + return; + +fail: + (void)umask(S_IWGRP | S_IWOTH); + + atf_tc_fail("umask(2) did not return the previous mask"); +} + +ATF_TC_CLEANUP(umask_previous, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, umask_fork); + ATF_TP_ADD_TC(tp, umask_open); + ATF_TP_ADD_TC(tp, umask_previous); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c new file mode 100644 index 0000000..8d94668 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c @@ -0,0 +1,162 @@ +/* $NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $"); + +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +static char path[] = "unlink"; + +ATF_TC_WITH_CLEANUP(unlink_basic); +ATF_TC_HEAD(unlink_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of unlink(2)"); +} + +ATF_TC_BODY(unlink_basic, tc) +{ + const size_t n = 512; + size_t i; + int fd; + + for (i = 0; i < n; i++) { + + fd = open(path, O_RDWR | O_CREAT, 0666); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1); + } +} + +ATF_TC_CLEANUP(unlink_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_err); +ATF_TC_HEAD(unlink_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of unlink(2)"); +} + +ATF_TC_BODY(unlink_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; +#ifdef __FreeBSD__ + ATF_REQUIRE_ERRNO(EISDIR, unlink("/") == -1); +#else + ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, unlink(buf) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, unlink("/a/b/c/d/e/f/g/h/i/j/k/l/m") == -1); +} + +ATF_TC_CLEANUP(unlink_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_fifo); +ATF_TC_HEAD(unlink_fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unlink(2) for a FIFO"); +} + +ATF_TC_BODY(unlink_fifo, tc) +{ + + ATF_REQUIRE(mkfifo(path, 0666) == 0); + ATF_REQUIRE(unlink(path) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1); +} + +ATF_TC_CLEANUP(unlink_fifo, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_perm); +ATF_TC_HEAD(unlink_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with unlink(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(unlink_perm, tc) +{ + int rv; + + errno = 0; + rv = unlink("/etc"); + ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM), + "unlinking a directory did not fail with EPERM or EACCESS; " + "unlink() returned %d, errno %d", rv, errno); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, unlink("/root/.profile") == -1); +} + +ATF_TC_CLEANUP(unlink_perm, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, unlink_basic); + ATF_TP_ADD_TC(tp, unlink_err); + ATF_TP_ADD_TC(tp, unlink_fifo); + ATF_TP_ADD_TC(tp, unlink_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_write.c b/contrib/netbsd-tests/lib/libc/sys/t_write.c new file mode 100644 index 0000000..a3783cb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c @@ -0,0 +1,236 @@ +/* $NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $ */ + +/*- + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $"); + +#include <sys/uio.h> +#ifdef __NetBSD__ +#include <sys/syslimits.h> +#endif + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +#ifdef __FreeBSD__ +#include <limits.h> +#endif + +static void sighandler(int); + +static bool fail = false; +static const char *path = "write"; + +static void +#ifdef __FreeBSD__ +sighandler(int signo __unused) +#else +sighandler(int signo) +#endif +{ + fail = false; +} + +ATF_TC_WITH_CLEANUP(write_err); +ATF_TC_HEAD(write_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)"); +} + +ATF_TC_BODY(write_err, tc) +{ + char rbuf[3] = { 'a', 'b', 'c' }; + char wbuf[3] = { 'x', 'y', 'z' }; + int fd; + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1); + + fd = open(path, O_RDWR | O_CREAT); + + if (fd >= 0) { + + errno = 0; + ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1); + + /* + * Check that the above bogus write(2) + * calls did not corrupt the file. + */ + ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0); + ATF_REQUIRE(read(fd, rbuf, 3) == 3); + ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0); + + (void)close(fd); + (void)unlink(path); + } +} + +ATF_TC_CLEANUP(write_err, tc) +{ + (void)unlink(path); +} + +ATF_TC(write_pipe); +ATF_TC_HEAD(write_pipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)"); +} + +ATF_TC_BODY(write_pipe, tc) +{ + int fds[2]; + + ATF_REQUIRE(pipe(fds) == 0); + ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0); + + ATF_REQUIRE(write(fds[1], "x", 1) != -1); + ATF_REQUIRE(close(fds[0]) == 0); + + errno = 0; + fail = true; + + if (write(fds[1], "x", 1) != -1 || errno != EPIPE) + atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded"); + + ATF_REQUIRE(close(fds[1]) == 0); + + if (fail != false) + atf_tc_fail_nonfatal("SIGPIPE was not raised"); +} + +ATF_TC_WITH_CLEANUP(write_pos); +ATF_TC_HEAD(write_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that write(2) " + "updates the file position"); +} + +ATF_TC_BODY(write_pos, tc) +{ + const size_t n = 123; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < n; i++) { + ATF_REQUIRE(write(fd, "x", 1) == 1); + ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1)); + } + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(write_pos, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(write_ret); +ATF_TC_HEAD(write_ret, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)"); +} + +ATF_TC_BODY(write_ret, tc) +{ + const size_t n = 99; + char buf[123]; + size_t i, j; + int fd; + + fd = open(path, O_WRONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + + for (i = j = 0; i < n; i++) + j += write(fd, buf, sizeof(buf)); + + if (j != n * 123) + atf_tc_fail("inconsistent return values from write(2)"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(write_ret, tc) +{ + (void)unlink(path); +} + +ATF_TC(writev_iovmax); +ATF_TC_HEAD(writev_iovmax, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Checks that file descriptor is properly FILE_UNUSE()d " + "when iovcnt is greater than IOV_MAX"); +} + +ATF_TC_BODY(writev_iovmax, tc) +{ + ssize_t retval; + + (void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n"); + + errno = 0; + retval = writev(2, NULL, IOV_MAX + 1); + + ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval); + ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, write_err); + ATF_TP_ADD_TC(tp, write_pipe); + ATF_TP_ADD_TC(tp, write_pos); + ATF_TP_ADD_TC(tp, write_ret); + ATF_TP_ADD_TC(tp, writev_iovmax); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/t_cdb.c b/contrib/netbsd-tests/lib/libc/t_cdb.c new file mode 100644 index 0000000..5e88e65 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_cdb.c @@ -0,0 +1,158 @@ +/* $NetBSD: t_cdb.c,v 1.1 2012/09/27 00:38:57 joerg Exp $ */ +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_cdb.c,v 1.1 2012/09/27 00:38:57 joerg Exp $"); + +#include <atf-c.h> +#include <assert.h> +#include <cdbr.h> +#include <cdbw.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define MAXKEYS 16384 + +static const char database_name[] = "test.cdb"; + +uint32_t keys[MAXKEYS]; + +static int +cmp_keys(const void *a_, const void *b_) +{ + uint32_t a = *(const uint32_t *)a_; + uint32_t b = *(const uint32_t *)b_; + + return a > b ? 1 : (a < b ? 1 : 0); +} + +static void +init_keys(size_t len) +{ + uint32_t sorted_keys[MAXKEYS]; + size_t i; + + assert(len <= MAXKEYS); + + if (len == 0) + return; + + do { + for (i = 0; i < len; ++i) + sorted_keys[i] = keys[i] = arc4random(); + + qsort(sorted_keys, len, sizeof(*sorted_keys), cmp_keys); + for (i = 1; i < len; ++i) { + if (sorted_keys[i - 1] == sorted_keys[i]) + break; + } + } while (i != len); +} + +static void +write_database(size_t len) +{ + struct cdbw *db; + int fd; + size_t i; + uint32_t buf[2]; + + ATF_REQUIRE((db = cdbw_open()) != NULL); + ATF_REQUIRE((fd = creat(database_name, S_IRUSR|S_IWUSR)) != -1); + for (i = 0; i < len; ++i) { + buf[0] = i; + buf[1] = keys[i]; + ATF_REQUIRE(cdbw_put(db, &keys[i], sizeof(keys[i]), + buf, sizeof(buf)) == 0); + } + ATF_REQUIRE(cdbw_output(db, fd, "test database", arc4random) == 0); + cdbw_close(db); + ATF_REQUIRE(close(fd) == 0); +} + +static void +check_database(size_t len) +{ + struct cdbr *db; + size_t i, data_len; + const void *data; + uint32_t buf[2]; + + ATF_REQUIRE((db = cdbr_open(database_name, CDBR_DEFAULT)) != NULL); + ATF_REQUIRE_EQ(cdbr_entries(db), len); + for (i = 0; i < len; ++i) { + ATF_REQUIRE(cdbr_find(db, &keys[i], sizeof(keys[i]), + &data, &data_len) != -1); + ATF_REQUIRE_EQ(data_len, sizeof(buf)); + memcpy(buf, data, sizeof(buf)); + ATF_REQUIRE_EQ(buf[0], i); + ATF_REQUIRE_EQ(buf[1], keys[i]); + } + cdbr_close(db); +} + +ATF_TC_WITH_CLEANUP(cdb); + +ATF_TC_HEAD(cdb, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test cdb(5) reading and writing"); +} + +ATF_TC_BODY(cdb, tc) +{ + size_t i, sizes[] = { 0, 16, 64, 1024, 2048 }; + for (i = 0; i < __arraycount(sizes); ++i) { + init_keys(sizes[i]); + write_database(sizes[i]); + check_database(sizes[i]); + unlink(database_name); + } +} + +ATF_TC_CLEANUP(cdb, tc) +{ + + unlink(database_name); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cdb); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/lib/libc/t_convfp.c b/contrib/netbsd-tests/lib/libc/t_convfp.c new file mode 100644 index 0000000..de68690 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_convfp.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_convfp.c,v 1.7 2011/06/14 11:58:22 njoly Exp $ */ + +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> + +/* + * This value is representable as an unsigned int, but not as an int. + * According to ISO C it must survive the convsion back from a double + * to an unsigned int (everything > -1 and < UINT_MAX+1 has to) + */ +#define UINT_TESTVALUE (INT_MAX+42U) + +/* The same for unsigned long */ +#define ULONG_TESTVALUE (LONG_MAX+42UL) + + +ATF_TC(conv_uint); +ATF_TC_HEAD(conv_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test conversions to unsigned int"); +} + +ATF_TC_BODY(conv_uint, tc) +{ + unsigned int ui; + double d; + + /* unsigned int test */ + d = UINT_TESTVALUE; + ui = (unsigned int)d; + + if (ui != UINT_TESTVALUE) + atf_tc_fail("FAILED: unsigned int %u (0x%x) != %u (0x%x)", + ui, ui, UINT_TESTVALUE, UINT_TESTVALUE); +} + +ATF_TC(conv_ulong); + +ATF_TC_HEAD(conv_ulong, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test conversions to unsigned long"); +} + +ATF_TC_BODY(conv_ulong, tc) +{ + unsigned long ul; + long double dt; + double d; + + /* unsigned long vs. {long} double test */ + if (sizeof(d) > sizeof(ul)) { + d = ULONG_TESTVALUE; + ul = (unsigned long)d; + printf("testing double vs. long\n"); + } else if (sizeof(dt) > sizeof(ul)) { + dt = ULONG_TESTVALUE; + ul = (unsigned long)dt; + printf("testing long double vs. long\n"); + } else { + printf("sizeof(long) = %zu, sizeof(double) = %zu, " + "sizeof(long double) = %zu\n", + sizeof(ul), sizeof(d), sizeof(dt)); + atf_tc_skip("no suitable {long} double type found"); + } + + if (ul != ULONG_TESTVALUE) + atf_tc_fail("unsigned long %lu (0x%lx) != %lu (0x%lx)", + ul, ul, ULONG_TESTVALUE, ULONG_TESTVALUE); +} + +ATF_TC(cast_ulong); + +ATF_TC_HEAD(cast_ulong, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test double to unsigned long cast"); +} + +ATF_TC_BODY(cast_ulong, tc) +{ + double nv; + unsigned long uv; + + nv = 5.6; + uv = (unsigned long)nv; + + ATF_CHECK_EQ_MSG(uv, 5, + "%.3f casted to unsigned long is %lu", nv, uv); +} + +ATF_TC(cast_ulong2); + +ATF_TC_HEAD(cast_ulong2, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test double/long double casts to unsigned long"); +} + +ATF_TC_BODY(cast_ulong2, tc) +{ + double dv = 1.9; + long double ldv = dv; + unsigned long l1 = dv; + unsigned long l2 = ldv; + + ATF_CHECK_EQ_MSG(l1, 1, + "double 1.9 casted to unsigned long should be 1, but is %lu", l1); + + ATF_CHECK_EQ_MSG(l2, 1, + "long double 1.9 casted to unsigned long should be 1, but is %lu", + l2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, conv_uint); + ATF_TP_ADD_TC(tp, conv_ulong); + ATF_TP_ADD_TC(tp, cast_ulong); + ATF_TP_ADD_TC(tp, cast_ulong2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/t_gdtoa.c b/contrib/netbsd-tests/lib/libc/t_gdtoa.c new file mode 100644 index 0000000..e040603 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_gdtoa.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_gdtoa.c,v 1.4 2012/09/27 08:19:18 martin Exp $"); + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> + +/* reported by Maksymilian Arciemowicz */ + +ATF_TC(long_format); + +ATF_TC_HEAD(long_format, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test printf with %%1.262159f format"); +} + +ATF_TC_BODY(long_format, tc) +{ + char *buf; + ATF_REQUIRE_EQ(262161, asprintf(&buf, "%1.262159f", 1.1)); + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, long_format); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c new file mode 100644 index 0000000..66b1735 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +ATF_TC(tcsetpgrp_err); +ATF_TC_HEAD(tcsetpgrp_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from tcsetpgrp(3)" + " (PR lib/41673)"); +} + +ATF_TC_BODY(tcsetpgrp_err, tc) +{ + int rv, sta; + pid_t pid; + + if (isatty(STDIN_FILENO) == 0) + return; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * The child process ID doesn't match any active + * process group ID, so the following call should + * fail with EPERM (and not EINVAL). + */ + errno = 0; + rv = tcsetpgrp(STDIN_FILENO, getpid()); + + if (rv == 0 || errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("wrong errno"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tcsetpgrp_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/time/t_mktime.c b/contrib/netbsd-tests/lib/libc/time/t_mktime.c new file mode 100644 index 0000000..8092361 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/time/t_mktime.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_mktime.c,v 1.5 2012/03/18 07:33:58 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <err.h> +#include <errno.h> +#include <string.h> +#include <time.h> + +ATF_TC(localtime_r_gmt); +ATF_TC_HEAD(localtime_r_gmt, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that localtime_r(3) " + "returns localtime, not GMT (PR lib/28324)"); +} + +ATF_TC_BODY(localtime_r_gmt, tc) +{ + struct tm *t; + struct tm tt; + time_t x; + + x = time(NULL); + localtime_r(&x, &tt); + t = localtime(&x); + + if (t->tm_sec != tt.tm_sec || t->tm_min != tt.tm_min || + t->tm_hour != tt.tm_hour || t->tm_mday != tt.tm_mday) + atf_tc_fail("inconsistencies between " + "localtime(3) and localtime_r(3)"); +} + +ATF_TC(mktime_negyear); +ATF_TC_HEAD(mktime_negyear, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mktime(3) with negative year"); +} + +ATF_TC_BODY(mktime_negyear, tc) +{ + struct tm tms; + time_t t; + + (void)memset(&tms, 0, sizeof(tms)); + tms.tm_year = ~0; + + errno = 0; + t = mktime(&tms); + ATF_REQUIRE_ERRNO(0, t != (time_t)-1); +} + +ATF_TC(timegm_epoch); +ATF_TC_HEAD(timegm_epoch, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test timegm(3) close to the epoch"); +} + +ATF_TC_BODY(timegm_epoch, tc) +{ + struct tm tms; + time_t t; + + /* midnight on 1 Jan 1970 */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)0); + + /* one second after midnight on 1 Jan 1970 */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = 1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)1); + + /* + * 1969-12-31 23:59:59 = one second before the epoch. + * Result should be -1 with errno = 0. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1969 - 1900; + tms.tm_mon = 12 - 1; + tms.tm_mday = 31; + tms.tm_hour = 23; + tms.tm_min = 59; + tms.tm_sec = 59; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-1); + + /* + * Another way of getting one second before the epoch: + * Set date to 1 Jan 1970, and time to -1 second. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = -1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-1); + + /* + * Two seconds before the epoch. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = -2; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-2); + +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, localtime_r_gmt); + ATF_TP_ADD_TC(tp, mktime_negyear); + ATF_TP_ADD_TC(tp, timegm_epoch); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/time/t_strptime.c b/contrib/netbsd-tests/lib/libc/time/t_strptime.c new file mode 100644 index 0000000..99871ff --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/time/t_strptime.c @@ -0,0 +1,281 @@ +/* $NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $ */ + +/*- + * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David Laight. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $"); + +#include <time.h> + +#include <atf-c.h> + +static void +h_pass(const char *buf, const char *fmt, int len, + int tm_sec, int tm_min, int tm_hour, int tm_mday, + int tm_mon, int tm_year, int tm_wday, int tm_yday) +{ + struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL }; + const char *ret, *exp; + + exp = buf + len; + ret = strptime(buf, fmt, &tm); + +#ifdef __FreeBSD__ + ATF_CHECK_MSG(ret == exp, + "strptime(\"%s\", \"%s\", tm): incorrect return code: " + "expected: %p, got: %p", buf, fmt, exp, ret); + +#define H_REQUIRE_FIELD(field) \ + ATF_CHECK_MSG(tm.field == field, \ + "strptime(\"%s\", \"%s\", tm): incorrect %s: " \ + "expected: %d, but got: %d", buf, fmt, \ + ___STRING(field), field, tm.field) +#else + ATF_REQUIRE_MSG(ret == exp, + "strptime(\"%s\", \"%s\", tm): incorrect return code: " + "expected: %p, got: %p", buf, fmt, exp, ret); + +#define H_REQUIRE_FIELD(field) \ + ATF_REQUIRE_MSG(tm.field == field, \ + "strptime(\"%s\", \"%s\", tm): incorrect %s: " \ + "expected: %d, but got: %d", buf, fmt, \ + ___STRING(field), field, tm.field) +#endif + + H_REQUIRE_FIELD(tm_sec); + H_REQUIRE_FIELD(tm_min); + H_REQUIRE_FIELD(tm_hour); + H_REQUIRE_FIELD(tm_mday); + H_REQUIRE_FIELD(tm_mon); + H_REQUIRE_FIELD(tm_year); + H_REQUIRE_FIELD(tm_wday); + H_REQUIRE_FIELD(tm_yday); + +#undef H_REQUIRE_FIELD +} + +static void +h_fail(const char *buf, const char *fmt) +{ + struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL }; + +#ifdef __FreeBSD__ + ATF_CHECK_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", " + "\"%s\", &tm) should fail, but it didn't", buf, fmt); +#else + ATF_REQUIRE_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", " + "\"%s\", &tm) should fail, but it didn't", buf, fmt); +#endif +} + +ATF_TC(common); + +ATF_TC_HEAD(common, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks strptime(3): various checks"); +} + +ATF_TC_BODY(common, tc) +{ + +#ifdef __FreeBSD__ + atf_tc_expect_fail("There are various issues with strptime on FreeBSD"); +#endif + + h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %T %Y", + 24, 46, 27, 23, 20, 0, 98, 2, -1); + h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %H:%M:%S %Y", + 24, 46, 27, 23, 20, 0, 98, 2, -1); + h_pass("Tue Jan 20 23:27:46 1998", "%c", + 24, 46, 27, 23, 20, 0, 98, 2, -1); + h_pass("Fri Mar 4 20:05:34 2005", "%a %b %e %H:%M:%S %Y", + 24, 34, 5, 20, 4, 2, 105, 5, -1); + h_pass("5\t3 4 8pm:05:34 2005", "%w%n%m%t%d%n%k%p:%M:%S %Y", + 21, 34, 5, 20, 4, 2, 105, 5, -1); + h_pass("Fri Mar 4 20:05:34 2005", "%c", + 24, 34, 5, 20, 4, 2, 105, 5, -1); + + h_pass("x20y", "x%Cy", 4, -1, -1, -1, -1, -1, 100, -1, -1); + h_pass("x84y", "x%yy", 4, -1, -1, -1, -1, -1, 84, -1, -1); + h_pass("x2084y", "x%C%yy", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_pass("x8420y", "x%y%Cy", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_pass("%20845", "%%%C%y5", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_fail("%", "%E%"); + + h_pass("1980", "%Y", 4, -1, -1, -1, -1, -1, 80, -1, -1); + h_pass("1980", "%EY", 4, -1, -1, -1, -1, -1, 80, -1, -1); + + h_pass("0", "%S", 1, 0, -1, -1, -1, -1, -1, -1, -1); + h_pass("59", "%S", 2, 59, -1, -1, -1, -1, -1, -1, -1); + h_pass("60", "%S", 2, 60, -1, -1, -1, -1, -1, -1, -1); + h_pass("61", "%S", 2, 61, -1, -1, -1, -1, -1, -1, -1); + h_fail("62", "%S"); +} + +ATF_TC(day); + +ATF_TC_HEAD(day, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks strptime(3): day names"); +} + +ATF_TC_BODY(day, tc) +{ + + h_pass("Sun", "%a", 3, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Sunday", "%a", 6, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Monday", "%a", 6, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Tue", "%a", 3, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Tuesday", "%a", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Wed", "%a", 3, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Wednesday", "%a", 9, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Thu", "%a", 3, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Thursday", "%a", 8, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Fri", "%a", 3, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Friday", "%a", 6, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Sat", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturday", "%a", 8, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturn", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_fail("Moon", "%a"); + h_pass("Sun", "%A", 3, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Mon", "%A", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Monday", "%A", 6, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Tue", "%A", 3, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Tuesday", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Wed", "%A", 3, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Wednesday", "%A", 9, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Thu", "%A", 3, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Thursday", "%A", 8, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Fri", "%A", 3, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Friday", "%A", 6, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Sat", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturday", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturn", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_fail("Moon", "%A"); + + h_pass("mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("tueSDay", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1); +#ifdef __NetBSD__ + h_fail("sunday", "%EA"); +#else + h_pass("Sunday", "%EA", 6, -1, -1, -1, -1, -1, -1, 0, -1); +#endif + h_pass("SaturDay", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1); +#ifdef __NetBSD__ + h_fail("SaturDay", "%OA"); +#else + h_pass("SaturDay", "%OA", 8, -1, -1, -1, -1, -1, -1, 6, -1); +#endif +} + +ATF_TC(month); + +ATF_TC_HEAD(month, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks strptime(3): month names"); +} + +ATF_TC_BODY(month, tc) +{ + + h_pass("Jan", "%b", 3, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("January", "%b", 7, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("Feb", "%b", 3, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("February", "%b", 8, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("Mar", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("March", "%b", 5, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("Apr", "%b", 3, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("April", "%b", 5, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("May", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Jun", "%b", 3, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("June", "%b", 4, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("Jul", "%b", 3, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("July", "%b", 4, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("Aug", "%b", 3, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("August", "%b", 6, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("Sep", "%b", 3, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("September", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("Oct", "%b", 3, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("October", "%b", 7, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("Nov", "%b", 3, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("November", "%b", 8, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("Dec", "%b", 3, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("December", "%b", 8, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("Mayor", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Mars", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_fail("Rover", "%b"); + h_pass("Jan", "%B", 3, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("January", "%B", 7, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("Feb", "%B", 3, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("February", "%B", 8, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("Mar", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("March", "%B", 5, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("Apr", "%B", 3, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("April", "%B", 5, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("May", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Jun", "%B", 3, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("June", "%B", 4, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("Jul", "%B", 3, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("July", "%B", 4, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("Aug", "%B", 3, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("August", "%B", 6, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("Sep", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("September", "%B", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("Oct", "%B", 3, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("October", "%B", 7, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("Nov", "%B", 3, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("November", "%B", 8, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("Dec", "%B", 3, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("December", "%B", 8, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("Mayor", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Mars", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_fail("Rover", "%B"); + + h_pass("september", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("septembe", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, common); + ATF_TP_ADD_TC(tp, day); + ATF_TP_ADD_TC(tp, month); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c new file mode 100644 index 0000000..6c913a4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c @@ -0,0 +1,62 @@ +/* $NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $"); + +#include <atf-c.h> +#include <unistd.h> +#ifdef __NetBSD__ +#include <sys/tls.h> +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +extern __thread int var1; +extern __thread int var2; +extern __thread int *var3; +__thread int var5 = 1; +static __thread pid_t (*local_var)(void) = getpid; + +void testf_dso_helper(int x, int y); + +void +testf_dso_helper(int x, int y) +{ + var1 = x; + var2 = y; + var3 = &optind; + ATF_CHECK_EQ(local_var, getpid); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c new file mode 100644 index 0000000..a268068 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c @@ -0,0 +1,115 @@ +/* $NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); + +#include <atf-c.h> +#include <dlfcn.h> +#include <pthread.h> +#include <unistd.h> + +#ifdef __NetBSD__ +#include <sys/tls.h> +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_dlopen); + +ATF_TC_HEAD(t_tls_dlopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables and dlopen"); +} + +void (*testf_helper)(int, int); + +__thread int var1 = 1; +__thread int var2; +__thread int *var3 = &optind; +int var4_helper; +__thread int *var4 = &var4_helper; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + ATF_CHECK_EQ(var3, &optind); + ATF_CHECK_EQ(var4, &var4_helper); + testf_helper(2, 2); + ATF_CHECK_EQ(var1, 2); + ATF_CHECK_EQ(var2, 2); + testf_helper(3, 3); + ATF_CHECK_EQ(var1, 3); + ATF_CHECK_EQ(var2, 3); + ATF_CHECK_EQ(var3, &optind); + + return NULL; +} + +ATF_TC_BODY(t_tls_dlopen, tc) +{ + void *handle; + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + handle = dlopen("h_tls_dlopen.so", RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE(handle != NULL); + + testf_helper = dlsym(handle, "testf_dso_helper"); + ATF_REQUIRE(testf_helper != NULL); + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + dlclose(handle); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_dlopen); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c new file mode 100644 index 0000000..1982a9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); + +#include <atf-c.h> +#include <pthread.h> +#include <unistd.h> + +#ifdef __NetBSD__ +#include <sys/tls.h> +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_dynamic); + +ATF_TC_HEAD(t_tls_dynamic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables in dynamic binaries"); +} + +void testf_dso_helper(int, int); + +extern __thread int var1; +extern __thread int var2; +extern __thread pid_t (*dso_var1)(void); + +__thread int *var3 = &optind; +int var4_helper; +__thread int *var4 = &var4_helper; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + testf_dso_helper(2, 2); + ATF_CHECK_EQ(var1, 2); + ATF_CHECK_EQ(var2, 2); + testf_dso_helper(3, 3); + ATF_CHECK_EQ(var1, 3); + ATF_CHECK_EQ(var2, 3); + ATF_CHECK_EQ(var3, &optind); + ATF_CHECK_EQ(var4, &var4_helper); + ATF_CHECK_EQ(dso_var1, getpid); + + return NULL; +} + +ATF_TC_BODY(t_tls_dynamic, tc) +{ + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_dynamic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c new file mode 100644 index 0000000..db0ff16 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); + +#include <atf-c.h> +#include <pthread.h> + +#ifdef __NetBSD__ +#include <sys/tls.h> +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_static); + +ATF_TC_HEAD(t_tls_static, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables in static binaries"); +} + +void testf_helper(void); + +__thread int var1 = 1; +__thread int var2; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + testf_helper(); + ATF_CHECK_EQ(var1, -1); + ATF_CHECK_EQ(var2, -1); + + return NULL; +} + +ATF_TC_BODY(t_tls_static, tc) +{ + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_static); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c new file mode 100644 index 0000000..841b2bf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c @@ -0,0 +1,55 @@ +/* $NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); + +#ifdef __NetBSD__ +#include <sys/tls.h> +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +extern __thread int var1; +extern __thread int var2; + +void testf_helper(void); + +void +testf_helper(void) +{ + var1 = -1; + var2 = -1; +} diff --git a/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c new file mode 100644 index 0000000..a5e78ff --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c @@ -0,0 +1,58 @@ +/* $NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $"); + +#include <unistd.h> +#ifdef __NetBSD__ +#include <sys/tls.h> +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +__thread int var1 = 1; +__thread int var2; + +__thread pid_t (*dso_var1)(void) = getpid; + +void testf_dso_helper(int x, int y); + +void +testf_dso_helper(int x, int y) +{ + var1 = x; + var2 = y; +} diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c new file mode 100644 index 0000000..5346898 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $ */ + +/* + * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $"); + +#include <sys/ioctl.h> +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> +#include <grp.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x, v) \ + ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno)) + +ATF_TC(ptm); + +ATF_TC_HEAD(ptm, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks /dev/ptm device"); +} + +ATF_TC_BODY(ptm, tc) +{ + struct stat stm, sts; + struct ptmget ptm; + int fdm; + struct group *gp; + + if ((fdm = open("/dev/ptm", O_RDWR)) == -1) { + if (errno == ENOENT || errno == ENODEV) + atf_tc_skip("/dev/ptm: %s", strerror(errno)); + atf_tc_fail("/dev/ptm: %s", strerror(errno)); + } + + REQUIRE_ERRNO(fstat(fdm, &stm), -1); + ATF_REQUIRE_EQ(major(stm.st_rdev), 165); + REQUIRE_ERRNO(ioctl(fdm, TIOCPTMGET, &ptm), -1); + + ATF_REQUIRE_MSG(strncmp(ptm.cn, "/dev/pty", 8) == 0 + || strncmp(ptm.cn, "/dev/null", 9) == 0, + "bad master name: %s", ptm.cn); + + ATF_REQUIRE_MSG(strncmp(ptm.sn, "/dev/tty", 8) == 0 + || strncmp(ptm.sn, "/dev/pts/", 9) == 0, + "bad slave name: %s", ptm.sn); + + if (strncmp(ptm.cn, "/dev/null", 9) != 0) { + REQUIRE_ERRNO(fstat(ptm.cfd, &stm), -1); + REQUIRE_ERRNO(stat(ptm.cn, &sts), -1); + ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev); + } + + REQUIRE_ERRNO(fstat(ptm.sfd, &stm), -1); + REQUIRE_ERRNO(stat(ptm.sn, &sts), -1); + ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev); + + ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid"); + + ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL, + "cannot find `tty' group"); + ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave grid"); + + (void)close(ptm.sfd); + (void)close(ptm.cfd); + (void)close(fdm); +} + +/* + * On NetBSD /dev/ptyp0 == /dev/pts/0 so we can check for major + * and minor device numbers. This check is non-portable. This + * check is now disabled because we might not have /dev/ptyp0 + * at all. + */ + +/* + * #define PTY_DEVNO_CHECK + */ + +ATF_TC(ptmx); + +ATF_TC_HEAD(ptmx, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks /dev/ptmx device"); +} + +ATF_TC_BODY(ptmx, tc) +{ + struct stat stm, sts; + char *pty; + int fdm, fds; + struct group *gp; + + if ((fdm = posix_openpt(O_RDWR|O_NOCTTY)) == -1) { + if (errno == ENOENT || errno == ENODEV) + atf_tc_skip("/dev/ptmx: %s", strerror(errno)); + + atf_tc_fail("/dev/ptmx: %s", strerror(errno)); + } + + REQUIRE_ERRNO(fstat(fdm, &stm), -1); + +#ifdef PTY_DEVNO_CHECK + REQUIRE_ERRNO(stat("/dev/ptyp0", &sts), -1); + + ATF_REQUIRE_EQ_MSG(major(stm.st_rdev), major(sts.st_rdev), + "bad master major number"); +#endif + + REQUIRE_ERRNO(grantpt(fdm), -1); + REQUIRE_ERRNO(unlockpt(fdm), -1); + REQUIRE_ERRNO((pty = ptsname(fdm)), NULL); + + REQUIRE_ERRNO((fds = open(pty, O_RDWR|O_NOCTTY)), -1); + REQUIRE_ERRNO(fstat(fds, &sts), -1); + +#ifdef PTY_DEVNO_CHECK + ATF_REQUIRE_EQ_MSG(minor(stm.st_rdev), minor(sts.st_rdev), + "bad slave minor number"); +#endif + + ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid"); + ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL, + "cannot find `tty' group"); + + ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave gid"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ptm); + ATF_TP_ADD_TC(tp, ptmx); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c new file mode 100644 index 0000000..5a5ec0f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $ */ + +/* + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Brown. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $"); + +#include <sys/types.h> +#include <sys/wait.h> + +#include <err.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> + +#if defined(__NetBSD__) +#include <util.h> +#elif defined(__bsdi__) +int openpty(int *, int *, char *, struct termios *, struct winsize *); +#elif defined(__FreeBSD__) +#include <libutil.h> +#else +#error where openpty? +#endif + +#include <atf-c.h> + +#define REQUIRE_ERRNO(x, v) ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno)) + +ATF_TC(ioctl); +ATF_TC_HEAD(ioctl, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that ioctl calls are restarted " + "properly after being interrupted"); +} + +/* ARGSUSED */ +static void +sigchld(int nsig) +{ + REQUIRE_ERRNO(wait(NULL), -1); +} + +ATF_TC_BODY(ioctl, tc) +{ + int m, s, rc; + char name[128], buf[128]; + struct termios term; + struct sigaction sa; + + /* unbuffer stdout */ + setbuf(stdout, NULL); + + /* + * Create default termios settings for later use + */ + memset(&term, 0, sizeof(term)); + term.c_iflag = TTYDEF_IFLAG; + term.c_oflag = TTYDEF_OFLAG; + term.c_cflag = TTYDEF_CFLAG; + term.c_lflag = TTYDEF_LFLAG; + cfsetspeed(&term, TTYDEF_SPEED); + + /* get a tty */ + REQUIRE_ERRNO(openpty(&m, &s, name, &term, NULL), -1); + + switch (fork()) { + case -1: + atf_tc_fail("fork(): %s", strerror(errno)); + /* NOTREACHED */ + case 0: + /* wait for parent to get set up */ + (void)sleep(1); + (void)printf("child1: exiting\n"); + exit(0); + /* NOTREACHED */ + default: + (void)printf("parent: spawned child1\n"); + break; + } + + switch (fork()) { + case -1: + atf_tc_fail("fork(): %s", strerror(errno)); + /* NOTREACHED */ + case 0: + /* wait for parent to get upset */ + (void)sleep(2); + /* drain the tty q */ + if (read(m, buf, sizeof(buf)) == -1) + err(1, "read"); + (void)printf("child2: exiting\n"); + exit(0); + /* NOTREACHED */ + default: + (void)printf("parent: spawned child2\n"); + break; + } + + /* set up a restarting signal handler */ + (void)sigemptyset(&sa.sa_mask); + sa.sa_handler = sigchld; + sa.sa_flags = SA_RESTART; + REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1); + + /* put something in the output q */ + REQUIRE_ERRNO(write(s, "Hello world\n", 12), -1); + + /* ask for output to drain but don't drain it */ + rc = 0; + if (tcsetattr(s, TCSADRAIN, &term) == -1) { + (void)printf("parent: tcsetattr: %s\n", strerror(errno)); + rc = 1; + } + + /* wait for last child */ + sa.sa_handler = SIG_DFL; + REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1); + (void) wait(NULL); + + ATF_REQUIRE_EQ(rc, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ioctl); + + return atf_no_error(); +} |