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