diff options
author | ngie <ngie@FreeBSD.org> | 2014-10-02 23:26:49 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2014-10-02 23:26:49 +0000 |
commit | 3f09b8d0af642c2aeb96a4d667cefb7fe3bce443 (patch) | |
tree | 544932e2a2c5a5a202b752beefba0b3e327b3858 /contrib/netbsd-tests/lib/libc/gen | |
parent | b941fec92da62b0eab650295f4e8a381dbbc04b4 (diff) | |
parent | e1f2d32c0e0678782c353c48364cddedfae58b0a (diff) | |
download | FreeBSD-src-3f09b8d0af642c2aeb96a4d667cefb7fe3bce443.zip FreeBSD-src-3f09b8d0af642c2aeb96a4d667cefb7fe3bce443.tar.gz |
Import the NetBSD test suite from ^/vendor/NetBSD/tests/09.30.2014_20.45 ,
minus the vendor Makefiles
Provide directions for how to bootstrap the vendor sources in
FREEBSD-upgrade
MFC after 2 weeks
Discussed with: rpaulo
Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'contrib/netbsd-tests/lib/libc/gen')
40 files changed, 6635 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c new file mode 100644 index 0000000..32de6e7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_execve.c,v 1.1 2014/04/29 06:29:02 uebayasi Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> + +ATF_TC(t_execve_null); + +ATF_TC_HEAD(t_execve_null, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests an empty execve(2) executing"); +} + +ATF_TC_BODY(t_execve_null, tc) +{ + int err; + + err = execve(NULL, NULL, NULL); + ATF_REQUIRE(err == -1); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_execve_null); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/isqemu.h b/contrib/netbsd-tests/lib/libc/gen/isqemu.h new file mode 100644 index 0000000..7d73a22 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/isqemu.h @@ -0,0 +1,63 @@ +/* $NetBSD: isqemu.h,v 1.3 2013/04/14 12:46:29 martin Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/sysctl.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> +#include <err.h> + +static __inline bool +isQEMU(void) { +#if defined(__i386__) || defined(__x86_64__) + char name[1024]; + size_t len = sizeof(name); + + if (sysctlbyname("machdep.cpu_brand", name, &len, NULL, 0) == -1) { + if (errno == ENOENT) + return false; + err(EXIT_FAILURE, "sysctl"); + } + return strstr(name, "QEMU") != NULL; +#else + return false; +#endif +} + +#ifdef TEST +int +main(void) { + return isQEMU(); +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c new file mode 100644 index 0000000..d923370 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c @@ -0,0 +1,104 @@ +/* $NetBSD: h_fileactions.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <sys/stat.h> + +#define BUFSIZE 16 + +/* + * This checks (hardcoded) the assumptions that are setup from the + * main test program via posix spawn file actions. + * Program exits with EXIT_SUCCESS or EXIT_FAILURE accordingly + * (and does some stderr diagnostics in case of errors). + */ +int +main(int argc, char **argv) +{ + int res = EXIT_SUCCESS; + char buf[BUFSIZE]; + struct stat sb0, sb1; + + strcpy(buf, "test..."); + /* file desc 3 should be closed via addclose */ + if (read(3, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 3 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 4 should be closed via closeonexec */ + if (read(4, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 4 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 5 remains open */ + if (write(5, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 5\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 6 should be open (via addopen) */ + if (write(6, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 6\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 7 should refer to stdout */ + fflush(stdout); + if (fstat(fileno(stdout), &sb0) != 0) { + fprintf(stderr, "%s: could not fstat stdout\n", + getprogname()); + res = EXIT_FAILURE; + } + if (fstat(7, &sb1) != 0) { + fprintf(stderr, "%s: could not fstat filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (write(7, buf, strlen(buf)) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (memcmp(&sb0, &sb1, sizeof sb0) != 0) { + fprintf(stderr, "%s: stat results differ\n", getprogname()); + res = EXIT_FAILURE; + } + + return res; +} + diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh new file mode 100755 index 0000000..deee6fe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh @@ -0,0 +1,3 @@ +#! /nonexistent + +# this is just a dummy script, trying to be non-executable diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c new file mode 100644 index 0000000..dbf5da5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c @@ -0,0 +1,50 @@ +/* $NetBSD: h_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char **argv) +{ + unsigned long ret; + char *endp; + + if (argc < 2) { + fprintf(stderr, "usage:\n\t%s (retcode)\n", getprogname()); + exit(255); + } + ret = strtoul(argv[1], &endp, 10); + + fprintf(stderr, "%s exiting with status %lu\n", getprogname(), ret); + return ret; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c new file mode 100644 index 0000000..1f13c54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c @@ -0,0 +1,90 @@ +/* $NetBSD: h_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +/* + * Helper to test the hardcoded assumptions from t_spawnattr.c + * Exit with apropriate exit status and print diagnostics to + * stderr explaining what is wrong. + */ +int +main(int argc, char **argv) +{ + int parent_pipe, res = EXIT_SUCCESS; + sigset_t sig; + struct sigaction act; + ssize_t rd; + char tmp; + + sigemptyset(&sig); + if (sigprocmask(0, NULL, &sig) < 0) { + fprintf(stderr, "%s: sigprocmask error\n", getprogname()); + res = EXIT_FAILURE; + } + if (!sigismember(&sig, SIGUSR1)) { + fprintf(stderr, "%s: SIGUSR not in procmask\n", getprogname()); + res = EXIT_FAILURE; + } + if (sigaction(SIGUSR1, NULL, &act) < 0) { + fprintf(stderr, "%s: sigaction error\n", getprogname()); + res = EXIT_FAILURE; + } + if (act.sa_sigaction != (void *)SIG_DFL) { + fprintf(stderr, "%s: SIGUSR1 action != SIG_DFL\n", + getprogname()); + res = EXIT_FAILURE; + } + + if (argc >= 2) { + parent_pipe = atoi(argv[1]); + if (parent_pipe > 2) { + printf("%s: waiting for command from parent on pipe " + "%d\n", getprogname(), parent_pipe); + rd = read(parent_pipe, &tmp, 1); + if (rd == 1) { + printf("%s: got command %c from parent\n", + getprogname(), tmp); + } else if (rd == -1) { + printf("%s: %d is no pipe, errno %d\n", + getprogname(), parent_pipe, errno); + res = EXIT_FAILURE; + } + } + } + + return res; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c new file mode 100644 index 0000000..1cf6433 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c @@ -0,0 +1,385 @@ +/* $NetBSD: t_fileactions.c,v 1.5 2012/04/09 19:42:07 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <spawn.h> +#include <unistd.h> +#include <sys/wait.h> + + +ATF_TC(t_spawn_openmode); + +ATF_TC_HEAD(t_spawn_openmode, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the proper handling of 'mode' for 'open' fileactions"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +static off_t +filesize(const char * restrict fname) +{ + struct stat st; + int err; + + err = stat(fname, &st); + ATF_REQUIRE(err == 0); + return st.st_size; +} + +#define TESTFILE "./the_input_data" +#define CHECKFILE "./the_output_data" +#define TESTCONTENT "marry has a little lamb" + +static void +make_testfile(const char *restrict file) +{ + FILE *f; + size_t written; + + f = fopen(file, "w"); + ATF_REQUIRE(f != NULL); + written = fwrite(TESTCONTENT, 1, strlen(TESTCONTENT), f); + fclose(f); + ATF_REQUIRE(written == strlen(TESTCONTENT)); +} + +static void +empty_outfile(const char *restrict filename) +{ + FILE *f; + + f = fopen(filename, "w"); + ATF_REQUIRE(f != NULL); + fclose(f); +} + +ATF_TC_BODY(t_spawn_openmode, tc) +{ + int status, err; + pid_t pid; + size_t insize, outsize; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * try a "cat < testfile > checkfile" + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_CREAT, 0600); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); + + /* + * try a "cat < testfile >> checkfile" + */ + make_testfile(TESTFILE); + make_testfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_APPEND, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that output is twice as long as input */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize*2 == outsize); + + /* + * try a "cat < testfile > checkfile" with input and output swapped + */ + make_testfile(TESTFILE); + empty_outfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + CHECKFILE, O_WRONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_FAILURE); + + /* now check that input and output are still the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(outsize == 0); +} + +ATF_TC(t_spawn_reopen); + +ATF_TC_HEAD(t_spawn_reopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "an open filehandle can be replaced by a 'open' fileaction"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_reopen, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * make sure stdin is open in the parent + */ + freopen("/dev/zero", "r", stdin); + /* + * now request an open for this fd again in the child + */ + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + "/dev/null", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_open_nonexistent); + +ATF_TC_HEAD(t_spawn_open_nonexistent, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent, tc) +{ + int err, status; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + if (err == 0) { + /* + * The child has been created - it should fail and + * return exit code 127 + */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 127); + } else { + /* + * The error has been noticed early enough, no child has + * been run + */ + ATF_REQUIRE(err == ENOENT); + } + posix_spawn_file_actions_destroy(&fa); +} + +ATF_TC(t_spawn_open_nonexistent_diag); + +ATF_TC_HEAD(t_spawn_open_nonexistent_diag, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist " + "and delivers proper diagnostic"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent_diag, tc) +{ + int err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawnattr_t attr; + posix_spawn_file_actions_t fa; + + posix_spawnattr_init(&attr); + /* + * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that + * will cause a "proper" return value from posix_spawn(2) + * instead of a (potential) success there and a 127 exit + * status from the child process (c.f. the non-diag variant + * of this test). + */ + posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, &attr, args, NULL); + ATF_REQUIRE(err == ENOENT); + posix_spawn_file_actions_destroy(&fa); + posix_spawnattr_destroy(&attr); +} + +ATF_TC(t_spawn_fileactions); + +ATF_TC_HEAD(t_spawn_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests various complex fileactions"); +} + +ATF_TC_BODY(t_spawn_fileactions, tc) +{ + int fd1, fd2, fd3, status, err; + pid_t pid; + char * const args[2] = { __UNCONST("h_fileactions"), NULL }; + char helper[FILENAME_MAX]; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + + closefrom(fileno(stderr)+1); + + fd1 = open("/dev/null", O_RDONLY); + ATF_REQUIRE(fd1 == 3); + + fd2 = open("/dev/null", O_WRONLY, O_CLOEXEC); + ATF_REQUIRE(fd2 == 4); + + fd3 = open("/dev/null", O_WRONLY); + ATF_REQUIRE(fd3 == 5); + + posix_spawn_file_actions_addclose(&fa, fd1); + posix_spawn_file_actions_addopen(&fa, 6, "/dev/null", O_RDWR, 0); + posix_spawn_file_actions_adddup2(&fa, 1, 7); + + snprintf(helper, sizeof helper, "%s/h_fileactions", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(&pid, helper, &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_empty_fileactions); + +ATF_TC_HEAD(t_spawn_empty_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn with empty fileactions (PR kern/46038)"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_empty_fileactions, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + size_t insize, outsize; + + /* + * try a "cat < testfile > checkfile", but set up stdin/stdout + * already in the parent and pass empty file actions to the child. + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + freopen(TESTFILE, "r", stdin); + freopen(CHECKFILE, "w", stdout); + + posix_spawn_file_actions_init(&fa); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_fileactions); + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent); + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag); + ATF_TP_ADD_TC(tp, t_spawn_reopen); + ATF_TP_ADD_TC(tp, t_spawn_openmode); + ATF_TP_ADD_TC(tp, t_spawn_empty_fileactions); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c new file mode 100644 index 0000000..178374b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c @@ -0,0 +1,184 @@ +/* $NetBSD: t_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include <atf-c.h> +#include <spawn.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/wait.h> + +ATF_TC(t_spawn_ls); + +ATF_TC_HEAD(t_spawn_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawn executing /bin/ls"); +} + +ATF_TC_BODY(t_spawn_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawnp_ls); + +ATF_TC_HEAD(t_spawnp_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawnp executing ls via $PATH"); +} + +ATF_TC_BODY(t_spawnp_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawn_zero); + +ATF_TC_HEAD(t_spawn_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn an invalid binary"); +} + +ATF_TC_BODY(t_spawn_zero, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_zero"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf); +} + +ATF_TC(t_spawn_missing); + +ATF_TC_HEAD(t_spawn_missing, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a non existant binary"); +} + +ATF_TC_BODY(t_spawn_missing, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexist"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexist", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_nonexec); + +ATF_TC_HEAD(t_spawn_nonexec, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a script with non existing interpreter"); +} + +ATF_TC_BODY(t_spawn_nonexec, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexec"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexec", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_child); + +ATF_TC_HEAD(t_spawn_child, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a child and get it's return code"); +} + +ATF_TC_BODY(t_spawn_child, tc) +{ + char buf[FILENAME_MAX]; + char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL }; + char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL }; + char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL }; + int err, status; + pid_t pid; + + snprintf(buf, sizeof buf, "%s/h_spawn", + atf_tc_get_config_var(tc, "srcdir")); + + err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); + + err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1); + + err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_ls); + ATF_TP_ADD_TC(tp, t_spawnp_ls); + ATF_TP_ADD_TC(tp, t_spawn_zero); + ATF_TP_ADD_TC(tp, t_spawn_missing); + ATF_TP_ADD_TC(tp, t_spawn_nonexec); + ATF_TP_ADD_TC(tp, t_spawn_child); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c new file mode 100644 index 0000000..eb99c41 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c @@ -0,0 +1,173 @@ +/* $NetBSD: t_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang <charles@NetBSD.org> and + * Martin Husemann <martin@NetBSD.org>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <sched.h> +#include <signal.h> +#include <spawn.h> +#include <unistd.h> +#include <sys/wait.h> + +#define MAX(a, b) (a) > (b) ? (a) : (b) +#define MIN(a, b) (a) > (b) ? (b) : (a) + +static int get_different_scheduler(void); +static int get_different_priority(void); + +static int +get_different_scheduler() +{ + int scheduler, max, min, new; + + max = MAX(MAX(SCHED_FIFO, SCHED_OTHER), SCHED_RR); + min = MIN(MIN(SCHED_FIFO, SCHED_OTHER), SCHED_RR); + + /* get current schedule policy */ + scheduler = sched_getscheduler(0); + + /* new scheduler */ + new = (scheduler + 1); + if (new > max) + new = min; + + return new; +} + +static int +get_different_priority() +{ + int scheduler, max, min, new, priority; + struct sched_param param; + + /* get current schedule policy */ + scheduler = sched_getscheduler(0); + + max = sched_get_priority_max(scheduler); + min = sched_get_priority_min(scheduler); + + sched_getparam(0, ¶m); + priority = param.sched_priority; + + /* new schedule policy */ + new = (priority + 1); + if (new > max) + new = min; + + return new; +} + +ATF_TC(t_spawnattr); + +ATF_TC_HEAD(t_spawnattr, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Tests posix_spawn with scheduler attributes"); +} + +ATF_TC_BODY(t_spawnattr, tc) +{ + int pid, scheduler, child_scheduler, priority, status, err, pfd[2]; + char helper_arg[128]; + char * const args[] = { __UNCONST("h_spawnattr"), helper_arg, NULL }; + struct sched_param sp, child_sp; + sigset_t sig; + posix_spawnattr_t attr; + char helper[FILENAME_MAX]; + + /* + * create a pipe to controll the child + */ + err = pipe(pfd); + ATF_REQUIRE_MSG(err == 0, "could not create pipe, errno %d", errno); + sprintf(helper_arg, "%d", pfd[0]); + + posix_spawnattr_init(&attr); + + scheduler = get_different_scheduler(); + priority = get_different_priority(); + sp.sched_priority = priority; + + sigemptyset(&sig); + sigaddset(&sig, SIGUSR1); + + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDULER | + POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETPGROUP | + POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF | + POSIX_SPAWN_SETSIGDEF); + posix_spawnattr_setpgroup(&attr, 0); + posix_spawnattr_setschedparam(&attr, &sp); + posix_spawnattr_setschedpolicy(&attr, scheduler); + posix_spawnattr_setsigmask(&attr, &sig); + posix_spawnattr_setsigdefault(&attr, &sig); + + sprintf(helper, "%s/h_spawnattr", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(&pid, helper, NULL, &attr, args, NULL); + ATF_REQUIRE_MSG(err == 0, "error %d", err); + + child_scheduler = sched_getscheduler(pid); + ATF_REQUIRE_MSG(scheduler == child_scheduler, + "scheduler = %d, child_scheduler = %d, pid %d, errno %d", + scheduler, child_scheduler, pid, errno); + + sched_getparam(pid, &child_sp); + ATF_REQUIRE_MSG(child_sp.sched_priority == sp.sched_priority, + "priority is: %d, but we requested: %d", + child_sp.sched_priority, sp.sched_priority); + + ATF_REQUIRE_MSG(pid == getpgid(pid), "child pid: %d, child pgid: %d", + pid, getpgid(pid)); + + /* ready, let child go */ + write(pfd[1], "q", 1); + close(pfd[0]); + close(pfd[1]); + + /* wait and check result from child */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + posix_spawnattr_destroy(&attr); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawnattr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_alarm.c b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c new file mode 100644 index 0000000..d9e903d1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +static bool fail; +static void handler(int); + +static void +handler(int signo) +{ + + if (signo == SIGALRM) + fail = false; +} + +ATF_TC(alarm_basic); +ATF_TC_HEAD(alarm_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of alarm(3)"); +} + +ATF_TC_BODY(alarm_basic, tc) +{ + + ATF_REQUIRE(signal(SIGALRM, handler) == 0); + + fail = true; + + (void)alarm(1); + (void)sleep(2); + + if (fail != false) + atf_tc_fail("alarm(3) failed to deliver signal"); +} + +ATF_TC(alarm_fork); +ATF_TC_HEAD(alarm_fork, tc) +{ + atf_tc_set_md_var(tc, "descr", "Does fork(2) clear a pending alarm?"); +} + +ATF_TC_BODY(alarm_fork, tc) +{ + unsigned int rv; + pid_t pid; + int sta; + + /* + * Any pending alarms should be + * cleared in the child process. + */ + (void)alarm(60); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = alarm(0); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)alarm(0); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("pending alarm was not cleared for child"); +} + +ATF_TC(alarm_previous); +ATF_TC_HEAD(alarm_previous, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test return value from alarm(3)"); +} + +ATF_TC_BODY(alarm_previous, tc) +{ + unsigned int rv; + + /* + * See that alarm(3) returns the amount + * left on the timer from the previous call. + */ + rv = alarm(60); + + if (rv != 0) + goto fail; + + rv = alarm(0); + + if (rv < 50) + goto fail; + + (void)alarm(0); + + return; + +fail: + atf_tc_fail("invalid return value from alarm(3)"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, alarm_basic); + ATF_TP_ADD_TC(tp, alarm_fork); + ATF_TP_ADD_TC(tp, alarm_previous); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_assert.c b/contrib/netbsd-tests/lib/libc/gen/t_assert.c new file mode 100644 index 0000000..140417a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_assert.c @@ -0,0 +1,132 @@ +/* $NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $"); + +#include <sys/wait.h> + +#include <assert.h> +#include <atf-c.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static void handler(int); + +static void +handler(int signo) +{ + /* Nothing. */ +} + +ATF_TC(assert_false); +ATF_TC_HEAD(assert_false, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #1"); +} + +ATF_TC_BODY(assert_false, tc) +{ + struct sigaction sa; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)closefrom(0); + (void)memset(&sa, 0, sizeof(struct sigaction)); + + sa.sa_flags = 0; + sa.sa_handler = handler; + + (void)sigemptyset(&sa.sa_mask); + (void)sigaction(SIGABRT, &sa, 0); + + assert(1 == 1); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WIFEXITED(sta) == 0) + atf_tc_fail("assert(3) fired haphazardly"); +} + +ATF_TC(assert_true); +ATF_TC_HEAD(assert_true, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #2"); +} + +ATF_TC_BODY(assert_true, tc) +{ + struct sigaction sa; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)closefrom(0); + (void)memset(&sa, 0, sizeof(struct sigaction)); + + sa.sa_flags = 0; + sa.sa_handler = handler; + + (void)sigemptyset(&sa.sa_mask); + (void)sigaction(SIGABRT, &sa, 0); + + assert(1 == 2); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGABRT) + atf_tc_fail("assert(3) did not fire"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, assert_false); + ATF_TP_ADD_TC(tp, assert_true); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c new file mode 100644 index 0000000..6c82cb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c @@ -0,0 +1,200 @@ +/* $NetBSD: t_basedirname.c,v 1.2 2011/07/07 09:49:59 jruoho Exp $ */ + +/* + * Regression test for basename(3). + * + * Written by Jason R. Thorpe <thorpej@NetBSD.org>, Oct. 2002. + * Public domain. + */ + +#include <atf-c.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <libgen.h> + +struct { + const char *input; + const char *output; +} test_basename_table[] = { +/* + * The following are taken from the "Sample Input and Output Strings + * for basename()" table in IEEE Std 1003.1-2001. + */ + { "/usr/lib", "lib" }, + { "/usr/", "usr" }, + { "/", "/" }, + { "///", "/" }, + { "//usr//lib//", "lib" }, +/* + * IEEE Std 1003.1-2001: + * + * If path is a null pointer or points to an empty string, + * basename() shall return a pointer to the string "." . + */ + { "", "." }, + { NULL, "." }, +/* + * IEEE Std 1003.1-2001: + * + * If the string is exactly "//", it is implementation-defined + * whether "/" or "//" is returned. + * + * The NetBSD implementation returns "/". + */ + { "//", "/" }, + + { NULL, NULL } +}; + +struct { + const char *input; + const char *output; +} test_dirname_table[] = { +/* + * The following are taken from the "Sample Input and Output Strings + * for dirname()" table in IEEE Std 1003.1-2001. + */ + { "/usr/lib", "/usr" }, + { "/usr/", "/" }, + { "usr", "." }, + { "/", "/" }, + { ".", "." }, + { "..", "." }, +/* + * IEEE Std 1003.1-2001: + * + * If path is a null pointer or points to an empty string, + * dirname() shall return a pointer to the string "." . + */ + { "", "." }, + { NULL, "." }, +/* + * IEEE Std 1003.1-2001: + * + * Since the meaning of the leading "//" is implementation-defined, + * dirname("//foo") may return either "//" or "/" (but nothing else). + * + * The NetBSD implementation returns "/". + */ + { "//foo", "/" }, +/* + * Make sure the trailing slashes after the directory name component + * get trimmed. The Std does not talk about this, but this is what + * Solaris 8's dirname(3) does. + */ + { "/usr///lib", "/usr" }, + + { NULL, NULL } +}; + +ATF_TC(basename_posix); +ATF_TC_HEAD(basename_posix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test basename(3) with POSIX examples"); +} + +ATF_TC_BODY(basename_posix, tc) +{ + char testbuf[32], *base; + int i; + + for (i = 0; test_basename_table[i].output != NULL; i++) { + if (test_basename_table[i].input != NULL) { + if (strlen(test_basename_table[i].input) >= + sizeof(testbuf)) + atf_tc_skip("Testbuf too small!"); + strcpy(testbuf, test_basename_table[i].input); + base = basename(testbuf); + } else + base = basename(NULL); + + /* + * basename(3) is allowed to modify the input buffer. + * However, that is considered hostile by some programs, + * and so we elect to consider this an error. + * + * This is not a problem, as basename(3) is also allowed + * to return a pointer to a statically-allocated buffer + * (it is explicitly not required to be reentrant). + */ + if (test_basename_table[i].input != NULL && + strcmp(test_basename_table[i].input, testbuf) != 0) { + fprintf(stderr, + "Input buffer for \"%s\" was modified\n", + test_basename_table[i].input); + atf_tc_fail("Input buffer was modified."); + } + + /* Make sure the result is correct. */ + if (strcmp(test_basename_table[i].output, base) != 0) { + fprintf(stderr, + "Input \"%s\", output \"%s\", expected \"%s\"\n", + test_basename_table[i].input == + NULL ? "(null)" : test_basename_table[i].input, + base, test_basename_table[i].output); + atf_tc_fail("Output does not match expected value."); + } + } +} + + +ATF_TC(dirname_posix); +ATF_TC_HEAD(dirname_posix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dirname(3) with POSIX examples"); +} + +ATF_TC_BODY(dirname_posix, tc) +{ + char testbuf[32], *base; + int i; + + for (i = 0; test_dirname_table[i].output != NULL; i++) { + if (test_dirname_table[i].input != NULL) { + if (strlen(test_dirname_table[i].input) >= + sizeof(testbuf)) + atf_tc_skip("Testbuf too small!"); + strcpy(testbuf, test_dirname_table[i].input); + base = dirname(testbuf); + } else + base = dirname(NULL); + + /* + * dirname(3) is allowed to modify the input buffer. + * However, that is considered hostile by some programs, + * and so we elect to consider this an error. + * + * This is not a problem, as dirname(3) is also allowed + * to return a pointer to a statically-allocated buffer + * (it is explicitly not required to be reentrant). + */ + if (test_dirname_table[i].input != NULL && + strcmp(test_dirname_table[i].input, testbuf) != 0) { + fprintf(stderr, + "Input buffer for \"%s\" was modified\n", + test_dirname_table[i].input); + atf_tc_fail("Input buffer was modified."); + } + + /* Make sure the result is correct. */ + if (strcmp(test_dirname_table[i].output, base) != 0) { + fprintf(stderr, + "Input \"%s\", output \"%s\", expected \"%s\"\n", + test_dirname_table[i].input == + NULL ? "(null)" : test_dirname_table[i].input, + base, test_dirname_table[i].output); + atf_tc_fail("Output does not match expected value."); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, basename_posix); + ATF_TP_ADD_TC(tp, dirname_posix); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c new file mode 100644 index 0000000..75ebabb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c @@ -0,0 +1,173 @@ +/* $NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <unistd.h> + +static const char path[] = "closefrom"; + +ATF_TC_WITH_CLEANUP(closefrom_basic); +ATF_TC_HEAD(closefrom_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #1"); +} + +ATF_TC_BODY(closefrom_basic, tc) +{ + int fd, cur1, cur2; + + (void)closefrom(STDERR_FILENO + 1); + + fd = open(path, O_RDONLY | O_CREAT, 0400); + ATF_REQUIRE(fd >= 0); + + cur1 = fcntl(0, F_MAXFD); + + ATF_REQUIRE(cur1 == STDERR_FILENO + 1); + ATF_REQUIRE(closefrom(cur1) == 0); + + cur2 = fcntl(0, F_MAXFD); + + ATF_REQUIRE(cur1 - 1 == cur2); + ATF_REQUIRE(close(fd) == -1); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(closefrom_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(closefrom_buffer); +ATF_TC_HEAD(closefrom_buffer, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #2"); +} + +ATF_TC_BODY(closefrom_buffer, tc) +{ + int buf[16], cur, half; + size_t i; + + /* + * Open a buffer of descriptors, close the half of + * these and verify that the result is consistent. + */ + ATF_REQUIRE(closefrom(STDERR_FILENO + 1) == 0); + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == STDERR_FILENO); + + for (i = 0; i < __arraycount(buf); i++) { + buf[i] = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(buf[i] >= 0); + } + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == __arraycount(buf) + STDERR_FILENO); + + half = STDERR_FILENO + __arraycount(buf) / 2; + ATF_REQUIRE(closefrom(half) == 0); + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == half - 1); + + for (i = 0; i < __arraycount(buf); i++) + (void)close(buf[i]); +} + +ATF_TC_CLEANUP(closefrom_buffer, tc) +{ + (void)unlink(path); +} + +ATF_TC(closefrom_err); +ATF_TC_HEAD(closefrom_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from closefrom(3)"); +} + +ATF_TC_BODY(closefrom_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, closefrom(-INT_MAX) == -1); +} + +ATF_TC(closefrom_one); +ATF_TC_HEAD(closefrom_one, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test closefrom(1)"); +} + +ATF_TC_BODY(closefrom_one, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (closefrom(1) != 0) + _exit(10); + + _exit(fcntl(0, F_MAXFD)); + } + + + (void)wait(&sta); + + /* + * STDIN_FILENO sould still be open; WEXITSTATUS(1) == 0. + */ + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != 0) + atf_tc_fail("not all descriptors were closed"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, closefrom_basic); + ATF_TP_ADD_TC(tp, closefrom_buffer); + ATF_TP_ADD_TC(tp, closefrom_err); + ATF_TP_ADD_TC(tp, closefrom_one); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c new file mode 100644 index 0000000..9eca03b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $"); + +#include <atf-c.h> +#include <limits.h> +#include <stdio.h> +#include <sched.h> + +ATF_TC(cpuset_err); +ATF_TC_HEAD(cpuset_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from cpuset(3)"); +} + +ATF_TC_BODY(cpuset_err, tc) +{ + cpuset_t *set; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + ATF_CHECK(cpuset_set(-1, set) == -1); + ATF_CHECK(cpuset_clr(-1, set) == -1); + ATF_CHECK(cpuset_isset(-1, set) == -1); + + ATF_CHECK(cpuset_set(INT_MAX, set) == -1); + ATF_CHECK(cpuset_clr(INT_MAX, set) == -1); + ATF_CHECK(cpuset_isset(INT_MAX, set) == -1); + + cpuset_destroy(set); +} + +ATF_TC(cpuset_set); +ATF_TC_HEAD(cpuset_set, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cpuset_set(3)"); +} + +ATF_TC_BODY(cpuset_set, tc) +{ + cpuset_t *set; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + ATF_REQUIRE(cpuset_set(0, set) == 0); + ATF_REQUIRE(cpuset_isset(0, set) > 0); + ATF_REQUIRE(cpuset_clr(0, set) == 0); + ATF_REQUIRE(cpuset_isset(0, set) == 0); + + cpuset_destroy(set); +} + +ATF_TC(cpuset_size); +ATF_TC_HEAD(cpuset_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test puset_size(3)"); +} + +ATF_TC_BODY(cpuset_size, tc) +{ + cpuset_t *set; + size_t size; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + size = cpuset_size(set); + + ATF_CHECK(cpuset_set((size * 8) - 1, set) == 0); + ATF_CHECK(cpuset_set((size * 8) + 1, set) == -1); + + cpuset_destroy(set); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cpuset_err); + ATF_TP_ADD_TC(tp, cpuset_set); + ATF_TP_ADD_TC(tp, cpuset_size); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_dir.c b/contrib/netbsd-tests/lib/libc/gen/t_dir.c new file mode 100644 index 0000000..81412c1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_dir.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_dir.c,v 1.6 2013/10/19 17:45:00 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <assert.h> +#include <dirent.h> +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/stat.h> + +ATF_TC(seekdir_basic); +ATF_TC_HEAD(seekdir_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check telldir(3) and seekdir(3) " + "for correct behavior (PR lib/24324)"); +} + +ATF_TC_BODY(seekdir_basic, tc) +{ + DIR *dp; + char *wasname; + struct dirent *entry; + long here; + + mkdir("t", 0755); + creat("t/a", 0600); + creat("t/b", 0600); + creat("t/c", 0600); + + dp = opendir("t"); + if ( dp == NULL) + atf_tc_fail("Could not open temp directory."); + + /* skip two for . and .. */ + entry = readdir(dp); + entry = readdir(dp); + + /* get first entry */ + entry = readdir(dp); + here = telldir(dp); + + /* get second entry */ + entry = readdir(dp); + wasname = strdup(entry->d_name); + if (wasname == NULL) + atf_tc_fail("cannot allocate memory"); + + /* get third entry */ + entry = readdir(dp); + + /* try to return to the position after the first entry */ + seekdir(dp, here); + entry = readdir(dp); + + if (entry == NULL) + atf_tc_fail("entry 1 not found"); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("1st seekdir found wrong name"); + + /* try again, and throw in a telldir() for good measure */ + seekdir(dp, here); + here = telldir(dp); + entry = readdir(dp); + + if (entry == NULL) + atf_tc_fail("entry 2 not found"); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("2nd seekdir found wrong name"); + + /* One more time, to make sure that telldir() doesn't affect result */ + seekdir(dp, here); + entry = readdir(dp); + + if (entry == NULL) + atf_tc_fail("entry 3 not found"); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("3rd seekdir found wrong name"); + + closedir(dp); +} + +ATF_TC(telldir_leak); +ATF_TC_HEAD(telldir_leak, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Check telldir(3) for memory leakage (PR lib/24324)"); +} + +ATF_TC_BODY(telldir_leak, tc) +{ + DIR *dp; + char *memused; + int i; + int oktouse = 4096; + + dp = opendir("."); + if (dp == NULL) + atf_tc_fail("Could not open current directory"); + + (void)telldir(dp); + memused = sbrk(0); + closedir(dp); + + for (i = 0; i < 1000; i++) { + dp = opendir("."); + if (dp == NULL) + atf_tc_fail("Could not open current directory"); + + (void)telldir(dp); + closedir(dp); + + if ((char *)sbrk(0) - memused > oktouse) { + (void)printf("Used %td extra bytes for %d telldir " + "calls", ((char *)sbrk(0) - memused), i); + oktouse = (char *)sbrk(0) - memused; + } + } + if (oktouse > 4096) { + atf_tc_fail("Failure: leaked %d bytes", oktouse); + } else { + (void)printf("OK: used %td bytes\n", (char *)(sbrk(0))-memused); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, seekdir_basic); + ATF_TP_ADD_TC(tp, telldir_leak); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c new file mode 100644 index 0000000..9561a3c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_floatunditf.c,v 1.5 2014/02/02 08:16:22 martin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <atf-c/config.h> +#include <inttypes.h> +#include <math.h> + +#ifdef __HAVE_LONG_DOUBLE +static const struct { + uint64_t u64; + long double ld; +} testcases[] = { + { 0xffffffffffffffffULL, 0xf.fffffffffffffffp+60L }, + { 0xfffffffffffffffeULL, 0xf.ffffffffffffffep+60L }, + { 0xfffffffffffffffdULL, 0xf.ffffffffffffffdp+60L }, + { 0xfffffffffffffffcULL, 0xf.ffffffffffffffcp+60L }, + { 0x7fffffffffffffffULL, 0xf.ffffffffffffffep+59L }, + { 0x3fffffffffffffffULL, 0xf.ffffffffffffffcp+58L }, + { 0x1fffffffffffffffULL, 0xf.ffffffffffffff8p+57L }, + { 0xfffffffffffffffULL, 0xf.ffffffffffffffp+56L }, + { 0x7ffffffffffffffULL, 0xf.fffffffffffffep+55L }, + { 0x3ffffffffffffffULL, 0xf.fffffffffffffcp+54L }, + { 0x1ffffffffffffffULL, 0xf.fffffffffffff8p+53L }, + { 0xffffffffffffffULL, 0xf.fffffffffffffp+52L }, + { 0x7fffffffffffffULL, 0xf.ffffffffffffep+51L }, + { 0x3fffffffffffffULL, 0xf.ffffffffffffcp+50L }, + { 0x1fffffffffffffULL, 0xf.ffffffffffff8p+49L }, + { 0xfffffffffffffULL, 0xf.ffffffffffffp+48L }, + { 0x7ffffffffffffULL, 0xf.fffffffffffep+47L }, + { 0x3ffffffffffffULL, 0xf.fffffffffffcp+46L }, + { 0x1ffffffffffffULL, 0xf.fffffffffff8p+45L }, + { 0xffffffffffffULL, 0xf.fffffffffffp+44L }, + { 0x7fffffffffffULL, 0xf.ffffffffffep+43L }, + { 0x3fffffffffffULL, 0xf.ffffffffffcp+42L }, + { 0x1fffffffffffULL, 0xf.ffffffffff8p+41L }, + { 0xfffffffffffULL, 0xf.ffffffffffp+40L }, + { 0x7ffffffffffULL, 0xf.fffffffffep+39L }, + { 0x3ffffffffffULL, 0xf.fffffffffcp+38L }, + { 0x1ffffffffffULL, 0xf.fffffffff8p+37L }, + { 0xffffffffffULL, 0xf.fffffffffp+36L }, + { 0x7fffffffffULL, 0xf.ffffffffep+35L }, + { 0x3fffffffffULL, 0xf.ffffffffcp+34L }, + { 0x1fffffffffULL, 0xf.ffffffff8p+33L }, + { 0xfffffffffULL, 0xf.ffffffffp+32L }, + { 0x7ffffffffULL, 0xf.fffffffep+31L }, + { 0x3ffffffffULL, 0xf.fffffffcp+30L }, + { 0x1ffffffffULL, 0xf.fffffff8p+29L }, + { 0xffffffffULL, 0xf.fffffffp+28L }, + { 0x7fffffffULL, 0xf.ffffffep+27L }, + { 0x3fffffffULL, 0xf.ffffffcp+26L }, + { 0x1fffffffULL, 0xf.ffffff8p+25L }, + { 0xfffffffULL, 0xf.ffffffp+24L }, + { 0x7ffffffULL, 0xf.fffffep+23L }, + { 0x3ffffffULL, 0xf.fffffcp+22L }, + { 0x1ffffffULL, 0xf.fffff8p+21L }, + { 0xffffffULL, 0xf.fffffp+20L }, + { 0x7fffffULL, 0xf.ffffep+19L }, + { 0x3fffffULL, 0xf.ffffcp+18L }, + { 0x1fffffULL, 0xf.ffff8p+17L }, + { 0xfffffULL, 0xf.ffffp+16L }, + { 0x7ffffULL, 0xf.fffep+15L }, + { 0x3ffffULL, 0xf.fffcp+14L }, + { 0x1ffffULL, 0xf.fff8p+13L }, + { 0xffffULL, 0xf.fffp+12L }, + { 0x7fffULL, 0xf.ffep+11L }, + { 0x3fffULL, 0xf.ffcp+10L }, + { 0x1fffULL, 0xf.ff8p+9L }, + { 0xfffULL, 0xf.ffp+8L }, + { 0x7ffULL, 0xf.fep+7L }, + { 0x3ffULL, 0xf.fcp+6L }, + { 0x1ffULL, 0xf.f8p+5L }, + { 0xffULL, 0xf.fp+4L }, + { 0x7fULL, 0xf.ep+3L }, + { 0x3fULL, 0xf.cp+2L }, + { 0x1fULL, 0xf.8p+1L }, + { 0xfULL, 0xfp+0L }, + { 0x7ULL, 0xep-1L }, + { 0x3ULL, 0xcp-2L }, + { 0x1ULL, 0x8p-3L }, +}; +#endif + +ATF_TC(floatunditf); +ATF_TC_HEAD(floatunditf, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that uint64 -> long double conversion works"); +} + +ATF_TC_BODY(floatunditf, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + size_t i; + + for (i = 0; i < __arraycount(testcases); ++i) + ATF_CHECK_MSG( + testcases[i].ld == (long double)testcases[i].u64, + "#%zu: expected %.20Lf, got %.20Lf\n", i, + testcases[i].ld, + (long double)testcases[i].u64); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, floatunditf); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c new file mode 100644 index 0000000..ab95400 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_fmtcheck.c,v 1.3 2014/06/14 08:19:02 apb Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Allen Briggs. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> + +const char *fmtcheck(const char *f1, const char *f2) + __attribute__((__format_arg__(2))); + +#include <err.h> + +struct test_fmt { + const char *fmt1; + const char *fmt2; + int correct; +} test_fmts[] = { + { "%d", "%d", 1 }, + { "%2d", "%2.2d", 1 }, + { "%x", "%d", 1 }, + { "%u", "%d", 1 }, + { "%03d", "%d", 1 }, + { "%-2d", "%d", 1 }, + { "%d", "%-12.1d", 1 }, + { "%d", "%-01.3d", 1 }, + { "%X", "%-01.3d", 1 }, + { "%D", "%ld", 1 }, + { "%s", "%s", 1 }, + { "%s", "This is a %s test", 1 }, + { "Hi, there. This is a %s test", "%s", 1 }, + { "%d", "%s", 2 }, + { "%e", "%s", 2 }, + { "%r", "%d", 2 }, + { "%*.2d", "%*d", 1 }, + { "%2.*d", "%*d", 2 }, + { "%*d", "%*d", 1 }, + { "%-3", "%d", 2 }, + { "%d %s", "%d", 2 }, + { "%*.*.*d", "%*.*.*d", 2 }, + { "%d", "%d %s", 1 }, + { "%40s", "%20s", 1 }, + { "%x %x %x", "%o %u %d", 1 }, + { "%o %u %d", "%x %x %X", 1 }, + { "%#o %u %#-d", "%x %#x %X", 1 }, + { "%qd", "%llx", 1 }, + { "%%", "%llx", 1 }, + { "%ld %30s %#llx %-10.*e", "This number %lu%% and string %s has %qd numbers and %.*g floats", 1 }, + { "%o", "%lx", 2 }, + { "%p", "%lu", 2 }, +}; + +ATF_TC(fmtcheck_basic); +ATF_TC_HEAD(fmtcheck_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test fmtcheck(3)"); +} + +ATF_TC_BODY(fmtcheck_basic, tc) +{ + unsigned int i, r; + const char *f, *cf, *f1, *f2; + + r = 0; + for (i = 0 ; i < __arraycount(test_fmts); i++) { + f1 = test_fmts[i].fmt1; + f2 = test_fmts[i].fmt2; + f = fmtcheck(f1, f2); + if (test_fmts[i].correct == 1) { + cf = f1; + } else { + cf = f2; + } + if (f != cf) { + r++; + atf_tc_fail_nonfatal("Test %d: (%s) vs. (%s) failed " + "(should have returned %s)", i, f1, f2, + (test_fmts[i].correct == 1) ? "1st" : "2nd"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fmtcheck_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c new file mode 100644 index 0000000..f90d8cf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c @@ -0,0 +1,167 @@ +/* $NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $"); + +#include <atf-c.h> +#include <fnmatch.h> +#include <stdio.h> + +ATF_TC(fnmatch_backslashes); +ATF_TC_HEAD(fnmatch_backslashes, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test translation of '\\' with fnmatch(3) (PR lib/41558)"); +} + +ATF_TC_BODY(fnmatch_backslashes, tc) +{ + const int rv = fnmatch(/* pattern */ "\\", "\\", 0); + + if (rv != FNM_NOMATCH) + atf_tc_fail("fnmatch(3) did not translate '\\'"); +} + +ATF_TC(fnmatch_casefold); +ATF_TC_HEAD(fnmatch_casefold, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_CASEFOLD"); +} + +ATF_TC_BODY(fnmatch_casefold, tc) +{ + ATF_CHECK(fnmatch("xxx", "XXX", 0) != 0); + ATF_CHECK(fnmatch("XXX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("xxx", "XxX", 0) != 0); + ATF_CHECK(fnmatch("XxX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("x*x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("**x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("*?x", "XXX", 0) != 0); + + ATF_CHECK(fnmatch("xxx", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XXX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("xxx", "XxX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XxX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("x*x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("**x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("*?x", "XXX", FNM_CASEFOLD) == 0); +} + +ATF_TC(fnmatch_leadingdir); +ATF_TC_HEAD(fnmatch_leadingdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_LEADING_DIR"); +} + +ATF_TC_BODY(fnmatch_leadingdir, tc) +{ + ATF_CHECK(fnmatch("", "/*", 0) != 0); + ATF_CHECK(fnmatch(" ", " /*", 0) != 0); + ATF_CHECK(fnmatch("x", "x/*", 0) != 0); + ATF_CHECK(fnmatch("///", "////*", 0) != 0); + + ATF_CHECK(fnmatch("", "/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch(" ", " /*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("x", "x/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("///", "////*", FNM_LEADING_DIR) == 0); +} + +ATF_TC(fnmatch_noescape); +ATF_TC_HEAD(fnmatch_noescape, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_NOESCAPE"); +} + +ATF_TC_BODY(fnmatch_noescape, tc) +{ + ATF_CHECK(fnmatch(" \\x", " \\x", 0) != 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", 0) != 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", 0) != 0); + + ATF_CHECK(fnmatch(" \\x", " \\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", FNM_NOESCAPE) == 0); +} + +ATF_TC(fnmatch_pathname); +ATF_TC_HEAD(fnmatch_pathname, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PATHNAME"); +} + +ATF_TC_BODY(fnmatch_pathname, tc) +{ + ATF_CHECK(fnmatch("???x", "xxx/x", FNM_PATHNAME) != 0); + ATF_CHECK(fnmatch("***x", "xxx/x", FNM_PATHNAME) != 0); + + ATF_CHECK(fnmatch("???x", "xxxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("*/xxx", "/xxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("x/*.y", "x/z.y", FNM_PATHNAME) == 0); +} + +ATF_TC(fnmatch_period); +ATF_TC_HEAD(fnmatch_period, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PERIOD"); +} + +ATF_TC_BODY(fnmatch_period, tc) +{ + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD | FNM_CASEFOLD) == 0); + + ATF_CHECK(fnmatch("x?y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x*y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*.c", "x.c", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/?", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/*", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch(".*/?", ".x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/.?", "x/.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x[.]y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + + ATF_CHECK(fnmatch("?x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/?y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/*y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fnmatch_backslashes); + ATF_TP_ADD_TC(tp, fnmatch_casefold); + ATF_TP_ADD_TC(tp, fnmatch_leadingdir); + ATF_TP_ADD_TC(tp, fnmatch_noescape); + ATF_TP_ADD_TC(tp, fnmatch_pathname); + ATF_TP_ADD_TC(tp, fnmatch_period); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c new file mode 100644 index 0000000..21dea9e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c @@ -0,0 +1,206 @@ +/* $NetBSD: t_fpclassify.c,v 1.3 2011/10/01 21:47:08 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <float.h> +#include <math.h> +#include <stdio.h> +#include <string.h> + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + atf_tc_set_md_var(tc, "descr", "Dummy test"); +} + +ATF_TC_BODY(no_test,tc) +{ + atf_tc_skip("Test not available on this architecture"); +} + +#else /* defined(_FLOAT_IEEE754) */ + +ATF_TC(fpclassify_float); +ATF_TC_HEAD(fpclassify_float, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test float operations"); +} + +ATF_TC_BODY(fpclassify_float, tc) +{ + float d0, d1, d2, f, ip; + int e, i; + + d0 = FLT_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpf(d0, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < FLT_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpf(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modff(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +ATF_TC(fpclassify_double); +ATF_TC_HEAD(fpclassify_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test double operations"); +} + +ATF_TC_BODY(fpclassify_double, tc) +{ + double d0, d1, d2, f, ip; + int e, i; + + d0 = DBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexp(d0, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < DBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexp(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modf(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +/* + * XXX NetBSD doesn't have long-double flavors of frexp, ldexp, and modf, + * XXX so this test is disabled. + */ + +#ifdef TEST_LONG_DOUBLE + +ATF_TC(fpclassify_long_double); +ATF_TC_HEAD(fpclassify_long_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test long double operations"); +} + +ATF_TC_BODY(fpclassify_long_double, tc) +{ + long double d0, d1, d2, f, ip; + int e, i; + + d0 = LDBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpl(d0, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < LDBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpl(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modfl(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpclassify_float); + ATF_TP_ADD_TC(tp, fpclassify_double); +#ifdef TEST_LONG_DOUBLE + ATF_TP_ADD_TC(tp, fpclassify_long_double); +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c new file mode 100644 index 0000000..998eb85 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c @@ -0,0 +1,355 @@ +/* $NetBSD: t_fpsetmask.c,v 1.13 2014/02/09 21:26:07 jmmv Exp $ */ + +/*- + * Copyright (c) 1995 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <stdio.h> +#include <signal.h> +#include <float.h> +#include <setjmp.h> +#include <stdlib.h> +#include <string.h> + +#include "isqemu.h" + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Dummy test case"); +} + +ATF_TC_BODY(no_test, tc) +{ + + atf_tc_skip("Test not available on this architecture."); +} + +#else /* defined(_FLOAT_IEEE754) */ + +#include <ieeefp.h> + +const char *skip_mesg; +const char *skip_arch; + +void sigfpe(int, siginfo_t *, void *); + +volatile sig_atomic_t signal_caught; +volatile int sicode; + +static volatile const float f_one = 1.0; +static volatile const float f_zero = 0.0; +static volatile const double d_one = 1.0; +static volatile const double d_zero = 0.0; +static volatile const long double ld_one = 1.0; +static volatile const long double ld_zero = 0.0; + +static volatile const float f_huge = FLT_MAX; +static volatile const float f_tiny = FLT_MIN; +static volatile const double d_huge = DBL_MAX; +static volatile const double d_tiny = DBL_MIN; +static volatile const long double ld_huge = LDBL_MAX; +static volatile const long double ld_tiny = LDBL_MIN; + +static volatile float f_x; +static volatile double d_x; +static volatile long double ld_x; + +/* trip divide by zero */ +static void +f_dz(void) +{ + + f_x = f_one / f_zero; +} + +static void +d_dz(void) +{ + + d_x = d_one / d_zero; +} + +static void +ld_dz(void) +{ + + ld_x = ld_one / ld_zero; +} + +/* trip invalid operation */ +static void +d_inv(void) +{ + + d_x = d_zero / d_zero; +} + +static void +ld_inv(void) +{ + + ld_x = ld_zero / ld_zero; +} + +static void +f_inv(void) +{ + + f_x = f_zero / f_zero; +} + +/* trip overflow */ +static void +f_ofl(void) +{ + + f_x = f_huge * f_huge; +} + +static void +d_ofl(void) +{ + + d_x = d_huge * d_huge; +} + +static void +ld_ofl(void) +{ + + ld_x = ld_huge * ld_huge; +} + +/* trip underflow */ +static void +f_ufl(void) +{ + + f_x = f_tiny * f_tiny; +} + +static void +d_ufl(void) +{ + + d_x = d_tiny * d_tiny; +} + +static void +ld_ufl(void) +{ + + ld_x = ld_tiny * ld_tiny; +} + +struct ops { + void (*op)(void); + fp_except mask; + int sicode; +}; + +static const struct ops float_ops[] = { + { f_dz, FP_X_DZ, FPE_FLTDIV }, + { f_inv, FP_X_INV, FPE_FLTINV }, + { f_ofl, FP_X_OFL, FPE_FLTOVF }, + { f_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops double_ops[] = { + { d_dz, FP_X_DZ, FPE_FLTDIV }, + { d_inv, FP_X_INV, FPE_FLTINV }, + { d_ofl, FP_X_OFL, FPE_FLTOVF }, + { d_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops long_double_ops[] = { + { ld_dz, FP_X_DZ, FPE_FLTDIV }, + { ld_inv, FP_X_INV, FPE_FLTINV }, + { ld_ofl, FP_X_OFL, FPE_FLTOVF }, + { ld_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static sigjmp_buf b; + +static void +fpsetmask_masked(const struct ops *test_ops) +{ + struct sigaction sa; + fp_except ex1, ex2; + const struct ops *t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exceptions masked, check whether "sticky" bits are set correctly + */ + for (t = test_ops; t->op != NULL; t++) { + (*t->op)(); + ex1 = fpgetsticky(); + ATF_CHECK_EQ(ex1 & t->mask, t->mask); + ATF_CHECK_EQ(signal_caught, 0); + + /* check correct fpsetsticky() behaviour */ + ex2 = fpsetsticky(0); + ATF_CHECK_EQ(fpgetsticky(), 0); + ATF_CHECK_EQ(ex1, ex2); + } +} + +/* force delayed exceptions to be delivered */ +#define BARRIER() fpsetmask(0); f_x = f_one * f_one + +static void +fpsetmask_unmasked(const struct ops *test_ops) +{ + struct sigaction sa; + int r; + const struct ops *volatile t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exception unmasked, check SIGFPE delivery and correct siginfo + */ + for (t = test_ops; t->op != NULL; t++) { + fpsetmask(t->mask); + r = sigsetjmp(b, 1); + if (!r) { + (*t->op)(); + BARRIER(); + } + ATF_CHECK_EQ(signal_caught, 1); + ATF_CHECK_EQ(sicode, t->sicode); + signal_caught = 0; + } +} + +void +sigfpe(int s, siginfo_t *si, void *c) +{ + signal_caught = 1; + sicode = si->si_code; + siglongjmp(b, 1); +} + +#define TEST(m, t) \ + ATF_TC(m##_##t); \ + \ + ATF_TC_HEAD(m##_##t, tc) \ + { \ + \ + atf_tc_set_md_var(tc, "descr", \ + "Test " ___STRING(m) " exceptions for " \ + ___STRING(t) "values"); \ + } \ + \ + ATF_TC_BODY(m##_##t, tc) \ + { \ + if (strcmp(MACHINE, "macppc") == 0) \ + atf_tc_expect_fail("PR port-macppc/46319"); \ + \ + if (isQEMU()) \ + atf_tc_expect_fail("PR misc/44767"); \ + \ + m(t##_ops); \ + } + +TEST(fpsetmask_masked, float) +TEST(fpsetmask_masked, double) +TEST(fpsetmask_masked, long_double) +TEST(fpsetmask_unmasked, float) +TEST(fpsetmask_unmasked, double) +TEST(fpsetmask_unmasked, long_double) + +ATF_TC(fpsetmask_basic); +ATF_TC_HEAD(fpsetmask_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fpsetmask(3)"); +} + +ATF_TC_BODY(fpsetmask_basic, tc) +{ + size_t i; + fp_except_t msk, lst[] = { FP_X_INV, FP_X_DZ, FP_X_OFL, FP_X_UFL }; + + msk = fpgetmask(); + for (i = 0; i < __arraycount(lst); i++) { + fpsetmask(msk | lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) != 0); + fpsetmask(msk & lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) == 0); + } + +} + +#endif /* defined(_FLOAT_IEEE754) */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpsetmask_basic); + ATF_TP_ADD_TC(tp, fpsetmask_masked_float); + ATF_TP_ADD_TC(tp, fpsetmask_masked_double); + ATF_TP_ADD_TC(tp, fpsetmask_masked_long_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_float); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_long_double); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c new file mode 100644 index 0000000..0f23e74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $"); + +#include <float.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <atf-c.h> + +ATF_TC(fpsetround_basic); +ATF_TC_HEAD(fpsetround_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Minimal testing of fpgetround(3) and fpsetround(3)"); +} + +#ifdef _FLOAT_IEEE754 +#include <ieeefp.h> + +static const struct { + const char *n; + int rm; + int rf; +} rnd[] = { + { "RN", FP_RN, 1 }, + { "RP", FP_RP, 2 }, + { "RM", FP_RM, 3 }, + { "RZ", FP_RZ, 0 }, + +}; + +static const struct { + const char *n; + int v[4]; +} tst[] = { /* RN RP RM RZ */ + { "1.1", { 1, 1, 2, 1 } }, + { "1.5", { 1, 2, 2, 1 } }, + { "1.9", { 1, 2, 2, 1 } }, + { "2.1", { 2, 2, 3, 2 } }, + { "2.5", { 2, 2, 3, 2 } }, + { "2.9", { 2, 3, 3, 2 } }, + { "-1.1", { -1, -1, -1, -2 } }, + { "-1.5", { -1, -2, -1, -2 } }, + { "-1.9", { -1, -2, -1, -2 } }, + { "-2.1", { -2, -2, -2, -3 } }, + { "-2.5", { -2, -2, -2, -3 } }, + { "-2.9", { -2, -3, -2, -3 } }, +}; + +static const char * +getname(int r) +{ + for (size_t i = 0; i < __arraycount(rnd); i++) + if (rnd[i].rm == r) + return rnd[i].n; + return "*unknown*"; +} + +static void +test(int r) +{ + int did = 0; + for (size_t i = 0; i < __arraycount(tst); i++) { + double d = strtod(tst[i].n, NULL); + int g = (int)rint(d); + int e = tst[i].v[r]; + ATF_CHECK_EQ(g, e); + if (g != e) { + if (!did) { + fprintf(stderr, "Mode Value Result Expected\n"); + did = 1; + } + fprintf(stderr, "%4.4s %-5.5s %6d %8d\n", rnd[r].n, + tst[i].n, (int)rint(d), tst[i].v[r]); + } + } +} +#endif + + +ATF_TC_BODY(fpsetround_basic, tc) +{ + +#ifndef _FLOAT_IEEE754 + atf_tc_skip("Test not applicable on this architecture."); +#else + int r; + + ATF_CHECK_EQ(r = fpgetround(), FP_RN); + if (FP_RN != r) + fprintf(stderr, "default expected=%s got=%s\n", getname(FP_RN), + getname(r)); + ATF_CHECK_EQ(FLT_ROUNDS, 1); + + for (size_t i = 0; i < __arraycount(rnd); i++) { + const size_t j = (i + 1) & 3; + const int o = rnd[i].rm; + const int n = rnd[j].rm; + + ATF_CHECK_EQ(r = fpsetround(n), o); + if (o != r) + fprintf(stderr, "set %s expected=%s got=%s\n", + getname(n), getname(o), getname(r)); + ATF_CHECK_EQ(r = fpgetround(), n); + if (n != r) + fprintf(stderr, "get expected=%s got=%s\n", getname(n), + getname(r)); + ATF_CHECK_EQ(r = FLT_ROUNDS, rnd[j].rf); + if (r != rnd[j].rf) + fprintf(stderr, "rounds expected=%x got=%x\n", + rnd[j].rf, r); + test(r); + } +#endif /* _FLOAT_IEEE754 */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fpsetround_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ftok.c b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c new file mode 100644 index 0000000..100bd1b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $"); + +#include <sys/types.h> +#include <sys/ipc.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <unistd.h> + +static const char *path = "ftok"; +static const char *hlnk = "hlnk"; +static const char *slnk = "slnk"; +static const int key = 123456789; + +ATF_TC(ftok_err); +ATF_TC_HEAD(ftok_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from ftok(3)"); +} + +ATF_TC_BODY(ftok_err, tc) +{ + ATF_REQUIRE(ftok("/a/b/c/d/e/f/g/h/i", key) == -1); +} + +ATF_TC_WITH_CLEANUP(ftok_link); +ATF_TC_HEAD(ftok_link, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that links return the same key"); +} + +ATF_TC_BODY(ftok_link, tc) +{ + key_t k1, k2, k3; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(link(path, hlnk) == 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + + k1 = ftok(path, key); + k2 = ftok(hlnk, key); + k3 = ftok(slnk, key); + + ATF_REQUIRE(k1 != -1); + ATF_REQUIRE(k2 != -1); + ATF_REQUIRE(k3 != -1); + + if (k1 != k2) + atf_tc_fail("ftok(3) gave different key for a hard link"); + + if (k1 != k3) + atf_tc_fail("ftok(3) gave different key for a symbolic link"); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(hlnk) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TC_CLEANUP(ftok_link, tc) +{ + (void)unlink(path); + (void)unlink(hlnk); + (void)unlink(slnk); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ftok_err); + ATF_TP_ADD_TC(tp, ftok_link); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c new file mode 100644 index 0000000..76c287a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c @@ -0,0 +1,151 @@ +/* $NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $"); + +#include <sys/param.h> +#include <sys/stat.h> + +#include <atf-c.h> +#include <errno.h> +#include <fts.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +ATF_TC(getcwd_err); +ATF_TC_HEAD(getcwd_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in getcwd(3)"); +} + +ATF_TC_BODY(getcwd_err, tc) +{ + char buf[MAXPATHLEN]; + + errno = 0; + + ATF_REQUIRE(getcwd(buf, 0) == NULL); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TC(getcwd_fts); +ATF_TC_HEAD(getcwd_fts, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of getcwd(3)"); +} + +ATF_TC_BODY(getcwd_fts, tc) +{ + const char *str = NULL; + char buf[MAXPATHLEN]; + char *argv[2]; + FTSENT *ftse; + FTS *fts; + int ops; + short depth; + + /* + * Do not traverse too deep; cf. PR bin/45180. + */ + depth = 2; + + argv[1] = NULL; + argv[0] = __UNCONST("/"); + + /* + * Test that getcwd(3) works with basic + * system directories. Note that having + * no FTS_NOCHDIR specified should ensure + * that the current directory is visited. + */ + ops = FTS_PHYSICAL | FTS_NOSTAT; + fts = fts_open(argv, ops, NULL); + + if (fts == NULL) { + str = "failed to initialize fts(3)"; + goto out; + } + + while ((ftse = fts_read(fts)) != NULL) { + + if (ftse->fts_level < 1) + continue; + + if (ftse->fts_level > depth) { + (void)fts_set(fts, ftse, FTS_SKIP); + continue; + } + + switch(ftse->fts_info) { + + case FTS_DP: + + (void)memset(buf, 0, sizeof(buf)); + + if (getcwd(buf, sizeof(buf)) == NULL) { + str = "getcwd(3) failed"; + goto out; + } + + if (strstr(ftse->fts_path, buf) == NULL) { + str = "getcwd(3) returned incorrect path"; + goto out; + } + + break; + + default: + break; + } + } + +out: + if (fts != NULL) + (void)fts_close(fts); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getcwd_err); + ATF_TP_ADD_TC(tp, getcwd_fts); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c new file mode 100644 index 0000000..df9cdd1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c @@ -0,0 +1,181 @@ +/* $NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <grp.h> +#include <stdlib.h> +#include <unistd.h> + +ATF_TC(getgrent_loop); +ATF_TC_HEAD(getgrent_loop, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sequential getgrent(2)"); +} + +ATF_TC_BODY(getgrent_loop, tc) +{ + struct group *gr; + size_t i, j; + + /* + * Loop over the group database. The first + * call returns the first entry and subsequent + * calls return the rest of the entries. + */ + i = j = 0; + + while((gr = getgrent()) != NULL) + i++; + + /* + * Rewind the database to the beginning + * and loop over again until the end. + */ + setgrent(); + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("sequential getgrent(3) failed"); + + /* + * Close the database and reopen it. + * The getgrent(3) call should always + * automatically rewind the database. + */ + endgrent(); + + j = 0; + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("getgrent(3) did not rewind"); +} + +ATF_TC(getgrent_setgid); +ATF_TC_HEAD(getgrent_setgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test consistency of the group db"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(getgrent_setgid, tc) +{ + struct group *gr, *gr1, *gr2; + int rv, sta; + pid_t pid; + + /* + * Verify that the database is consistent. + * + * Note that because of the static buffers + * used by getgrent(3), fork(2) is required, + * even without the setgid(2) check. + */ + while((gr = getgrent()) != NULL) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + gr1 = getgrgid(gr->gr_gid); + + if (gr1 == NULL) + _exit(EXIT_FAILURE); + + gr2 = getgrnam(gr->gr_name); + + if (gr2 == NULL) + _exit(EXIT_FAILURE); + + rv = setgid(gr->gr_gid); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + goto fail; + } + + return; + +fail: + atf_tc_fail("group database is inconsistent"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgrent_loop); + ATF_TP_ADD_TC(tp, getgrent_setgid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_glob.c b/contrib/netbsd-tests/lib/libc/gen/t_glob.c new file mode 100644 index 0000000..ff62b63 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c @@ -0,0 +1,273 @@ +/* $NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $"); + +#include <atf-c.h> + +#include <sys/param.h> +#include <sys/stat.h> + +#include <dirent.h> +#include <glob.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "../../../h_macros.h" + + +#ifdef DEBUG +#define DPRINTF(a) printf a +#else +#define DPRINTF(a) +#endif + +struct gl_file { + const char *name; + int dir; +}; + +static struct gl_file a[] = { + { "1", 0 }, + { "b", 1 }, + { "3", 0 }, + { "4", 0 }, +}; + +static struct gl_file b[] = { + { "x", 0 }, + { "y", 0 }, + { "z", 0 }, + { "w", 0 }, +}; + +struct gl_dir { + const char *name; /* directory name */ + const struct gl_file *dir; + size_t len, pos; +}; + +static struct gl_dir d[] = { + { "a", a, __arraycount(a), 0 }, + { "a/b", b, __arraycount(b), 0 }, +}; + +static const char *glob_star[] = { + "a/1", "a/3", "a/4", "a/b", "a/b/w", "a/b/x", "a/b/y", "a/b/z", +}; + +static const char *glob_star_not[] = { + "a/1", "a/3", "a/4", "a/b", +}; + +static void +trim(char *buf, size_t len, const char *name) +{ + char *path = buf, *epath = buf + len; + while (path < epath && (*path++ = *name++) != '\0') + continue; + path--; + while (path > buf && *--path == '/') + *path = '\0'; +} + +static void * +gl_opendir(const char *dir) +{ + size_t i; + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), dir); + + for (i = 0; i < __arraycount(d); i++) + if (strcmp(buf, d[i].name) == 0) { + DPRINTF(("opendir %s %zu\n", buf, i)); + return &d[i]; + } + errno = ENOENT; + return NULL; +} + +static struct dirent * +gl_readdir(void *v) +{ + static struct dirent dir; + struct gl_dir *dd = v; + if (dd->pos < dd->len) { + const struct gl_file *f = &dd->dir[dd->pos++]; + strcpy(dir.d_name, f->name); + dir.d_namlen = strlen(f->name); + dir.d_ino = dd->pos; + dir.d_type = f->dir ? DT_DIR : DT_REG; + DPRINTF(("readdir %s %d\n", dir.d_name, dir.d_type)); + dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen); + return &dir; + } + return NULL; +} + +static int +gl_stat(const char *name , __gl_stat_t *st) +{ + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), name); + memset(st, 0, sizeof(*st)); + + if (strcmp(buf, "a") == 0 || strcmp(buf, "a/b") == 0) { + st->st_mode |= _S_IFDIR; + return 0; + } + + if (buf[0] == 'a' && buf[1] == '/') { + struct gl_file *f; + size_t offs, count; + + if (buf[2] == 'b' && buf[3] == '/') { + offs = 4; + count = __arraycount(b); + f = b; + } else { + offs = 2; + count = __arraycount(a); + f = a; + } + + for (size_t i = 0; i < count; i++) + if (strcmp(f[i].name, buf + offs) == 0) + return 0; + } + DPRINTF(("stat %s %d\n", buf, st->st_mode)); + errno = ENOENT; + return -1; +} + +static int +gl_lstat(const char *name , __gl_stat_t *st) +{ + return gl_stat(name, st); +} + +static void +gl_closedir(void *v) +{ + struct gl_dir *dd = v; + dd->pos = 0; + DPRINTF(("closedir %p\n", dd)); +} + +static void +run(const char *p, int flags, const char **res, size_t len) +{ + glob_t gl; + size_t i; + + memset(&gl, 0, sizeof(gl)); + gl.gl_opendir = gl_opendir; + gl.gl_readdir = gl_readdir; + gl.gl_closedir = gl_closedir; + gl.gl_stat = gl_stat; + gl.gl_lstat = gl_lstat; + + RZ(glob(p, GLOB_ALTDIRFUNC | flags, NULL, &gl)); + + for (i = 0; i < gl.gl_pathc; i++) + DPRINTF(("%s\n", gl.gl_pathv[i])); + + ATF_CHECK(len == gl.gl_pathc); + for (i = 0; i < gl.gl_pathc; i++) + ATF_CHECK_STREQ(gl.gl_pathv[i], res[i]); + + globfree(&gl); +} + + +ATF_TC(glob_star); +ATF_TC_HEAD(glob_star, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** with GLOB_STAR"); +} + +ATF_TC_BODY(glob_star, tc) +{ + run("a/**", GLOB_STAR, glob_star, __arraycount(glob_star)); +} + +ATF_TC(glob_star_not); +ATF_TC_HEAD(glob_star_not, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** without GLOB_STAR"); +} + + +ATF_TC_BODY(glob_star_not, tc) +{ + run("a/**", 0, glob_star_not, __arraycount(glob_star_not)); +} + +#if 0 +ATF_TC(glob_nocheck); +ATF_TC_HEAD(glob_nocheck, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) pattern with backslash and GLOB_NOCHECK"); +} + + +ATF_TC_BODY(glob_nocheck, tc) +{ + static const char pattern[] = { 'f', 'o', 'o', '\\', ';', 'b', 'a', + 'r', '\0' }; + static const char *glob_nocheck[] = { + pattern + }; + run(pattern, GLOB_NOCHECK, glob_nocheck, __arraycount(glob_nocheck)); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, glob_star); + ATF_TP_ADD_TC(tp, glob_star_not); +/* + * Remove this test for now - the GLOB_NOCHECK return value has been + * re-defined to return a modified pattern in revision 1.33 of glob.c + * + * ATF_TP_ADD_TC(tp, glob_nocheck); + */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c new file mode 100644 index 0000000..1af579e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c @@ -0,0 +1,312 @@ +/* $NetBSD: t_humanize_number.c,v 1.8 2012/03/18 07:14:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <err.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <util.h> + +const struct hnopts { + size_t ho_len; + int64_t ho_num; + const char *ho_suffix; + int ho_scale; + int ho_flags; + int ho_retval; /* expected return value */ + const char *ho_retstr; /* expected string in buffer */ +} hnopts[] = { + /* + * Rev. 1.6 produces "10.0". + */ + { 5, 10737418236ULL * 1024, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10T" }, + + { 5, 10450000, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + { 5, 10500000, "", /* just for reference */ + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + + /* + * Trailing space. Rev. 1.7 produces "1 ". + */ + { 5, 1, "", 0, HN_NOSPACE, 1, "1" }, + + { 5, 1, "", 0, 0, 2, "1 " }, /* just for reference */ + { 5, 1, "", 0, HN_B, 3, "1 B" }, /* and more ... */ + { 5, 1, "", 0, HN_DECIMAL, 2, "1 " }, + { 5, 1, "", 0, HN_NOSPACE | HN_B, 2, "1B" }, + { 5, 1, "", 0, HN_B | HN_DECIMAL, 3, "1 B" }, + { 5, 1, "", 0, HN_NOSPACE | HN_B | HN_DECIMAL, 2, "1B" }, + + /* + * Space and HN_B. Rev. 1.7 produces "1B". + */ + { 5, 1, "", HN_AUTOSCALE, HN_B, 3, "1 B" }, + { 5, 1000, "", /* just for reference */ + HN_AUTOSCALE, HN_B, 3, "1 K" }, + + /* + * Truncated output. Rev. 1.7 produces "1.0 K". + */ + { 6, 1000, "A", HN_AUTOSCALE, HN_DECIMAL, -1, "" }, + + /* + * Failure case reported by Greg Troxel <gdt@NetBSD.org>. + * Rev. 1.11 incorrectly returns 5 with filling the buffer + * with "1000". + */ + { 5, 1048258238, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0G" }, + /* Similar case it prints 1000 where it shouldn't */ + { 5, 1023488, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, + { 5, 1023999, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, +}; + +struct hnflags { + int hf_flags; + const char *hf_name; +}; + +const struct hnflags scale_flags[] = { + { HN_GETSCALE, "HN_GETSCALE" }, + { HN_AUTOSCALE, "HN_AUTOSCALE" }, +}; +const struct hnflags normal_flags[] = { + { HN_DECIMAL, "HN_DECIMAL" }, + { HN_NOSPACE, "HN_NOSPACE" }, + { HN_B, "HN_B" }, + { HN_DIVISOR_1000, "HN_DIVISOR_1000" }, +}; + +const char *formatflags(char *, size_t, const struct hnflags *, size_t, int); +void newline(void); +void w_printf(const char *, ...) __printflike(1, 2); +int main(int, char *[]); + +const char * +formatflags(char *buf, size_t buflen, const struct hnflags *hfs, + size_t hfslen, int flags) +{ + const struct hnflags *hf; + char *p = buf; + ssize_t len = buflen; + unsigned int i, found; + int n; + + if (flags == 0) { + snprintf(buf, buflen, "0"); + return (buf); + } + for (i = found = 0; i < hfslen && flags & ~found; i++) { + hf = &hfs[i]; + if (flags & hf->hf_flags) { + found |= hf->hf_flags; + n = snprintf(p, len, "|%s", hf->hf_name); + if (n >= len) { + p = buf; + len = buflen; + /* Print `flags' as number */ + goto bad; + } + p += n; + len -= n; + } + } + flags &= ~found; + if (flags) +bad: + snprintf(p, len, "|0x%x", flags); + return (*buf == '|' ? buf + 1 : buf); +} + +static int col, bol = 1; +void +newline(void) +{ + + fprintf(stderr, "\n"); + col = 0; + bol = 1; +} + +void +w_printf(const char *fmt, ...) +{ + char buf[80]; + va_list ap; + int n; + + va_start(ap, fmt); + if (col >= 0) { + n = vsnprintf(buf, sizeof(buf), fmt, ap); + if (n >= (int)sizeof(buf)) { + col = -1; + goto overflow; + } else if (n == 0) + goto out; + + if (!bol) { + if (col + n > 75) + fprintf(stderr, "\n "), col = 4; + else + fprintf(stderr, " "), col++; + } + fprintf(stderr, "%s", buf); + col += n; + bol = 0; + } else { +overflow: + vfprintf(stderr, fmt, ap); + } +out: + va_end(ap); +} + +ATF_TC(humanize_number_basic); +ATF_TC_HEAD(humanize_number_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize_number(3)"); +} + +ATF_TC_BODY(humanize_number_basic, tc) +{ + char fbuf[128]; + const struct hnopts *ho; + char *buf = NULL; + size_t buflen = 0; + unsigned int i; + int rv = 0; + + for (i = 0; i < __arraycount(hnopts); i++) { + ho = &hnopts[i]; + if (buflen < ho->ho_len) { + buflen = ho->ho_len; + buf = realloc(buf, buflen); + if (buf == NULL) + atf_tc_fail("realloc(..., %zu) failed", buflen); + } + + rv = humanize_number(buf, ho->ho_len, ho->ho_num, + ho->ho_suffix, ho->ho_scale, ho->ho_flags); + + if (rv == ho->ho_retval && + (rv == -1 || strcmp(buf, ho->ho_retstr) == 0)) + continue; + + w_printf("humanize_number(\"%s\", %zu, %" PRId64 ",", + ho->ho_retstr, ho->ho_len, ho->ho_num); + w_printf("\"%s\",", ho->ho_suffix); + w_printf("%s,", formatflags(fbuf, sizeof(fbuf), scale_flags, + sizeof(scale_flags) / sizeof(scale_flags[0]), + ho->ho_scale)); + w_printf("%s)", formatflags(fbuf, sizeof(fbuf), normal_flags, + sizeof(normal_flags) / sizeof(normal_flags[0]), + ho->ho_flags)); + w_printf("= %d,", ho->ho_retval); + w_printf("but got"); + w_printf("%d/[%s]", rv, rv == -1 ? "" : buf); + newline(); + atf_tc_fail_nonfatal("Failed for table entry %d", i); + } +} + +ATF_TC(humanize_number_big); +ATF_TC_HEAD(humanize_number_big, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize " + "big numbers (PR lib/44097)"); +} + +ATF_TC_BODY(humanize_number_big, tc) +{ + char buf[1024]; + int rv; + + /* + * Seems to work. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, 10000, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_CHECK_STREQ(buf, "10000"); + + /* + * A bogus value with large number. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, INT64_MAX, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0") != 0); + + /* + * Large buffer with HN_AUTOSCALE. Entirely bogus. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, sizeof(buf), 10000, "", + HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0%d%s%d%s%s%s") != 0); + + /* + * Tight buffer. + * + * The man page says that len must be at least 4. + * 3 works, but anything less that will not. This + * is because baselen starts with 2 for positive + * numbers. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 3, 1, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, humanize_number_basic); + ATF_TP_ADD_TC(tp, humanize_number_big); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_isnan.c b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c new file mode 100644 index 0000000..2a97b9a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c @@ -0,0 +1,67 @@ +/* $NetBSD: t_isnan.c,v 1.4 2014/02/09 21:26:07 jmmv Exp $ */ + +/* + * This file is in the Public Domain. + * + * The nan test is blatently copied by Simon Burge from the infinity + * test by Ben Harris. + */ + +#include <sys/param.h> + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <math.h> +#include <string.h> + +ATF_TC(isnan_basic); +ATF_TC_HEAD(isnan_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isnan(3) works"); +} + +ATF_TC_BODY(isnan_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + +#ifdef NAN + /* NAN is meant to be a (float)NaN. */ + ATF_CHECK(isnan(NAN) != 0); + ATF_CHECK(isnan((double)NAN) != 0); +#else + atf_tc_skip("Test not applicable"); +#endif +} + +ATF_TC(isinf_basic); +ATF_TC_HEAD(isinf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isinf(3) works"); +} + +ATF_TC_BODY(isinf_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + + /* HUGE_VAL is meant to be an infinity. */ + ATF_CHECK(isinf(HUGE_VAL) != 0); + + /* HUGE_VALF is the float analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALF) != 0); + + /* HUGE_VALL is the long double analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALL) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, isnan_basic); + ATF_TP_ADD_TC(tp, isinf_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_nice.c b/contrib/netbsd-tests/lib/libc/gen/t_nice.c new file mode 100644 index 0000000..f4a62e9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c @@ -0,0 +1,193 @@ +/* $NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); + +#include <sys/resource.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <stdlib.h> +#include <unistd.h> + +static void *threadfunc(void *); + +static void * +threadfunc(void *arg) +{ + int pri, val; + + val = *(int *)arg; + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (pri != val) + atf_tc_fail("nice(3) value was not propagated to threads"); + + return NULL; +} + +ATF_TC(nice_err); +ATF_TC_HEAD(nice_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test nice(3) for invalid parameters (PR lib/42587)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(nice_err, tc) +{ + int i; + + /* + * The call should fail with EPERM if the + * supplied parameter is negative and the + * caller does not have privileges. + */ + for (i = -20; i < 0; i++) { + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1); + } +} + +ATF_TC(nice_priority); +ATF_TC_HEAD(nice_priority, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)"); +} + +ATF_TC_BODY(nice_priority, tc) +{ + int i, pri, nic; + pid_t pid; + int sta; + + for (i = 0; i <= 20; i++) { + + nic = nice(i); + ATF_REQUIRE(nic != -1); + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (nic != pri) + atf_tc_fail("nice(3) and getpriority(2) conflict"); + + /* + * Also verify that the nice(3) values + * are inherited by child processes. + */ + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (nic != pri) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("nice(3) value was not inherited"); + } +} + +ATF_TC(nice_root); +ATF_TC_HEAD(nice_root, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that nice(3) works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(nice_root, tc) +{ + int i; + + for (i = -20; i <= 20; i++) { + + ATF_REQUIRE(nice(i) != -1); + } +} + +ATF_TC(nice_thread); +ATF_TC_HEAD(nice_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads"); +} + +ATF_TC_BODY(nice_thread, tc) +{ + pthread_t tid[5]; + int rv, val; + size_t i; + + /* + * Test that the scheduling priority is + * propagated to all system scope threads. + */ + for (i = 0; i < __arraycount(tid); i++) { + + val = nice(i); + ATF_REQUIRE(val != -1); + + rv = pthread_create(&tid[i], NULL, threadfunc, &val); + ATF_REQUIRE(rv == 0); + + rv = pthread_join(tid[i], NULL); + ATF_REQUIRE(rv == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nice_err); + ATF_TP_ADD_TC(tp, nice_priority); + ATF_TP_ADD_TC(tp, nice_root); + ATF_TP_ADD_TC(tp, nice_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_pause.c b/contrib/netbsd-tests/lib/libc/gen/t_pause.c new file mode 100644 index 0000000..62a74c9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_pause.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $"); + +#include <sys/wait.h> + +#include <atf-c.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +static bool fail; +static void handler(int); + +static void +handler(int signo) +{ + + if (signo == SIGALRM) + fail = false; +} + +ATF_TC(pause_basic); +ATF_TC_HEAD(pause_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #1"); +} + +ATF_TC_BODY(pause_basic, tc) +{ + + fail = true; + + ATF_REQUIRE(signal(SIGALRM, handler) == 0); + + (void)alarm(1); + + if (pause() != -1 || fail != false) + atf_tc_fail("pause(3) did not cancel out from a signal"); +} + +ATF_TC(pause_kill); +ATF_TC_HEAD(pause_kill, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #2"); +} + +ATF_TC_BODY(pause_kill, tc) +{ + pid_t pid; + int sta; + + fail = true; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)pause(); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + + if (fail != true) + atf_tc_fail("child terminated before signal"); + + (void)kill(pid, SIGKILL); + (void)sleep(1); + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("pause(3) did not cancel from SIGKILL"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pause_basic); + ATF_TP_ADD_TC(tp, pause_kill); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_raise.c b/contrib/netbsd-tests/lib/libc/gen/t_raise.c new file mode 100644 index 0000000..adc032f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c @@ -0,0 +1,190 @@ +/* $NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $"); + +#include <atf-c.h> + +#include <signal.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +static bool fail; +static int count; +static void handler_err(int); +static void handler_ret(int); +static void handler_stress(int); +static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR }; + +static void +handler_stress(int signo) +{ + count++; +} + +static void +handler_err(int signo) +{ + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + if (sig[i] == signo) { + fail = false; + break; + } + } +} + +static void +handler_ret(int signo) +{ + + (void)sleep(1); + + fail = false; +} + +ATF_TC(raise_err); +ATF_TC_HEAD(raise_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test raise(3) for invalid parameters"); +} + +ATF_TC_BODY(raise_err, tc) +{ + int i = 0; + + while (i < 10) { + + ATF_REQUIRE(raise(10240 + i) == -1); + + i++; + } +} + +ATF_TC(raise_ret); +ATF_TC_HEAD(raise_ret, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test return order of raise(3)"); +} + +ATF_TC_BODY(raise_ret, tc) +{ + struct sigaction sa; + + fail = true; + + sa.sa_flags = 0; + sa.sa_handler = handler_ret; + + /* + * Verify that raise(3) does not return + * before the signal handler returns. + */ + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + ATF_REQUIRE(raise(SIGUSR1) == 0); + + if (fail != false) + atf_tc_fail("raise(3) returned before signal handler"); +} + +ATF_TC(raise_sig); +ATF_TC_HEAD(raise_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of raise(3)"); +} + +ATF_TC_BODY(raise_sig, tc) +{ + struct timespec tv, tr; + struct sigaction sa; + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + (void)memset(&sa, 0, sizeof(struct sigaction)); + + fail = true; + + tv.tv_sec = 0; + tv.tv_nsec = 2; + + sa.sa_flags = 0; + sa.sa_handler = handler_err; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(sig[i], &sa, 0) == 0); + + ATF_REQUIRE(raise(sig[i]) == 0); + ATF_REQUIRE(nanosleep(&tv, &tr) == 0); + + if (fail != false) + atf_tc_fail("raise(3) did not raise a signal"); + } +} + +ATF_TC(raise_stress); +ATF_TC_HEAD(raise_stress, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic stress test with raise(3)"); +} + +ATF_TC_BODY(raise_stress, tc) +{ + static const int maxiter = 1000 * 10; + struct sigaction sa; + int i; + + sa.sa_flags = 0; + sa.sa_handler = handler_stress; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + + for (count = i = 0; i < maxiter; i++) + (void)raise(SIGUSR1); + + if (count != maxiter) + atf_tc_fail("not all signals were catched"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, raise_err); + ATF_TP_ADD_TC(tp, raise_ret); + ATF_TP_ADD_TC(tp, raise_sig); + ATF_TP_ADD_TC(tp, raise_stress); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_randomid.c b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c new file mode 100644 index 0000000..8377806 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_randomid.c,v 1.3 2011/07/07 09:49:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <sys/types.h> + +#include <assert.h> +#include <inttypes.h> +#include <randomid.h> +#include <stdio.h> +#include <string.h> + +#define PERIOD 30000 + +uint64_t last[65536]; + +ATF_TC(randomid_basic); +ATF_TC_HEAD(randomid_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check randomid(3)"); +} + +ATF_TC_BODY(randomid_basic, tc) +{ + static randomid_t ctx = NULL; + uint64_t lowest, n, diff; + uint16_t id; + + memset(last, 0, sizeof(last)); + ctx = randomid_new(16, (long)3600); + + lowest = UINT64_MAX; + + for (n = 0; n < 1000000; n++) { + id = randomid(ctx); + + if (last[id] > 0) { + diff = n - last[id]; + + if (diff <= lowest) { + if (lowest != UINT64_MAX) + printf("id %5d: last call at %9"PRIu64 + ", current call %9"PRIu64 + " (diff %5"PRIu64"), " + "lowest %"PRIu64"\n", + id, last[id], n, diff, lowest); + + ATF_REQUIRE_MSG(diff >= PERIOD, + "diff (%"PRIu64") less than minimum " + "period (%d)", diff, PERIOD); + + lowest = diff; + } + } + + last[id] = n; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, randomid_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_realpath.c b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c new file mode 100644 index 0000000..d4998c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static const struct { + const char *path; + const char *result; +} paths[] = { + + { "/", "/" }, + { "///////", "/" }, + { "", NULL }, + { " ", NULL }, + { "/ ", NULL }, + { " /", NULL }, + { "/etc///", "/etc" }, + { "///////etc", "/etc" }, + { "/a/b/c/d/e", NULL }, + { " /usr/bin ", NULL }, + { "\\//////usr//bin", NULL }, + { "//usr//bin//", "/usr/bin" }, + { "//////usr//bin//", "/usr/bin" }, + { "/usr/bin//////////", "/usr/bin" }, +}; + +ATF_TC(realpath_basic); +ATF_TC_HEAD(realpath_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)"); +} + +ATF_TC_BODY(realpath_basic, tc) +{ + char buf[MAXPATHLEN]; + char *ptr; + size_t i; + + for (i = 0; i < __arraycount(paths); i++) { + + (void)memset(buf, '\0', sizeof(buf)); + + ptr = realpath(paths[i].path, buf); + + if (ptr == NULL && paths[i].result == NULL) + continue; + + if (ptr == NULL && paths[i].result != NULL) + atf_tc_fail("realpath failed for '%s'", paths[i].path); + + if (strcmp(paths[i].result, buf) != 0) + atf_tc_fail("expected '%s', got '%s'", + paths[i].result, buf); + } +} + +ATF_TC(realpath_huge); +ATF_TC_HEAD(realpath_huge, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)"); +} + +ATF_TC_BODY(realpath_huge, tc) +{ + char result[MAXPATHLEN] = { 0 }; + char buffer[MAXPATHLEN] = { 0 }; + + (void)memset(buffer, '/', sizeof(buffer) - 1); + + ATF_CHECK(realpath(buffer, result) != NULL); + ATF_CHECK(strlen(result) == 1); + ATF_CHECK(result[0] == '/'); +} + +ATF_TC(realpath_symlink); +ATF_TC_HEAD(realpath_symlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)"); +} + +ATF_TC_BODY(realpath_symlink, tc) +{ + char path[MAXPATHLEN] = { 0 }; + char slnk[MAXPATHLEN] = { 0 }; + char resb[MAXPATHLEN] = { 0 }; + int fd; + + (void)getcwd(path, sizeof(path)); + (void)getcwd(slnk, sizeof(slnk)); + + (void)strlcat(path, "/realpath", sizeof(path)); + (void)strlcat(slnk, "/symbolic", sizeof(slnk)); + + fd = open(path, O_RDONLY | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(realpath(slnk, resb) != NULL); + ATF_REQUIRE(strcmp(resb, path) == 0); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, realpath_basic); + ATF_TP_ADD_TC(tp, realpath_huge); + ATF_TP_ADD_TC(tp, realpath_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c new file mode 100644 index 0000000..89818f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c @@ -0,0 +1,132 @@ +/* $NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +static char domain[MAXHOSTNAMELEN]; + +static const char domains[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(setdomainname_basic); +ATF_TC_HEAD(setdomainname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setdomainname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + for (i = 0; i < __arraycount(domains); i++) { + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0); + ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0); + ATF_REQUIRE(strcmp(domains[i], name) == 0); + } + + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_CLEANUP(setdomainname_basic, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_limit); +ATF_TC_HEAD(setdomainname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long domain name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(setdomainname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_limit, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_perm); +ATF_TC_HEAD(setdomainname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setdomainname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_perm, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(domain, 0, sizeof(domain)); + + ATF_REQUIRE(getdomainname(domain, sizeof(domain)) == 0); + + ATF_TP_ADD_TC(tp, setdomainname_basic); + ATF_TP_ADD_TC(tp, setdomainname_limit); + ATF_TP_ADD_TC(tp, setdomainname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c new file mode 100644 index 0000000..a753ac7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c @@ -0,0 +1,132 @@ +/* $NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $"); + +#include <sys/param.h> + +#include <atf-c.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +static char host[MAXHOSTNAMELEN]; + +static const char hosts[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(sethostname_basic); +ATF_TC_HEAD(sethostname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of sethostname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + for (i = 0; i < __arraycount(hosts); i++) { + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i])) == 0); + ATF_REQUIRE(gethostname(name, sizeof(name)) == 0); + ATF_REQUIRE(strcmp(hosts[i], name) == 0); + } + + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_CLEANUP(sethostname_basic, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_limit); +ATF_TC_HEAD(sethostname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long host name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(sethostname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(sethostname_limit, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_perm); +ATF_TC_HEAD(sethostname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the host name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(sethostname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, sethostname(host, sizeof(host)) == -1); +} + +ATF_TC_CLEANUP(sethostname_perm, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(host, 0, sizeof(host)); + + ATF_REQUIRE(gethostname(host, sizeof(host)) == 0); + + ATF_TP_ADD_TC(tp, sethostname_basic); + ATF_TP_ADD_TC(tp, sethostname_limit); + ATF_TP_ADD_TC(tp, sethostname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c new file mode 100644 index 0000000..2fb53e4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c @@ -0,0 +1,500 @@ +/* $NetBSD: t_siginfo.c,v 1.23 2014/02/09 21:26:07 jmmv Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <atf-c/config.h> + +#include <sys/inttypes.h> +#include <sys/resource.h> +#include <sys/sysctl.h> +#include <sys/time.h> +#include <sys/ucontext.h> +#include <sys/wait.h> + +#include <assert.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <setjmp.h> +#include <float.h> + +#ifdef HAVE_FENV +#include <fenv.h> +#elif defined(_FLOAT_IEEE754) +#include <ieeefp.h> +#endif + +#include "isqemu.h" + +/* for sigbus */ +volatile char *addr; + +/* for sigchild */ +pid_t child; +int code; +int status; + +/* for sigfpe */ +sig_atomic_t fltdiv_signalled = 0; +sig_atomic_t intdiv_signalled = 0; + +static void +sig_debug(int signo, siginfo_t *info, ucontext_t *ctx) +{ + unsigned int i; + + printf("%d %p %p\n", signo, info, ctx); + if (info != NULL) { + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_value.sival_int=%d\n", info->si_value.sival_int); + } + if (ctx != NULL) { + printf("uc_flags 0x%x\n", ctx->uc_flags); + printf("uc_link %p\n", ctx->uc_link); + for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++) + printf("uc_sigmask[%d] 0x%x\n", i, + ctx->uc_sigmask.__bits[i]); + printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp, + (unsigned long)ctx->uc_stack.ss_size, + ctx->uc_stack.ss_flags); + for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++) + printf("uc_mcontext.greg[%d] 0x%lx\n", i, + (long)ctx->uc_mcontext.__gregs[i]); + } +} + +static void +sigalrm_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGALRM); + ATF_REQUIRE_EQ(info->si_code, SI_TIMER); + ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigalarm); + +ATF_TC_HEAD(sigalarm, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGALRM handler"); +} + +ATF_TC_BODY(sigalarm, tc) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigalrm_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + for (;;) { + alarm(1); + sleep(1); + } + atf_tc_fail("SIGALRM handler wasn't called"); +} + +static void +sigchild_action(int signo, siginfo_t *info, void *ptr) +{ + if (info != NULL) { + printf("info=%p\n", info); + printf("ptr=%p\n", ptr); + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_uid=%d\n", info->si_uid); + printf("si_pid=%d\n", info->si_pid); + printf("si_status=%d\n", info->si_status); + printf("si_utime=%lu\n", (unsigned long int)info->si_utime); + printf("si_stime=%lu\n", (unsigned long int)info->si_stime); + } + ATF_REQUIRE_EQ(info->si_code, code); + ATF_REQUIRE_EQ(info->si_signo, SIGCHLD); + ATF_REQUIRE_EQ(info->si_uid, getuid()); + ATF_REQUIRE_EQ(info->si_pid, child); + if (WIFEXITED(info->si_status)) + ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status); + else if (WIFSTOPPED(info->si_status)) + ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status); + else if (WIFSIGNALED(info->si_status)) + ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status); +} + +static void +setchildhandler(void (*action)(int, siginfo_t *, void *)) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = action; + sigemptyset(&sa.sa_mask); + sigaction(SIGCHLD, &sa, NULL); +} + +static void +sigchild_setup(void) +{ + sigset_t set; + struct rlimit rlim; + + (void)getrlimit(RLIMIT_CORE, &rlim); + rlim.rlim_cur = rlim.rlim_max; + (void)setrlimit(RLIMIT_CORE, &rlim); + + setchildhandler(sigchild_action); + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, NULL); +} + +ATF_TC(sigchild_normal); +ATF_TC_HEAD(sigchild_normal, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child exits normally"); +} + +ATF_TC_BODY(sigchild_normal, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = 25; + code = CLD_EXITED; + + switch ((child = fork())) { + case 0: + sleep(1); + exit(status); + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_dump); +ATF_TC_HEAD(sigchild_dump, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child segfaults"); +} + +ATF_TC_BODY(sigchild_dump, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGSEGV; + code = CLD_DUMPED; + + switch ((child = fork())) { + case 0: + sleep(1); + *(volatile long *)0 = 0; + atf_tc_fail("Child did not segfault"); + /* NOTREACHED */ + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_kill); +ATF_TC_HEAD(sigchild_kill, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child is killed"); +} + +ATF_TC_BODY(sigchild_kill, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGPIPE; + code = CLD_KILLED; + + switch ((child = fork())) { + case 0: + sigemptyset(&set); + sigsuspend(&set); + break; + case -1: + atf_tc_fail("fork failed"); + default: + kill(child, SIGPIPE); + sigemptyset(&set); + sigsuspend(&set); + } +} + +static sigjmp_buf sigfpe_flt_env; +static void +sigfpe_flt_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (fltdiv_signalled++ != 0) + atf_tc_fail("FPE handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_flt_env, 1); +} + +ATF_TC(sigfpe_flt); +ATF_TC_HEAD(sigfpe_flt, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for floating div-by-zero"); +} + +ATF_TC_BODY(sigfpe_flt, tc) +{ + struct sigaction sa; + double d = strtod("0", NULL); + + if (isQEMU()) + atf_tc_skip("Test does not run correctly under QEMU"); +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#endif + if (sigsetjmp(sigfpe_flt_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_flt_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%g\n", 1 / d); + } + if (fltdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static sigjmp_buf sigfpe_int_env; +static void +sigfpe_int_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (intdiv_signalled++ != 0) + atf_tc_fail("INTDIV handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV); + atf_tc_expect_pass(); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_int_env, 1); +} + +ATF_TC(sigfpe_int); +ATF_TC_HEAD(sigfpe_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for integer div-by-zero (PR port-i386/43655)"); +} + +ATF_TC_BODY(sigfpe_int, tc) +{ + struct sigaction sa; + long l = strtol("0", NULL, 10); + +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#endif + if (sigsetjmp(sigfpe_int_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_int_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%ld\n", 1 / l); + } + if (intdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static void +sigsegv_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGSEGV); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR); + ATF_REQUIRE_EQ(info->si_addr, (void *)0); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigsegv); +ATF_TC_HEAD(sigsegv, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGSEGV handler"); +} + +ATF_TC_BODY(sigsegv, tc) +{ + struct sigaction sa; + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigsegv_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + + *(volatile long *)0 = 0; + atf_tc_fail("Test did not fault as expected"); +} + +static void +sigbus_action(int signo, siginfo_t *info, void *ptr) +{ + + printf("si_addr = %p\n", info->si_addr); + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGBUS); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN); + +#if defined(__i386__) || defined(__x86_64__) + atf_tc_expect_fail("x86 architecture does not correctly " + "report the address where the unaligned access occured"); +#endif + ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigbus_adraln); +ATF_TC_HEAD(sigbus_adraln, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGBUS handler " + "for invalid address alignment"); +} + +ATF_TC_BODY(sigbus_adraln, tc) +{ + struct sigaction sa; + +#if defined(__alpha__) + int rv, val; + size_t len = sizeof(val); + rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0); + ATF_REQUIRE(rv == 0); + if (val == 0) + atf_tc_skip("SIGBUS signal not enabled for unaligned accesses"); +#endif + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigbus_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGBUS, &sa, NULL); + + /* Enable alignment checks for x86. 0x40000 is PSL_AC. */ +#if defined(__i386__) + __asm__("pushf; orl $0x40000, (%esp); popf"); +#elif defined(__amd64__) + __asm__("pushf; orl $0x40000, (%rsp); popf"); +#endif + + addr = calloc(2, sizeof(int)); + ATF_REQUIRE(addr != NULL); + + if (isQEMU()) + atf_tc_expect_fail("QEMU fails to trap unaligned accesses"); + + /* Force an unaligned access */ + addr++; + printf("now trying to access unaligned address %p\n", addr); + ATF_REQUIRE_EQ(*(volatile int *)addr, 0); + + atf_tc_fail("Test did not fault as expected"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigalarm); + ATF_TP_ADD_TC(tp, sigchild_normal); + ATF_TP_ADD_TC(tp, sigchild_dump); + ATF_TP_ADD_TC(tp, sigchild_kill); + ATF_TP_ADD_TC(tp, sigfpe_flt); + ATF_TP_ADD_TC(tp, sigfpe_int); + ATF_TP_ADD_TC(tp, sigsegv); + ATF_TP_ADD_TC(tp, sigbus_adraln); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sleep.c b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c new file mode 100644 index 0000000..e4dc94e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c @@ -0,0 +1,337 @@ +/* $NetBSD: t_sleep.c,v 1.8 2014/07/15 14:56:34 gson Exp $ */ + +/*- + * Copyright (c) 2006 Frank Kardel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <errno.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <sys/cdefs.h> +#include <sys/event.h> +#include <sys/signal.h> + +#include "isqemu.h" + +#define BILLION 1000000000LL /* nano-seconds per second */ +#define MILLION 1000000LL /* nano-seconds per milli-second */ + +#define ALARM 6 /* SIGALRM after this many seconds */ +#define MAXSLEEP 22 /* Maximum delay in seconds */ +#define KEVNT_TIMEOUT 10300 /* measured in milli-seconds */ +#define FUZZ (40 * MILLION) /* scheduling fuzz accepted - 40 ms */ + +/* + * Timer notes + * + * Most tests use FUZZ as their initial delay value, but 'sleep' + * starts at 1sec (since it cannot handle sub-second intervals). + * Subsequent passes double the previous interval, up to MAXSLEEP. + * + * The current values result in 5 passes for the 'sleep' test (at 1, + * 2, 4, 8, and 16 seconds) and 10 passes for the other tests (at + * 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, and 20.48 + * seconds). + * + * The ALARM is only set if the current pass's delay is longer, and + * only if the ALARM has not already been triggered. + * + * The 'kevent' test needs the ALARM to be set on a different pass + * from when the KEVNT_TIMEOUT fires. So set ALARM to fire on the + * penultimate pass, and the KEVNT_TIMEOUT on the final pass. We + * set KEVNT_TIMEOUT just barely long enough to put it into the + * last test pass, and set MAXSLEEP a couple seconds longer than + * necessary, in order to avoid a QEMU bug which nearly doubles + * some timers. + */ + +static volatile int sig; + +int sleeptest(int (*)(struct timespec *, struct timespec *), bool, bool); +int do_nanosleep(struct timespec *, struct timespec *); +int do_select(struct timespec *, struct timespec *); +int do_poll(struct timespec *, struct timespec *); +int do_sleep(struct timespec *, struct timespec *); +int do_kevent(struct timespec *, struct timespec *); +void sigalrm(int); + +void +sigalrm(int s) +{ + + sig++; +} + +int +do_nanosleep(struct timespec *delay, struct timespec *remain) +{ + int ret; + + if (nanosleep(delay, remain) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_select(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (select(0, NULL, NULL, NULL, &tv) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_poll(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (pollts(NULL, 0, delay, NULL) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_sleep(struct timespec *delay, struct timespec *remain) +{ + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + remain->tv_sec = sleep(delay->tv_sec); + remain->tv_nsec = 0; + + return 0; +} + +int +do_kevent(struct timespec *delay, struct timespec *remain) +{ + struct kevent ktimer; + struct kevent kresult; + int rtc, kq, kerrno; + int tmo; + + ATF_REQUIRE_MSG((kq = kqueue()) != -1, "kqueue: %s", strerror(errno)); + + tmo = KEVNT_TIMEOUT; + + /* + * If we expect the KEVNT_TIMEOUT to fire, and we're running + * under QEMU, make sure the delay is long enough to account + * for the effects of PR kern/43997 ! + */ + if (isQEMU() && + tmo/1000 < delay->tv_sec && tmo/500 > delay->tv_sec) + delay->tv_sec = MAXSLEEP; + + EV_SET(&ktimer, 1, EVFILT_TIMER, EV_ADD, 0, tmo, 0); + + rtc = kevent(kq, &ktimer, 1, &kresult, 1, delay); + kerrno = errno; + + (void)close(kq); + + if (rtc == -1) { + ATF_REQUIRE_MSG(kerrno == EINTR, "kevent: %s", strerror(errno)); + return 0; + } + + if (delay->tv_sec * BILLION + delay->tv_nsec > tmo * MILLION) + ATF_REQUIRE_MSG(rtc > 0, + "kevent: KEVNT_TIMEOUT did not cause EVFILT_TIMER event"); + + return 0; +} + +ATF_TC(nanosleep); +ATF_TC_HEAD(nanosleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test nanosleep(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(nanosleep, tc) +{ + + sleeptest(do_nanosleep, true, false); +} + +ATF_TC(select); +ATF_TC_HEAD(select, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test select(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(select, tc) +{ + + sleeptest(do_select, true, true); +} + +ATF_TC(poll); +ATF_TC_HEAD(poll, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test poll(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(poll, tc) +{ + + sleeptest(do_poll, true, true); +} + +ATF_TC(sleep); +ATF_TC_HEAD(sleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sleep(3) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(sleep, tc) +{ + + sleeptest(do_sleep, false, false); +} + +ATF_TC(kevent); +ATF_TC_HEAD(kevent, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test kevent(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(kevent, tc) +{ + + sleeptest(do_kevent, true, true); +} + +int +sleeptest(int (*test)(struct timespec *, struct timespec *), + bool subsec, bool sim_remain) +{ + struct timespec tsa, tsb, tslp, tremain; + int64_t delta1, delta2, delta3, round; + + sig = 0; + signal(SIGALRM, sigalrm); + + if (subsec) { + round = 1; + delta3 = FUZZ; + } else { + round = 1000000000; + delta3 = round; + } + + tslp.tv_sec = delta3 / 1000000000; + tslp.tv_nsec = delta3 % 1000000000; + + while (tslp.tv_sec <= MAXSLEEP) { + /* + * disturb sleep by signal on purpose + */ + if (tslp.tv_sec > ALARM && sig == 0) + alarm(ALARM); + + clock_gettime(CLOCK_REALTIME, &tsa); + (*test)(&tslp, &tremain); + clock_gettime(CLOCK_REALTIME, &tsb); + + if (sim_remain) { + timespecsub(&tsb, &tsa, &tremain); + timespecsub(&tslp, &tremain, &tremain); + } + + delta1 = (int64_t)tsb.tv_sec - (int64_t)tsa.tv_sec; + delta1 *= BILLION; + delta1 += (int64_t)tsb.tv_nsec - (int64_t)tsa.tv_nsec; + + delta2 = (int64_t)tremain.tv_sec * BILLION; + delta2 += (int64_t)tremain.tv_nsec; + + delta3 = (int64_t)tslp.tv_sec * BILLION; + delta3 += (int64_t)tslp.tv_nsec - delta1 - delta2; + + delta3 /= round; + delta3 *= round; + + if (delta3 > FUZZ || delta3 < -FUZZ) { + if (!sim_remain) + atf_tc_expect_fail("Long reschedule latency " + "due to PR kern/43997"); + + atf_tc_fail("Reschedule latency %"PRId64" exceeds " + "allowable fuzz %lld", delta3, FUZZ); + } + delta3 = (int64_t)tslp.tv_sec * 2 * BILLION; + delta3 += (int64_t)tslp.tv_nsec * 2; + + delta3 /= round; + delta3 *= round; + if (delta3 < FUZZ) + break; + tslp.tv_sec = delta3 / BILLION; + tslp.tv_nsec = delta3 % BILLION; + } + ATF_REQUIRE_MSG(sig == 1, "Alarm did not fire!"); + + atf_tc_pass(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, nanosleep); + ATF_TP_ADD_TC(tp, select); + ATF_TP_ADD_TC(tp, poll); + ATF_TP_ADD_TC(tp, sleep); + ATF_TP_ADD_TC(tp, kevent); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_syslog.c b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c new file mode 100644 index 0000000..c9417c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c @@ -0,0 +1,56 @@ +/* $NetBSD: t_syslog.c,v 1.2 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> + +#include <atf-c.h> +#include <syslog.h> + +ATF_TC(syslog_pthread); +ATF_TC_HEAD(syslog_pthread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test that syslog(3) " + "works when linked to pthread(3) (PR lib/44248)"); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(syslog_pthread, tc) +{ + syslog(LOG_DEBUG, "from tests/lib/libc/gen/t_syslog"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, syslog_pthread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_time.c b/contrib/netbsd-tests/lib/libc/gen/t_time.c new file mode 100644 index 0000000..bfbdc73 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +ATF_TC(time_copy); +ATF_TC_HEAD(time_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test the return values of time(3)"); +} + +ATF_TC_BODY(time_copy, tc) +{ + time_t t1, t2 = 0; + + t1 = time(&t2); + + if (t1 != t2) + atf_tc_fail("incorrect return values from time(3)"); +} + +ATF_TC(time_mono); +ATF_TC_HEAD(time_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test monotonicity of time(3)"); +} + +ATF_TC_BODY(time_mono, tc) +{ + const size_t maxiter = 10; + time_t t1, t2; + size_t i; + + for (i = 0; i < maxiter; i++) { + + t1 = time(NULL); + (void)sleep(1); + t2 = time(NULL); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t1, (int64_t)t2); + + if (t1 >= t2) + atf_tc_fail("time(3) is not monotonic"); + } +} + +ATF_TC(time_timeofday); +ATF_TC_HEAD(time_timeofday, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test time(3) vs. gettimeofday(2)"); +} + +ATF_TC_BODY(time_timeofday, tc) +{ + struct timeval tv = { 0, 0 }; + time_t t; + + t = time(NULL); + ATF_REQUIRE(gettimeofday(&tv, NULL) == 0); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t, (int64_t)tv.tv_sec); + + if (t != tv.tv_sec) + atf_tc_fail("time(3) and gettimeofday(2) differ"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, time_copy); + ATF_TP_ADD_TC(tp, time_mono); + ATF_TP_ADD_TC(tp, time_timeofday); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c new file mode 100644 index 0000000..0c10c24 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c @@ -0,0 +1,188 @@ +/* $NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static long ttymax = 0; + +ATF_TC(ttyname_err); +ATF_TC_HEAD(ttyname_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname(3)"); +} + +ATF_TC_BODY(ttyname_err, tc) +{ + int fd; + + fd = open("XXX", O_RDONLY); + + if (fd < 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == EBADF); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == EBADF); + } + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == ENOTTY); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == ENOTTY); + } +} + +ATF_TC(ttyname_r_err); +ATF_TC_HEAD(ttyname_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname_r(3)"); +} + +ATF_TC_BODY(ttyname_r_err, tc) +{ + char sbuf[0]; + char *buf; + int fd; + int rv; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + if (isatty(STDIN_FILENO) != 0) { + + rv = ttyname_r(STDIN_FILENO, sbuf, sizeof(sbuf)); + ATF_REQUIRE(rv == ERANGE); + } + + rv = ttyname_r(-1, buf, ttymax); + ATF_REQUIRE(rv == EBADF); + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + rv = ttyname_r(fd, buf, ttymax); + ATF_REQUIRE(rv == ENOTTY); + ATF_REQUIRE(close(fd) == 0); + } + + free(buf); +} + +ATF_TC(ttyname_r_stdin); +ATF_TC_HEAD(ttyname_r_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname_r(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_r_stdin, tc) +{ + const char *str; + char *buf; + int rv; + + if (isatty(STDIN_FILENO) == 0) + return; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + str = ttyname(STDIN_FILENO); + rv = ttyname_r(STDIN_FILENO, buf, ttymax); + + ATF_REQUIRE(rv == 0); + ATF_REQUIRE(str != NULL); + + if (strcmp(str, buf) != 0) + atf_tc_fail("ttyname(3) and ttyname_r(3) conflict"); + + free(buf); +} + +ATF_TC(ttyname_stdin); +ATF_TC_HEAD(ttyname_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_stdin, tc) +{ + + if (isatty(STDIN_FILENO) != 0) + ATF_REQUIRE(ttyname(STDIN_FILENO) != NULL); + + (void)close(STDIN_FILENO); + + ATF_REQUIRE(isatty(STDIN_FILENO) != 1); + ATF_REQUIRE(ttyname(STDIN_FILENO) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ttymax = sysconf(_SC_TTY_NAME_MAX); + ATF_REQUIRE(ttymax >= 0); + + ATF_TP_ADD_TC(tp, ttyname_err); + ATF_TP_ADD_TC(tp, ttyname_r_err); + ATF_TP_ADD_TC(tp, ttyname_r_stdin); + ATF_TP_ADD_TC(tp, ttyname_stdin); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_vis.c b/contrib/netbsd-tests/lib/libc/gen/t_vis.c new file mode 100644 index 0000000..525bafa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_vis.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_vis.c,v 1.7 2014/09/08 19:01:03 christos Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> + +#include <string.h> +#include <stdlib.h> +#include <err.h> +#include <vis.h> + +static int styles[] = { + VIS_OCTAL, + VIS_CSTYLE, + VIS_SP, + VIS_TAB, + VIS_NL, + VIS_WHITE, + VIS_SAFE, +#if 0 /* Not reversible */ + VIS_NOSLASH, +#endif + VIS_HTTP1808, + VIS_MIMESTYLE, +#if 0 /* Not supported by vis(3) */ + VIS_HTTP1866, +#endif +}; + +#define SIZE 256 + +ATF_TC(strvis_basic); +ATF_TC_HEAD(strvis_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test strvis(3)"); +} + +ATF_TC_BODY(strvis_basic, tc) +{ + char *srcbuf, *dstbuf, *visbuf; + unsigned int i, j; + + ATF_REQUIRE((dstbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((srcbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((visbuf = malloc(SIZE * 4 + 1)) != NULL); + + for (i = 0; i < SIZE; i++) + srcbuf[i] = (char)i; + + for (i = 0; i < __arraycount(styles); i++) { + ATF_REQUIRE(strsvisx(visbuf, srcbuf, SIZE, styles[i], "") > 0); + memset(dstbuf, 0, SIZE); + ATF_REQUIRE(strunvisx(dstbuf, visbuf, + styles[i] & (VIS_HTTP1808|VIS_MIMESTYLE)) > 0); + for (j = 0; j < SIZE; j++) + if (dstbuf[j] != (char)j) + atf_tc_fail_nonfatal("Failed for style %x, " + "char %d [%d]", styles[i], j, dstbuf[j]); + } + free(dstbuf); + free(srcbuf); + free(visbuf); +} + +ATF_TC(strvis_null); +ATF_TC_HEAD(strvis_null, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) NULL"); +} + +ATF_TC_BODY(strvis_null, tc) +{ + char dst[] = "fail"; + strvis(dst, NULL, VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strvis_empty); +ATF_TC_HEAD(strvis_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) empty"); +} + +ATF_TC_BODY(strvis_empty, tc) +{ + char dst[] = "fail"; + strvis(dst, "", VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strunvis_hex); +ATF_TC_HEAD(strunvis_hex, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strunvis(3) \\xXX"); +} + +ATF_TC_BODY(strunvis_hex, tc) +{ + static const struct { + const char *e; + const char *d; + int error; + } ed[] = { + { "\\xff", "\xff", 1 }, + { "\\x1", "\x1", 1 }, + { "\\x1\\x02", "\x1\x2", 2 }, + { "\\x1x", "\x1x", 2 }, + { "\\xx", "", -1 }, + }; + char uv[10]; + + for (size_t i = 0; i < __arraycount(ed); i++) { + ATF_REQUIRE(strunvis(uv, ed[i].e) == ed[i].error); + if (ed[i].error > 0) + ATF_REQUIRE(memcmp(ed[i].d, uv, ed[i].error) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strvis_basic); + ATF_TP_ADD_TC(tp, strvis_null); + ATF_TP_ADD_TC(tp, strvis_empty); + ATF_TP_ADD_TC(tp, strunvis_hex); + + return atf_no_error(); +} |