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