5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner/*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * This file and its contents are supplied under the terms of the
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Common Development and Distribution License ("CDDL"), version 1.0.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * You may only use this file in accordance with the terms of version
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * 1.0 of the CDDL.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner *
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * A full copy of the text of the CDDL should have accompanied this
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * source. A copy of the CDDL is also available via the Internet at
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * http://www.illumos.org/license/CDDL.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner/*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Copyright 2013 David Hoeppner. All rights reserved.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner/*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Queue maximum number of signals and test if we can queue more signals then
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * allowed.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner#include <sys/types.h>
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner#include <stdarg.h>
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner#include <stdio.h>
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner#include <stdlib.h>
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner#include <unistd.h>
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner#include <signal.h>
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner#define SIGQUEUE_SIGNAL SIGRTMIN /* Signal used for testing */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerint nreceived = 0;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerstatic void
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnertest_start(const char *test_name, const char *format, ...)
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner{
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner va_list args;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) printf("TEST STARTING %s: ", test_name);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner va_start(args, format);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) vprintf(format, args);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner va_end(args);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) fflush(stdout);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner}
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerstatic void
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnertest_failed(const char *test_name, const char *format, ...)
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner{
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner va_list args;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) printf("TEST FAILED %s: ", test_name);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner va_start(args, format);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) vprintf(format, args);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner va_end(args);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) exit(-1);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner}
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerstatic void
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnertest_passed(const char *test_name)
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner{
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) printf("TEST PASS: %s\n", test_name);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner (void) fflush(stdout);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner}
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner/* ARGSUSED */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerstatic void
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnermaximum_test_handler(int signal, siginfo_t *siginfo, void *context)
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner{
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner nreceived++;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner}
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerstatic void
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnersigqueue_maximum_test(void)
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner{
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner const char *test_name = __func__;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner struct sigaction action;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner long sigqueue_max, i;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner pid_t pid;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner union sigval value;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner int error;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_start(test_name, "queue maximum number of signals\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner /*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Get the maximum size of the queue.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner sigqueue_max = sysconf(_SC_SIGQUEUE_MAX);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (sigqueue_max == -1) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "sysconf\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner /*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Put the signal on hold.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner error = sighold(SIGQUEUE_SIGNAL);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (error == -1) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "sighold\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner pid = getpid();
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner value.sival_int = 0;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner action.sa_flags = SA_SIGINFO;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner action.sa_sigaction = maximum_test_handler;
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner error = sigemptyset(&action.sa_mask);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (error == -1) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "sigemptyset\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner /*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Set signal handler.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner error = sigaction(SIGQUEUE_SIGNAL, &action, 0);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (error == -1) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "sigaction\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner /*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Fill the signal queue to the maximum.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner for (i = 0; i < sigqueue_max; i++) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner error = sigqueue(pid, SIGQUEUE_SIGNAL, value);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (error == -1) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "sigqueue\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner /*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Send a further signal and test if we get the expected
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * error.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner error = sigqueue(pid, SIGQUEUE_SIGNAL, value);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (error != -1) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "sigqueue\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner /*
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * Unblock the signals and check if we received all messages
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner * from the signal queue.
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner error = sigrelse(SIGQUEUE_SIGNAL);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (error == -1) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "sigrelse\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner if (nreceived != sigqueue_max) {
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_failed(test_name, "nreceived != sigqueue_max\n");
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner }
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner test_passed(test_name);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner}
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerstatic void
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerrun_tests(void)
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner{
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner sigqueue_maximum_test();
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner}
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner/* ARGSUSED */
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnerint
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppnermain(int argc, char *argv[])
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner{
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner run_tests();
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner return (EXIT_SUCCESS);
5e989a96186a37eb528fb7bb4d28a150874ec799David Höppner}