Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libedit/sig.c
39478 views
1
/* $NetBSD: sig.c,v 1.28 2024/12/18 15:38:52 christos Exp $ */
2
3
/*-
4
* Copyright (c) 1992, 1993
5
* The Regents of the University of California. All rights reserved.
6
*
7
* This code is derived from software contributed to Berkeley by
8
* Christos Zoulas of Cornell University.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include "config.h"
36
#if !defined(lint) && !defined(SCCSID)
37
#if 0
38
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
39
#else
40
__RCSID("$NetBSD: sig.c,v 1.28 2024/12/18 15:38:52 christos Exp $");
41
#endif
42
#endif /* not lint && not SCCSID */
43
44
/*
45
* sig.c: Signal handling stuff.
46
* our policy is to trap all signals, set a good state
47
* and pass the ball to our caller.
48
*/
49
#include <errno.h>
50
#include <stdlib.h>
51
52
#include "el.h"
53
#include "common.h"
54
55
static EditLine *sel = NULL;
56
57
static const int sighdl[] = {
58
#define _DO(a) (a),
59
ALLSIGS
60
#undef _DO
61
- 1
62
};
63
64
static void sig_handler(int);
65
66
/* sig_handler():
67
* This is the handler called for all signals
68
* XXX: we cannot pass any data so we just store the old editline
69
* state in a private variable
70
*/
71
static void
72
sig_handler(int signo)
73
{
74
int i, save_errno;
75
sigset_t nset, oset;
76
77
save_errno = errno;
78
(void) sigemptyset(&nset);
79
(void) sigaddset(&nset, signo);
80
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
81
82
sel->el_signal->sig_no = signo;
83
84
switch (signo) {
85
case SIGCONT:
86
tty_rawmode(sel);
87
if (ed_redisplay(sel, 0) == CC_REFRESH)
88
re_refresh(sel);
89
terminal__flush(sel);
90
break;
91
92
case SIGWINCH:
93
el_resize(sel);
94
break;
95
96
default:
97
tty_cookedmode(sel);
98
break;
99
}
100
101
for (i = 0; sighdl[i] != -1; i++)
102
if (signo == sighdl[i])
103
break;
104
105
(void) sigaction(signo, &sel->el_signal->sig_action[i], NULL);
106
sel->el_signal->sig_action[i].sa_handler = SIG_ERR;
107
sel->el_signal->sig_action[i].sa_flags = 0;
108
sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
109
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
110
(void) kill(0, signo);
111
errno = save_errno;
112
}
113
114
115
/* sig_init():
116
* Initialize all signal stuff
117
*/
118
libedit_private int
119
sig_init(EditLine *el)
120
{
121
size_t i;
122
sigset_t *nset, oset;
123
124
el->el_signal = el_malloc(sizeof(*el->el_signal));
125
if (el->el_signal == NULL)
126
return -1;
127
128
nset = &el->el_signal->sig_set;
129
(void) sigemptyset(nset);
130
#define _DO(a) (void) sigaddset(nset, a);
131
ALLSIGS
132
#undef _DO
133
(void) sigprocmask(SIG_BLOCK, nset, &oset);
134
135
for (i = 0; sighdl[i] != -1; i++) {
136
el->el_signal->sig_action[i].sa_handler = SIG_ERR;
137
el->el_signal->sig_action[i].sa_flags = 0;
138
sigemptyset(&el->el_signal->sig_action[i].sa_mask);
139
}
140
141
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
142
143
return 0;
144
}
145
146
147
/* sig_end():
148
* Clear all signal stuff
149
*/
150
libedit_private void
151
sig_end(EditLine *el)
152
{
153
154
el_free(el->el_signal);
155
el->el_signal = NULL;
156
}
157
158
159
/* sig_set():
160
* set all the signal handlers
161
*/
162
libedit_private void
163
sig_set(EditLine *el)
164
{
165
size_t i;
166
sigset_t oset;
167
struct sigaction osa, nsa;
168
169
nsa.sa_handler = sig_handler;
170
nsa.sa_flags = SA_ONSTACK;
171
sigemptyset(&nsa.sa_mask);
172
173
sel = el;
174
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
175
176
for (i = 0; sighdl[i] != -1; i++) {
177
/* This could happen if we get interrupted */
178
if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
179
osa.sa_handler != sig_handler)
180
el->el_signal->sig_action[i] = osa;
181
}
182
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
183
}
184
185
186
/* sig_clr():
187
* clear all the signal handlers
188
*/
189
libedit_private void
190
sig_clr(EditLine *el)
191
{
192
size_t i;
193
sigset_t oset;
194
195
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
196
197
for (i = 0; sighdl[i] != -1; i++)
198
if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
199
(void)sigaction(sighdl[i],
200
&el->el_signal->sig_action[i], NULL);
201
202
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
203
}
204
205