1 /* vlock-all.c -- console grabbing routine 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
18 #include <sys/ioctl.h>
24 #include <sys/consio.h>
27 #endif /* __FreeBSD__ */
31 /* This handler is called by a signal whenever a user tries to
32 * switch away from this virtual console. */
33 void release_vt(int __attribute__((__unused__
)) signum
) {
34 /* kernel is not allowed to switch */
35 ioctl(STDIN_FILENO
, VT_RELDISP
, 0);
38 /* This handler is called whenever a user switches to this
40 void acquire_vt(int __attribute__((__unused__
)) signum
) {
41 /* acknowledge, this is a noop */
42 ioctl(STDIN_FILENO
, VT_RELDISP
, VT_ACKACQ
);
45 /* Disable console switching while running vlock-current. */
47 struct vt_mode vtmode
, vtmode_bak
;
51 /* get the virtual console mode */
52 if (ioctl(STDIN_FILENO
, VT_GETMODE
, &vtmode
) < 0) {
53 if (errno
== ENOTTY
|| errno
== EINVAL
)
54 fprintf(stderr
, "vlock-all: this terminal is not a virtual console\n");
56 perror("vlock-all: could not get virtual console mode");
61 /* back up current terminal mode */
63 /* set terminal switching to be process governed */
64 vtmode
.mode
= VT_PROCESS
;
65 /* set terminal release signal, i.e. sent when switching away */
66 vtmode
.relsig
= SIGUSR1
;
67 /* set terminal acquire signal, i.e. sent when switching here */
68 vtmode
.acqsig
= SIGUSR2
;
69 /* set terminal free signal, not implemented on either FreeBSD or Linux */
70 /* Linux ignores it but FreeBSD wants a valid signal number here */
71 vtmode
.frsig
= SIGHUP
;
73 /* set console switching signal handlers */
74 if (signal(SIGUSR1
, release_vt
) == SIG_ERR
75 || signal(SIGUSR2
, acquire_vt
) == SIG_ERR
) {
76 perror("vlock-all: could not install signal handlers");
80 /* set virtual console mode to be process governed
81 * thus disabling console switching */
82 if (ioctl(STDIN_FILENO
, VT_SETMODE
, &vtmode
) < 0) {
83 perror("vlock-all: could not set virtual console mode");
93 (void) setuid(getuid());
96 execl(VLOCK_CURRENT
, VLOCK_CURRENT
, (char *) NULL
);
97 perror("vlock-all: exec of vlock-current failed");
100 perror("vlock-all: could not create child process");
103 if (pid
> 0 && waitpid(pid
, &status
, 0) < 0) {
104 perror("vlock-all: child process missing");
108 /* globally enable virtual console switching */
109 if (ioctl(STDIN_FILENO
, VT_SETMODE
, &vtmode_bak
) < 0)
110 perror("vlock-all: could not restore console mode");
112 /* exit with the exit status of the child or 128+signal if it was killed */
114 if (WIFEXITED(status
))
115 exit (WEXITSTATUS(status
));
116 else if (WIFSIGNALED(status
))
117 exit (128+WTERMSIG(status
));