mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Implement /dev/tty for donated host TTYs
Fixes #10925 PiperOrigin-RevId: 681684673
This commit is contained in:
committed by
gVisor bot
parent
72193f12c9
commit
d5a9d523bb
@@ -272,6 +272,13 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
|
||||
if ttyFile != nil {
|
||||
// Index does not matter here. This tty is not coming from a
|
||||
// devpts mount, so it won't collide with any of the ptys
|
||||
// created there.
|
||||
initArgs.TTY = kernel.NewTTY(0, ttyFile)
|
||||
}
|
||||
|
||||
// Set cgroups to the new exec task if cgroups are mounted.
|
||||
cgroupRegistry := proc.Kernel.CgroupRegistry()
|
||||
initialCgrps := map[kernel.Cgroup]struct{}{}
|
||||
|
||||
@@ -31,6 +31,8 @@ import (
|
||||
// TTYFileDescription implements vfs.FileDescriptionImpl for a host file
|
||||
// descriptor that wraps a TTY FD.
|
||||
//
|
||||
// It implements kernel.TTYOperations.
|
||||
//
|
||||
// +stateify savable
|
||||
type TTYFileDescription struct {
|
||||
fileDescription
|
||||
@@ -49,6 +51,13 @@ type TTYFileDescription struct {
|
||||
termios linux.KernelTermios
|
||||
}
|
||||
|
||||
// Open re-opens the tty fd, for example via open(/dev/tty). See Linux's
|
||||
// tty_repoen().
|
||||
func (t *TTYFileDescription) Open(_ context.Context, _ *vfs.Mount, _ *vfs.Dentry, _ vfs.OpenOptions) (*vfs.FileDescription, error) {
|
||||
t.vfsfd.IncRef()
|
||||
return &t.vfsfd, nil
|
||||
}
|
||||
|
||||
// InitForegroundProcessGroup sets the foreground process group and session for
|
||||
// the TTY. This should only be called once, after the foreground process group
|
||||
// has been created, but before it has started running.
|
||||
|
||||
@@ -991,6 +991,9 @@ type CreateProcessArgs struct {
|
||||
|
||||
// Origin indicates how the task was first created.
|
||||
Origin TaskOrigin
|
||||
|
||||
// TTY is the optional TTY to associate with this process.
|
||||
TTY *TTY
|
||||
}
|
||||
|
||||
// NewContext returns a context.Context that represents the task that will be
|
||||
@@ -1222,6 +1225,12 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
|
||||
}
|
||||
t.traceExecEvent(image) // Simulate exec for tracing.
|
||||
|
||||
// Set TTY if configured.
|
||||
if args.TTY != nil {
|
||||
t.tg.tty = args.TTY
|
||||
args.TTY.tg = t.tg
|
||||
}
|
||||
|
||||
// Success.
|
||||
cu.Release()
|
||||
tgid := k.tasks.Root.IDOfThreadGroup(tg)
|
||||
|
||||
@@ -1110,6 +1110,13 @@ func (l *Loader) createContainerProcess(info *containerInfo) (*kernel.ThreadGrou
|
||||
// ours either way.
|
||||
info.procArgs.FDTable = fdTable
|
||||
|
||||
if ttyFile != nil {
|
||||
// Index does not matter here. This tty is not coming from a
|
||||
// devpts mount, so it won't collide with any of the ptys
|
||||
// created there.
|
||||
info.procArgs.TTY = kernel.NewTTY(0, ttyFile)
|
||||
}
|
||||
|
||||
if info.execFD != nil {
|
||||
if info.procArgs.Filename != "" {
|
||||
return nil, nil, fmt.Errorf("process must either be started from a file or a filename, not both")
|
||||
|
||||
@@ -594,6 +594,16 @@ func TestMultiContainerTerminal(t *testing.T) {
|
||||
if err := testutil.WaitUntilRead(ptyBuf, "foo-/-123", 5*time.Second); err != nil {
|
||||
t.Fatalf("echo didn't execute: %v", err)
|
||||
}
|
||||
|
||||
// Make sure we can open /dev/tty. We do this
|
||||
// by asking `head` to to read 0 bytes, which
|
||||
// causes it to simply open & close the file.
|
||||
if _, err := tc.master.Write([]byte("head -n 0 /dev/tty; echo $?\n")); err != nil {
|
||||
t.Fatalf("master.Write(): %v", err)
|
||||
}
|
||||
if err := testutil.WaitUntilRead(ptyBuf, "0", 5*time.Second); err != nil {
|
||||
t.Fatalf("head didn't execute: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user