Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/misc/sigcrit.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
/*
24
* Glenn Fowler
25
* AT&T Research
26
*
27
* signal critical region support
28
*/
29
30
#include <ast.h>
31
#include <sig.h>
32
33
static struct
34
{
35
int sig;
36
int op;
37
}
38
signals[] = /* held inside critical region */
39
{
40
SIGINT, SIG_REG_EXEC,
41
#ifdef SIGPIPE
42
SIGPIPE, SIG_REG_EXEC,
43
#endif
44
#ifdef SIGQUIT
45
SIGQUIT, SIG_REG_EXEC,
46
#endif
47
#ifdef SIGHUP
48
SIGHUP, SIG_REG_EXEC,
49
#endif
50
#if defined(SIGCHLD) && ( !defined(SIGCLD) || SIGCHLD != SIGCLD || _lib_sigprocmask || _lib_sigsetmask )
51
SIGCHLD, SIG_REG_PROC,
52
#endif
53
#ifdef SIGTSTP
54
SIGTSTP, SIG_REG_TERM,
55
#endif
56
#ifdef SIGTTIN
57
SIGTTIN, SIG_REG_TERM,
58
#endif
59
#ifdef SIGTTOU
60
SIGTTOU, SIG_REG_TERM,
61
#endif
62
};
63
64
#ifndef SIG_SETMASK
65
#undef _lib_sigprocmask
66
#endif
67
68
#if !_lib_sigprocmask && !_lib_sigsetmask
69
70
static long hold; /* held signal mask */
71
72
/*
73
* hold last signal for later delivery
74
*/
75
76
static void
77
interrupt(int sig)
78
{
79
signal(sig, interrupt);
80
hold |= sigmask(sig);
81
}
82
83
#endif
84
85
/*
86
* critical signal region handler
87
*
88
* op>0 new region according to SIG_REG_*, return region level
89
* op==0 pop region, return region level
90
* op<0 return non-zero if any signals held in current region
91
*
92
* signals[] held until region popped
93
*/
94
95
int
96
sigcritical(int op)
97
{
98
register int i;
99
static int region;
100
static int level;
101
#if _lib_sigprocmask
102
static sigset_t mask;
103
sigset_t nmask;
104
#else
105
#if _lib_sigsetmask
106
static long mask;
107
#else
108
static Sig_handler_t handler[elementsof(signals)];
109
#endif
110
#endif
111
112
if (op > 0)
113
{
114
if (!level++)
115
{
116
region = op;
117
if (op & SIG_REG_SET)
118
level--;
119
#if _lib_sigprocmask
120
sigemptyset(&nmask);
121
for (i = 0; i < elementsof(signals); i++)
122
if (op & signals[i].op)
123
sigaddset(&nmask, signals[i].sig);
124
sigprocmask(SIG_BLOCK, &nmask, &mask);
125
#else
126
#if _lib_sigsetmask
127
mask = 0;
128
for (i = 0; i < elementsof(signals); i++)
129
if (op & signals[i].op)
130
mask |= sigmask(signals[i].sig);
131
mask = sigblock(mask);
132
#else
133
hold = 0;
134
for (i = 0; i < elementsof(signals); i++)
135
if ((op & signals[i].op) && (handler[i] = signal(signals[i].sig, interrupt)) == SIG_IGN)
136
{
137
signal(signals[i].sig, handler[i]);
138
hold &= ~sigmask(signals[i].sig);
139
}
140
#endif
141
#endif
142
}
143
return level;
144
}
145
else if (op < 0)
146
{
147
#if _lib_sigprocmask
148
sigpending(&nmask);
149
for (i = 0; i < elementsof(signals); i++)
150
if (region & signals[i].op)
151
{
152
if (sigismember(&nmask, signals[i].sig))
153
return 1;
154
}
155
return 0;
156
#else
157
#if _lib_sigsetmask
158
/* no way to get pending signals without installing handler */
159
return 0;
160
#else
161
return hold != 0;
162
#endif
163
#endif
164
}
165
else
166
{
167
/*
168
* a vfork() may have intervened so we
169
* allow apparent nesting mismatches
170
*/
171
172
if (--level <= 0)
173
{
174
level = 0;
175
#if _lib_sigprocmask
176
sigprocmask(SIG_SETMASK, &mask, NiL);
177
#else
178
#if _lib_sigsetmask
179
sigsetmask(mask);
180
#else
181
for (i = 0; i < elementsof(signals); i++)
182
if (region & signals[i].op)
183
signal(signals[i].sig, handler[i]);
184
if (hold)
185
{
186
for (i = 0; i < elementsof(signals); i++)
187
if (region & signals[i].op)
188
{
189
if (hold & sigmask(signals[i].sig))
190
kill(getpid(), signals[i].sig);
191
}
192
pause();
193
}
194
#endif
195
#endif
196
}
197
return level;
198
}
199
}
200
201