diff options
author | Kevin Krakauer <krakauer@google.com> | 2018-08-27 10:48:02 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-08-27 10:49:16 -0700 |
commit | 2524111fc63343fd7372f5ea0266130adea778a5 (patch) | |
tree | a751e8af72899aff4d0540a1b71ea5a440e14e32 | |
parent | b17e80ef5a44e773e9032e7dbcb7438ff851ab7c (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
-rw-r--r-- | pkg/abi/linux/tty.go | 10 | ||||
-rw-r--r-- | pkg/sentry/fs/tty/line_discipline.go | 24 | ||||
-rw-r--r-- | pkg/sentry/fs/tty/master.go | 4 | ||||
-rw-r--r-- | pkg/sentry/fs/tty/slave.go | 4 |
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 } |