Date: Wed, 13 Aug 2014 04:56:28 +0000 (UTC) From: Garrett Cooper <ngie@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r269904 - in head: lib/libutil lib/libutil/tests tools/regression/lib/libutil Message-ID: <201408130456.s7D4uS9F087555@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ngie Date: Wed Aug 13 04:56:27 2014 New Revision: 269904 URL: http://svnweb.freebsd.org/changeset/base/269904 Log: Integrate lib/libutil into the build/kyua Remove the .t wrappers Rename all of the TAP test applications from test-<test> to <test>_test to match the convention described in the TestSuite wiki page humanize_number_test.c: - Fix -Wformat warnings with counter variables - Fix minor style(9) issues: -- Header sorting -- Variable declaration alignment/sorting in main(..) -- Fit the lines in <80 columns - Fix an off by one index error in the testcase output [*] - Remove unnecessary `extern char * optarg;` (this is already provided by unistd.h) Phabric: D555 Approved by: jmmv (mentor) MFC after: 2 weeks Obtained from: EMC / Isilon Storage Division [*] Submitted by: Casey Peel <cpeel@isilon.com> [*] Sponsored by: EMC / Isilon Storage Division Added: head/lib/libutil/tests/ head/lib/libutil/tests/Makefile (contents, props changed) head/lib/libutil/tests/flopen_test.c - copied unchanged from r269903, head/tools/regression/lib/libutil/test-flopen.c head/lib/libutil/tests/grp_test.c - copied unchanged from r269562, head/tools/regression/lib/libutil/test-grp.c head/lib/libutil/tests/humanize_number_test.c - copied, changed from r269562, head/tools/regression/lib/libutil/test-humanize_number.c head/lib/libutil/tests/pidfile_test.c - copied unchanged from r269562, head/tools/regression/lib/libutil/test-pidfile.c head/lib/libutil/tests/trimdomain-nodomain_test.c - copied unchanged from r269562, head/tools/regression/lib/libutil/test-trimdomain-nodomain.c head/lib/libutil/tests/trimdomain_test.c - copied unchanged from r269562, head/tools/regression/lib/libutil/test-trimdomain.c Deleted: head/tools/regression/lib/libutil/ Modified: head/lib/libutil/Makefile Modified: head/lib/libutil/Makefile ============================================================================== --- head/lib/libutil/Makefile Wed Aug 13 04:43:29 2014 (r269903) +++ head/lib/libutil/Makefile Wed Aug 13 04:56:27 2014 (r269904) @@ -81,4 +81,8 @@ MLINKS+=pw_util.3 pw_copy.3 \ pw_util.3 pw_tempname.3 \ pw_util.3 pw_tmp.3 +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.lib.mk> Added: head/lib/libutil/tests/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libutil/tests/Makefile Wed Aug 13 04:56:27 2014 (r269904) @@ -0,0 +1,15 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/lib/libutil + +TAP_TESTS_C+= flopen_test +TAP_TESTS_C+= grp_test +TAP_TESTS_C+= humanize_number_test +TAP_TESTS_C+= pidfile_test +TAP_TESTS_C+= trimdomain_test +TAP_TESTS_C+= trimdomain-nodomain_test + +DPADD+= ${LIBUTIL} +LDADD+= -lutil + +.include <bsd.test.mk> Copied: head/lib/libutil/tests/flopen_test.c (from r269903, head/tools/regression/lib/libutil/test-flopen.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libutil/tests/flopen_test.c Wed Aug 13 04:56:27 2014 (r269904, copy of r269903, head/tools/regression/lib/libutil/test-flopen.c) @@ -0,0 +1,210 @@ +/*- + * Copyright (c) 2007-2009 Dag-Erling Coïdan Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/fcntl.h> + +#include <errno.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libutil.h> + +/* + * Test that flopen() can create a file. + */ +const char * +test_flopen_create(void) +{ + const char *fn = "test_flopen_create"; + const char *result = NULL; + int fd; + + unlink(fn); + fd = flopen(fn, O_RDWR|O_CREAT, 0640); + if (fd < 0) { + result = strerror(errno); + } else { + close(fd); + } + unlink(fn); + return (result); +} + +/* + * Test that flopen() can open an existing file. + */ +const char * +test_flopen_open(void) +{ + const char *fn = "test_flopen_open"; + const char *result = NULL; + int fd; + + fd = open(fn, O_RDWR|O_CREAT, 0640); + if (fd < 0) { + result = strerror(errno); + } else { + close(fd); + fd = flopen(fn, O_RDWR); + if (fd < 0) { + result = strerror(errno); + } else { + close(fd); + } + } + unlink(fn); + return (result); +} + +/* + * Test that flopen() can lock against itself + */ +const char * +test_flopen_lock_self(void) +{ + const char *fn = "test_flopen_lock_self"; + const char *result = NULL; + int fd1, fd2; + + unlink(fn); + fd1 = flopen(fn, O_RDWR|O_CREAT, 0640); + if (fd1 < 0) { + result = strerror(errno); + } else { + fd2 = flopen(fn, O_RDWR|O_NONBLOCK); + if (fd2 >= 0) { + result = "second open succeeded"; + close(fd2); + } + close(fd1); + } + unlink(fn); + return (result); +} + +/* + * Test that flopen() can lock against other processes + */ +const char * +test_flopen_lock_other(void) +{ + const char *fn = "test_flopen_lock_other"; + const char *result = NULL; + volatile int fd1, fd2; + + unlink(fn); + fd1 = flopen(fn, O_RDWR|O_CREAT, 0640); + if (fd1 < 0) { + result = strerror(errno); + } else { + fd2 = -42; + if (vfork() == 0) { + fd2 = flopen(fn, O_RDWR|O_NONBLOCK); + close(fd2); + _exit(0); + } + if (fd2 == -42) + result = "vfork() doesn't work as expected"; + if (fd2 >= 0) + result = "second open succeeded"; + close(fd1); + } + unlink(fn); + return (result); +} + +/* + * Test that child processes inherit the lock + */ +const char * +test_flopen_lock_child(void) +{ + const char *fn = "test_flopen_lock_child"; + const char *result = NULL; + pid_t pid; + volatile int fd1, fd2; + + unlink(fn); + fd1 = flopen(fn, O_RDWR|O_CREAT, 0640); + if (fd1 < 0) { + result = strerror(errno); + } else { + pid = fork(); + if (pid == -1) { + result = strerror(errno); + } else if (pid == 0) { + select(0, 0, 0, 0, 0); + _exit(0); + } + close(fd1); + if ((fd2 = flopen(fn, O_RDWR|O_NONBLOCK)) != -1) { + result = "second open succeeded"; + close(fd2); + } + kill(pid, SIGINT); + } + unlink(fn); + return (result); +} + +static struct test { + const char *name; + const char *(*func)(void); +} t[] = { + { "flopen_create", test_flopen_create }, + { "flopen_open", test_flopen_open }, + { "flopen_lock_self", test_flopen_lock_self }, + { "flopen_lock_other", test_flopen_lock_other }, + { "flopen_lock_child", test_flopen_lock_child }, +}; + +int +main(void) +{ + const char *result; + int i, nt; + + nt = sizeof(t) / sizeof(*t); + printf("1..%d\n", nt); + for (i = 0; i < nt; ++i) { + if ((result = t[i].func()) != NULL) + printf("not ok %d - %s # %s\n", i + 1, + t[i].name, result); + else + printf("ok %d - %s\n", i + 1, + t[i].name); + } + exit(0); +} Copied: head/lib/libutil/tests/grp_test.c (from r269562, head/tools/regression/lib/libutil/test-grp.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libutil/tests/grp_test.c Wed Aug 13 04:56:27 2014 (r269904, copy of r269562, head/tools/regression/lib/libutil/test-grp.c) @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2008 Sean C. Farley <scf@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <errno.h> +#include <grp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <libutil.h> + + +/* + * Static values for building and testing an artificial group. + */ +static char grpName[] = "groupName"; +static char grpPasswd[] = "groupPwd"; +static gid_t grpGID = 1234; +static char *grpMems[] = { "mem1", "mem2", "mem3", NULL }; +static const char *origStrGrp = "groupName:groupPwd:1234:mem1,mem2,mem3"; + + +/* + * Build a group to test against without depending on a real group to be found + * within /etc/group. + */ +static void +build_grp(struct group *grp) +{ + grp->gr_name = grpName; + grp->gr_passwd = grpPasswd; + grp->gr_gid = grpGID; + grp->gr_mem = grpMems; + + return; +} + + +int +main(void) +{ + char *strGrp; + int testNdx; + struct group *dupGrp; + struct group *scanGrp; + struct group origGrp; + + /* Setup. */ + printf("1..4\n"); + testNdx = 0; + + /* Manually build a group using static values. */ + build_grp(&origGrp); + + /* Copy the group. */ + testNdx++; + if ((dupGrp = gr_dup(&origGrp)) == NULL) + printf("not "); + printf("ok %d - %s\n", testNdx, "gr_dup"); + + /* Compare the original and duplicate groups. */ + testNdx++; + if (! gr_equal(&origGrp, dupGrp)) + printf("not "); + printf("ok %d - %s\n", testNdx, "gr_equal"); + + /* Create group string from the duplicate group structure. */ + testNdx++; + strGrp = gr_make(dupGrp); + if (strcmp(strGrp, origStrGrp) != 0) + printf("not "); + printf("ok %d - %s\n", testNdx, "gr_make"); + + /* + * Create group structure from string and compare it to the original + * group structure. + */ + testNdx++; + if ((scanGrp = gr_scan(strGrp)) == NULL || ! gr_equal(&origGrp, + scanGrp)) + printf("not "); + printf("ok %d - %s\n", testNdx, "gr_scan"); + + /* Clean up. */ + free(scanGrp); + free(strGrp); + free(dupGrp); + + exit(EXIT_SUCCESS); +} Copied and modified: head/lib/libutil/tests/humanize_number_test.c (from r269562, head/tools/regression/lib/libutil/test-humanize_number.c) ============================================================================== --- head/tools/regression/lib/libutil/test-humanize_number.c Tue Aug 5 05:00:22 2014 (r269562, copy source) +++ head/lib/libutil/tests/humanize_number_test.c Wed Aug 13 04:56:27 2014 (r269904) @@ -28,17 +28,15 @@ * */ -#include <sys/types.h> -#include <stdlib.h> +#include <sys/param.h> +#include <inttypes.h> #include <libutil.h> +#include <limits.h> +#include <math.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> -#include <inttypes.h> -#include <math.h> #include <unistd.h> -#include <limits.h> - -extern char * optarg; #define MAX_STR_FLAGS_RESULT 80 #define MAX_INT_STR_DIGITS 12 @@ -490,7 +488,7 @@ static void testskipped(size_t i) { - printf("ok %lu # skip - not turned on\n", i); + printf("ok %zu # skip - not turned on\n", i); } int @@ -498,10 +496,8 @@ main(int argc, char * const argv[]) { char *buf; char *flag_str, *scale_str; - size_t i; - size_t errcnt, tested, skipped; + size_t buflen, errcnt, i, skipped, tested; int r; - size_t buflen; int includeNegScale; int includeExabyteTests; int verbose; @@ -522,8 +518,8 @@ main(int argc, char * const argv[]) if (buflen != 4) printf("Warning: buffer size %zu != 4, expect some results to differ.\n", buflen); - printf("1..%lu\n", sizeof test_args / sizeof *test_args); - for (i = 0; i < sizeof test_args / sizeof *test_args; i++) { + printf("1..%zu\n", nitems(test_args)); + for (i = 0; i < nitems(test_args); i++) { /* KLUDGE */ if (test_args[i].num == INT64_MAX && buflen == 4) { /* Start final tests which require buffer of 6 */ @@ -537,12 +533,12 @@ main(int argc, char * const argv[]) if (test_args[i].scale < 0 && ! includeNegScale) { skipped++; - testskipped(i); + testskipped(i + 1); continue; } if (test_args[i].num >= halfExabyte && ! includeExabyteTests) { skipped++; - testskipped(i); + testskipped(i + 1); continue; } @@ -553,36 +549,46 @@ main(int argc, char * const argv[]) if (r != test_args[i].retval) { if (verbose) - printf("wrong return value on index %lu, buflen: %zu, got: %d + \"%s\", expected %d + \"%s\"; num = %" PRId64 ", scale = %s, flags= %s.\n", + printf("wrong return value on index %zu, " + "buflen: %zu, got: %d + \"%s\", " + "expected %d + \"%s\"; num = %jd, " + "scale = %s, flags= %s.\n", i, buflen, r, buf, test_args[i].retval, - test_args[i].res, test_args[i].num, + test_args[i].res, + (intmax_t)test_args[i].num, scale_str, flag_str); else - printf("not ok %lu # return %d != %d\n", i, r, - test_args[i].retval); + printf("not ok %zu # return %d != %d\n", + i + 1, r, test_args[i].retval); errcnt++; } else if (strcmp(buf, test_args[i].res) != 0) { if (verbose) - printf("result mismatch on index %lu, got: \"%s\", expected \"%s\"; num = %" PRId64 ", scale = %s, flags= %s.\n", - i, buf, test_args[i].res, test_args[i].num, + printf("result mismatch on index %zu, got: " + "\"%s\", expected \"%s\"; num = %jd, " + "scale = %s, flags= %s.\n", + i, buf, test_args[i].res, + (intmax_t)test_args[i].num, scale_str, flag_str); else - printf("not ok %lu # buf \"%s\" != \"%s\"\n", i, - buf, test_args[i].res); + printf("not ok %zu # buf \"%s\" != \"%s\"\n", + i + 1, buf, test_args[i].res); errcnt++; } else { if (verbose) - printf("successful result on index %lu, returned %d, got: \"%s\"; num = %" PRId64 ", scale = %s, flags= %s.\n", - i, r, buf, test_args[i].num, scale_str, - flag_str); + printf("successful result on index %zu, " + "returned %d, got: \"%s\"; num = %jd, " + "scale = %s, flags= %s.\n", + i, r, buf, + (intmax_t)test_args[i].num, + scale_str, flag_str); else - printf("ok %lu\n", i); + printf("ok %zu\n", i + 1); } tested++; } if (verbose) - printf("total errors: %lu/%lu tests, %lu skipped\n", errcnt, + printf("total errors: %zu/%zu tests, %zu skipped\n", errcnt, tested, skipped); if (errcnt) Copied: head/lib/libutil/tests/pidfile_test.c (from r269562, head/tools/regression/lib/libutil/test-pidfile.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libutil/tests/pidfile_test.c Wed Aug 13 04:56:27 2014 (r269904, copy of r269562, head/tools/regression/lib/libutil/test-pidfile.c) @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 2007-2009 Dag-Erling Coïdan Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/wait.h> + +#include <fcntl.h> +#include <errno.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libutil.h> + +/* + * We need a signal handler so kill(2) will interrupt our child's + * select(2) instead of killing it. + */ +static void +signal_handler(int sig) +{ + (void)sig; +} + +/* + * Test that pidfile_open() can create a pidfile and that pidfile_write() + * can write to it. + */ +static const char * +test_pidfile_uncontested(void) +{ + const char *fn = "test_pidfile_uncontested"; + struct pidfh *pf; + pid_t other = 0; + + unlink(fn); + pf = pidfile_open(fn, 0600, &other); + if (pf == NULL && other != 0) + return ("pidfile exists and is locked"); + if (pf == NULL) + return (strerror(errno)); + if (pidfile_write(pf) != 0) { + pidfile_close(pf); + unlink(fn); + return ("failed to write PID"); + } + pidfile_close(pf); + unlink(fn); + return (NULL); +} + +/* + * Test that pidfile_open() locks against self. + */ +static const char * +test_pidfile_self(void) +{ + const char *fn = "test_pidfile_self"; + struct pidfh *pf1, *pf2; + pid_t other = 0; + int serrno; + + unlink(fn); + pf1 = pidfile_open(fn, 0600, &other); + if (pf1 == NULL && other != 0) + return ("pidfile exists and is locked"); + if (pf1 == NULL) + return (strerror(errno)); + if (pidfile_write(pf1) != 0) { + serrno = errno; + pidfile_close(pf1); + unlink(fn); + return (strerror(serrno)); + } + // second open should fail + pf2 = pidfile_open(fn, 0600, &other); + if (pf2 != NULL) { + pidfile_close(pf1); + pidfile_close(pf2); + unlink(fn); + return ("managed to opened pidfile twice"); + } + if (other != getpid()) { + pidfile_close(pf1); + unlink(fn); + return ("pidfile contained wrong PID"); + } + pidfile_close(pf1); + unlink(fn); + return (NULL); +} + +/* + * Common code for test_pidfile_{contested,inherited}. + */ +static const char * +common_test_pidfile_child(const char *fn, int parent_open) +{ + struct pidfh *pf = NULL; + pid_t other = 0, pid = 0; + int fd[2], serrno, status; + char ch; + + unlink(fn); + if (pipe(fd) != 0) + return (strerror(errno)); + + if (parent_open) { + pf = pidfile_open(fn, 0600, &other); + if (pf == NULL && other != 0) + return ("pidfile exists and is locked"); + if (pf == NULL) + return (strerror(errno)); + } + + pid = fork(); + if (pid == -1) + return (strerror(errno)); + if (pid == 0) { + // child + close(fd[0]); + signal(SIGINT, signal_handler); + if (!parent_open) { + pf = pidfile_open(fn, 0600, &other); + if (pf == NULL && other != 0) + return ("pidfile exists and is locked"); + if (pf == NULL) + return (strerror(errno)); + } + if (pidfile_write(pf) != 0) { + serrno = errno; + pidfile_close(pf); + unlink(fn); + return (strerror(serrno)); + } + if (pf == NULL) + _exit(1); + if (pidfile_write(pf) != 0) + _exit(1); + if (write(fd[1], "*", 1) != 1) + _exit(1); + select(0, 0, 0, 0, 0); + _exit(0); + } + // parent + close(fd[1]); + if (pf) + pidfile_close(pf); + + // wait for the child to signal us + if (read(fd[0], &ch, 1) != 1) { + serrno = errno; + unlink(fn); + kill(pid, SIGTERM); + errno = serrno; + return (strerror(errno)); + } + + // We shouldn't be able to lock the same pidfile as our child + pf = pidfile_open(fn, 0600, &other); + if (pf != NULL) { + pidfile_close(pf); + unlink(fn); + return ("managed to lock contested pidfile"); + } + + // Failed to lock, but not because it was contested + if (other == 0) { + unlink(fn); + return (strerror(errno)); + } + + // Locked by the wrong process + if (other != pid) { + unlink(fn); + return ("pidfile contained wrong PID"); + } + + // check our child's fate + if (pf) + pidfile_close(pf); + unlink(fn); + if (kill(pid, SIGINT) != 0) + return (strerror(errno)); + if (waitpid(pid, &status, 0) == -1) + return (strerror(errno)); + if (WIFSIGNALED(status)) + return ("child caught signal"); + if (WEXITSTATUS(status) != 0) + return ("child returned non-zero status"); + + // success + return (NULL); +} + +/* + * Test that pidfile_open() fails when attempting to open a pidfile that + * is already locked, and that it returns the correct PID. + */ +static const char * +test_pidfile_contested(void) +{ + const char *fn = "test_pidfile_contested"; + const char *result; + + result = common_test_pidfile_child(fn, 0); + return (result); +} + +/* + * Test that the pidfile lock is inherited. + */ +static const char * +test_pidfile_inherited(void) +{ + const char *fn = "test_pidfile_inherited"; + const char *result; + + result = common_test_pidfile_child(fn, 1); + return (result); +} + +static struct test { + const char *name; + const char *(*func)(void); +} t[] = { + { "pidfile_uncontested", test_pidfile_uncontested }, + { "pidfile_self", test_pidfile_self }, + { "pidfile_contested", test_pidfile_contested }, + { "pidfile_inherited", test_pidfile_inherited }, +}; + +int +main(void) +{ + const char *result; + int i, nt; + + nt = sizeof(t) / sizeof(*t); + printf("1..%d\n", nt); + for (i = 0; i < nt; ++i) { + if ((result = t[i].func()) != NULL) + printf("not ok %d - %s # %s\n", i + 1, + t[i].name, result); + else + printf("ok %d - %s\n", i + 1, + t[i].name); + } + exit(0); +} Copied: head/lib/libutil/tests/trimdomain-nodomain_test.c (from r269562, head/tools/regression/lib/libutil/test-trimdomain-nodomain.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libutil/tests/trimdomain-nodomain_test.c Wed Aug 13 04:56:27 2014 (r269904, copy of r269562, head/tools/regression/lib/libutil/test-trimdomain-nodomain.c) @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2005 Brooks Davis. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/param.h> +#include <errno.h> +#include <libutil.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define TESTDOMAIN "" +#define TESTHOST "testhost" +#define TESTFQDN "testhost" TESTDOMAIN + +int failures = 0; +int tests = 0; + +/* + * Evily override gethostname(3) so trimdomain always gets the same result. + * This makes the tests much easier to write and less likely to fail on + * oddly configured systems. + */ +int +gethostname(char *name, size_t namelen) +{ + if (strlcpy(name, TESTFQDN, namelen) > namelen) { + errno = ENAMETOOLONG; + return (-1); + } + return (0); +} + +void +testit(const char *input, int hostsize, const char *output, const char *test) +{ + char *testhost; + const char *expected = (output == NULL) ? input : output; + + testhost = strdup(input); + trimdomain(testhost, hostsize < 0 ? (int)strlen(testhost) : hostsize); + tests++; + if (strcmp(testhost, expected) != 0) { + printf("not ok %d - %s\n", tests, test); + printf("# %s -> %s (expected %s)\n", input, testhost, expected); + } else + printf("ok %d - %s\n", tests, test); + free(testhost); + return; +} + +int +main(void) +{ + + printf("1..5\n"); + + testit(TESTFQDN, -1, TESTHOST, "self"); + testit("XXX" TESTDOMAIN, -1, "XXX", "different host, same domain"); + testit("XXX" TESTDOMAIN, 1, NULL, "short hostsize"); + testit("bogus.example.net", -1, NULL, "arbitrary host"); + testit("XXX." TESTFQDN, -1, NULL, "domain is local hostname"); + + return (0); +} Copied: head/lib/libutil/tests/trimdomain_test.c (from r269562, head/tools/regression/lib/libutil/test-trimdomain.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libutil/tests/trimdomain_test.c Wed Aug 13 04:56:27 2014 (r269904, copy of r269562, head/tools/regression/lib/libutil/test-trimdomain.c) @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2005 Brooks Davis. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/param.h> +#include <errno.h> +#include <libutil.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define TESTDOMAIN ".domain.example.com" +#define TESTHOST "testhost" +#define TESTFQDN "testhost" TESTDOMAIN + +int failures = 0; +int tests = 0; + +/* + * Evily override gethostname(3) so trimdomain always gets the same result. + * This makes the tests much easier to write and less likely to fail on + * oddly configured systems. + */ +int +gethostname(char *name, size_t namelen) +{ + if (strlcpy(name, TESTFQDN, namelen) > namelen) { + errno = ENAMETOOLONG; + return (-1); + } + return (0); +} + +void +testit(const char *input, int hostsize, const char *output, const char *test) +{ + char *testhost; + const char *expected = (output == NULL) ? input : output; + + testhost = strdup(input); + trimdomain(testhost, hostsize < 0 ? (int)strlen(testhost) : hostsize); + tests++; + if (strcmp(testhost, expected) != 0) { + printf("not ok %d - %s\n", tests, test); + printf("# %s -> %s (expected %s)\n", input, testhost, expected); + } else + printf("ok %d - %s\n", tests, test); + free(testhost); + return; +} + +int +main(void) +{ + + printf("1..5\n"); + + testit(TESTFQDN, -1, TESTHOST, "self"); + testit("XXX" TESTDOMAIN, -1, "XXX", "different host, same domain"); + testit("XXX" TESTDOMAIN, 1, NULL, "short hostsize"); + testit("bogus.example.net", -1, NULL, "arbitrary host"); + testit("XXX." TESTFQDN, -1, NULL, "domain is local hostname"); + + return (0); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408130456.s7D4uS9F087555>