File: signals.c

package info (click to toggle)
vlock 1.2-1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 112 kB
  • ctags: 49
  • sloc: ansic: 443; makefile: 44
file content (122 lines) | stat: -rw-r--r-- 3,074 bytes parent folder | download
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);


}