Merge with vlock-2
[vlock.git] / src / console_switch.c
blob36139acf76f87483953e1e06fabd869841a34ff3
1 /* console_switch.c -- console grabbing routines for vlock,
2 * the VT locking program for linux
4 * This program is copyright (C) 2007 Frank Benkstein, and is free
5 * software which is freely distributable under the terms of the
6 * GNU General Public License version 2, included as the file COPYING in this
7 * distribution. It is NOT public domain software, and any
8 * redistribution not permitted by the GNU General Public License is
9 * expressly forbidden without prior written permission from
10 * the author.
14 #if !defined(__FreeBSD__) && !defined(_GNU_SOURCE)
15 #define _GNU_SOURCE
16 #endif
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <errno.h>
25 #include <signal.h>
27 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
28 #include <sys/consio.h>
29 #else
30 #include <sys/vt.h>
31 #endif
33 #include "console_switch.h"
35 /* Is console switching currently disabled? */
36 bool console_switch_locked = false;
38 /* This handler is called whenever a user tries to
39 * switch away from this virtual console. */
40 static void release_vt(int __attribute__ ((__unused__)) signum)
42 /* Deny console switch. */
43 (void) ioctl(STDIN_FILENO, VT_RELDISP, 0);
46 /* This handler is called whenever a user switches to this
47 * virtual console. */
48 static void acquire_vt(int __attribute__ ((__unused__)) signum)
50 /* Acknowledge console switch. */
51 (void) ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
54 /* Console mode before switching was disabled. */
55 static struct vt_mode vtm;
56 /* Signal actions before console handling was disabled. */
57 static struct sigaction sa_usr1;
58 static struct sigaction sa_usr2;
60 /* Disable virtual console switching in the kernel. If disabling fails false
61 * is returned and errno is set. */
62 bool lock_console_switch(void)
64 /* Console mode when switching is disabled. */
65 struct vt_mode lock_vtm;
66 struct sigaction sa;
68 /* Get the virtual console mode. */
69 if (ioctl(STDIN_FILENO, VT_GETMODE, &vtm) < 0)
70 return false;
72 /* Copy the current virtual console mode. */
73 lock_vtm = vtm;
75 (void) sigemptyset(&(sa.sa_mask));
76 sa.sa_flags = SA_RESTART;
77 sa.sa_handler = release_vt;
78 (void) sigaction(SIGUSR1, &sa, &sa_usr1);
79 sa.sa_handler = acquire_vt;
80 (void) sigaction(SIGUSR2, &sa, &sa_usr2);
82 /* Set terminal switching to be process governed. */
83 lock_vtm.mode = VT_PROCESS;
84 /* Set terminal release signal, i.e. sent when switching away. */
85 lock_vtm.relsig = SIGUSR1;
86 /* Set terminal acquire signal, i.e. sent when switching here. */
87 lock_vtm.acqsig = SIGUSR2;
88 /* Set terminal free signal, not implemented on either FreeBSD or Linux. */
89 /* Linux ignores this but FreeBSD wants a valid signal number here. */
90 lock_vtm.frsig = SIGHUP;
92 /* Set virtual console mode to be process governed thus disabling console
93 * switching through the signal handlers above. */
94 if (ioctl(STDIN_FILENO, VT_SETMODE, &lock_vtm) < 0) {
95 int errsv = errno;
96 (void) sigaction(SIGUSR1, &sa_usr1, NULL);
97 (void) sigaction(SIGUSR2, &sa_usr2, NULL);
98 errno = errsv;
99 return false;
102 console_switch_locked = true;
103 return true;
106 /* Reenable console switching if it was previously disabled. */
107 bool unlock_console_switch(void)
109 if (console_switch_locked) {
110 console_switch_locked = (ioctl(STDIN_FILENO, VT_SETMODE, &vtm) < 0);
112 if (console_switch_locked)
113 return false;
115 (void) sigaction(SIGUSR1, &sa_usr1, NULL);
116 (void) sigaction(SIGUSR2, &sa_usr2, NULL);
119 return true;