setconsole.c revision 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53
1#include <stdio.h> 2#include <stdlib.h> 3#include <fcntl.h> 4#include <string.h> 5#include <linux/kd.h> 6#include <linux/vt.h> 7#include <errno.h> 8#include <pthread.h> 9 10static int activate_thread_switch_vc; 11static void *activate_thread(void *arg) 12{ 13 int res; 14 int fd = (int)arg; 15 while(activate_thread_switch_vc >= 0) { 16 do { 17 res = ioctl(fd, VT_ACTIVATE, (void*)activate_thread_switch_vc); 18 } while(res < 0 && errno == EINTR); 19 if (res < 0) { 20 fprintf(stderr, "ioctl( vcfd, VT_ACTIVATE, vtnum) failed, %d %d %s for %d\n", res, errno, strerror(errno), activate_thread_switch_vc); 21 } 22 if(activate_thread_switch_vc >= 0) 23 sleep(1); 24 } 25 return NULL; 26} 27 28 29int setconsole_main(int argc, char *argv[]) 30{ 31 int c; 32 int fd; 33 int res; 34 35 int mode = -1; 36 int new_vc = 0; 37 int close_vc = 0; 38 int switch_vc = -1; 39 int printvc = 0; 40 char *ttydev = "/dev/tty0"; 41 42 do { 43 c = getopt(argc, argv, "d:gtncv:poh"); 44 if (c == EOF) 45 break; 46 switch (c) { 47 case 'd': 48 ttydev = optarg; 49 break; 50 case 'g': 51 if(mode == KD_TEXT) { 52 fprintf(stderr, "%s: cannot specify both -g and -t\n", argv[0]); 53 exit(1); 54 } 55 mode = KD_GRAPHICS; 56 break; 57 case 't': 58 if(mode == KD_GRAPHICS) { 59 fprintf(stderr, "%s: cannot specify both -g and -t\n", argv[0]); 60 exit(1); 61 } 62 mode = KD_TEXT; 63 break; 64 case 'n': 65 new_vc = 1; 66 break; 67 case 'c': 68 close_vc = 1; 69 break; 70 case 'v': 71 switch_vc = atoi(optarg); 72 break; 73 case 'p': 74 printvc |= 1; 75 break; 76 case 'o': 77 printvc |= 2; 78 break; 79 case 'h': 80 fprintf(stderr, "%s [-d <dev>] [-v <vc>] [-gtncpoh]\n" 81 " -d <dev> Use <dev> instead of /dev/tty0\n" 82 " -v <vc> Switch to virtual console <vc>\n" 83 " -g Switch to graphics mode\n" 84 " -t Switch to text mode\n" 85 " -n Create and switch to new virtual console\n" 86 " -c Close unused virtual consoles\n" 87 " -p Print new virtual console\n" 88 " -o Print old virtual console\n" 89 " -h Print help\n", argv[0]); 90 return -1; 91 case '?': 92 fprintf(stderr, "%s: invalid option -%c\n", 93 argv[0], optopt); 94 exit(1); 95 } 96 } while (1); 97 if(mode == -1 && new_vc == 0 && close_vc == 0 && switch_vc == -1 && printvc == 0) { 98 fprintf(stderr,"%s [-d <dev>] [-v <vc>] [-gtncpoh]\n", argv[0]); 99 return -1; 100 } 101 102 fd = open(ttydev, O_RDWR | O_SYNC); 103 if (fd < 0) { 104 fprintf(stderr, "cannot open %s\n", ttydev); 105 return -1; 106 } 107 108 if ((printvc && !new_vc) || (printvc & 2)) { 109 struct vt_stat vs; 110 111 res = ioctl(fd, VT_GETSTATE, &vs); 112 if (res < 0) { 113 fprintf(stderr, "ioctl(vcfd, VT_GETSTATE, &vs) failed, %d\n", res); 114 } 115 printf("%d\n", vs.v_active); 116 } 117 118 if (new_vc) { 119 int vtnum; 120 res = ioctl(fd, VT_OPENQRY, &vtnum); 121 if (res < 0 || vtnum == -1) { 122 fprintf(stderr, "ioctl(vcfd, VT_OPENQRY, &vtnum) failed, res %d, vtnum %d\n", res, vtnum); 123 } 124 switch_vc = vtnum; 125 } 126 if (switch_vc != -1) { 127 pthread_t thread; 128 pthread_attr_t attr; 129 activate_thread_switch_vc = switch_vc; 130 pthread_attr_init(&attr); 131 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 132 pthread_create(&thread, &attr, activate_thread, (void*)fd); 133 134 do { 135 res = ioctl(fd, VT_WAITACTIVE, (void*)switch_vc); 136 } while(res < 0 && errno == EINTR); 137 activate_thread_switch_vc = -1; 138 if (res < 0) { 139 fprintf(stderr, "ioctl( vcfd, VT_WAITACTIVE, vtnum) failed, %d %d %s for %d\n", res, errno, strerror(errno), switch_vc); 140 } 141 if(printvc & 1) 142 printf("%d\n", switch_vc); 143 144 close(fd); 145 fd = open(ttydev, O_RDWR | O_SYNC); 146 if (fd < 0) { 147 fprintf(stderr, "cannot open %s\n", ttydev); 148 return -1; 149 } 150 } 151 if (close_vc) { 152 res = ioctl(fd, VT_DISALLOCATE, 0); 153 if (res < 0) { 154 fprintf(stderr, "ioctl(vcfd, VT_DISALLOCATE, 0) failed, %d\n", res); 155 } 156 } 157 if (mode != -1) { 158 if (ioctl(fd, KDSETMODE, (void*)mode) < 0) { 159 fprintf(stderr, "KDSETMODE %d failed\n", mode); 160 return -1; 161 } 162 } 163 return 0; 164} 165