20.6. Example: The open Command Here is sample code to find an unused VC, to run a shell on it, to wait for the shell to exit, and to switch back and deallocate the VC when the program exits. The open program, which is distributed with Linux, does the same, but it has more options and error checking, and is thus more robust. Although this version works, it is hardly friendly, robust, or secure. 1: /* minopen.c */ 2: 3: #include <stdio.h> 4: #include <unistd.h> 5: #include <stdlib.h> 6: #include <signal.h> 7: #include <fcntl.h> 8: #include <sys/ioctl.h> 9: #include <sys/vt.h> 10: #include <sys/stat.h> 11: #include <sys/types.h> 12: #include <sys/wait.h> 13: 14: int main (int argc, const char **argv) { 15: int vtnum; 16: int vtfd; 17: struct vt_stat vtstat; 18: char device[32]; 19: int child; 20: 21: vtfd = open("/dev/tty", O_RDWR, 0); 22: if (vtfd < 0) { 23: perror("minopen: could not open /dev/tty"); 24: exit (1); 25: } 26: if (ioctl(vtfd, VT_GETSTATE, &vtstat) < 0) { 27: perror("minopen: tty is not virtual console"); 28: exit (1); 29: } 30: if (ioctl(vtfd, VT_OPENQRY, &vtnum) < 0) { 31: perror("minopen: no free virtual consoles"); 32: exit (1); 33: } 34: sprintf(device, "/dev/tty%d", vtnum); 35: if (access(device, (W_OK|R_OK)) < 0) { 36: perror("minopen: insufficient permission on tty"); 37: exit (1); 38: } 39: child = fork(); 40: if (child == 0) { 41: ioctl(vtfd, VT_ACTIVATE, vtnum); 42: ioctl(vtfd, VT_WAITACTIVE, vtnum); 43: setsid(); 44: close (0); close (1); close (2); 45: close (vtfd); 46: vtfd = open(device, O_RDWR, 0); dup(vtfd); dup(vtfd); 47: execlp("/bin/bash", "bash", NULL); 48: } 49: wait (&child); 50: ioctl(vtfd, VT_ACTIVATE, vtstat.v_active); 51: ioctl(vtfd, VT_WAITACTIVE, vtstat.v_active); 52: ioctl(vtfd, VT_DISALLOCATE, vtnum); 53: exit(0); 54: } |