This commit is contained in:
parent
bf6f7741b1
commit
24b20ee0fb
@ -1,141 +0,0 @@
|
||||
chvt: add --userwait option
|
||||
|
||||
From: Daniel Drake <d.drake@mmm.com>
|
||||
|
||||
At http://bugs.gentoo.org/159729 we see chvt hanging in some scenario's. As
|
||||
the solution to this is not immediately obvious, add a --userwait option
|
||||
which repeatedly tries changing the terminal until the change has taken place.
|
||||
|
||||
Index: kbd-1.14.1/man/man1/chvt.1
|
||||
===================================================================
|
||||
--- kbd-1.14.1.orig/docs/man/man1/chvt.1
|
||||
+++ kbd-1.14.1/docs/man/man1/chvt.1
|
||||
@@ -4,6 +4,9 @@
|
||||
chvt \- change foreground virtual terminal
|
||||
.SH SYNOPSIS
|
||||
.B chvt
|
||||
+[
|
||||
+.B --userwait
|
||||
+]
|
||||
.I N
|
||||
.SH DESCRIPTION
|
||||
The command
|
||||
@@ -21,3 +24,10 @@ The key combination
|
||||
(with
|
||||
.I N
|
||||
in the range 1-12) usually has a similar effect.
|
||||
+.LP
|
||||
+The
|
||||
+.B --userwait
|
||||
+option causes the system to loop in userspace waiting for the new terminal
|
||||
+to become active, as opposed to the kernel-side
|
||||
+.I VT_WAITACTIVE
|
||||
+ioctl.
|
||||
Index: kbd-1.14.1/src/chvt.c
|
||||
===================================================================
|
||||
--- kbd-1.14.1.orig/src/chvt.c
|
||||
+++ kbd-1.14.1/src/chvt.c
|
||||
@@ -7,13 +7,43 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
+#include <getopt.h>
|
||||
+#include <unistd.h>
|
||||
#include "getfd.h"
|
||||
#include "nls.h"
|
||||
#include "version.h"
|
||||
|
||||
+#define USER_WAIT_SLEEP_US 100000
|
||||
+#define USER_WAIT_MAX_ITERATIONS 50
|
||||
+
|
||||
+static int fd;
|
||||
+
|
||||
+static void chvt(int num)
|
||||
+{
|
||||
+ if (ioctl(fd,VT_ACTIVATE,num)) {
|
||||
+ perror("VT_ACTIVATE");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int fgconsole(void)
|
||||
+{
|
||||
+ struct vt_stat vtstat;
|
||||
+ if (ioctl(fd, VT_GETSTATE, &vtstat)) {
|
||||
+ perror("VT_GETSTATE");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ return vtstat.v_active;
|
||||
+}
|
||||
+
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
- int fd, num;
|
||||
+ int c, num;
|
||||
+ int user_wait = 0;
|
||||
+ const struct option long_opts[] = {
|
||||
+ { "version", no_argument, NULL, 'V' },
|
||||
+ { "userwait", no_argument, NULL, 'u' },
|
||||
+ };
|
||||
|
||||
set_progname(argv[0]);
|
||||
|
||||
@@ -21,22 +51,46 @@ main(int argc, char *argv[]) {
|
||||
bindtextdomain(PACKAGE_NAME, LOCALEDIR);
|
||||
textdomain(PACKAGE_NAME);
|
||||
|
||||
- if (argc == 2 && !strcmp(argv[1], "-V"))
|
||||
- print_version_and_exit();
|
||||
+ while ((c = getopt_long(argc, argv, "Vu", long_opts, NULL)) != -1) {
|
||||
+ switch (c) {
|
||||
+ case 'V':
|
||||
+ print_version_and_exit();
|
||||
+ case 'u':
|
||||
+ user_wait = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (argc != 2) {
|
||||
- fprintf(stderr, _("usage: chvt N\n"));
|
||||
+ if (optind >= argc) {
|
||||
+ fprintf(stderr, _("usage: chvt [--userwait] N\n"));
|
||||
exit(1);
|
||||
}
|
||||
+
|
||||
fd = getfd(NULL);
|
||||
- num = atoi(argv[1]);
|
||||
- if (ioctl(fd,VT_ACTIVATE,num)) {
|
||||
- perror("chvt: VT_ACTIVATE");
|
||||
- exit(1);
|
||||
- }
|
||||
- if (ioctl(fd,VT_WAITACTIVE,num)) {
|
||||
- perror("VT_WAITACTIVE");
|
||||
- exit(1);
|
||||
+ num = atoi(argv[optind++]);
|
||||
+ chvt(num);
|
||||
+
|
||||
+ if (user_wait) {
|
||||
+ int active = 0;
|
||||
+ int i;
|
||||
+ for (i = 0; i < USER_WAIT_MAX_ITERATIONS; i++) {
|
||||
+ if (fgconsole() == num) {
|
||||
+ active = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ chvt(num);
|
||||
+ usleep(USER_WAIT_SLEEP_US);
|
||||
+ }
|
||||
+ if (!active) {
|
||||
+ fprintf(stderr, _("VT change timed out\n"));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (ioctl(fd,VT_WAITACTIVE,num)) {
|
||||
+ perror("VT_WAITACTIVE");
|
||||
+ exit(1);
|
||||
+ }
|
||||
}
|
||||
exit(0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user