tc.sig.c 3.72 KB
Newer Older
1
/* $Header: /p/tcsh/cvsroot/tcsh/tc.sig.c,v 3.40 2012/01/25 15:34:41 christos Exp $ */
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
/*
 * tc.sig.c: Signal routine emulations
 */
/*-
 * Copyright (c) 1980, 1991 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "sh.h"

35
RCSID("$tcsh: tc.sig.c,v 3.40 2012/01/25 15:34:41 christos Exp $")
36 37 38 39

#include "tc.wait.h"

void
40 41 42 43 44 45 46 47 48 49 50 51 52
sigset_interrupting(int sig, void (*fn) (int))
{
    struct sigaction act;

    act.sa_handler = fn;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (sigaction(sig, &act, NULL) == 0) {
	sigset_t set;
	sigemptyset(&set);
	sigaddset(&set, sig);
	sigprocmask(SIG_UNBLOCK, &set, NULL);
    }
53 54
}

55 56 57 58 59 60 61 62
static volatile sig_atomic_t alrmcatch_pending; /* = 0; */
static volatile sig_atomic_t pchild_pending; /* = 0; */
static volatile sig_atomic_t phup_pending; /* = 0; */
static volatile sig_atomic_t pintr_pending; /* = 0; */
int alrmcatch_disabled; /* = 0; */
int phup_disabled; /* = 0; */
int pchild_disabled; /* = 0; */
int pintr_disabled; /* = 0; */
63
int handle_interrupt; /* = 0; */
64

65
int
66
handle_pending_signals(void)
67
{
68
    int rv = 0;
69 70
    if (!phup_disabled && phup_pending) {
	phup_pending = 0;
71
	handle_interrupt++;
72
	phup();
73
	handle_interrupt--;
74
    }
75 76
    if (!pintr_disabled && pintr_pending) {
	pintr_pending = 0;
77
	handle_interrupt++;
78
	pintr();
79 80
	handle_interrupt--;
	rv = 1;
81 82 83
    }
    if (!pchild_disabled && pchild_pending) {
	pchild_pending = 0;
84
	handle_interrupt++;
85
	pchild();
86
	handle_interrupt--;
87 88 89
    }
    if (!alrmcatch_disabled && alrmcatch_pending) {
	alrmcatch_pending = 0;
90
	handle_interrupt++;
91
	alrmcatch();
92
	handle_interrupt--;
93
    }
94
    return rv;
95 96 97
}

void
98
queue_alrmcatch(int sig)
99
{
100 101
    USE(sig);
    alrmcatch_pending = 1;
102 103
}

104 105
void
queue_pchild(int sig)
106
{
107 108
    USE(sig);
    pchild_pending = 1;
109 110
}

111 112
void
queue_phup(int sig)
113
{
114 115
    USE(sig);
    phup_pending = 1;
116 117
}

118 119
void
queue_pintr(int sig)
120
{
121 122
    USE(sig);
    pintr_pending = 1;
123 124 125
}

void
126
disabled_cleanup(void *xdisabled)
127
{
128
    int *disabled;
129

130 131 132
    disabled = xdisabled;
    if (--*disabled == 0)
	handle_pending_signals();
133 134
}

135 136
void
pintr_disabled_restore(void *xold)
137
{
138
    int *old;
139

140 141
    old = xold;
    pintr_disabled = *old;
142 143
}

144 145
void
pintr_push_enable(int *saved)
146
{
147 148 149 150
    *saved = pintr_disabled;
    pintr_disabled = 0;
    cleanup_push(saved, pintr_disabled_restore);
    handle_pending_signals();
151
}