summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.c
blob: b20da3f3813f0d1b047da58b205042cdf1924f45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "signal_handlers.h"
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>


#define PPID_ALARM_INTERVAL 2 // send SIGALRM every this seconds


static pid_t orig_ppid;


static void signal_handler(int _) {
  exit(EXIT_FAILURE);
}

static void check_ppid(void) {
  if (getppid() != orig_ppid) {
    exit(EXIT_FAILURE);
  }
}

static void check_stdout_open(void) {
  if (fcntl(STDOUT_FILENO, F_GETFD) < 0) {
    exit(EXIT_FAILURE);
  }
}

static void alarm_handler(int _) {
  check_ppid();
  check_stdout_open();
  alarm(PPID_ALARM_INTERVAL);
  signal(SIGALRM, alarm_handler);
}

static void die(const char *msg) {
  fprintf(stderr, "\nFATAL: %s\n", msg);
  abort();
}

static void install_signal_handler(int sig, void (*handler)(int)) {
  if (signal(sig, handler) == SIG_ERR) {
    die("Could not install signal handler");
  }
}

void install_signal_handlers(void) {
  // check pipe is still connected
  check_stdout_open();

  // watch getppid() every PPID_ALARM_INTERVAL seconds 
  orig_ppid = getppid();
  if (orig_ppid <= 1) {
    die("prematurely zombied");
  }
  install_signal_handler(SIGALRM, alarm_handler);
  alarm(PPID_ALARM_INTERVAL);

  // be sure to exit on SIGHUP, SIGPIPE
  install_signal_handler(SIGHUP,  signal_handler);
  install_signal_handler(SIGPIPE, signal_handler);
}