1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
/* signals.c -- signal handline routine for vlock
*
* This program is copyright (C) 1994 Michael K. Johnson, and is free
* software which is freely distributable under the terms of the
* GNU public license, included as the file COPYING in this
* distribution. It is NOT public domain software, and any
* redistribution not permitted by the GNU General Public License is
* expressly forbidden without prior written permission from
* the author.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/vt.h>
#include "vlock.h"
static char rcsid[] = "$Id: signals.c,v 1.10 1997/10/10 17:08:15 johnsonm Exp $";
/* In release_vt() and acquire_vt(), anything which is done in
* release_vt() must be undone in acquire_vt(). Right now, that's
* not much...
*/
/* This is called by a signal whenever a user tries to change the VC
with a ALT-Fn key */
void release_vt(int signo) {
if (!o_lock_all)
ioctl(vfd, VT_RELDISP, 1); /* kernel is allowed to switch */
else
ioctl(vfd, VT_RELDISP, 0); /* kernel is not allowed to switch */
}
/* This is called whenever a user switches to that VC */
void acquire_vt(int signo) {
/* This call is not currently required under Linux, but it won't hurt,
either... */
ioctl(vfd, VT_RELDISP, VT_ACKACQ);
}
void signal_ignorer(int signo) {
return;
}
static sigset_t osig; /* for both mask_signals() and restore_signals() */
void set_signal_mask(int save) {
static sigset_t sig;
static struct sigaction sa;
/* We don't want to get any signals we don't have to, but there are */
/* several we must get. I don't know whether to take the current */
/* signal mask and change it or to do a sigfillset and go from there. */
/* The code should handle either, I think. */
sigprocmask(SIG_SETMASK, NULL, &sig);
sigdelset(&sig, SIGUSR1);
sigdelset(&sig, SIGUSR2);
sigaddset(&sig, SIGTSTP);
sigaddset(&sig, SIGTTIN);
sigaddset(&sig, SIGTTOU);
sigaddset(&sig, SIGHUP);
sigaddset(&sig, SIGCHLD);
sigaddset(&sig, SIGQUIT);
sigaddset(&sig, SIGINT);
if (save)
sigprocmask(SIG_SETMASK, &sig, &osig);
else
sigprocmask(SIG_SETMASK, &sig, NULL);
/* we set SIGUSR{1,2} to point to *_vt() above */
sigemptyset(&(sa.sa_mask));
sa.sa_flags = SA_RESTART;
sa.sa_handler = release_vt;
sigaction(SIGUSR1, &sa, NULL);
sa.sa_handler = acquire_vt;
sigaction(SIGUSR2, &sa, NULL);
/* Need to handle some signals so that we don't get killed by them */
sa.sa_handler = signal_ignorer;
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTSTP, &sa, NULL);
}
void mask_signals(void) {
set_signal_mask(1); /* set the signal masks and handlers and save */
}
void restore_signals(void) {
/* This probably isn't useful, but I'm including it anyway... */
/* It might become useful later, specifically if someone wants
to include this code within another program. */
sigprocmask(SIG_SETMASK, &osig, NULL);
}
|