Home | History | Annotate | Download | only in sigaction
      1 /*
      2 * Copyright (c) 2005, Bull S.A..  All rights reserved.
      3 * Created by: Sebastien Decugis
      4 * Copyright (c) 2013 Cyril Hrubis <chrubis (at) suse.cz>
      5 *
      6 * This program is free software; you can redistribute it and/or modify it
      7 * under the terms of version 2 of the GNU General Public License as
      8 * published by the Free Software Foundation.
      9 *
     10 * This program is distributed in the hope that it would be useful, but
     11 * WITHOUT ANY WARRANTY; without even the implied warranty of
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     13 *
     14 * You should have received a copy of the GNU General Public License along
     15 * with this program; if not, write the Free Software Foundation, Inc.,
     16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     17 *
     18 * This sample test aims to check the following assertions:
     19 *
     20 * If SA_SIGINFO is set in sa_flags and Real Time Signals extension is supported,
     21 * sa_sigaction is used as the signal handling function.
     22 *
     23 * The steps are:
     24 * -> test for RTS extension
     25 * -> register a handler for SIGFPE with SA_SIGINFO, and a known function
     26 *   as sa_sigaction
     27 * -> raise SIGFPE, and check the function has been called.
     28 *
     29 * The test fails if the function is not called
     30 */
     31 
     32 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
     33 #define _POSIX_C_SOURCE 200112L
     34 
     35 #include <pthread.h>
     36 #include <stdarg.h>
     37 #include <stdio.h>
     38 #include <stdlib.h>
     39 #include <string.h>
     40 #include <unistd.h>
     41 #include <signal.h>
     42 #include <errno.h>
     43 #include "posixtest.h"
     44 
     45 #define WRITE(str) write(STDOUT_FILENO, str, sizeof(str) - 1)
     46 
     47 static volatile sig_atomic_t called = 0;
     48 
     49 static void handler(int sig, siginfo_t *info, void *context)
     50 {
     51 	(void) sig;
     52 	(void) context;
     53 
     54 	if (info->si_signo != SIGFPE) {
     55 		WRITE("Wrong signal generated?\n");
     56 		_exit(PTS_FAIL);
     57 	}
     58 
     59 	called = 1;
     60 }
     61 
     62 int main(void)
     63 {
     64 	int ret;
     65 	long rts;
     66 
     67 	struct sigaction sa;
     68 
     69 	/* Test the RTS extension */
     70 	rts = sysconf(_SC_REALTIME_SIGNALS);
     71 
     72 	if (rts < 0L) {
     73 		fprintf(stderr, "This test needs the RTS extension");
     74 		return PTS_UNTESTED;
     75 	}
     76 
     77 	/* Set the signal handler */
     78 	sa.sa_flags = SA_SIGINFO;
     79 	sa.sa_sigaction = handler;
     80 
     81 	ret = sigemptyset(&sa.sa_mask);
     82 
     83 	if (ret != 0) {
     84 		perror("Failed to empty signal set");
     85 		return PTS_UNRESOLVED;
     86 	}
     87 
     88 	/* Install the signal handler for SIGFPE */
     89 	ret = sigaction(SIGFPE, &sa, 0);
     90 
     91 	if (ret != 0) {
     92 		perror("Failed to set signal handler");
     93 		return PTS_UNTESTED;
     94 	}
     95 
     96 	if (called) {
     97 		fprintf(stderr,
     98 			"The signal handler has been called before signal was raised");
     99 		return PTS_FAIL;
    100 	}
    101 
    102 	ret = raise(SIGFPE);
    103 
    104 	if (ret != 0) {
    105 		perror("Failed to raise SIGFPE");
    106 		return PTS_UNRESOLVED;
    107 	}
    108 
    109 	if (!called) {
    110 		fprintf(stderr, "The sa_handler was not called");
    111 		return PTS_FAIL;
    112 	}
    113 
    114 	printf("Test PASSED\n");
    115 
    116 	return PTS_PASS;
    117 }
    118