diff --git a/pkg/sentry/fsimpl/devpts/line_discipline.go b/pkg/sentry/fsimpl/devpts/line_discipline.go index 4b0f3fd3b..9b58051db 100644 --- a/pkg/sentry/fsimpl/devpts/line_discipline.go +++ b/pkg/sentry/fsimpl/devpts/line_discipline.go @@ -111,6 +111,9 @@ type lineDiscipline struct { // replicaWaiter is used to wait on the replica end of the TTY. replicaWaiter waiter.Queue + + // terminal is the terminal linked to this lineDiscipline. + terminal *Terminal } func newLineDiscipline(termios linux.KernelTermios) *lineDiscipline { @@ -393,6 +396,12 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) if l.termios.IEnabled(linux.INLCR) { cBytes[0] = '\r' } + case l.termios.ControlCharacters[linux.VINTR]: // ctrl-c + l.terminal.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGINT)) + case l.termios.ControlCharacters[linux.VSUSP]: // ctrl-z + l.terminal.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGTSTP)) + case l.termios.ControlCharacters[linux.VQUIT]: // ctrl-\ + l.terminal.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGQUIT)) } // In canonical mode, we discard non-terminating characters diff --git a/pkg/sentry/fsimpl/devpts/terminal.go b/pkg/sentry/fsimpl/devpts/terminal.go index d9e0164a6..a3068f8a4 100644 --- a/pkg/sentry/fsimpl/devpts/terminal.go +++ b/pkg/sentry/fsimpl/devpts/terminal.go @@ -39,6 +39,10 @@ type Terminal struct { // replicaKTTY contains the controlling process of the replica end of this // terminal. This field is immutable. replicaKTTY *kernel.TTY + + // fgProcessGroup is the foreground process group that is currently + // connected to this TTY. + fgProcessGroup *kernel.ProcessGroup } func newTerminal(n uint32) *Terminal { @@ -49,6 +53,9 @@ func newTerminal(n uint32) *Terminal { masterKTTY: &kernel.TTY{Index: n}, replicaKTTY: &kernel.TTY{Index: n}, } + + t.ld.terminal = &t + return &t } @@ -106,6 +113,9 @@ func (tm *Terminal) setForegroundProcessGroup(ctx context.Context, args arch.Sys } ret, err := task.ThreadGroup().SetForegroundProcessGroup(tm.tty(isMaster), kernel.ProcessGroupID(pgid)) + if err == nil { + tm.fgProcessGroup = task.PIDNamespace().ProcessGroupWithID(kernel.ProcessGroupID(pgid)) + } return uintptr(ret), err }