diff options
-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 } |