1 /*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Christos Zoulas of Cornell University. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #if !defined(lint) && !defined(SCCSID) 12 static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 06/04/93"; 13 #endif /* not lint && not SCCSID */ 14 15 /* 16 * sig.c: Signal handling stuff. 17 * our policy is to trap all signals, set a good state 18 * and pass the ball to our caller. 19 */ 20 #include "sys.h" 21 #include "el.h" 22 #include <stdlib.h> 23 24 private EditLine *sel = NULL; 25 26 private int sighdl[] = { 27 #define _DO(a) (a), 28 ALLSIGS 29 #undef _DO 30 -1 31 }; 32 33 private void sig_handler __P((int)); 34 35 /* sig_handler(): 36 * This is the handler called for all signals 37 * XXX: we cannot pass any data so we just store the old editline 38 * state in a private variable 39 */ 40 private void 41 sig_handler(signo) 42 int signo; 43 { 44 int i; 45 sigset_t nset, oset; 46 47 (void) sigemptyset(&nset); 48 (void) sigaddset(&nset, signo); 49 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 50 51 switch (signo) { 52 case SIGCONT: 53 tty_rawmode(sel); 54 if (ed_redisplay(sel, 0) == CC_REFRESH) 55 re_refresh(sel); 56 term__flush(); 57 break; 58 59 case SIGWINCH: 60 el_resize(sel); 61 break; 62 63 default: 64 tty_cookedmode(sel); 65 break; 66 } 67 68 for (i = 0; sighdl[i] != -1; i++) 69 if (signo == sighdl[i]) 70 break; 71 72 (void) signal(signo, sel->el_signal[i]); 73 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 74 (void) kill(0, signo); 75 } 76 77 78 /* sig_init(): 79 * Initialize all signal stuff 80 */ 81 protected int 82 sig_init(el) 83 EditLine *el; 84 { 85 int i; 86 sigset_t nset, oset; 87 88 (void) sigemptyset(&nset); 89 #define _DO(a) (void) sigaddset(&nset, SIGWINCH); 90 ALLSIGS 91 #undef _DO 92 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 93 94 #define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t)) 95 96 el->el_signal = (sig_t *) el_malloc(SIGSIZE); 97 for (i = 0; sighdl[i] != -1; i++) 98 el->el_signal[i] = BADSIG; 99 100 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 101 102 return 0; 103 } 104 105 106 /* sig_end(): 107 * Clear all signal stuff 108 */ 109 protected void 110 sig_end(el) 111 EditLine *el; 112 { 113 el_free((ptr_t) el->el_signal); 114 el->el_signal = NULL; 115 } 116 117 118 /* sig_set(): 119 * set all the signal handlers 120 */ 121 protected void 122 sig_set(el) 123 EditLine *el; 124 { 125 int i; 126 sigset_t nset, oset; 127 128 (void) sigemptyset(&nset); 129 #define _DO(a) (void) sigaddset(&nset, SIGWINCH); 130 ALLSIGS 131 #undef _DO 132 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 133 134 for (i = 0; sighdl[i] != -1; i++) { 135 sig_t s; 136 /* This could happen if we get interrupted */ 137 if ((s = signal(sighdl[i], sig_handler)) != sig_handler) 138 el->el_signal[i] = s; 139 } 140 sel = el; 141 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 142 } 143 144 145 /* sig_clr(): 146 * clear all the signal handlers 147 */ 148 protected void 149 sig_clr(el) 150 EditLine *el; 151 { 152 int i; 153 sigset_t nset, oset; 154 155 (void) sigemptyset(&nset); 156 #define _DO(a) (void) sigaddset(&nset, SIGWINCH); 157 ALLSIGS 158 #undef _DO 159 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 160 161 for (i = 0; sighdl[i] != -1; i++) 162 if (el->el_signal[i] != BADSIG) 163 (void) signal(sighdl[i], el->el_signal[i]); 164 165 sel = NULL; /* we are going to die if the handler is called */ 166 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 167 } 168