| 17 | ) |
| 18 | |
| 19 | func newPty(opt ...Option) (retPTY *otherPty, err error) { |
| 20 | var opts ptyOptions |
| 21 | for _, o := range opt { |
| 22 | o(&opts) |
| 23 | } |
| 24 | |
| 25 | ptyFile, ttyFile, err := pty.Open() |
| 26 | if err != nil { |
| 27 | return nil, err |
| 28 | } |
| 29 | opty := &otherPty{ |
| 30 | pty: ptyFile, |
| 31 | tty: ttyFile, |
| 32 | opts: opts, |
| 33 | name: ttyFile.Name(), |
| 34 | } |
| 35 | defer func() { |
| 36 | if err != nil { |
| 37 | _ = opty.Close() |
| 38 | } |
| 39 | }() |
| 40 | |
| 41 | if opts.sshReq != nil { |
| 42 | err = opty.control(opty.tty, func(fd uintptr) error { |
| 43 | return applyTerminalModesToFd(opts.logger, fd, *opts.sshReq) |
| 44 | }) |
| 45 | if err != nil { |
| 46 | return nil, err |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | return opty, nil |
| 51 | } |
| 52 | |
| 53 | type otherPty struct { |
| 54 | mutex sync.Mutex |