1/*	$NetBSD: sig.c,v 1.6 2005/06/09 16:48:58 lukem Exp $	*/
2/*	from	NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc 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 "tnftp.h"
37#include "sys.h"
38
39/*
40 * sig.c: Signal handling stuff.
41 *	  our policy is to trap all signals, set a good state
42 *	  and pass the ball to our caller.
43 */
44#include "el.h"
45#include <stdlib.h>
46
47#include "src/progressbar.h"	/* for xsignal_restart() */
48
49private EditLine *sel = NULL;
50
51private const int sighdl[] = {
52#define	_DO(a)	(a),
53	ALLSIGS
54#undef	_DO
55	- 1
56};
57
58private 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 */
65private void
66sig_handler(int signo)
67{
68	int i;
69	sigset_t nset, oset;
70
71	(void) sigemptyset(&nset);
72	(void) sigaddset(&nset, signo);
73	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
74
75	switch (signo) {
76	case SIGCONT:
77		tty_rawmode(sel);
78		if (ed_redisplay(sel, 0) == CC_REFRESH)
79			re_refresh(sel);
80		term__flush();
81		break;
82
83	case SIGWINCH:
84		el_resize(sel);
85		break;
86
87	default:
88		tty_cookedmode(sel);
89		break;
90	}
91
92	for (i = 0; sighdl[i] != -1; i++)
93		if (signo == sighdl[i])
94			break;
95
96	(void) xsignal_restart(signo, sel->el_signal[i], 1);
97	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
98	(void) kill(0, signo);
99}
100
101
102/* sig_init():
103 *	Initialize all signal stuff
104 */
105protected int
106sig_init(EditLine *el)
107{
108	int i;
109	sigset_t nset, oset;
110
111	(void) sigemptyset(&nset);
112#define	_DO(a) (void) sigaddset(&nset, a);
113	ALLSIGS
114#undef	_DO
115	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
116
117#define	SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t))
118
119	el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE);
120	if (el->el_signal == NULL)
121		return (-1);
122	for (i = 0; sighdl[i] != -1; i++)
123		el->el_signal[i] = SIG_ERR;
124
125	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
126
127	return (0);
128}
129
130
131/* sig_end():
132 *	Clear all signal stuff
133 */
134protected void
135sig_end(EditLine *el)
136{
137
138	el_free((ptr_t) el->el_signal);
139	el->el_signal = NULL;
140}
141
142
143/* sig_set():
144 *	set all the signal handlers
145 */
146protected void
147sig_set(EditLine *el)
148{
149	int i;
150	sigset_t nset, oset;
151
152	(void) sigemptyset(&nset);
153#define	_DO(a) (void) sigaddset(&nset, a);
154	ALLSIGS
155#undef	_DO
156	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
157
158	for (i = 0; sighdl[i] != -1; i++) {
159		el_signalhandler_t s;
160		/* This could happen if we get interrupted */
161		if ((s = xsignal_restart(sighdl[i], sig_handler, 1)) != sig_handler)
162			el->el_signal[i] = s;
163	}
164	sel = el;
165	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
166}
167
168
169/* sig_clr():
170 *	clear all the signal handlers
171 */
172protected void
173sig_clr(EditLine *el)
174{
175	int i;
176	sigset_t nset, oset;
177
178	(void) sigemptyset(&nset);
179#define	_DO(a) (void) sigaddset(&nset, a);
180	ALLSIGS
181#undef	_DO
182	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
183
184	for (i = 0; sighdl[i] != -1; i++)
185		if (el->el_signal[i] != SIG_ERR)
186			(void) xsignal_restart(sighdl[i], el->el_signal[i], 1);
187
188	sel = NULL;		/* we are going to die if the handler is
189				 * called */
190	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
191}
192