src/vlock-all.c: remove superfluous braces
[vlock.git] / src / vlock-all.c
blobb6ed392a48f8f96753c4738b7ede8d6c5b971fa6
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
10 * the author.
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <sys/vt.h>
19 #include <sys/ioctl.h>
20 #include <sys/wait.h>
21 #include <errno.h>
22 #include <signal.h>
24 #include "vlock.h"
26 /* This handler is called by a signal whenever a user tries to
27 * switch away from this virtual console. */
28 void release_vt(int __attribute__((__unused__)) signum) {
29 /* kernel is not allowed to switch */
30 ioctl(STDIN_FILENO, VT_RELDISP, 0);
33 /* This handler is called whenever a user switches to this
34 * virtual console. */
35 void acquire_vt(int __attribute__((__unused__)) signum) {
36 /* acknowledge, this is a noop */
37 ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
40 /* Run the program given by argv+1. Console switching is forbidden
41 * while the program is running. */
42 int main(void) {
43 struct vt_mode vtmode;
44 struct vt_mode vtmode_bak;
45 int pid;
46 int status;
48 /* get the virtual console mode */
49 if (ioctl(STDIN_FILENO, VT_GETMODE, &vtmode) < 0) {
50 if (errno == ENOTTY || errno == EINVAL)
51 fprintf(stderr, "vlock-all: this terminal is not a virtual console\n");
52 else
53 perror("vlock-all: could not get virtual console mode");
55 exit (111);
58 vtmode_bak = vtmode;
59 vtmode.mode = VT_PROCESS;
60 vtmode.relsig = SIGUSR1;
61 vtmode.acqsig = SIGUSR2;
63 /* set virtual console mode to be process governed
64 * thus disabling console switching */
65 if (ioctl(STDIN_FILENO, VT_SETMODE, &vtmode) < 0) {
66 perror("vlock-all: could not set virtual console mode");
67 exit (111);
70 if (signal(SIGUSR1, release_vt) == SIG_ERR
71 || signal(SIGUSR2, acquire_vt) == SIG_ERR) {
72 perror("vlock-all: could not install signal handlers");
73 exit (111);
76 pid = fork();
78 if (pid == 0) {
79 /* child */
81 /* drop privleges */
82 (void) setuid(getuid());
84 /* run child */
85 execl(VLOCK_CURRENT, VLOCK_CURRENT, (char *) NULL);
86 perror("vlock-all: exec of vlock-current failed");
87 _exit(127);
88 } else if (pid < 0) {
89 perror("vlock-all: could not create child process");
92 if (pid > 0 && waitpid(pid, &status, 0) < 0) {
93 perror("vlock-all: child process missing");
94 pid = -1;
97 /* globally enable virtual console switching */
98 if (ioctl(STDIN_FILENO, VT_SETMODE, &vtmode_bak) < 0)
99 perror("vlock-all: could not restore console mode");
101 /* exit with the exit status of the child or 128+signal if it was killed */
102 if (pid > 0)
103 if (WIFEXITED(status))
104 exit (WEXITSTATUS(status));
105 else if (WIFSIGNALED(status))
106 exit (128+WTERMSIG(status));
108 return 0;