sig.cxx

Go to the documentation of this file.
00001 // @(#)root/editline:$Id: sig.cxx 32454 2010-03-04 11:06:09Z axel $
00002 // Author: Mary-Louise Gill, 2009
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 /*      $NetBSD: sig.c,v 1.8 2001/01/09 17:31:04 jdolecek Exp $ */
00013 
00014 /*-
00015  * Copyright (c) 1992, 1993
00016  *      The Regents of the University of California.  All rights reserved.
00017  *
00018  * This code is derived from software contributed to Berkeley by
00019  * Christos Zoulas of Cornell University.
00020  *
00021  * Redistribution and use in source and binary forms, with or without
00022  * modification, are permitted provided that the following conditions
00023  * are met:
00024  * 1. Redistributions of source code must retain the above copyright
00025  *    notice, this list of conditions and the following disclaimer.
00026  * 2. Redistributions in binary form must reproduce the above copyright
00027  *    notice, this list of conditions and the following disclaimer in the
00028  *    documentation and/or other materials provided with the distribution.
00029  * 3. Neither the name of the University nor the names of its contributors
00030  *    may be used to endorse or promote products derived from this software
00031  *    without specific prior written permission.
00032  *
00033  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00034  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00035  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00036  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00037  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00038  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00039  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00040  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00041  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00042  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00043  * SUCH DAMAGE.
00044  */
00045 
00046 #include "compat.h"
00047 
00048 /*
00049  * sig.c: Signal handling stuff.
00050  *        our policy is to trap all signals, set a good state
00051  *        and pass the ball to our caller.
00052  */
00053 #include "sys.h"
00054 #include "el.h"
00055 #include <stdlib.h>
00056 
00057 el_private EditLine_t* sel = NULL;
00058 
00059 el_private const int sighdl[] = {
00060 #define _DO(a) (a),
00061    ALLSIGS
00062 #undef  _DO
00063    - 1
00064 };
00065 
00066 el_private extern "C" void sig_handler(int);
00067 
00068 /* sig_handler():
00069  *      This is the handler called for all signals
00070  *      XXX: we cannot pass any data so we just store the old SEditLine_t
00071  *      state in a el_private variable
00072  */
00073 el_private void
00074 sig_handler(int signo) {
00075 
00076    sigset_t nset, oset;
00077    (void) sigemptyset(&nset);
00078    (void) sigaddset(&nset, signo);
00079    /* not needed; a signal is always blocked before invoking
00080       the signal handler for that signal.
00081    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
00082    */
00083 
00084    switch (signo) {
00085    case SIGCONT:
00086       if (tty_can_output()) {
00087          tty_rawmode(sel);
00088          //if (ed_redisplay(sel, 0) == CC_REFRESH) {
00089          re_clear_display(sel);
00090          re_refresh(sel);
00091          //}
00092          term__flush();
00093       }
00094       break;
00095 
00096    case SIGWINCH:
00097       el_resize(sel);
00098       break;
00099 
00100    default:
00101       tty_cookedmode(sel);
00102       break;
00103    } // switch
00104 
00105    int i = 0;
00106    for (; sighdl[i] != -1; i++) {
00107       if (signo == sighdl[i]) {
00108          break;
00109       }
00110    }
00111    if (sighdl[i] == -1)
00112       i = -1;
00113    else {
00114       (void) sigprocmask(SIG_UNBLOCK, &nset, &oset);
00115       (void) signal(signo, sel->fSignal[i]);
00116       // forward to previous signal handler:
00117       (void) kill(0, signo);
00118       (void) sigprocmask(SIG_SETMASK, &oset, NULL);
00119 
00120       // re-enable us
00121       sig_t s;
00122       /* This could happen if we get interrupted */
00123       if (i != -1 ) {
00124          if ((s = signal(signo, sig_handler)) != sig_handler) {
00125             sel->fSignal[i] = s;
00126          }
00127       }
00128    }
00129 } // sig_handler
00130 
00131 
00132 /* sig_init():
00133  *      Initialize all signal stuff
00134  */
00135 el_protected int
00136 sig_init(EditLine_t* el) {
00137    int i;
00138    sigset_t nset, oset;
00139 
00140    (void) sigemptyset(&nset);
00141 #define _DO(a) (void) sigaddset(&nset, a);
00142    ALLSIGS
00143 #undef  _DO
00144       (void) sigprocmask(SIG_BLOCK, &nset, &oset);
00145 
00146 #define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
00147 
00148    el->fSignal = (sig_t*) el_malloc(SIGSIZE);
00149 
00150    if (el->fSignal == NULL) {
00151       return -1;
00152    }
00153 
00154    for (i = 0; sighdl[i] != -1; i++) {
00155       el->fSignal[i] = SIG_ERR;
00156    }
00157 
00158    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
00159 
00160    return 0;
00161 } // sig_init
00162 
00163 
00164 /* sig_end():
00165  *      Clear all signal stuff
00166  */
00167 el_protected void
00168 sig_end(EditLine_t* el) {
00169    el_free((ptr_t) el->fSignal);
00170    el->fSignal = NULL;
00171 }
00172 
00173 
00174 /* sig_set():
00175  *      set all the signal handlers
00176  */
00177 el_protected void
00178 sig_set(EditLine_t* el) {
00179    int i;
00180    sigset_t nset, oset;
00181 
00182    (void) sigemptyset(&nset);
00183 #define _DO(a) (void) sigaddset(&nset, a);
00184    ALLSIGS
00185 #undef  _DO
00186       (void) sigprocmask(SIG_BLOCK, &nset, &oset);
00187 
00188    for (i = 0; sighdl[i] != -1; i++) {
00189       sig_t s;
00190 
00191       /* This could happen if we get interrupted */
00192       if ((s = signal(sighdl[i], sig_handler)) != sig_handler) {
00193          el->fSignal[i] = s;
00194       }
00195    }
00196    sel = el;
00197    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
00198 } // sig_set
00199 
00200 
00201 /* sig_clr():
00202  *      clear all the signal handlers
00203  */
00204 el_protected void
00205 sig_clr(EditLine_t* el) {
00206    int i;
00207    sigset_t nset, oset;
00208 
00209    (void) sigemptyset(&nset);
00210 #define _DO(a) (void) sigaddset(&nset, a);
00211    ALLSIGS
00212 #undef  _DO
00213       (void) sigprocmask(SIG_BLOCK, &nset, &oset);
00214 
00215    for (i = 0; sighdl[i] != -1; i++) {
00216       if (el->fSignal[i] != SIG_ERR) {
00217          (void) signal(sighdl[i], el->fSignal[i]);
00218       }
00219    }
00220 
00221    sel = NULL;                  /* we are going to die if the handler is
00222                                  * called */
00223    (void) sigprocmask(SIG_SETMASK, &oset, NULL);
00224 } // sig_clr

Generated on Tue Jul 5 14:11:38 2011 for ROOT_528-00b_version by  doxygen 1.5.1