1*f1d4de73Schristos /* $NetBSD: sig.c,v 1.28 2024/12/18 15:38:52 christos Exp $ */ 22543e3e6Slukem 36dc2f1dbScgd /*- 46dc2f1dbScgd * Copyright (c) 1992, 1993 56dc2f1dbScgd * The Regents of the University of California. All rights reserved. 66dc2f1dbScgd * 76dc2f1dbScgd * This code is derived from software contributed to Berkeley by 86dc2f1dbScgd * Christos Zoulas of Cornell University. 96dc2f1dbScgd * 106dc2f1dbScgd * Redistribution and use in source and binary forms, with or without 116dc2f1dbScgd * modification, are permitted provided that the following conditions 126dc2f1dbScgd * are met: 136dc2f1dbScgd * 1. Redistributions of source code must retain the above copyright 146dc2f1dbScgd * notice, this list of conditions and the following disclaimer. 156dc2f1dbScgd * 2. Redistributions in binary form must reproduce the above copyright 166dc2f1dbScgd * notice, this list of conditions and the following disclaimer in the 176dc2f1dbScgd * documentation and/or other materials provided with the distribution. 18eb7c1594Sagc * 3. Neither the name of the University nor the names of its contributors 196dc2f1dbScgd * may be used to endorse or promote products derived from this software 206dc2f1dbScgd * without specific prior written permission. 216dc2f1dbScgd * 226dc2f1dbScgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 236dc2f1dbScgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 246dc2f1dbScgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 256dc2f1dbScgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 266dc2f1dbScgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 276dc2f1dbScgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 286dc2f1dbScgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 296dc2f1dbScgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 306dc2f1dbScgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 316dc2f1dbScgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 326dc2f1dbScgd * SUCH DAMAGE. 336dc2f1dbScgd */ 346dc2f1dbScgd 350e0ac6b7Schristos #include "config.h" 366dc2f1dbScgd #if !defined(lint) && !defined(SCCSID) 372543e3e6Slukem #if 0 386dc2f1dbScgd static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; 392543e3e6Slukem #else 40*f1d4de73Schristos __RCSID("$NetBSD: sig.c,v 1.28 2024/12/18 15:38:52 christos Exp $"); 412543e3e6Slukem #endif 426dc2f1dbScgd #endif /* not lint && not SCCSID */ 436dc2f1dbScgd 446dc2f1dbScgd /* 456dc2f1dbScgd * sig.c: Signal handling stuff. 466dc2f1dbScgd * our policy is to trap all signals, set a good state 476dc2f1dbScgd * and pass the ball to our caller. 486dc2f1dbScgd */ 49a539b892Schristos #include <errno.h> 50747f6811Schristos #include <stdlib.h> 51747f6811Schristos 52747f6811Schristos #include "el.h" 53747f6811Schristos #include "common.h" 54c807fdffSchristos 55469d44f8Schristos static EditLine *sel = NULL; 566dc2f1dbScgd 57469d44f8Schristos static const int sighdl[] = { 586dc2f1dbScgd #define _DO(a) (a), 596dc2f1dbScgd ALLSIGS 606dc2f1dbScgd #undef _DO 616dc2f1dbScgd - 1 626dc2f1dbScgd }; 636dc2f1dbScgd 64469d44f8Schristos static void sig_handler(int); 656dc2f1dbScgd 666dc2f1dbScgd /* sig_handler(): 676dc2f1dbScgd * This is the handler called for all signals 686dc2f1dbScgd * XXX: we cannot pass any data so we just store the old editline 696dc2f1dbScgd * state in a private variable 706dc2f1dbScgd */ 71469d44f8Schristos static void 72d30d584aSlukem sig_handler(int signo) 736dc2f1dbScgd { 745367da5fSchristos int i, save_errno; 756dc2f1dbScgd sigset_t nset, oset; 766dc2f1dbScgd 775367da5fSchristos save_errno = errno; 786dc2f1dbScgd (void) sigemptyset(&nset); 796dc2f1dbScgd (void) sigaddset(&nset, signo); 806dc2f1dbScgd (void) sigprocmask(SIG_BLOCK, &nset, &oset); 816dc2f1dbScgd 82e8bbf84cSchristos sel->el_signal->sig_no = signo; 83e8bbf84cSchristos 846dc2f1dbScgd switch (signo) { 856dc2f1dbScgd case SIGCONT: 866dc2f1dbScgd tty_rawmode(sel); 876dc2f1dbScgd if (ed_redisplay(sel, 0) == CC_REFRESH) 886dc2f1dbScgd re_refresh(sel); 89e63c844aSchristos terminal__flush(sel); 906dc2f1dbScgd break; 916dc2f1dbScgd 926dc2f1dbScgd case SIGWINCH: 936dc2f1dbScgd el_resize(sel); 946dc2f1dbScgd break; 956dc2f1dbScgd 966dc2f1dbScgd default: 976dc2f1dbScgd tty_cookedmode(sel); 986dc2f1dbScgd break; 996dc2f1dbScgd } 1006dc2f1dbScgd 1016dc2f1dbScgd for (i = 0; sighdl[i] != -1; i++) 1026dc2f1dbScgd if (signo == sighdl[i]) 1036dc2f1dbScgd break; 1046dc2f1dbScgd 105d25b6758Schristos (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL); 106d25b6758Schristos sel->el_signal->sig_action[i].sa_handler = SIG_ERR; 107d25b6758Schristos sel->el_signal->sig_action[i].sa_flags = 0; 108d25b6758Schristos sigemptyset(&sel->el_signal->sig_action[i].sa_mask); 1096dc2f1dbScgd (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1106dc2f1dbScgd (void) kill(0, signo); 1115367da5fSchristos errno = save_errno; 1126dc2f1dbScgd } 1136dc2f1dbScgd 1146dc2f1dbScgd 1156dc2f1dbScgd /* sig_init(): 1166dc2f1dbScgd * Initialize all signal stuff 1176dc2f1dbScgd */ 118a2d6b270Schristos libedit_private int 119d30d584aSlukem sig_init(EditLine *el) 1206dc2f1dbScgd { 121d25b6758Schristos size_t i; 122d25b6758Schristos sigset_t *nset, oset; 1236dc2f1dbScgd 124d25b6758Schristos el->el_signal = el_malloc(sizeof(*el->el_signal)); 125d25b6758Schristos if (el->el_signal == NULL) 126d25b6758Schristos return -1; 127d25b6758Schristos 128d25b6758Schristos nset = &el->el_signal->sig_set; 129d25b6758Schristos (void) sigemptyset(nset); 130d25b6758Schristos #define _DO(a) (void) sigaddset(nset, a); 1316dc2f1dbScgd ALLSIGS 1326dc2f1dbScgd #undef _DO 133d25b6758Schristos (void) sigprocmask(SIG_BLOCK, nset, &oset); 1346dc2f1dbScgd 135d25b6758Schristos for (i = 0; sighdl[i] != -1; i++) { 136d25b6758Schristos el->el_signal->sig_action[i].sa_handler = SIG_ERR; 137d25b6758Schristos el->el_signal->sig_action[i].sa_flags = 0; 138d25b6758Schristos sigemptyset(&el->el_signal->sig_action[i].sa_mask); 139d25b6758Schristos } 1406dc2f1dbScgd 1416dc2f1dbScgd (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1426dc2f1dbScgd 143d25b6758Schristos return 0; 1446dc2f1dbScgd } 1456dc2f1dbScgd 1466dc2f1dbScgd 1476dc2f1dbScgd /* sig_end(): 1486dc2f1dbScgd * Clear all signal stuff 1496dc2f1dbScgd */ 150a2d6b270Schristos libedit_private void 151d30d584aSlukem sig_end(EditLine *el) 1526dc2f1dbScgd { 153d30d584aSlukem 154a13cd756Schristos el_free(el->el_signal); 1556dc2f1dbScgd el->el_signal = NULL; 1566dc2f1dbScgd } 1576dc2f1dbScgd 1586dc2f1dbScgd 1596dc2f1dbScgd /* sig_set(): 1606dc2f1dbScgd * set all the signal handlers 1616dc2f1dbScgd */ 162a2d6b270Schristos libedit_private void 163d30d584aSlukem sig_set(EditLine *el) 1646dc2f1dbScgd { 165d25b6758Schristos size_t i; 166d25b6758Schristos sigset_t oset; 167d25b6758Schristos struct sigaction osa, nsa; 1686dc2f1dbScgd 169d25b6758Schristos nsa.sa_handler = sig_handler; 170*f1d4de73Schristos nsa.sa_flags = SA_ONSTACK; 171d25b6758Schristos sigemptyset(&nsa.sa_mask); 172d25b6758Schristos 1730428f1e1Schristos sel = el; 174d25b6758Schristos (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 1756dc2f1dbScgd 1766dc2f1dbScgd for (i = 0; sighdl[i] != -1; i++) { 1776dc2f1dbScgd /* This could happen if we get interrupted */ 178d25b6758Schristos if (sigaction(sighdl[i], &nsa, &osa) != -1 && 179d25b6758Schristos osa.sa_handler != sig_handler) 180d25b6758Schristos el->el_signal->sig_action[i] = osa; 1816dc2f1dbScgd } 1826dc2f1dbScgd (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1836dc2f1dbScgd } 1846dc2f1dbScgd 1856dc2f1dbScgd 1866dc2f1dbScgd /* sig_clr(): 1876dc2f1dbScgd * clear all the signal handlers 1886dc2f1dbScgd */ 189a2d6b270Schristos libedit_private void 190d30d584aSlukem sig_clr(EditLine *el) 1916dc2f1dbScgd { 192d25b6758Schristos size_t i; 193d25b6758Schristos sigset_t oset; 1946dc2f1dbScgd 195d25b6758Schristos (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 1966dc2f1dbScgd 1976dc2f1dbScgd for (i = 0; sighdl[i] != -1; i++) 198d25b6758Schristos if (el->el_signal->sig_action[i].sa_handler != SIG_ERR) 199d25b6758Schristos (void)sigaction(sighdl[i], 200d25b6758Schristos &el->el_signal->sig_action[i], NULL); 2016dc2f1dbScgd 2026dc2f1dbScgd (void)sigprocmask(SIG_SETMASK, &oset, NULL); 2036dc2f1dbScgd } 204