File: signals.c

package info (click to toggle)
nmh 1.8-4
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 7,860 kB
  • sloc: ansic: 50,445; sh: 22,697; makefile: 1,138; lex: 740; perl: 509; yacc: 265
file content (108 lines) | stat: -rw-r--r-- 2,666 bytes parent folder | download | duplicates (3)
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
101
102
103
104
105
106
107
108
/* signals.c -- general signals interface for nmh
 *
 * This code is Copyright (c) 2002, by the authors of nmh.  See the
 * COPYRIGHT file in the root directory of the nmh distribution for
 * complete copyright information.
 */

#include "h/mh.h"
#include <signal.h>
#include "signals.h"
#include "m_mktemp.h"


/*
 * A version of the function `signal' that uses reliable
 * signals, if the machine supports them.  Also, (assuming
 * OS support), it restarts interrupted system calls for all
 * signals except SIGALRM.
 *
 * Since we are now assuming POSIX signal support everywhere, we always
 * use reliable signals.
 */

SIGNAL_HANDLER
SIGNAL (int sig, SIGNAL_HANDLER func)
{
    struct sigaction act, oact;

    act.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    if (sig == SIGALRM) {
# ifdef SA_INTERRUPT
	act.sa_flags |= SA_INTERRUPT;     /* SunOS */
# endif
    } else {
# ifdef SA_RESTART
	act.sa_flags |= SA_RESTART;       /* SVR4, BSD4.4 */
# endif
    }
    if (sigaction(sig, &act, &oact) < 0)
	return SIG_ERR;
    return oact.sa_handler;
}


/*
 * A version of the function `signal' that will set
 * the handler of `sig' to `func' if the signal is
 * not currently set to SIG_IGN.  Also uses reliable
 * signals if available.
 */
SIGNAL_HANDLER
SIGNAL2 (int sig, SIGNAL_HANDLER func)
{
    struct sigaction act, oact;

    if (sigaction(sig, NULL, &oact) < 0)
	return SIG_ERR;
    if (oact.sa_handler != SIG_IGN) {
	act.sa_handler = func;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;

	if (sig == SIGALRM) {
# ifdef SA_INTERRUPT
	    act.sa_flags |= SA_INTERRUPT;     /* SunOS */
# endif
	} else {
# ifdef SA_RESTART
	    act.sa_flags |= SA_RESTART;       /* SVR4, BSD4.4 */
# endif
	}
	if (sigaction(sig, &act, &oact) < 0)
	    return SIG_ERR;
    }
    return oact.sa_handler;
}


/*
 * For use by nmh_init().
 */
int
setup_signal_handlers(void)
{
    /*
     * Catch HUP, INT, QUIT, and TERM so that we can clean up tmp
     * files when the user terminates the process early.  And also a
     * few other common signals that can be thrown due to bugs, stack
     * overflow, etc.
     */

    if (SIGNAL(SIGHUP,  remove_registered_files) == SIG_ERR  ||
        SIGNAL(SIGINT,  remove_registered_files) == SIG_ERR  ||
        SIGNAL(SIGQUIT, remove_registered_files) == SIG_ERR  ||
        SIGNAL(SIGTERM, remove_registered_files) == SIG_ERR  ||
        SIGNAL(SIGILL,  remove_registered_files) == SIG_ERR  ||
#       ifdef SIGBUS
        SIGNAL(SIGBUS,  remove_registered_files) == SIG_ERR  ||
#       endif
        SIGNAL(SIGSEGV, remove_registered_files) == SIG_ERR) {
        return NOTOK;
    }

    return OK;
}