...

Source file src/github.com/rogpeppe/go-internal/testscript/internal/pty/pty.go

Documentation: github.com/rogpeppe/go-internal/testscript/internal/pty

     1  //go:build linux || darwin
     2  // +build linux darwin
     3  
     4  package pty
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"os/exec"
    10  	"syscall"
    11  )
    12  
    13  const Supported = true
    14  
    15  func SetCtty(cmd *exec.Cmd, tty *os.File) {
    16  	cmd.SysProcAttr = &syscall.SysProcAttr{
    17  		Setctty: true,
    18  		Setsid:  true,
    19  		Ctty:    3,
    20  	}
    21  	cmd.ExtraFiles = []*os.File{tty}
    22  }
    23  
    24  func Open() (pty, tty *os.File, err error) {
    25  	p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
    26  	if err != nil {
    27  		return nil, nil, fmt.Errorf("failed to open pty multiplexer: %v", err)
    28  	}
    29  	defer func() {
    30  		if err != nil {
    31  			p.Close()
    32  		}
    33  	}()
    34  
    35  	name, err := ptyName(p)
    36  	if err != nil {
    37  		return nil, nil, fmt.Errorf("failed to obtain tty name: %v", err)
    38  	}
    39  
    40  	if err := ptyGrant(p); err != nil {
    41  		return nil, nil, fmt.Errorf("failed to grant pty: %v", err)
    42  	}
    43  
    44  	if err := ptyUnlock(p); err != nil {
    45  		return nil, nil, fmt.Errorf("failed to unlock pty: %v", err)
    46  	}
    47  
    48  	t, err := os.OpenFile(name, os.O_RDWR|syscall.O_NOCTTY, 0)
    49  	if err != nil {
    50  		return nil, nil, fmt.Errorf("failed to open TTY: %v", err)
    51  	}
    52  
    53  	return p, t, nil
    54  }
    55  
    56  func ioctl(f *os.File, name string, cmd, ptr uintptr) error {
    57  	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), cmd, ptr)
    58  	if err != 0 {
    59  		return fmt.Errorf("%s ioctl failed: %v", name, err)
    60  	}
    61  	return nil
    62  }
    63  

View as plain text