ktest: Give console process a dedicated tty
authorJosh Poimboeuf <jpoimboe@redhat.com>
Wed, 28 Jan 2015 19:38:38 +0000 (13:38 -0600)
committerSteven Rostedt <rostedt@goodmis.org>
Mon, 2 Feb 2015 15:43:12 +0000 (10:43 -0500)
Create a pseudoterminal (pty pair) to give the console a dedicated tty
so it doesn't mess with ktest's terminal settings.

Link: http://lkml.kernel.org/r/37b0127f9efad09ff4fc994334db998141e4f6ca.1422473610.git.jpoimboe@redhat.com
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
tools/testing/ktest/ktest.pl

index 6ae890a0d48681b28d9e6f0c3bd96a67c671dd6f..2d3191693567232884b808e3eaeda5a19b6865fa 100755 (executable)
@@ -1410,23 +1410,71 @@ sub dodie {
     die @_, "\n";
 }
 
-sub open_console {
-    my ($fp) = @_;
+sub create_pty {
+    my ($ptm, $pts) = @_;
+    my $tmp;
+    my $TIOCSPTLCK = 0x40045431;
+    my $TIOCGPTN = 0x80045430;
+
+    sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
+       dodie "Cant open /dev/ptmx";
+
+    # unlockpt()
+    $tmp = pack("i", 0);
+    ioctl($ptm, $TIOCSPTLCK, $tmp) or
+       dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
+
+    # ptsname()
+    ioctl($ptm, $TIOCGPTN, $tmp) or
+       dodie "ioctl TIOCGPTN for /dev/ptmx failed";
+    $tmp = unpack("i", $tmp);
+
+    sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
+       dodie "Can't open /dev/pts/$tmp";
+}
+
+sub exec_console {
+    my ($ptm, $pts) = @_;
+
+    close($ptm);
+
+    close(\*STDIN);
+    close(\*STDOUT);
+    close(\*STDERR);
 
-    my $flags;
+    open(\*STDIN, '<&', $pts);
+    open(\*STDOUT, '>&', $pts);
+    open(\*STDERR, '>&', $pts);
+
+    close($pts);
+
+    exec $console or
+       dodie "Can't open console $console";
+}
+
+sub open_console {
+    my ($ptm) = @_;
+    my $pts = \*PTSFD;
+    my $pid;
 
     # save terminal settings
     $stty = `stty -g`;
 
-    my $pid = open($fp, "$console|") or
-       dodie "Can't open console $console";
+    create_pty($ptm, $pts);
 
-    $flags = fcntl($fp, F_GETFL, 0) or
-       dodie "Can't get flags for the socket: $!";
-    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
-       dodie "Can't set flags for the socket: $!";
+    $pid = fork;
+
+    if (!$pid) {
+       # child
+       exec_console($ptm, $pts)
+    }
+
+    # parent
+    close($pts);
 
     return $pid;
+
+    open(PTSFD, "Stop perl from warning about single use of PTSFD");
 }
 
 sub close_console {