Signals.cpp revision b576c94c15af9a440f69d9d03c2afead7971118c
1//===- Signals.cpp - Signal Handling support ------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines some helpful functions for dealing with the possibility of
11// Unix signals occuring while your program is running.
12//
13//===----------------------------------------------------------------------===//
14
15#include "Support/Signals.h"
16#include <vector>
17#include <algorithm>
18#include <cstdlib>
19#include <cstdio>
20#include <signal.h>
21#include "Config/config.h"     // Get the signal handler return type
22
23static std::vector<std::string> FilesToRemove;
24
25// IntSigs - Signals that may interrupt the program at any time.
26static const int IntSigs[] = {
27  SIGHUP, SIGINT, SIGQUIT, SIGKILL, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
28};
29static const int *IntSigsEnd = IntSigs + sizeof(IntSigs)/sizeof(IntSigs[0]);
30
31// KillSigs - Signals that are synchronous with the program that will cause it
32// to die.
33static const int KillSigs[] = {
34  SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
35#ifdef SIGEMT
36  , SIGEMT
37#endif
38};
39static const int *KillSigsEnd = KillSigs + sizeof(KillSigs)/sizeof(KillSigs[0]);
40
41
42// SignalHandler - The signal handler that runs...
43static RETSIGTYPE SignalHandler(int Sig) {
44  while (!FilesToRemove.empty()) {
45    std::remove(FilesToRemove.back().c_str());
46    FilesToRemove.pop_back();
47  }
48
49  if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd)
50    exit(1);   // If this is an interrupt signal, exit the program
51
52  // Otherwise if it is a fault (like SEGV) reissue the signal to die...
53  signal(Sig, SIG_DFL);
54}
55
56static void RegisterHandler(int Signal) { signal(Signal, SignalHandler); }
57
58// RemoveFileOnSignal - The public API
59void RemoveFileOnSignal(const std::string &Filename) {
60  FilesToRemove.push_back(Filename);
61
62  std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
63  std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
64}
65