root/user/lib/hostcompat/hostcompat.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hostcompat_ttyreset
  2. hostcompat_ttyresume
  3. hostcompat_ttysetup
  4. hostcompat_die
  5. hostcompat_stop
  6. hostcompat_cont
  7. hostcompat_init

   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 #include <unistd.h>
  31 #include <termios.h>
  32 #include <signal.h>
  33 #include <stdlib.h>
  34 #include <stdio.h>
  35 
  36 #include "hostcompat.h"
  37 
  38 /*
  39  * The program name.
  40  * This is used in err.c.
  41  */
  42 const char *hostcompat_progname = NULL;
  43 
  44 /*
  45  * Unix tty state, for when we're running and to put it back the way it was,
  46  * respectively.
  47  */
  48 static struct termios hostcompat_runtios;
  49 static struct termios hostcompat_savetios;
  50 
  51 /*
  52  * Put the tty state back the way it was.
  53  */
  54 static
  55 void
  56 hostcompat_ttyreset(void)
  57 {
  58         tcsetattr(STDIN_FILENO, TCSADRAIN, &hostcompat_savetios);
  59 }
  60 
  61 /*
  62  * Set the tty state back to the way we want it for running.
  63  */
  64 static
  65 void
  66 hostcompat_ttyresume(void)
  67 {
  68         tcsetattr(STDIN_FILENO, TCSADRAIN, &hostcompat_runtios);
  69 }
  70 
  71 /*
  72  * Set up the tty state stuff.
  73  */
  74 static
  75 int
  76 hostcompat_ttysetup(void)
  77 {
  78         struct termios tios;
  79 
  80         /* Get the current tty state. */
  81         if (tcgetattr(STDIN_FILENO, &tios) < 0) {
  82                 /* stdin is not a tty */
  83                 return -1;
  84         }
  85 
  86         hostcompat_savetios = tios;
  87 
  88         /* Turn off canonical ("cooked") input. */
  89         tios.c_lflag &= ~ICANON;
  90 
  91         /*
  92          * With canonical input off, this says how many characters must be
  93          * typed before read() will return.
  94          */
  95         tios.c_cc[VMIN] = 1;
  96 
  97         /* This can be used to set up read timeouts, but we don't need that. */
  98         tios.c_cc[VTIME] = 0;
  99 
 100         /* Turn off echoing of keypresses. */
 101         tios.c_lflag &= ~(ECHO|ECHONL|ECHOCTL);
 102 
 103         /* Do not support XON/XOFF flow control. */
 104         tios.c_iflag &= ~(IXON|IXOFF);
 105 
 106         /* On input, we want no CR/LF translation. */
 107         tios.c_iflag &= ~(INLCR|IGNCR|ICRNL);
 108 
 109         /* However, on output we want LF ('\n') mapped to CRLF. */
 110 #ifdef OCRNL    /* missing on OS X */
 111         tios.c_oflag &= ~(OCRNL);
 112 #endif
 113         tios.c_oflag |= OPOST|ONLCR;
 114 
 115         /* Enable keyboard signals (^C, ^Z, etc.) because they're useful. */
 116         tios.c_lflag |= ISIG;
 117 
 118         /* Set the new tty state. */
 119         hostcompat_runtios = tios;
 120         tcsetattr(STDIN_FILENO, TCSADRAIN, &tios);
 121 
 122         return 0;
 123 }
 124 
 125 /*
 126  * Signal handler for all the fatal signals (SIGSEGV, SIGTERM, etc.)
 127  */
 128 static
 129 void
 130 hostcompat_die(int sig)
 131 {
 132         /* Set the tty back to the way we found it */
 133         hostcompat_ttyreset();
 134 
 135         /* Make sure the default action will occur when we get another signal*/
 136         signal(sig, SIG_DFL);
 137 
 138         /* Post the signal back to ourselves, to cause the right exit status.*/
 139         kill(getpid(), sig);
 140 
 141         /* Just in case. */
 142         _exit(255);
 143 }
 144 
 145 /*
 146  * Signal handler for the stop signals (SIGTSTP, SIGTTIN, etc.)
 147  */
 148 static
 149 void
 150 hostcompat_stop(int sig)
 151 {
 152         /* Set the tty back to the way we found it */
 153         hostcompat_ttyreset();
 154 
 155         /* Make sure the default action will occur when we get another signal*/
 156         signal(sig, SIG_DFL);
 157 
 158         /* Post the signal back to ourselves. */
 159         kill(getpid(), sig);
 160 }
 161 
 162 /*
 163  * Signal handler for SIGCONT.
 164  */
 165 static
 166 void
 167 hostcompat_cont(int sig)
 168 {
 169         (void)sig;
 170 
 171         /* Set the tty to the way we want it for running. */
 172         hostcompat_ttyresume();
 173 
 174         /*
 175          * Reload the signal handlers for stop/continue signals, in case
 176          * they were set up with one-shot signals.
 177          */
 178         signal(SIGTTIN, hostcompat_stop);
 179         signal(SIGTTOU, hostcompat_stop);
 180         signal(SIGTSTP, hostcompat_stop);
 181         signal(SIGCONT, hostcompat_cont);
 182 }
 183 
 184 /*
 185  * Initialize the hostcompat library.
 186  */
 187 void
 188 hostcompat_init(int argc, char *argv[])
 189 {
 190         /* Set the program name */
 191         if (argc > 0 && argv[0] != NULL) {
 192                 hostcompat_progname = argv[0];
 193         }
 194 
 195         /* Set the tty modes */
 196         if (hostcompat_ttysetup() < 0) {
 197                 return;
 198         }
 199 
 200         /* When exit() is called, clean up */
 201         atexit(hostcompat_ttyreset);
 202 
 203         /* stdout/stderr should be unbuffered */
 204         setvbuf(stdout, NULL, _IONBF, 0);
 205         setvbuf(stderr, NULL, _IONBF, 0);
 206 
 207         /* Catch all the fatal signals, so we can clean up */
 208         signal(SIGHUP, hostcompat_die);
 209         signal(SIGINT, hostcompat_die);
 210         signal(SIGQUIT, hostcompat_die);
 211         signal(SIGILL, hostcompat_die);
 212         signal(SIGTRAP, hostcompat_die);
 213         signal(SIGABRT, hostcompat_die);
 214 #ifdef SIGEMT
 215         signal(SIGEMT, hostcompat_die);
 216 #endif
 217         signal(SIGFPE, hostcompat_die);
 218         signal(SIGBUS, hostcompat_die);
 219         signal(SIGSEGV, hostcompat_die);
 220         signal(SIGSYS, hostcompat_die);
 221         signal(SIGPIPE, hostcompat_die);
 222         signal(SIGALRM, hostcompat_die);
 223         signal(SIGTERM, hostcompat_die);
 224         signal(SIGXCPU, hostcompat_die);
 225         signal(SIGXFSZ, hostcompat_die);
 226         signal(SIGVTALRM, hostcompat_die);
 227         signal(SIGPROF, hostcompat_die);
 228         signal(SIGUSR1, hostcompat_die);
 229         signal(SIGUSR2, hostcompat_die);
 230 
 231         /* Catch the stop signals, so we can adjust the tty */
 232         signal(SIGTTIN, hostcompat_stop);
 233         signal(SIGTTOU, hostcompat_stop);
 234         signal(SIGTSTP, hostcompat_stop);
 235 
 236         /* Catch the continue signal, so we can adjust the tty */
 237         signal(SIGCONT, hostcompat_cont);
 238 }

/* [<][>][^][v][top][bottom][index][help] */