diff options
author | wollman <wollman@FreeBSD.org> | 2000-04-22 15:29:21 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 2000-04-22 15:29:21 +0000 |
commit | bf9193e8ba2ad2dfe6268d45955e42b58ca05032 (patch) | |
tree | 757ccd3d18b3019a6383c323fa036a1909fa967f /tools/test/posixshm | |
parent | 32fbc9e863be198e0effc829f64834dc543425aa (diff) | |
download | FreeBSD-src-bf9193e8ba2ad2dfe6268d45955e42b58ca05032.zip FreeBSD-src-bf9193e8ba2ad2dfe6268d45955e42b58ca05032.tar.gz |
Add a little test program to demonstrate POSIX Shared Memory Objects.
Diffstat (limited to 'tools/test/posixshm')
-rw-r--r-- | tools/test/posixshm/README | 4 | ||||
-rw-r--r-- | tools/test/posixshm/shm_test.c | 144 |
2 files changed, 148 insertions, 0 deletions
diff --git a/tools/test/posixshm/README b/tools/test/posixshm/README new file mode 100644 index 0000000..514e18b --- /dev/null +++ b/tools/test/posixshm/README @@ -0,0 +1,4 @@ +$FreeBSD$ + +This is a simple program to test/demonstrate the POSIX Shared Memory +Objects feature set. `make shm_test' to build. diff --git a/tools/test/posixshm/shm_test.c b/tools/test/posixshm/shm_test.c new file mode 100644 index 0000000..6cee558 --- /dev/null +++ b/tools/test/posixshm/shm_test.c @@ -0,0 +1,144 @@ +/* + * Test the POSIX shared-memory API. + * Dedicated to tyhe public domain by Garrett A. Wollman, 2000. + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/wait.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/* + * Signal handler which does nothing. + */ +static void +ignoreit(int sig) +{ + ; +} + +int +main(int argc, char **argv) +{ + char buf[1024], *cp; + int desc, rv; + long scval; + sigset_t ss; + struct sigaction sa; + void *region; + size_t psize; + +#ifndef _POSIX_SHARED_MEMORY_OBJECTS + printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n"); +#else + printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n", + (long)_POSIX_SHARED_MEMORY_OBJECTS - 0); + if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1) + printf("***Indicates this feature may be unsupported!\n"); +#endif + errno = 0; + scval = sysconf(_SC_SHARED_MEMORY_OBJECTS); + if (scval == -1 && errno != 0) { + err(1, "sysconf(_SC_SHARED_MEMORY_OBJECTS)"); + } else { + printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n", + scval); + if (scval == -1) + printf("***Indicates this feature is unsupported!\n"); + } + + errno = 0; + scval = sysconf(_SC_PAGESIZE); + if (scval == -1 && errno != 0) { + err(1, "sysconf(_SC_PAGESIZE)"); + } else if (scval <= 0 || (size_t)psize != psize) { + warnx("bogus return from sysconf(_SC_PAGESIZE): %ld", + scval); + psize = 4096; + } else { + printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval); + psize = scval; + } + + argc--, argv++; + + if (*argv) { + strncat(buf, *argv, (sizeof buf) - 1); + desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600); + } else { + do { + /* + * Can't use mkstemp for obvious reasons... + */ + strcpy(buf, "/tmp/shmtest.XXXXXXXXXXXX"); + mktemp(buf); + desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600); + } while (desc < 0 && errno == EEXIST); + } + + if (desc < 0) + err(1, "shm_open"); + + if (shm_unlink(buf) < 0) + err(1, "shm_unlink"); + + if (ftruncate(desc, (off_t)psize) < 0) + err(1, "ftruncate"); + + region = mmap((void *)0, psize, PROT_READ | PROT_WRITE, MAP_SHARED, + desc, (off_t)0); + if (region == MAP_FAILED) + err(1, "mmap"); + memset(region, '\377', psize); + + sa.sa_flags = 0; + sa.sa_handler = ignoreit; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGUSR1, &sa, (struct sigaction *)0) < 0) + err(1, "sigaction"); + + sigemptyset(&ss); + sigaddset(&ss, SIGUSR1); + if (sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) < 0) + err(1, "sigprocmask"); + + rv = fork(); + if (rv < 0) { + err(1, "fork"); + } else if (rv == 0) { + sigemptyset(&ss); + sigsuspend(&ss); + + for (cp = region; cp < (char *)region + psize; cp++) + if (*cp != '\151') + _exit(1); + _exit(0); + } else { + int status; + + memset(region, '\151', psize); + kill(rv, SIGUSR1); + waitpid(rv, &status, 0); + + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + printf("Functionality test successful\n"); + exit(0); + } else if (WIFEXITED(status)) { + printf("Child process exited with status %d\n", + WEXITSTATUS(status)); + } else { + printf("Child process terminated with %s\n", + strsignal(WTERMSIG(status))); + } + } + exit(1); +} |