summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2018-08-27 10:48:02 -0700
committerShentubot <shentubot@google.com>2018-08-27 10:49:16 -0700
commit2524111fc63343fd7372f5ea0266130adea778a5 (patch)
treea751e8af72899aff4d0540a1b71ea5a440e14e32 /pkg
parentb17e80ef5a44e773e9032e7dbcb7438ff851ab7c (diff)
runsc: Terminal resizing support.
Implements the TIOCGWINSZ and TIOCSWINSZ ioctls, which allow processes to resize the terminal. This allows, for example, sshd to properly set the window size for ssh sessions. PiperOrigin-RevId: 210392504 Change-Id: I0d4789154d6d22f02509b31d71392e13ee4a50ba
Diffstat (limited to 'pkg')
-rw-r--r--pkg/abi/linux/tty.go10
-rw-r--r--pkg/sentry/fs/tty/line_discipline.go24
-rw-r--r--pkg/sentry/fs/tty/master.go4
-rw-r--r--pkg/sentry/fs/tty/slave.go4
4 files changed, 42 insertions, 0 deletions
diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go
index 81156867c..f63dc52aa 100644
--- a/pkg/abi/linux/tty.go
+++ b/pkg/abi/linux/tty.go
@@ -328,3 +328,13 @@ var DefaultSlaveTermios = KernelTermios{
InputSpeed: 38400,
OutputSpeed: 38400,
}
+
+// WindowSize corresponds to struct winsize defined in
+// include/uapi/asm-generic/termios.h.
+//
+// +stateify savable
+type WindowSize struct {
+ Rows uint16
+ Cols uint16
+ _ [4]byte // Padding for 2 unused shorts.
+}
diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go
index c7f6c5645..31804571e 100644
--- a/pkg/sentry/fs/tty/line_discipline.go
+++ b/pkg/sentry/fs/tty/line_discipline.go
@@ -76,6 +76,12 @@ const (
//
// +stateify savable
type lineDiscipline struct {
+ // sizeMu protects size.
+ sizeMu sync.Mutex `state:"nosave"`
+
+ // size is the terminal size (width and height).
+ size linux.WindowSize
+
// inQueue is the input queue of the terminal.
inQueue queue
@@ -142,6 +148,24 @@ func (l *lineDiscipline) setTermios(ctx context.Context, io usermem.IO, args arc
return 0, err
}
+func (l *lineDiscipline) windowSize(ctx context.Context, io usermem.IO, args arch.SyscallArguments) error {
+ l.sizeMu.Lock()
+ defer l.sizeMu.Unlock()
+ _, err := usermem.CopyObjectOut(ctx, io, args[2].Pointer(), l.size, usermem.IOOpts{
+ AddressSpaceActive: true,
+ })
+ return err
+}
+
+func (l *lineDiscipline) setWindowSize(ctx context.Context, io usermem.IO, args arch.SyscallArguments) error {
+ l.sizeMu.Lock()
+ defer l.sizeMu.Unlock()
+ _, err := usermem.CopyObjectIn(ctx, io, args[2].Pointer(), &l.size, usermem.IOOpts{
+ AddressSpaceActive: true,
+ })
+ return err
+}
+
func (l *lineDiscipline) masterReadiness() waiter.EventMask {
// We don't have to lock a termios because the default master termios
// is immutable.
diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go
index c8dc08c1a..ae7540eff 100644
--- a/pkg/sentry/fs/tty/master.go
+++ b/pkg/sentry/fs/tty/master.go
@@ -172,6 +172,10 @@ func (mf *masterFileOperations) Ioctl(ctx context.Context, io usermem.IO, args a
case linux.TIOCSPTLCK:
// TODO: Implement pty locking. For now just pretend we do.
return 0, nil
+ case linux.TIOCGWINSZ:
+ return 0, mf.t.ld.windowSize(ctx, io, args)
+ case linux.TIOCSWINSZ:
+ return 0, mf.t.ld.setWindowSize(ctx, io, args)
default:
return 0, syserror.ENOTTY
}
diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go
index ab92ced7e..963331b9b 100644
--- a/pkg/sentry/fs/tty/slave.go
+++ b/pkg/sentry/fs/tty/slave.go
@@ -150,6 +150,10 @@ func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args ar
AddressSpaceActive: true,
})
return 0, err
+ case linux.TIOCGWINSZ:
+ return 0, sf.si.t.ld.windowSize(ctx, io, args)
+ case linux.TIOCSWINSZ:
+ return 0, sf.si.t.ld.setWindowSize(ctx, io, args)
default:
return 0, syserror.ENOTTY
}