sig.c revision 1573
11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1992, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * This code is derived from software contributed to Berkeley by
61573Srgrimes * Christos Zoulas of Cornell University.
71573Srgrimes *
81573Srgrimes * Redistribution and use in source and binary forms, with or without
91573Srgrimes * modification, are permitted provided that the following conditions
101573Srgrimes * are met:
111573Srgrimes * 1. Redistributions of source code must retain the above copyright
121573Srgrimes *    notice, this list of conditions and the following disclaimer.
131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141573Srgrimes *    notice, this list of conditions and the following disclaimer in the
151573Srgrimes *    documentation and/or other materials provided with the distribution.
161573Srgrimes * 3. All advertising materials mentioning features or use of this software
171573Srgrimes *    must display the following acknowledgement:
181573Srgrimes *	This product includes software developed by the University of
191573Srgrimes *	California, Berkeley and its contributors.
201573Srgrimes * 4. Neither the name of the University nor the names of its contributors
211573Srgrimes *    may be used to endorse or promote products derived from this software
221573Srgrimes *    without specific prior written permission.
231573Srgrimes *
241573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341573Srgrimes * SUCH DAMAGE.
351573Srgrimes */
361573Srgrimes
371573Srgrimes#if !defined(lint) && !defined(SCCSID)
381573Srgrimesstatic char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 6/4/93";
391573Srgrimes#endif /* not lint && not SCCSID */
401573Srgrimes
411573Srgrimes/*
421573Srgrimes * sig.c: Signal handling stuff.
431573Srgrimes *	  our policy is to trap all signals, set a good state
441573Srgrimes *	  and pass the ball to our caller.
451573Srgrimes */
461573Srgrimes#include "sys.h"
471573Srgrimes#include "el.h"
481573Srgrimes#include <stdlib.h>
491573Srgrimes
501573Srgrimesprivate EditLine *sel = NULL;
511573Srgrimes
521573Srgrimesprivate int sighdl[] = {
531573Srgrimes#define _DO(a)	(a),
541573Srgrimes    ALLSIGS
551573Srgrimes#undef _DO
561573Srgrimes    -1
571573Srgrimes};
581573Srgrimes
591573Srgrimesprivate void sig_handler	__P((int));
601573Srgrimes
611573Srgrimes/* sig_handler():
621573Srgrimes *	This is the handler called for all signals
631573Srgrimes *	XXX: we cannot pass any data so we just store the old editline
641573Srgrimes *	state in a private variable
651573Srgrimes */
661573Srgrimesprivate void
671573Srgrimessig_handler(signo)
681573Srgrimes    int signo;
691573Srgrimes{
701573Srgrimes    int i;
711573Srgrimes    sigset_t nset, oset;
721573Srgrimes
731573Srgrimes    (void) sigemptyset(&nset);
741573Srgrimes    (void) sigaddset(&nset, signo);
751573Srgrimes    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
761573Srgrimes
771573Srgrimes    switch (signo) {
781573Srgrimes    case SIGCONT:
791573Srgrimes	tty_rawmode(sel);
801573Srgrimes	if (ed_redisplay(sel, 0) == CC_REFRESH)
811573Srgrimes	    re_refresh(sel);
821573Srgrimes	term__flush();
831573Srgrimes	break;
841573Srgrimes
851573Srgrimes    case SIGWINCH:
861573Srgrimes	el_resize(sel);
871573Srgrimes	break;
881573Srgrimes
891573Srgrimes    default:
901573Srgrimes	tty_cookedmode(sel);
911573Srgrimes	break;
921573Srgrimes    }
931573Srgrimes
941573Srgrimes    for (i = 0; sighdl[i] != -1; i++)
951573Srgrimes	if (signo == sighdl[i])
961573Srgrimes	    break;
971573Srgrimes
981573Srgrimes    (void) signal(signo, sel->el_signal[i]);
991573Srgrimes    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
1001573Srgrimes    (void) kill(0, signo);
1011573Srgrimes}
1021573Srgrimes
1031573Srgrimes
1041573Srgrimes/* sig_init():
1051573Srgrimes *	Initialize all signal stuff
1061573Srgrimes */
1071573Srgrimesprotected int
1081573Srgrimessig_init(el)
1091573Srgrimes    EditLine *el;
1101573Srgrimes{
1111573Srgrimes    int i;
1121573Srgrimes    sigset_t nset, oset;
1131573Srgrimes
1141573Srgrimes    (void) sigemptyset(&nset);
1151573Srgrimes#define _DO(a) (void) sigaddset(&nset, SIGWINCH);
1161573Srgrimes    ALLSIGS
1171573Srgrimes#undef _DO
1181573Srgrimes    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1191573Srgrimes
1201573Srgrimes#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
1211573Srgrimes
1221573Srgrimes    el->el_signal = (sig_t *) el_malloc(SIGSIZE);
1231573Srgrimes    for (i = 0; sighdl[i] != -1; i++)
1241573Srgrimes	el->el_signal[i] = BADSIG;
1251573Srgrimes
1261573Srgrimes    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
1271573Srgrimes
1281573Srgrimes    return 0;
1291573Srgrimes}
1301573Srgrimes
1311573Srgrimes
1321573Srgrimes/* sig_end():
1331573Srgrimes *	Clear all signal stuff
1341573Srgrimes */
1351573Srgrimesprotected void
1361573Srgrimessig_end(el)
1371573Srgrimes    EditLine *el;
1381573Srgrimes{
1391573Srgrimes    el_free((ptr_t) el->el_signal);
1401573Srgrimes    el->el_signal = NULL;
1411573Srgrimes}
1421573Srgrimes
1431573Srgrimes
1441573Srgrimes/* sig_set():
1451573Srgrimes *	set all the signal handlers
1461573Srgrimes */
1471573Srgrimesprotected void
1481573Srgrimessig_set(el)
1491573Srgrimes    EditLine *el;
1501573Srgrimes{
1511573Srgrimes    int i;
1521573Srgrimes    sigset_t nset, oset;
1531573Srgrimes
1541573Srgrimes    (void) sigemptyset(&nset);
1551573Srgrimes#define _DO(a) (void) sigaddset(&nset, SIGWINCH);
1561573Srgrimes    ALLSIGS
1571573Srgrimes#undef _DO
1581573Srgrimes    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1591573Srgrimes
1601573Srgrimes    for (i = 0; sighdl[i] != -1; i++) {
1611573Srgrimes	sig_t s;
1621573Srgrimes	/* This could happen if we get interrupted */
1631573Srgrimes	if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
1641573Srgrimes	    el->el_signal[i] = s;
1651573Srgrimes    }
1661573Srgrimes    sel = el;
1671573Srgrimes    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
1681573Srgrimes}
1691573Srgrimes
1701573Srgrimes
1711573Srgrimes/* sig_clr():
1721573Srgrimes *	clear all the signal handlers
1731573Srgrimes */
1741573Srgrimesprotected void
1751573Srgrimessig_clr(el)
1761573Srgrimes    EditLine *el;
1771573Srgrimes{
1781573Srgrimes    int i;
1791573Srgrimes    sigset_t nset, oset;
1801573Srgrimes
1811573Srgrimes    (void) sigemptyset(&nset);
1821573Srgrimes#define _DO(a) (void) sigaddset(&nset, SIGWINCH);
1831573Srgrimes    ALLSIGS
1841573Srgrimes#undef _DO
1851573Srgrimes    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1861573Srgrimes
1871573Srgrimes    for (i = 0; sighdl[i] != -1; i++)
1881573Srgrimes	if (el->el_signal[i] != BADSIG)
1891573Srgrimes	    (void) signal(sighdl[i], el->el_signal[i]);
1901573Srgrimes
1911573Srgrimes    sel = NULL;	/* we are going to die if the handler is called */
1921573Srgrimes    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
1931573Srgrimes}
194