Ejemplo n.º 1
0
static void
sigchld_handler(int signo __unused)
{
	struct shmid_ds s_ds;
	int cstatus;

	/*
	 * Reap the child; if it exited successfully, then the test passed!
	 */
	if (waitpid(child_pid, &cstatus, 0) != child_pid)
		err(1, "waitpid");

	if (WIFEXITED(cstatus) == 0)
		errx(1, "receiver exited abnormally");

	if (WEXITSTATUS(cstatus) != 0)
		errx(1, "receiver exited with status %d",
		    WEXITSTATUS(cstatus));

	/*
	 * If we get here, the child has exited normally, and thus
	 * we should exit normally too.  First, tho, we print out
	 * the final stats for the message queue.
	 */

	if (shmctl(sender_shmid, IPC_STAT, &s_ds) == -1)
		err(1, "shmctl IPC_STAT");

	print_shmid_ds(&s_ds, 0600);

	exit(0);
}
Ejemplo n.º 2
0
int
main(int argc, char *argv[])
{
	struct sigaction sa;
	struct shmid_ds s_ds;
	sigset_t sigmask;
	char *shm_buf;

	if (argc != 2)
		usage();

	/*
	 * Install a SIGSYS handler so that we can exit gracefully if
	 * System V Shared Memory support isn't in the kernel.
	 */
	sa.sa_handler = sigsys_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if (sigaction(SIGSYS, &sa, NULL) == -1)
		err(1, "sigaction SIGSYS");

	/*
	 * Install and SIGCHLD handler to deal with all possible exit
	 * conditions of the receiver.
	 */
	sa.sa_handler = sigchld_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if (sigaction(SIGCHLD, &sa, NULL) == -1)
		err(1, "sigaction SIGCHLD");

	pgsize = sysconf(_SC_PAGESIZE);

	shmkey = ftok(argv[1], 4160);

	/*
	 * Initialize child_pid to ourselves to that the cleanup function
	 * works before we create the receiver.
	 */
	child_pid = getpid();

	/*
	 * Make sure that when the sender exits, the message queue is
	 * removed.
	 */
	if (atexit(cleanup) == -1)
		err(1, "atexit");

	if ((sender_shmid = shmget(shmkey, pgsize, IPC_CREAT | 0640)) == -1)
		err(1, "shmget");

	if (shmctl(sender_shmid, IPC_STAT, &s_ds) == -1)
		err(1, "shmctl IPC_STAT");

	print_shmid_ds(&s_ds, 0640);

	s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600;

	if (shmctl(sender_shmid, IPC_SET, &s_ds) == -1)
		err(1, "shmctl IPC_SET");

	memset(&s_ds, 0, sizeof(s_ds));

	if (shmctl(sender_shmid, IPC_STAT, &s_ds) == -1)
		err(1, "shmctl IPC_STAT");

	if ((s_ds.shm_perm.mode & 0777) != 0600)
		err(1, "IPC_SET of mode didn't hold");

	print_shmid_ds(&s_ds, 0600);

	if ((shm_buf = shmat(sender_shmid, NULL, 0)) == (void *) -1)
		err(1, "sender: shmat");

	/*
	 * Write the test pattern into the shared memory buffer.
	 */
	strcpy(shm_buf, m_str);

	switch ((child_pid = fork())) {
	case -1:
		err(1, "fork");
		/* NOTREACHED */

	case 0:
		receiver();
		break;

	default:
		break;
	}

	/*
	 * Suspend forever; when we get SIGCHLD, the handler will exit.
	 */
	sigemptyset(&sigmask);
	(void) sigsuspend(&sigmask);

	/*
	 * ...and any other signal is an unexpected error.
	 */
	errx(1, "sender: received unexpected signal");
}
Ejemplo n.º 3
0
ATF_TC_BODY(shm, tc)
{
	struct sigaction sa;
	struct shmid_ds s_ds;
	sigset_t sigmask;
	char *shm_buf;
	int sender_shmid;
	int c_status;

	/*
	 * Install a SIGSYS handler so that we can exit gracefully if
	 * System V Shared Memory support isn't in the kernel.
	 */
	did_sigsys = 0;
	sa.sa_handler = sigsys_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
	    "sigaction SIGSYS: %d", errno);

	/*
	 * Install a SIGCHLD handler to deal with all possible exit
	 * conditions of the sharer.
	 */
	did_sigchild = 0;
	child_count = 0;
	sa.sa_handler = sigchld_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
	    "sigaction SIGCHLD: %d", errno);

	pgsize = sysconf(_SC_PAGESIZE);

	shmkey = get_ftok(4160);
	ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed");

	ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize,
					       IPC_CREAT | 0640)) != -1,
	    "shmget: %d", errno);
	write_int("sender_shmid", sender_shmid);

	ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
	    "shmctl IPC_STAT: %d", errno);

	print_shmid_ds(&s_ds, 0640);

	s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600;

	ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_SET, &s_ds) != -1,
	    "shmctl IPC_SET: %d", errno);

	memset(&s_ds, 0, sizeof(s_ds));

	ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
	    "shmctl IPC_STAT: %d", errno);

	ATF_REQUIRE_MSG((s_ds.shm_perm.mode & 0777) == 0600,
	    "IPC_SET of mode didn't hold");

	print_shmid_ds(&s_ds, 0600);

	shm_buf = shmat(sender_shmid, NULL, 0);
	ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno);

	/*
	 * Write the test pattern into the shared memory buffer.
	 */
	strcpy(shm_buf, m2_str);

	switch ((child_pid = fork())) {
	case -1:
		atf_tc_fail("fork: %d", errno);
		return;

	case 0:
		sharer();
		break;

	default:
		break;
	}

	/*
	 * Wait for child to finish
	 */
	sigemptyset(&sigmask);
	(void) sigsuspend(&sigmask);

	if (did_sigchild) {
		c_status = child_status;
		if (c_status < 0)
			atf_tc_fail("waitpid: %d", -c_status);
		else if (WIFEXITED(c_status) == 0)
			atf_tc_fail("c abnormal exit: %d", c_status);
		else if (WEXITSTATUS(c_status) != 0)
			atf_tc_fail("c status: %d", WEXITSTATUS(c_status));
		else {
			ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT,
					       &s_ds) != -1,
			    "shmctl IPC_STAT: %d", errno);

			print_shmid_ds(&s_ds, 0600);
			atf_tc_pass();
		}
	} else
		atf_tc_fail("sender: received unexpected signal");
}