[go: up one dir, main page]

File: signals.c

package info (click to toggle)
trinity 1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,252 kB
  • ctags: 2,738
  • sloc: ansic: 24,011; sh: 322; makefile: 141
file content (100 lines) | stat: -rw-r--r-- 2,117 bytes parent folder | download
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

#include "trinity.h"	// __unused__
#include "params.h"	// debug
#include "pids.h"
#include "signals.h"
#include "shm.h"

jmp_buf ret_jump;

int sigwas;

static void ctrlc_handler(__unused__ int sig)
{
	shm->exit_reason = EXIT_SIGINT;
}

static void sighandler(int sig)
{
	int slot;

	sigwas = sig;

	switch (sig) {
	case SIGALRM:
		slot = find_pid_slot(getpid());
		if (slot == PIDSLOT_NOT_FOUND)
			_exit(EXIT_SUCCESS);	/* Hell knows what happened, just bail. */

		/* Check if we're blocking because we're stuck on an fd. */
		if (check_if_fd(slot) == TRUE) {

			/* avoid doing it again from other threads. */
			shm->fd_lifetime = 0;

			/* TODO: Somehow mark the fd in the parent not to be used again too. */
		}

		/* Re-arm the alarm. */
		alarm(1);

		/* TODO: If we get back here after the 10s alarm, we should exit instead of longjmp */

		/* Jump back, maybe we'll make progress. */
		(void)signal(sig, sighandler);
		siglongjmp(ret_jump, 1);
		break;

	default:
		_exit(EXIT_SUCCESS);
	}
}

void mask_signals_child(void)
{
	struct sigaction sa;
	sigset_t ss;
	int i;

	for (i = 1; i < 512; i++) {
		(void)sigfillset(&ss);
		sa.sa_flags = SA_RESTART;
		sa.sa_handler = sighandler;
		sa.sa_mask = ss;
		(void)sigaction(i, &sa, NULL);
	}
	/* we want default behaviour for child process signals */
	(void)signal(SIGCHLD, SIG_DFL);

	/* ignore signals we don't care about */
	(void)signal(SIGFPE, SIG_IGN);
	(void)signal(SIGXCPU, SIG_IGN);
	(void)signal(SIGTSTP, SIG_IGN);
	(void)signal(SIGWINCH, SIG_IGN);
	(void)signal(SIGIO, SIG_IGN);
	(void)signal(SIGPIPE, SIG_IGN);

	/* Ignore the RT signals. */
	for (i = SIGRTMIN; i <= SIGRTMAX; i++)
		(void)signal(i, SIG_IGN);

	/* If we are in debug mode, we want segfaults and core dumps */
	if (debug == TRUE)
		(void)signal(SIGSEGV, SIG_DFL);

	/* trap ctrl-c */
	(void)signal(SIGINT, ctrlc_handler);
}


void setup_main_signals(void)
{
	/* we want default behaviour for child process signals */
	(void)signal(SIGFPE, SIG_DFL);
	(void)signal(SIGCHLD, SIG_DFL);

	(void)signal(SIGINT, ctrlc_handler);
}