From 0bba68feaae2960c1f2b5feb6978a8918f571707 Mon Sep 17 00:00:00 2001 From: Antonio Huete Jimenez Date: Wed, 8 Jul 2015 03:38:27 -0700 Subject: [PATCH] testcases: Attempt to integrate POSIX IPC tests to dfregress(8) - Tests have been split up so they run separately --- test/testcases/posixipc/Makefile | 25 ++ .../posixipc/close_unnamed_semaphore/Makefile | 10 + .../close_unnamed_semaphore.c | 18 + test/testcases/posixipc/common/common.c | 385 ++++++++++++++++++ test/testcases/posixipc/common/common.h | 103 +++++ .../create_excl_existing_sem/Makefile | 10 + .../create_excl_existing_sem.c | 20 + .../create_unnamed_semaphore/Makefile | 10 + .../create_unnamed_semaphore.c | 16 + .../posixipc/destroy_named_semaphore/Makefile | 10 + .../destroy_named_semaphore.c | 19 + test/testcases/posixipc/file_test/Makefile | 10 + test/testcases/posixipc/file_test/file_test.c | 28 ++ .../posixipc/init_bad_value/Makefile | 10 + .../posixipc/init_bad_value/init_bad_value.c | 10 + test/testcases/posixipc/max_value/Makefile | 10 + test/testcases/posixipc/max_value/max_value.c | 32 ++ .../posixipc/open_after_unlink/Makefile | 10 + .../open_after_unlink/open_after_unlink.c | 23 ++ .../posixipc/open_bad_value/Makefile | 10 + .../posixipc/open_bad_value/open_bad_value.c | 12 + .../posixipc/open_extra_flags/Makefile | 10 + .../open_extra_flags/open_extra_flags.c | 10 + .../posixipc/open_invalid_path/Makefile | 10 + .../open_invalid_path/open_invalid_path.c | 10 + .../posixipc/open_named_semaphore/Makefile | 10 + .../open_named_semaphore.c | 23 ++ .../posixipc/open_non_existing/Makefile | 10 + .../open_non_existing/open_non_existing.c | 10 + .../posixipc/open_path_too_long/Makefile | 10 + .../open_path_too_long/open_path_too_long.c | 16 + test/testcases/posixipc/post_test/Makefile | 10 + test/testcases/posixipc/post_test/post_test.c | 29 ++ .../posixipc/timedwait_expired/Makefile | 10 + .../timedwait_expired/timedwait_expired.c | 34 ++ .../posixipc/timedwait_locked/Makefile | 10 + .../timedwait_locked/timedwait_locked.c | 43 ++ .../posixipc/timedwait_unlocked/Makefile | 10 + .../timedwait_unlocked/timedwait_unlocked.c | 34 ++ .../posixipc/trywait_locked/Makefile | 10 + .../posixipc/trywait_locked/trywait_locked.c | 32 ++ .../posixipc/trywait_unlocked/Makefile | 10 + .../trywait_unlocked/trywait_unlocked.c | 28 ++ .../posixipc/unlink_path_too_long/Makefile | 10 + .../unlink_path_too_long.c | 15 + .../posixipc/use_after_unlink/Makefile | 10 + .../use_after_unlink/use_after_unlink.c | 53 +++ test/testcases/posixipc/wait_locked/Makefile | 10 + .../posixipc/wait_locked/wait_locked.c | 39 ++ .../testcases/posixipc/wait_two_proc/Makefile | 10 + .../posixipc/wait_two_proc/wait_two_proc.c | 57 +++ .../testcases/posixipc/wait_unlocked/Makefile | 10 + .../posixipc/wait_unlocked/wait_unlocked.c | 34 ++ test/testcases/sample.run | 27 ++ 54 files changed, 1435 insertions(+) create mode 100644 test/testcases/posixipc/close_unnamed_semaphore/Makefile create mode 100644 test/testcases/posixipc/close_unnamed_semaphore/close_unnamed_semaphore.c create mode 100644 test/testcases/posixipc/common/common.c create mode 100644 test/testcases/posixipc/common/common.h create mode 100644 test/testcases/posixipc/create_excl_existing_sem/Makefile create mode 100644 test/testcases/posixipc/create_excl_existing_sem/create_excl_existing_sem.c create mode 100644 test/testcases/posixipc/create_unnamed_semaphore/Makefile create mode 100644 test/testcases/posixipc/create_unnamed_semaphore/create_unnamed_semaphore.c create mode 100644 test/testcases/posixipc/destroy_named_semaphore/Makefile create mode 100644 test/testcases/posixipc/destroy_named_semaphore/destroy_named_semaphore.c create mode 100644 test/testcases/posixipc/file_test/Makefile create mode 100644 test/testcases/posixipc/file_test/file_test.c create mode 100644 test/testcases/posixipc/init_bad_value/Makefile create mode 100644 test/testcases/posixipc/init_bad_value/init_bad_value.c create mode 100644 test/testcases/posixipc/max_value/Makefile create mode 100644 test/testcases/posixipc/max_value/max_value.c create mode 100644 test/testcases/posixipc/open_after_unlink/Makefile create mode 100644 test/testcases/posixipc/open_after_unlink/open_after_unlink.c create mode 100644 test/testcases/posixipc/open_bad_value/Makefile create mode 100644 test/testcases/posixipc/open_bad_value/open_bad_value.c create mode 100644 test/testcases/posixipc/open_extra_flags/Makefile create mode 100644 test/testcases/posixipc/open_extra_flags/open_extra_flags.c create mode 100644 test/testcases/posixipc/open_invalid_path/Makefile create mode 100644 test/testcases/posixipc/open_invalid_path/open_invalid_path.c create mode 100644 test/testcases/posixipc/open_named_semaphore/Makefile create mode 100644 test/testcases/posixipc/open_named_semaphore/open_named_semaphore.c create mode 100644 test/testcases/posixipc/open_non_existing/Makefile create mode 100644 test/testcases/posixipc/open_non_existing/open_non_existing.c create mode 100644 test/testcases/posixipc/open_path_too_long/Makefile create mode 100644 test/testcases/posixipc/open_path_too_long/open_path_too_long.c create mode 100644 test/testcases/posixipc/post_test/Makefile create mode 100644 test/testcases/posixipc/post_test/post_test.c create mode 100644 test/testcases/posixipc/timedwait_expired/Makefile create mode 100644 test/testcases/posixipc/timedwait_expired/timedwait_expired.c create mode 100644 test/testcases/posixipc/timedwait_locked/Makefile create mode 100644 test/testcases/posixipc/timedwait_locked/timedwait_locked.c create mode 100644 test/testcases/posixipc/timedwait_unlocked/Makefile create mode 100644 test/testcases/posixipc/timedwait_unlocked/timedwait_unlocked.c create mode 100644 test/testcases/posixipc/trywait_locked/Makefile create mode 100644 test/testcases/posixipc/trywait_locked/trywait_locked.c create mode 100644 test/testcases/posixipc/trywait_unlocked/Makefile create mode 100644 test/testcases/posixipc/trywait_unlocked/trywait_unlocked.c create mode 100644 test/testcases/posixipc/unlink_path_too_long/Makefile create mode 100644 test/testcases/posixipc/unlink_path_too_long/unlink_path_too_long.c create mode 100644 test/testcases/posixipc/use_after_unlink/Makefile create mode 100644 test/testcases/posixipc/use_after_unlink/use_after_unlink.c create mode 100644 test/testcases/posixipc/wait_locked/Makefile create mode 100644 test/testcases/posixipc/wait_locked/wait_locked.c create mode 100644 test/testcases/posixipc/wait_two_proc/Makefile create mode 100644 test/testcases/posixipc/wait_two_proc/wait_two_proc.c create mode 100644 test/testcases/posixipc/wait_unlocked/Makefile create mode 100644 test/testcases/posixipc/wait_unlocked/wait_unlocked.c diff --git a/test/testcases/posixipc/Makefile b/test/testcases/posixipc/Makefile index d975781033..8408add2d6 100644 --- a/test/testcases/posixipc/Makefile +++ b/test/testcases/posixipc/Makefile @@ -1,3 +1,28 @@ +SUBDIR+= close_unnamed_semaphore +SUBDIR+= create_excl_existing_sem +SUBDIR+= create_unnamed_semaphore +SUBDIR+= destroy_named_semaphore +SUBDIR+= file_test +SUBDIR+= init_bad_value +SUBDIR+= max_value +SUBDIR+= open_after_unlink +SUBDIR+= open_bad_value +SUBDIR+= open_extra_flags +SUBDIR+= open_invalid_path +SUBDIR+= open_named_semaphore +SUBDIR+= open_non_existing +SUBDIR+= open_path_too_long +SUBDIR+= post_test SUBDIR+= sem +SUBDIR+= timedwait_expired +SUBDIR+= timedwait_locked +SUBDIR+= timedwait_unlocked +SUBDIR+= trywait_locked +SUBDIR+= trywait_unlocked +SUBDIR+= unlink_path_too_long +SUBDIR+= use_after_unlink +SUBDIR+= wait_locked +SUBDIR+= wait_two_proc +SUBDIR+= wait_unlocked .include diff --git a/test/testcases/posixipc/close_unnamed_semaphore/Makefile b/test/testcases/posixipc/close_unnamed_semaphore/Makefile new file mode 100644 index 0000000000..75dd9f9e64 --- /dev/null +++ b/test/testcases/posixipc/close_unnamed_semaphore/Makefile @@ -0,0 +1,10 @@ +PROG= close_unnamed_semaphore +SRCS= close_unnamed_semaphore.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/close_unnamed_semaphore/close_unnamed_semaphore.c b/test/testcases/posixipc/close_unnamed_semaphore/close_unnamed_semaphore.c new file mode 100644 index 0000000000..67f1d19d3c --- /dev/null +++ b/test/testcases/posixipc/close_unnamed_semaphore/close_unnamed_semaphore.c @@ -0,0 +1,18 @@ +#include + +int +main(void) { + int retval = 0; + sem_t id; + + if (sem_init(&id, 0, 1) < 0) { + perror("sem_init"); + return 1; + } + + retval = sem_close_should_fail(&id, EINVAL); + + sem_destroy(&id); + + return retval; +} diff --git a/test/testcases/posixipc/common/common.c b/test/testcases/posixipc/common/common.c new file mode 100644 index 0000000000..fc97e6bf6a --- /dev/null +++ b/test/testcases/posixipc/common/common.c @@ -0,0 +1,385 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* + * Use a timer to post a specific semaphore after a timeout. A timer + * is scheduled via schedule_post(). check_alarm() must be called + * afterwards to clean up and check for errors. + */ +sem_t *alarm_id = SEM_FAILED; +int alarm_errno; +int alarm_handler_installed; + +int +checkvalue(sem_t *id, int expected) +{ + int val; + + if (sem_getvalue(id, &val) < 0) { + perror("sem_getvalue"); + return (-1); + } + if (val != expected) { + fprintf(stderr, "sem value should be %d instead of %d", + expected, val); + return (-1); + } + return (0); +} + +sem_t * +construct_shared_unnamed_sem(unsigned int count) +{ + sem_t *id = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_ANON, -1, 0); + if (id == MAP_FAILED) { + perror("mmap"); + return SEM_FAILED; + } + + if (sem_init(id, 1, count) < 0) { + perror("sem_init"); + munmap(id, sizeof(sem_t)); + return SEM_FAILED; + } + + return id; +} + +void +destruct_shared_unnamed_sem(sem_t *id) +{ + if (sem_destroy(id) < 0) + perror("sem_destroy"); + + if (munmap(id, sizeof(sem_t)) < 0) + perror("munmap"); +} + +int +testwait(sem_t *id, u_int *delta) +{ + struct timespec start, end; + + if (clock_gettime(CLOCK_REALTIME, &start) < 0) { + perror("clock_gettime(CLOCK_REALTIME)"); + return (-1); + } + if (sem_wait(id) < 0) { + perror("sem_wait"); + return (-1); + } + if (clock_gettime(CLOCK_REALTIME, &end) < 0) { + perror("clock_gettime(CLOCK_REALTIME)"); + return (-1); + } + timespecsub(&end, &start); + *delta = end.tv_nsec / 1000000; + *delta += end.tv_sec * 1000; + return (0); +} + +static void +alarm_handler(int signo) +{ + + if (sem_post(alarm_id) < 0) + alarm_errno = errno; +} + +int +schedule_post(sem_t *id, u_int msec) +{ + struct itimerval it; + + if (!alarm_handler_installed) { + if (signal(SIGALRM, alarm_handler) == SIG_ERR) { + perror("signal(SIGALRM)"); + return (-1); + } + alarm_handler_installed = 1; + } + if (alarm_id != SEM_FAILED) { + fprintf(stderr, "sem_post() already scheduled"); + return (-1); + } + alarm_id = id; + bzero(&it, sizeof(it)); + it.it_value.tv_sec = msec / 1000; + it.it_value.tv_usec = (msec % 1000) * 1000; + if (setitimer(ITIMER_REAL, &it, NULL) < 0) { + perror("setitimer"); + return (-1); + } + return (0); +} + +int +check_alarm(int just_clear) +{ + struct itimerval it; + + bzero(&it, sizeof(it)); + if (just_clear) { + setitimer(ITIMER_REAL, &it, NULL); + alarm_errno = 0; + alarm_id = SEM_FAILED; + return (0); + } + if (setitimer(ITIMER_REAL, &it, NULL) < 0) { + perror("setitimer"); + return (-1); + } + if (alarm_errno != 0 && !just_clear) { + errno = alarm_errno; + perror("sem_post() (via timeout)"); + alarm_errno = 0; + return (-1); + } + alarm_id = SEM_FAILED; + + return (0); +} + +/* + * Helper routine for tests that use a child process. This routine + * creates a pipe and forks a child process. The child process runs + * the 'func' routine which returns a status integer. The status + * integer gets written over the pipe to the parent and returned in + * '*stat'. If there is an error in pipe(), fork(), or wait() this + * returns -1 and fails the test. + */ +int +child_worker(int (*func)(void *arg), void *arg, int *stat) +{ + pid_t pid; + int pfd[2], cstat; + + if (pipe(pfd) < 0) { + perror("pipe"); + return (-1); + } + + pid = fork(); + switch (pid) { + case -1: + /* Error. */ + perror("fork"); + close(pfd[0]); + close(pfd[1]); + return (-1); + case 0: + /* Child. */ + cstat = func(arg); + write(pfd[1], &cstat, sizeof(cstat)); + exit(0); + } + + if (read(pfd[0], stat, sizeof(*stat)) < 0) { + perror("read(pipe)"); + close(pfd[0]); + close(pfd[1]); + return (-1); + } + if (waitpid(pid, NULL, 0) < 0) { + perror("wait"); + close(pfd[0]); + close(pfd[1]); + return (-1); + } + close(pfd[0]); + close(pfd[1]); + return (0); +} + +/* + * Fork off a child process. The child will open the semaphore via + * the same name. The child will then block on the semaphore waiting + * for the parent to post it. + */ +int +wait_twoproc_child(void *arg) +{ + sem_t *id; + + id = sem_open(TEST_PATH, 0, 0, 0); + if (id == SEM_FAILED) + return (CSTAT(1, errno)); + if (sem_wait(id) < 0) + return (CSTAT(2, errno)); + if (sem_close(id) < 0) + return (CSTAT(3, errno)); + return (CSTAT(0, 0)); +} + +int +timedwait(sem_t *id, u_int msec, u_int *delta, int error) +{ + struct timespec start, end; + + if (clock_gettime(CLOCK_REALTIME, &start) < 0) { + perror("clock_gettime(CLOCK_REALTIME)"); + return (-1); + } + end.tv_sec = msec / 1000; + end.tv_nsec = msec % 1000 * 1000000; + timespecadd(&end, &start); + if (sem_timedwait(id, &end) < 0) { + if (errno != error) { + perror("sem_timedwait"); + return (-1); + } + } else if (error != 0) { + return (-1); + } + if (clock_gettime(CLOCK_REALTIME, &end) < 0) { + perror("clock_gettime(CLOCK_REALTIME)"); + return (-1); + } + timespecsub(&end, &start); + *delta = end.tv_nsec / 1000000; + *delta += end.tv_sec * 1000; + return (0); +} + +/* + * Attempt a sem_open() that should fail with an expected error of + * 'error'. + */ +int +sem_open_should_fail(const char *path, int flags, mode_t mode, + unsigned int value, int error) +{ + int retval = 0; + sem_t *id; + + id = sem_open(path, flags, mode, value); + if (id != SEM_FAILED) { + sem_close(id); + retval = 1; + } + if (errno != error) { + fprintf(stderr, "sem_open: %s\n", strerror(errno)); + retval = 1; + } + return retval; +} + +/* + * Attempt a sem_init() that should fail with an expected error of + * 'error'. + */ +int +sem_init_should_fail(unsigned int value, int error) +{ + sem_t id; + + if (sem_init(&id, 0, value) >= 0) { + sem_destroy(&id); + return 1; + } + if (errno != error) { + perror("sem_init"); + return 1; + } + + return 0; +} + +/* + * Attempt a sem_unlink() that should fail with an expected error of + * 'error'. + */ +int +sem_unlink_should_fail(const char *path, int error) +{ + + if (sem_unlink(path) >= 0) { + return 1; + } + if (errno != error) { + perror("sem_unlink"); + return 1; + } + return 0; +} + +/* + * Attempt a sem_destroy() that should fail with an expected error of + * 'error'. + */ +int +sem_destroy_should_fail(sem_t *id, int error) +{ + if (sem_destroy(id) >= 0) { + return 1; + } + if (errno != error) { + perror("sem_destroy"); + return 1; + } + return 0; +} + +/* + * Attempt a sem_close() that should fail with an expected error of + * 'error'. + */ +int +sem_close_should_fail(sem_t *id, int error) +{ + + if (sem_close(id) >= 0) { + return 1; + } + if (errno != error) { + perror("sem_close"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/common/common.h b/test/testcases/posixipc/common/common.h new file mode 100644 index 0000000000..e5c3d37c39 --- /dev/null +++ b/test/testcases/posixipc/common/common.h @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define ELAPSED(elapsed, limit) (abs((elapsed) - (limit)) < 100) + +#define TEST_PATH "/posixsem_regression_test" + +extern sem_t *alarm_id; +extern int alarm_errno; +extern int alarm_handler_installed; + +/* Cut and pasted from kernel header, bah! */ + +/* Operations on timespecs */ +#define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0) +#define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) +#define timespeccmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#define timespecadd(vvp, uvp) \ + do { \ + (vvp)->tv_sec += (uvp)->tv_sec; \ + (vvp)->tv_nsec += (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec >= 1000000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_nsec -= 1000000000; \ + } \ + } while (0) +#define timespecsub(vvp, uvp) \ + do { \ + (vvp)->tv_sec -= (uvp)->tv_sec; \ + (vvp)->tv_nsec -= (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_nsec += 1000000000; \ + } \ + } while (0) + + +/* Macros for passing child status to parent over a pipe. */ +#define CSTAT(class, error) ((class) << 16 | (error)) +#define CSTAT_CLASS(stat) ((stat) >> 16) +#define CSTAT_ERROR(stat) ((stat) & 0xffff) + +int checkvalue(sem_t *, int); +sem_t *construct_shared_unnamed_sem(unsigned int); +void destruct_shared_unnamed_sem(sem_t *); +int testwait(sem_t *, u_int *); +int timedwait(sem_t *, u_int, u_int *, int); +int schedule_post(sem_t *, u_int); +int check_alarm(int); +int child_worker(int (*)(void *), void *, int *); +int wait_twoproc_child(void *); +int sem_open_should_fail(const char *, int, mode_t, unsigned int, int); +int sem_init_should_fail(unsigned int, int); +int sem_unlink_should_fail(const char *, int); +int sem_destroy_should_fail(sem_t *, int); +int sem_close_should_fail(sem_t *, int); + +#endif diff --git a/test/testcases/posixipc/create_excl_existing_sem/Makefile b/test/testcases/posixipc/create_excl_existing_sem/Makefile new file mode 100644 index 0000000000..ebe9e173d0 --- /dev/null +++ b/test/testcases/posixipc/create_excl_existing_sem/Makefile @@ -0,0 +1,10 @@ +PROG= create_excl_existing_sem +SRCS= create_excl_existing_sem.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/create_excl_existing_sem/create_excl_existing_sem.c b/test/testcases/posixipc/create_excl_existing_sem/create_excl_existing_sem.c new file mode 100644 index 0000000000..2fb69e512c --- /dev/null +++ b/test/testcases/posixipc/create_excl_existing_sem/create_excl_existing_sem.c @@ -0,0 +1,20 @@ +#include + +int +main(void) { + int retval = 0; + sem_t *id; + + id = sem_open(TEST_PATH, O_CREAT, 0777, 1); + if (id == SEM_FAILED) { + perror("sem_open(O_CREAT)"); + return 1; + } + sem_close(id); + + retval = sem_open_should_fail(TEST_PATH, O_CREAT | O_EXCL, 0777, 1, EEXIST); + + sem_unlink(TEST_PATH); + + return retval; +} diff --git a/test/testcases/posixipc/create_unnamed_semaphore/Makefile b/test/testcases/posixipc/create_unnamed_semaphore/Makefile new file mode 100644 index 0000000000..85564b974b --- /dev/null +++ b/test/testcases/posixipc/create_unnamed_semaphore/Makefile @@ -0,0 +1,10 @@ +PROG= create_unnamed_semaphore +SRCS= create_unnamed_semaphore.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/create_unnamed_semaphore/create_unnamed_semaphore.c b/test/testcases/posixipc/create_unnamed_semaphore/create_unnamed_semaphore.c new file mode 100644 index 0000000000..a666dacfab --- /dev/null +++ b/test/testcases/posixipc/create_unnamed_semaphore/create_unnamed_semaphore.c @@ -0,0 +1,16 @@ +#include + +int +main(void) { + sem_t id; + + if (sem_init(&id, 0, 1) < 0) { + return 1; + } + + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/destroy_named_semaphore/Makefile b/test/testcases/posixipc/destroy_named_semaphore/Makefile new file mode 100644 index 0000000000..c814181960 --- /dev/null +++ b/test/testcases/posixipc/destroy_named_semaphore/Makefile @@ -0,0 +1,10 @@ +PROG= destroy_named_semaphore +SRCS= destroy_named_semaphore.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/destroy_named_semaphore/destroy_named_semaphore.c b/test/testcases/posixipc/destroy_named_semaphore/destroy_named_semaphore.c new file mode 100644 index 0000000000..7fe320ab83 --- /dev/null +++ b/test/testcases/posixipc/destroy_named_semaphore/destroy_named_semaphore.c @@ -0,0 +1,19 @@ +#include + +int +main(void) { + int retval = 0; + sem_t *id; + + id = sem_open(TEST_PATH, O_CREAT, 0777, 1); + if (id == SEM_FAILED) { + return 1; + } + + retval = sem_destroy_should_fail(id, EINVAL); + + sem_close(id); + sem_unlink(TEST_PATH); + + return retval; +} diff --git a/test/testcases/posixipc/file_test/Makefile b/test/testcases/posixipc/file_test/Makefile new file mode 100644 index 0000000000..5c267766c9 --- /dev/null +++ b/test/testcases/posixipc/file_test/Makefile @@ -0,0 +1,10 @@ +PROG= file_test +SRCS= file_test.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/file_test/file_test.c b/test/testcases/posixipc/file_test/file_test.c new file mode 100644 index 0000000000..98e63c2d48 --- /dev/null +++ b/test/testcases/posixipc/file_test/file_test.c @@ -0,0 +1,28 @@ +#include + +int +main(void) { + struct stat sb; + sem_t *id; + int error; + + id = sem_open(TEST_PATH, O_CREAT, 0777, 0); + if (id == SEM_FAILED) { + perror("sem_open"); + return 1; + } + + error = stat("/var/run/sem", &sb); + if (error) { + perror("stat"); + return 1; + } + if ((sb.st_mode & ALLPERMS) != (S_IRWXU|S_IRWXG|S_IRWXO|S_ISTXT)) { + fprintf(stderr, "semaphore dir has incorrect mode: 0%o\n", + (sb.st_mode & ALLPERMS)); + return 1; + } + + sem_close(id); + return 0; +} diff --git a/test/testcases/posixipc/init_bad_value/Makefile b/test/testcases/posixipc/init_bad_value/Makefile new file mode 100644 index 0000000000..23017ad6b8 --- /dev/null +++ b/test/testcases/posixipc/init_bad_value/Makefile @@ -0,0 +1,10 @@ +PROG= init_bad_value +SRCS= init_bad_value.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/init_bad_value/init_bad_value.c b/test/testcases/posixipc/init_bad_value/init_bad_value.c new file mode 100644 index 0000000000..ea82e5d65c --- /dev/null +++ b/test/testcases/posixipc/init_bad_value/init_bad_value.c @@ -0,0 +1,10 @@ +#include + +int +main(void) { + int retval = 0; + + retval = sem_init_should_fail(SEM_VALUE_MAX+1U, EINVAL); + + return retval; +} diff --git a/test/testcases/posixipc/max_value/Makefile b/test/testcases/posixipc/max_value/Makefile new file mode 100644 index 0000000000..b65e6e0ec4 --- /dev/null +++ b/test/testcases/posixipc/max_value/Makefile @@ -0,0 +1,10 @@ +PROG= max_value +SRCS= max_value.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/max_value/max_value.c b/test/testcases/posixipc/max_value/max_value.c new file mode 100644 index 0000000000..a94a4d143f --- /dev/null +++ b/test/testcases/posixipc/max_value/max_value.c @@ -0,0 +1,32 @@ +#include + +int +main(void) { + sem_t id; + int val; + + if (sem_init(&id, 0, SEM_VALUE_MAX) < 0) { + perror("sem_init"); + return 1; + } + if (sem_getvalue(&id, &val) < 0) { + perror("sem_getvalue"); + sem_destroy(&id); + return 1; + } + if (val != SEM_VALUE_MAX) { + fprintf(stderr, "value %d != SEM_VALUE_MAX", val); + sem_destroy(&id); + return 1; + } + if (val < 0) { + fprintf(stderr, "value < 0"); + sem_destroy(&id); + return 1; + } + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/open_after_unlink/Makefile b/test/testcases/posixipc/open_after_unlink/Makefile new file mode 100644 index 0000000000..78e999da3a --- /dev/null +++ b/test/testcases/posixipc/open_after_unlink/Makefile @@ -0,0 +1,10 @@ +PROG= open_after_unlink +SRCS= open_after_unlink.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/open_after_unlink/open_after_unlink.c b/test/testcases/posixipc/open_after_unlink/open_after_unlink.c new file mode 100644 index 0000000000..3352b2ac02 --- /dev/null +++ b/test/testcases/posixipc/open_after_unlink/open_after_unlink.c @@ -0,0 +1,23 @@ +#include + +int +main(void) { + int retval = 0; + sem_t *id; + + id = sem_open(TEST_PATH, O_CREAT, 0777, 1); + if (id == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(id); + + if (sem_unlink(TEST_PATH) < 0) { + perror("sem_unlink"); + return 1; + } + + retval = sem_open_should_fail(TEST_PATH, O_RDONLY, 0777, 1, ENOENT); + + return retval; +} diff --git a/test/testcases/posixipc/open_bad_value/Makefile b/test/testcases/posixipc/open_bad_value/Makefile new file mode 100644 index 0000000000..2ee9b946fd --- /dev/null +++ b/test/testcases/posixipc/open_bad_value/Makefile @@ -0,0 +1,10 @@ +PROG= open_bad_value +SRCS= open_bad_value.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/open_bad_value/open_bad_value.c b/test/testcases/posixipc/open_bad_value/open_bad_value.c new file mode 100644 index 0000000000..a683516bef --- /dev/null +++ b/test/testcases/posixipc/open_bad_value/open_bad_value.c @@ -0,0 +1,12 @@ +#include + +int +main(void) { + int retval = 0; + + (void)sem_unlink(TEST_PATH); + retval = sem_open_should_fail(TEST_PATH, O_CREAT, 0777, + SEM_VALUE_MAX+1U, EINVAL); + + return retval; +} diff --git a/test/testcases/posixipc/open_extra_flags/Makefile b/test/testcases/posixipc/open_extra_flags/Makefile new file mode 100644 index 0000000000..2693d22080 --- /dev/null +++ b/test/testcases/posixipc/open_extra_flags/Makefile @@ -0,0 +1,10 @@ +PROG= open_extra_flags +SRCS= open_extra_flags.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/open_extra_flags/open_extra_flags.c b/test/testcases/posixipc/open_extra_flags/open_extra_flags.c new file mode 100644 index 0000000000..4cfe48bd62 --- /dev/null +++ b/test/testcases/posixipc/open_extra_flags/open_extra_flags.c @@ -0,0 +1,10 @@ +#include + +int +main(void) { + int retval = 0; + + retval = sem_open_should_fail(TEST_PATH, O_RDONLY | O_DIRECT, 0777, 1, EINVAL); + + return retval; +} diff --git a/test/testcases/posixipc/open_invalid_path/Makefile b/test/testcases/posixipc/open_invalid_path/Makefile new file mode 100644 index 0000000000..497e4df458 --- /dev/null +++ b/test/testcases/posixipc/open_invalid_path/Makefile @@ -0,0 +1,10 @@ +PROG= open_invalid_path +SRCS= open_invalid_path.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/open_invalid_path/open_invalid_path.c b/test/testcases/posixipc/open_invalid_path/open_invalid_path.c new file mode 100644 index 0000000000..48dadecca2 --- /dev/null +++ b/test/testcases/posixipc/open_invalid_path/open_invalid_path.c @@ -0,0 +1,10 @@ +#include + +int +main(void) { + int retval = 0; + + retval = sem_open_should_fail("blah", 0, 0777, 1, ENOENT); + + return retval; +} diff --git a/test/testcases/posixipc/open_named_semaphore/Makefile b/test/testcases/posixipc/open_named_semaphore/Makefile new file mode 100644 index 0000000000..ef11f8d3d8 --- /dev/null +++ b/test/testcases/posixipc/open_named_semaphore/Makefile @@ -0,0 +1,10 @@ +PROG= open_named_semaphore +SRCS= open_named_semaphore.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/open_named_semaphore/open_named_semaphore.c b/test/testcases/posixipc/open_named_semaphore/open_named_semaphore.c new file mode 100644 index 0000000000..8932e073b7 --- /dev/null +++ b/test/testcases/posixipc/open_named_semaphore/open_named_semaphore.c @@ -0,0 +1,23 @@ +#include + +int +main(void) { + sem_t *id; + + id = sem_open(TEST_PATH, O_CREAT, 0777, 1); + if (id == SEM_FAILED) { + perror("sem_open(O_CREAT)"); + return 1; + } + + if (sem_close(id) < 0) { + perror("sem_close"); + return 1; + } + + if (sem_unlink(TEST_PATH) < 0) { + perror("sem_unlink"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/open_non_existing/Makefile b/test/testcases/posixipc/open_non_existing/Makefile new file mode 100644 index 0000000000..4d55b20b17 --- /dev/null +++ b/test/testcases/posixipc/open_non_existing/Makefile @@ -0,0 +1,10 @@ +PROG= open_non_existing +SRCS= open_non_existing.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/open_non_existing/open_non_existing.c b/test/testcases/posixipc/open_non_existing/open_non_existing.c new file mode 100644 index 0000000000..3e5af6a082 --- /dev/null +++ b/test/testcases/posixipc/open_non_existing/open_non_existing.c @@ -0,0 +1,10 @@ +#include + +int +main(void) { + int retval = 0; + + sem_open_should_fail("/notreallythere", 0, 0777, 1, ENOENT); + + return retval; +} diff --git a/test/testcases/posixipc/open_path_too_long/Makefile b/test/testcases/posixipc/open_path_too_long/Makefile new file mode 100644 index 0000000000..1f3feda801 --- /dev/null +++ b/test/testcases/posixipc/open_path_too_long/Makefile @@ -0,0 +1,10 @@ +PROG= open_path_too_long +SRCS= open_path_too_long.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/open_path_too_long/open_path_too_long.c b/test/testcases/posixipc/open_path_too_long/open_path_too_long.c new file mode 100644 index 0000000000..0dc3f8a273 --- /dev/null +++ b/test/testcases/posixipc/open_path_too_long/open_path_too_long.c @@ -0,0 +1,16 @@ +#include + +int +main(void) { + int retval = 0; + char *page; + + page = malloc(MAXPATHLEN + 1); + memset(page, 'a', MAXPATHLEN); + page[0] = '/'; + page[MAXPATHLEN] = '\0'; + sem_open_should_fail(page, O_RDONLY, 0777, 1, ENAMETOOLONG); + free(page); + + return retval; +} diff --git a/test/testcases/posixipc/post_test/Makefile b/test/testcases/posixipc/post_test/Makefile new file mode 100644 index 0000000000..335ae665c2 --- /dev/null +++ b/test/testcases/posixipc/post_test/Makefile @@ -0,0 +1,10 @@ +PROG= post_test +SRCS= post_test.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/post_test/post_test.c b/test/testcases/posixipc/post_test/post_test.c new file mode 100644 index 0000000000..af40b78bf5 --- /dev/null +++ b/test/testcases/posixipc/post_test/post_test.c @@ -0,0 +1,29 @@ +#include + +int +main(void) { + sem_t id; + + if (sem_init(&id, 0, 1) < 0) { + perror("sem_init"); + return 1; + } + if (checkvalue(&id, 1) < 0) { + sem_destroy(&id); + return 1; + } + if (sem_post(&id) < 0) { + perror("sem_post"); + sem_destroy(&id); + return 1; + } + if (checkvalue(&id, 2) < 0) { + sem_destroy(&id); + return 1; + } + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/timedwait_expired/Makefile b/test/testcases/posixipc/timedwait_expired/Makefile new file mode 100644 index 0000000000..5966d33128 --- /dev/null +++ b/test/testcases/posixipc/timedwait_expired/Makefile @@ -0,0 +1,10 @@ +PROG= timedwait_expired +SRCS= timedwait_expired.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/timedwait_expired/timedwait_expired.c b/test/testcases/posixipc/timedwait_expired/timedwait_expired.c new file mode 100644 index 0000000000..1a5b9683fe --- /dev/null +++ b/test/testcases/posixipc/timedwait_expired/timedwait_expired.c @@ -0,0 +1,34 @@ +#include + +int +main(void) { + sem_t id; + u_int elapsed; + + if (sem_init(&id, 0, 0) < 0) { + perror("sem_init"); + return 1; + } + + /* This should fail with a timeout and leave the value at 0. */ + if (timedwait(&id, 2500, &elapsed, ETIMEDOUT) < 0) { + sem_destroy(&id); + return 1; + } + if (!ELAPSED(elapsed, 2500)) { + fprintf(stderr, "sem_timedwait() of locked sem took %ums " + "instead of 2500ms", elapsed); + sem_destroy(&id); + return 1; + } + if (checkvalue(&id, 0) < 0) { + sem_destroy(&id); + return 1; + } + + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/timedwait_locked/Makefile b/test/testcases/posixipc/timedwait_locked/Makefile new file mode 100644 index 0000000000..40399e49ef --- /dev/null +++ b/test/testcases/posixipc/timedwait_locked/Makefile @@ -0,0 +1,10 @@ +PROG= timedwait_locked +SRCS= timedwait_locked.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/timedwait_locked/timedwait_locked.c b/test/testcases/posixipc/timedwait_locked/timedwait_locked.c new file mode 100644 index 0000000000..a3ea5e7892 --- /dev/null +++ b/test/testcases/posixipc/timedwait_locked/timedwait_locked.c @@ -0,0 +1,43 @@ +#include + +int +main(void) { + sem_t *id; + u_int elapsed; + pid_t pid; + + id = construct_shared_unnamed_sem(0); + if (id == SEM_FAILED) { + fprintf(stderr, "construct sem\n"); + return 1; + } + + pid = fork(); + switch (pid) { + case -1: + /* Error. */ + perror("fork"); + destruct_shared_unnamed_sem(id); + return 1; + case 0: + /* Child. */ + sleep(1); + sem_post(id); + exit(0); + } + + if (timedwait(id, 2000, &elapsed, 0) < 0) { + destruct_shared_unnamed_sem(id); + return 1; + } + if (!ELAPSED(elapsed, 1000)) { + fprintf(stderr, "sem_timedwait() with delayed post took %ums " + "instead of 1000ms", elapsed); + destruct_shared_unnamed_sem(id); + return 1; + } + + destruct_shared_unnamed_sem(id); + + return 0; +} diff --git a/test/testcases/posixipc/timedwait_unlocked/Makefile b/test/testcases/posixipc/timedwait_unlocked/Makefile new file mode 100644 index 0000000000..74d3b4a895 --- /dev/null +++ b/test/testcases/posixipc/timedwait_unlocked/Makefile @@ -0,0 +1,10 @@ +PROG= timedwait_unlocked +SRCS= timedwait_unlocked.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/timedwait_unlocked/timedwait_unlocked.c b/test/testcases/posixipc/timedwait_unlocked/timedwait_unlocked.c new file mode 100644 index 0000000000..ea294954d8 --- /dev/null +++ b/test/testcases/posixipc/timedwait_unlocked/timedwait_unlocked.c @@ -0,0 +1,34 @@ +#include + +int +main(void) { + sem_t id; + u_int elapsed; + + if (sem_init(&id, 0, 1) < 0) { + perror("sem_init"); + return 1; + } + + /* This should succeed right away and set the value to 0. */ + if (timedwait(&id, 5000, &elapsed, 0) < 0) { + sem_destroy(&id); + return 1; + } + if (!ELAPSED(elapsed, 0)) { + fprintf(stderr, "sem_timedwait() of unlocked sem took %ums", + elapsed); + sem_destroy(&id); + return 1; + } + if (checkvalue(&id, 0) < 0) { + sem_destroy(&id); + return 1; + } + + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/trywait_locked/Makefile b/test/testcases/posixipc/trywait_locked/Makefile new file mode 100644 index 0000000000..a978c2aef1 --- /dev/null +++ b/test/testcases/posixipc/trywait_locked/Makefile @@ -0,0 +1,10 @@ +PROG= trywait_locked +SRCS= trywait_locked.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/trywait_locked/trywait_locked.c b/test/testcases/posixipc/trywait_locked/trywait_locked.c new file mode 100644 index 0000000000..a5c4f6ef62 --- /dev/null +++ b/test/testcases/posixipc/trywait_locked/trywait_locked.c @@ -0,0 +1,32 @@ +#include + +int +main(void) { + sem_t id; + + if (sem_init(&id, 0, 0) < 0) { + perror("sem_init"); + return 1; + } + + /* This should fail with EAGAIN and leave the value at 0. */ + if (sem_trywait(&id) >= 0) { + sem_destroy(&id); + return 1; + } + if (errno != EAGAIN) { + perror("wrong error from sem_trywait()"); + sem_destroy(&id); + return 1; + } + if (checkvalue(&id, 0) < 0) { + sem_destroy(&id); + return 1; + } + + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/trywait_unlocked/Makefile b/test/testcases/posixipc/trywait_unlocked/Makefile new file mode 100644 index 0000000000..1481133465 --- /dev/null +++ b/test/testcases/posixipc/trywait_unlocked/Makefile @@ -0,0 +1,10 @@ +PROG= trywait_unlocked +SRCS= trywait_unlocked.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/trywait_unlocked/trywait_unlocked.c b/test/testcases/posixipc/trywait_unlocked/trywait_unlocked.c new file mode 100644 index 0000000000..9c71dd64fd --- /dev/null +++ b/test/testcases/posixipc/trywait_unlocked/trywait_unlocked.c @@ -0,0 +1,28 @@ +#include + +int +main(void) { + sem_t id; + + if (sem_init(&id, 0, 1) < 0) { + perror("sem_init"); + return 1; + } + + /* This should succeed and decrement the value to 0. */ + if (sem_trywait(&id) < 0) { + perror("sem_trywait()"); + sem_destroy(&id); + return 1; + } + if (checkvalue(&id, 0) < 0) { + sem_destroy(&id); + return 1; + } + + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/unlink_path_too_long/Makefile b/test/testcases/posixipc/unlink_path_too_long/Makefile new file mode 100644 index 0000000000..a9500db41a --- /dev/null +++ b/test/testcases/posixipc/unlink_path_too_long/Makefile @@ -0,0 +1,10 @@ +PROG= unlink_path_too_long +SRCS= unlink_path_too_long.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/unlink_path_too_long/unlink_path_too_long.c b/test/testcases/posixipc/unlink_path_too_long/unlink_path_too_long.c new file mode 100644 index 0000000000..cfac61fabe --- /dev/null +++ b/test/testcases/posixipc/unlink_path_too_long/unlink_path_too_long.c @@ -0,0 +1,15 @@ +#include + +int +main(void) { + int retval = 0; + char *page; + + page = malloc(MAXPATHLEN + 1); + memset(page, 'a', MAXPATHLEN); + page[MAXPATHLEN] = '\0'; + retval = sem_unlink_should_fail(page, ENAMETOOLONG); + free(page); + + return retval; +} diff --git a/test/testcases/posixipc/use_after_unlink/Makefile b/test/testcases/posixipc/use_after_unlink/Makefile new file mode 100644 index 0000000000..7422e8c111 --- /dev/null +++ b/test/testcases/posixipc/use_after_unlink/Makefile @@ -0,0 +1,10 @@ +PROG= use_after_unlink +SRCS= use_after_unlink.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/use_after_unlink/use_after_unlink.c b/test/testcases/posixipc/use_after_unlink/use_after_unlink.c new file mode 100644 index 0000000000..1152d204d8 --- /dev/null +++ b/test/testcases/posixipc/use_after_unlink/use_after_unlink.c @@ -0,0 +1,53 @@ +#include + +int +main(void) { + sem_t *id; + + /* + * Create named semaphore with value of 1 and then unlink it + * while still retaining the initial reference. + */ + id = sem_open(TEST_PATH, O_CREAT | O_EXCL, 0777, 1); + if (id == SEM_FAILED) { + perror("sem_open(O_CREAT | O_EXCL)"); + return 1; + } + if (sem_unlink(TEST_PATH) < 0) { + perror("sem_unlink"); + sem_close(id); + return 1; + } + if (checkvalue(id, 1) < 0) { + sem_close(id); + return 1; + } + + /* Post the semaphore to set its value to 2. */ + if (sem_post(id) < 0) { + perror("sem_post"); + sem_close(id); + return 1; + } + if (checkvalue(id, 2) < 0) { + sem_close(id); + return 1; + } + + /* Wait on the semaphore which should set its value to 1. */ + if (sem_wait(id) < 0) { + perror("sem_wait"); + sem_close(id); + return 1; + } + if (checkvalue(id, 1) < 0) { + sem_close(id); + return 1; + } + + if (sem_close(id) < 0) { + perror("sem_close"); + return 1; + } + return 0; +} diff --git a/test/testcases/posixipc/wait_locked/Makefile b/test/testcases/posixipc/wait_locked/Makefile new file mode 100644 index 0000000000..88c7b90308 --- /dev/null +++ b/test/testcases/posixipc/wait_locked/Makefile @@ -0,0 +1,10 @@ +PROG= wait_locked +SRCS= wait_locked.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/wait_locked/wait_locked.c b/test/testcases/posixipc/wait_locked/wait_locked.c new file mode 100644 index 0000000000..46239ce409 --- /dev/null +++ b/test/testcases/posixipc/wait_locked/wait_locked.c @@ -0,0 +1,39 @@ +#include + +int +main(void) { + sem_t *id; + u_int elapsed; + pid_t pid; + + id = construct_shared_unnamed_sem(0); + + pid = fork(); + switch (pid) { + case -1: + /* Error. */ + perror("fork"); + destruct_shared_unnamed_sem(id); + return 1; + case 0: + /* Child. */ + sleep(1); + sem_post(id); + exit(0); + } + + if (testwait(id, &elapsed) < 0) { + destruct_shared_unnamed_sem(id); + return 1; + } + if (!ELAPSED(elapsed, 1000)) { + fprintf(stderr, "sem_wait() with delayed post took %ums " + "instead of 1000ms", elapsed); + destruct_shared_unnamed_sem(id); + return 1; + } + + destruct_shared_unnamed_sem(id); + + return 0; +} diff --git a/test/testcases/posixipc/wait_two_proc/Makefile b/test/testcases/posixipc/wait_two_proc/Makefile new file mode 100644 index 0000000000..3f9546a2f8 --- /dev/null +++ b/test/testcases/posixipc/wait_two_proc/Makefile @@ -0,0 +1,10 @@ +PROG= wait_two_proc +SRCS= wait_two_proc.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/wait_two_proc/wait_two_proc.c b/test/testcases/posixipc/wait_two_proc/wait_two_proc.c new file mode 100644 index 0000000000..c0bb1919ad --- /dev/null +++ b/test/testcases/posixipc/wait_two_proc/wait_two_proc.c @@ -0,0 +1,57 @@ +#include + +int +main(void) { + sem_t *id; + int retval = 0; + int stat; + + id = sem_open(TEST_PATH, O_CREAT, 0777, 0); + if (id == SEM_FAILED) { + perror("sem_open"); + return 1; + } + + if (schedule_post(id, 500) < 0) { + sem_close(id); + sem_unlink(TEST_PATH); + return 1; + } + + if (child_worker(wait_twoproc_child, NULL, &stat) < 0) { + check_alarm(1); + sem_close(id); + sem_unlink(TEST_PATH); + return 1; + } + + errno = CSTAT_ERROR(stat); + switch (CSTAT_CLASS(stat)) { + case 0: + /* Pass! */ + retval = 0; + break; + case 1: + perror("child sem_open()"); + retval = 1; + break; + case 2: + perror("child sem_wait()"); + retval = 1; + break; + case 3: + perror("child sem_close()"); + retval = 1; + break; + default: + fprintf(stderr, "bad child state %#x", stat); + retval = 1; + break; + } + + check_alarm(1); + sem_close(id); + sem_unlink(TEST_PATH); + + return retval; +} diff --git a/test/testcases/posixipc/wait_unlocked/Makefile b/test/testcases/posixipc/wait_unlocked/Makefile new file mode 100644 index 0000000000..efe91208b7 --- /dev/null +++ b/test/testcases/posixipc/wait_unlocked/Makefile @@ -0,0 +1,10 @@ +PROG= wait_unlocked +SRCS= wait_unlocked.c common.c +NO_MAN= +LDADD= -lpthread + +CFLAGS= -I ${.CURDIR}/../common +WARNS?= 3 + +.include +.PATH: ${.CURDIR}/../common diff --git a/test/testcases/posixipc/wait_unlocked/wait_unlocked.c b/test/testcases/posixipc/wait_unlocked/wait_unlocked.c new file mode 100644 index 0000000000..fe844ed572 --- /dev/null +++ b/test/testcases/posixipc/wait_unlocked/wait_unlocked.c @@ -0,0 +1,34 @@ +#include + +int +main(void) { + sem_t id; + u_int elapsed; + + if (sem_init(&id, 0, 1) < 0) { + perror("sem_init"); + return 1; + } + + /* This should succeed right away and set the value to 0. */ + if (testwait(&id, &elapsed) < 0) { + sem_destroy(&id); + return 1; + } + if (!ELAPSED(elapsed, 0)) { + fprintf(stderr, "sem_wait() of unlocked sem took %ums", + elapsed); + sem_destroy(&id); + return 1; + } + if (checkvalue(&id, 0) < 0) { + sem_destroy(&id); + return 1; + } + + if (sem_destroy(&id) < 0) { + perror("sem_destroy"); + return 1; + } + return 0; +} diff --git a/test/testcases/sample.run b/test/testcases/sample.run index 9336fa0dbb..4df41675a5 100644 --- a/test/testcases/sample.run +++ b/test/testcases/sample.run @@ -42,6 +42,33 @@ crypto/serpent/serpent_test userland defaults serpentecb_vt.txt crypto/twofish/twofish_test userland defaults twofishecb_vk.txt crypto/twofish/twofish_test userland defaults twofishecb_vt.txt +# POSIX IPC tests +posixipc/close_unnamed_semaphore/close_unnamed_semaphore userland defaults +posixipc/create_excl_existing_sem/create_excl_existing_sem userland defaults +posixipc/create_unnamed_semaphore/create_unnamed_semaphore userland defaults +posixipc/destroy_named_semaphore/destroy_named_semaphore userland defaults +posixipc/file_test/file_test userland defaults +posixipc/init_bad_value/init_bad_value userland defaults +posixipc/max_value/max_value userland defaults +posixipc/open_after_unlink/open_after_unlink userland defaults +posixipc/open_bad_value/open_bad_value userland defaults +posixipc/open_extra_flags/open_extra_flags userland defaults +posixipc/open_invalid_path/open_invalid_path userland defaults +posixipc/open_named_semaphore/open_named_semaphore userland defaults +posixipc/open_non_existing/open_non_existing userland defaults +posixipc/open_path_too_long/open_path_too_long userland defaults +posixipc/post_test/post_test userland defaults +posixipc/timedwait_expired/timedwait_expired userland defaults +posixipc/timedwait_locked/timedwait_locked userland defaults +posixipc/timedwait_unlocked/timedwait_unlocked userland defaults +posixipc/trywait_locked/trywait_locked userland defaults +posixipc/trywait_unlocked/trywait_unlocked userland defaults +posixipc/unlink_path_too_long/unlink_path_too_long userland defaults +posixipc/use_after_unlink/use_after_unlink userland defaults +posixipc/wait_locked/wait_locked userland defaults +posixipc/wait_two_proc/wait_two_proc userland defaults +posixipc/wait_unlocked/wait_unlocked userland defaults + #openat_1 userland intpre,intpost,timeout=100 #openat_1 userland intpre,intpost,timeout=100 #openat_1 userland intpre,intpost,timeout=100 -- 2.41.0