67 lines · cpp
1// RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t2 3#include <assert.h>4#include <signal.h>5#include <unistd.h>6 7static bool sahandler_done;8static bool sasigaction_done;9 10static void sahandler(int) { sahandler_done = true; }11 12static void sasigaction(int, siginfo_t *, void *) { sasigaction_done = true; }13 14template <typename T> void install(T *handler, struct sigaction *prev) {15 bool siginfo = handler == (T *)&sasigaction;16 struct sigaction act = {};17 if (siginfo) {18 act.sa_flags = SA_SIGINFO;19 act.sa_sigaction = (decltype(act.sa_sigaction))handler;20 } else {21 act.sa_handler = (decltype(act.sa_handler))handler;22 }23 int ret = sigaction(SIGHUP, &act, prev);24 assert(ret == 0);25 26 if (handler == (T *)&sahandler) {27 sahandler_done = false;28 raise(SIGHUP);29 assert(sahandler_done);30 }31 32 if (handler == (T *)&sasigaction) {33 sasigaction_done = false;34 raise(SIGHUP);35 assert(sasigaction_done);36 }37}38 39template <typename T1, typename T2> void test(T1 *from, T2 *to) {40 install(from, nullptr);41 struct sigaction prev = {};42 install(to, &prev);43 44 bool siginfo_from = (from == (T1 *)&sasigaction);45 if (siginfo_from) {46 assert(prev.sa_flags & SA_SIGINFO);47 assert(prev.sa_sigaction == (decltype(prev.sa_sigaction))from);48 } else {49 assert((prev.sa_flags & SA_SIGINFO) == 0);50 assert(prev.sa_handler == (decltype(prev.sa_handler))from);51 }52}53 54template <typename T> void testAll(T *to) {55 test(&sahandler, to);56 test(&sasigaction, to);57 test(SIG_IGN, to);58 test(SIG_DFL, to);59}60 61int main(void) {62 testAll(&sahandler);63 testAll(&sasigaction);64 testAll(SIG_IGN);65 testAll(SIG_DFL);66}67