GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libedit/sig.c Lines: 14 61 23.0 %
Date: 2017-11-13 Branches: 3 23 13.0 %

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