shm_test.c revision 59498
159498Swollman/*
259498Swollman * Test the POSIX shared-memory API.
359498Swollman * Dedicated to tyhe public domain by Garrett A. Wollman, 2000.
459498Swollman * $FreeBSD: head/tools/test/posixshm/shm_test.c 59498 2000-04-22 15:29:21Z wollman $
559498Swollman */
659498Swollman
759498Swollman#include <sys/types.h>
859498Swollman#include <sys/mman.h>
959498Swollman#include <sys/wait.h>
1059498Swollman
1159498Swollman#include <err.h>
1259498Swollman#include <errno.h>
1359498Swollman#include <fcntl.h>
1459498Swollman#include <signal.h>
1559498Swollman#include <stdio.h>
1659498Swollman#include <stdlib.h>
1759498Swollman#include <string.h>
1859498Swollman#include <unistd.h>
1959498Swollman
2059498Swollman/*
2159498Swollman * Signal handler which does nothing.
2259498Swollman */
2359498Swollmanstatic void
2459498Swollmanignoreit(int sig)
2559498Swollman{
2659498Swollman	;
2759498Swollman}
2859498Swollman
2959498Swollmanint
3059498Swollmanmain(int argc, char **argv)
3159498Swollman{
3259498Swollman	char buf[1024], *cp;
3359498Swollman	int desc, rv;
3459498Swollman	long scval;
3559498Swollman	sigset_t ss;
3659498Swollman	struct sigaction sa;
3759498Swollman	void *region;
3859498Swollman	size_t psize;
3959498Swollman
4059498Swollman#ifndef _POSIX_SHARED_MEMORY_OBJECTS
4159498Swollman	printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n");
4259498Swollman#else
4359498Swollman	printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n",
4459498Swollman	       (long)_POSIX_SHARED_MEMORY_OBJECTS - 0);
4559498Swollman	if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1)
4659498Swollman		printf("***Indicates this feature may be unsupported!\n");
4759498Swollman#endif
4859498Swollman	errno = 0;
4959498Swollman	scval = sysconf(_SC_SHARED_MEMORY_OBJECTS);
5059498Swollman	if (scval == -1 && errno != 0) {
5159498Swollman		err(1, "sysconf(_SC_SHARED_MEMORY_OBJECTS)");
5259498Swollman	} else {
5359498Swollman		printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n",
5459498Swollman		       scval);
5559498Swollman		if (scval == -1)
5659498Swollman			printf("***Indicates this feature is unsupported!\n");
5759498Swollman	}
5859498Swollman
5959498Swollman	errno = 0;
6059498Swollman	scval = sysconf(_SC_PAGESIZE);
6159498Swollman	if (scval == -1 && errno != 0) {
6259498Swollman		err(1, "sysconf(_SC_PAGESIZE)");
6359498Swollman	} else if (scval <= 0 || (size_t)psize != psize) {
6459498Swollman		warnx("bogus return from sysconf(_SC_PAGESIZE): %ld",
6559498Swollman		      scval);
6659498Swollman		psize = 4096;
6759498Swollman	} else {
6859498Swollman		printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval);
6959498Swollman		psize = scval;
7059498Swollman	}
7159498Swollman
7259498Swollman	argc--, argv++;
7359498Swollman
7459498Swollman	if (*argv) {
7559498Swollman		strncat(buf, *argv, (sizeof buf) - 1);
7659498Swollman		desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
7759498Swollman	} else {
7859498Swollman		do {
7959498Swollman			/*
8059498Swollman			 * Can't use mkstemp for obvious reasons...
8159498Swollman			 */
8259498Swollman			strcpy(buf, "/tmp/shmtest.XXXXXXXXXXXX");
8359498Swollman			mktemp(buf);
8459498Swollman			desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
8559498Swollman		} while (desc < 0 && errno == EEXIST);
8659498Swollman	}
8759498Swollman
8859498Swollman	if (desc < 0)
8959498Swollman		err(1, "shm_open");
9059498Swollman
9159498Swollman	if (shm_unlink(buf) < 0)
9259498Swollman		err(1, "shm_unlink");
9359498Swollman
9459498Swollman	if (ftruncate(desc, (off_t)psize) < 0)
9559498Swollman		err(1, "ftruncate");
9659498Swollman
9759498Swollman	region = mmap((void *)0, psize, PROT_READ | PROT_WRITE, MAP_SHARED,
9859498Swollman		      desc, (off_t)0);
9959498Swollman	if (region == MAP_FAILED)
10059498Swollman		err(1, "mmap");
10159498Swollman	memset(region, '\377', psize);
10259498Swollman
10359498Swollman	sa.sa_flags = 0;
10459498Swollman	sa.sa_handler = ignoreit;
10559498Swollman	sigemptyset(&sa.sa_mask);
10659498Swollman	if (sigaction(SIGUSR1, &sa, (struct sigaction *)0) < 0)
10759498Swollman		err(1, "sigaction");
10859498Swollman
10959498Swollman	sigemptyset(&ss);
11059498Swollman	sigaddset(&ss, SIGUSR1);
11159498Swollman	if (sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) < 0)
11259498Swollman		err(1, "sigprocmask");
11359498Swollman
11459498Swollman	rv = fork();
11559498Swollman	if (rv < 0) {
11659498Swollman		err(1, "fork");
11759498Swollman	} else if (rv == 0) {
11859498Swollman		sigemptyset(&ss);
11959498Swollman		sigsuspend(&ss);
12059498Swollman
12159498Swollman		for (cp = region; cp < (char *)region + psize; cp++)
12259498Swollman			if (*cp != '\151')
12359498Swollman				_exit(1);
12459498Swollman		_exit(0);
12559498Swollman	} else {
12659498Swollman		int status;
12759498Swollman
12859498Swollman		memset(region, '\151', psize);
12959498Swollman		kill(rv, SIGUSR1);
13059498Swollman		waitpid(rv, &status, 0);
13159498Swollman
13259498Swollman		if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
13359498Swollman			printf("Functionality test successful\n");
13459498Swollman			exit(0);
13559498Swollman		} else if (WIFEXITED(status)) {
13659498Swollman			printf("Child process exited with status %d\n",
13759498Swollman			       WEXITSTATUS(status));
13859498Swollman		} else {
13959498Swollman			printf("Child process terminated with %s\n",
14059498Swollman			       strsignal(WTERMSIG(status)));
14159498Swollman		}
14259498Swollman	}
14359498Swollman	exit(1);
14459498Swollman}
145