testcases: Attempt to integrate POSIX IPC tests to dfregress(8)
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Wed, 8 Jul 2015 10:38:27 +0000 (03:38 -0700)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Wed, 8 Jul 2015 10:38:27 +0000 (03:38 -0700)
- Tests have been split up so they run separately

54 files changed:
test/testcases/posixipc/Makefile
test/testcases/posixipc/close_unnamed_semaphore/Makefile [new file with mode: 0644]
test/testcases/posixipc/close_unnamed_semaphore/close_unnamed_semaphore.c [new file with mode: 0644]
test/testcases/posixipc/common/common.c [new file with mode: 0644]
test/testcases/posixipc/common/common.h [new file with mode: 0644]
test/testcases/posixipc/create_excl_existing_sem/Makefile [new file with mode: 0644]
test/testcases/posixipc/create_excl_existing_sem/create_excl_existing_sem.c [new file with mode: 0644]
test/testcases/posixipc/create_unnamed_semaphore/Makefile [new file with mode: 0644]
test/testcases/posixipc/create_unnamed_semaphore/create_unnamed_semaphore.c [new file with mode: 0644]
test/testcases/posixipc/destroy_named_semaphore/Makefile [new file with mode: 0644]
test/testcases/posixipc/destroy_named_semaphore/destroy_named_semaphore.c [new file with mode: 0644]
test/testcases/posixipc/file_test/Makefile [new file with mode: 0644]
test/testcases/posixipc/file_test/file_test.c [new file with mode: 0644]
test/testcases/posixipc/init_bad_value/Makefile [new file with mode: 0644]
test/testcases/posixipc/init_bad_value/init_bad_value.c [new file with mode: 0644]
test/testcases/posixipc/max_value/Makefile [new file with mode: 0644]
test/testcases/posixipc/max_value/max_value.c [new file with mode: 0644]
test/testcases/posixipc/open_after_unlink/Makefile [new file with mode: 0644]
test/testcases/posixipc/open_after_unlink/open_after_unlink.c [new file with mode: 0644]
test/testcases/posixipc/open_bad_value/Makefile [new file with mode: 0644]
test/testcases/posixipc/open_bad_value/open_bad_value.c [new file with mode: 0644]
test/testcases/posixipc/open_extra_flags/Makefile [new file with mode: 0644]
test/testcases/posixipc/open_extra_flags/open_extra_flags.c [new file with mode: 0644]
test/testcases/posixipc/open_invalid_path/Makefile [new file with mode: 0644]
test/testcases/posixipc/open_invalid_path/open_invalid_path.c [new file with mode: 0644]
test/testcases/posixipc/open_named_semaphore/Makefile [new file with mode: 0644]
test/testcases/posixipc/open_named_semaphore/open_named_semaphore.c [new file with mode: 0644]
test/testcases/posixipc/open_non_existing/Makefile [new file with mode: 0644]
test/testcases/posixipc/open_non_existing/open_non_existing.c [new file with mode: 0644]
test/testcases/posixipc/open_path_too_long/Makefile [new file with mode: 0644]
test/testcases/posixipc/open_path_too_long/open_path_too_long.c [new file with mode: 0644]
test/testcases/posixipc/post_test/Makefile [new file with mode: 0644]
test/testcases/posixipc/post_test/post_test.c [new file with mode: 0644]
test/testcases/posixipc/timedwait_expired/Makefile [new file with mode: 0644]
test/testcases/posixipc/timedwait_expired/timedwait_expired.c [new file with mode: 0644]
test/testcases/posixipc/timedwait_locked/Makefile [new file with mode: 0644]
test/testcases/posixipc/timedwait_locked/timedwait_locked.c [new file with mode: 0644]
test/testcases/posixipc/timedwait_unlocked/Makefile [new file with mode: 0644]
test/testcases/posixipc/timedwait_unlocked/timedwait_unlocked.c [new file with mode: 0644]
test/testcases/posixipc/trywait_locked/Makefile [new file with mode: 0644]
test/testcases/posixipc/trywait_locked/trywait_locked.c [new file with mode: 0644]
test/testcases/posixipc/trywait_unlocked/Makefile [new file with mode: 0644]
test/testcases/posixipc/trywait_unlocked/trywait_unlocked.c [new file with mode: 0644]
test/testcases/posixipc/unlink_path_too_long/Makefile [new file with mode: 0644]
test/testcases/posixipc/unlink_path_too_long/unlink_path_too_long.c [new file with mode: 0644]
test/testcases/posixipc/use_after_unlink/Makefile [new file with mode: 0644]
test/testcases/posixipc/use_after_unlink/use_after_unlink.c [new file with mode: 0644]
test/testcases/posixipc/wait_locked/Makefile [new file with mode: 0644]
test/testcases/posixipc/wait_locked/wait_locked.c [new file with mode: 0644]
test/testcases/posixipc/wait_two_proc/Makefile [new file with mode: 0644]
test/testcases/posixipc/wait_two_proc/wait_two_proc.c [new file with mode: 0644]
test/testcases/posixipc/wait_unlocked/Makefile [new file with mode: 0644]
test/testcases/posixipc/wait_unlocked/wait_unlocked.c [new file with mode: 0644]
test/testcases/sample.run

index d975781..8408add 100644 (file)
@@ -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 <bsd.subdir.mk>
diff --git a/test/testcases/posixipc/close_unnamed_semaphore/Makefile b/test/testcases/posixipc/close_unnamed_semaphore/Makefile
new file mode 100644 (file)
index 0000000..75dd9f9
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..67f1d19
--- /dev/null
@@ -0,0 +1,18 @@
+#include <common.h>
+
+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 (file)
index 0000000..fc97e6b
--- /dev/null
@@ -0,0 +1,385 @@
+/*-
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb@FreeBSD.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.
+ * 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 <sys/cdefs.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <kvm.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <common.h>
+
+/*
+ * 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 (file)
index 0000000..e5c3d37
--- /dev/null
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb@FreeBSD.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.
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#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 (file)
index 0000000..ebe9e17
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..2fb69e5
--- /dev/null
@@ -0,0 +1,20 @@
+#include <common.h>
+
+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 (file)
index 0000000..85564b9
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..a666dac
--- /dev/null
@@ -0,0 +1,16 @@
+#include <common.h>
+
+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 (file)
index 0000000..c814181
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..7fe320a
--- /dev/null
@@ -0,0 +1,19 @@
+#include <common.h>
+
+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 (file)
index 0000000..5c26776
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  file_test
+SRCS=  file_test.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..98e63c2
--- /dev/null
@@ -0,0 +1,28 @@
+#include <common.h>
+
+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 (file)
index 0000000..23017ad
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..ea82e5d
--- /dev/null
@@ -0,0 +1,10 @@
+#include <common.h>
+
+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 (file)
index 0000000..b65e6e0
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  max_value
+SRCS=  max_value.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..a94a4d1
--- /dev/null
@@ -0,0 +1,32 @@
+#include <common.h>
+
+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 (file)
index 0000000..78e999d
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..3352b2a
--- /dev/null
@@ -0,0 +1,23 @@
+#include <common.h>
+
+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 (file)
index 0000000..2ee9b94
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..a683516
--- /dev/null
@@ -0,0 +1,12 @@
+#include <common.h>
+
+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 (file)
index 0000000..2693d22
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..4cfe48b
--- /dev/null
@@ -0,0 +1,10 @@
+#include <common.h>
+
+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 (file)
index 0000000..497e4df
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..48dadec
--- /dev/null
@@ -0,0 +1,10 @@
+#include <common.h>
+
+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 (file)
index 0000000..ef11f8d
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..8932e07
--- /dev/null
@@ -0,0 +1,23 @@
+#include <common.h>
+
+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 (file)
index 0000000..4d55b20
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..3e5af6a
--- /dev/null
@@ -0,0 +1,10 @@
+#include <common.h>
+
+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 (file)
index 0000000..1f3feda
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..0dc3f8a
--- /dev/null
@@ -0,0 +1,16 @@
+#include <common.h>
+
+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 (file)
index 0000000..335ae66
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  post_test
+SRCS=  post_test.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..af40b78
--- /dev/null
@@ -0,0 +1,29 @@
+#include <common.h>
+
+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 (file)
index 0000000..5966d33
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  timedwait_expired
+SRCS=  timedwait_expired.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..1a5b968
--- /dev/null
@@ -0,0 +1,34 @@
+#include <common.h>
+
+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 (file)
index 0000000..40399e4
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  timedwait_locked
+SRCS=  timedwait_locked.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..a3ea5e7
--- /dev/null
@@ -0,0 +1,43 @@
+#include <common.h>
+
+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 (file)
index 0000000..74d3b4a
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  timedwait_unlocked
+SRCS=  timedwait_unlocked.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..ea29495
--- /dev/null
@@ -0,0 +1,34 @@
+#include <common.h>
+
+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 (file)
index 0000000..a978c2a
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  trywait_locked
+SRCS=  trywait_locked.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..a5c4f6e
--- /dev/null
@@ -0,0 +1,32 @@
+#include <common.h>
+
+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 (file)
index 0000000..1481133
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  trywait_unlocked
+SRCS=  trywait_unlocked.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..9c71dd6
--- /dev/null
@@ -0,0 +1,28 @@
+#include <common.h>
+
+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 (file)
index 0000000..a9500db
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..cfac61f
--- /dev/null
@@ -0,0 +1,15 @@
+#include <common.h>
+
+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 (file)
index 0000000..7422e8c
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..1152d20
--- /dev/null
@@ -0,0 +1,53 @@
+#include <common.h>
+
+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 (file)
index 0000000..88c7b90
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  wait_locked
+SRCS=  wait_locked.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..46239ce
--- /dev/null
@@ -0,0 +1,39 @@
+#include <common.h>
+
+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 (file)
index 0000000..3f9546a
--- /dev/null
@@ -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 <bsd.prog.mk>
+.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 (file)
index 0000000..c0bb191
--- /dev/null
@@ -0,0 +1,57 @@
+#include <common.h>
+
+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 (file)
index 0000000..efe9120
--- /dev/null
@@ -0,0 +1,10 @@
+PROG=  wait_unlocked
+SRCS=  wait_unlocked.c common.c
+NO_MAN=
+LDADD=  -lpthread
+
+CFLAGS= -I ${.CURDIR}/../common
+WARNS?=        3
+
+.include <bsd.prog.mk>
+.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 (file)
index 0000000..fe844ed
--- /dev/null
@@ -0,0 +1,34 @@
+#include <common.h>
+
+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;
+}
index 9336fa0..4df4167 100644 (file)
@@ -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