github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/os/signal/internal/pty/pty.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build (aix || darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd) && cgo 6 7 // Package pty is a simple pseudo-terminal package for Unix systems, 8 // implemented by calling C functions via cgo. 9 // This is only used for testing the os/signal package. 10 package pty 11 12 /* 13 #define _XOPEN_SOURCE 600 14 #include <fcntl.h> 15 #include <stdlib.h> 16 #include <unistd.h> 17 */ 18 import "C" 19 20 import ( 21 "fmt" 22 "os" 23 "syscall" 24 ) 25 26 type PtyError struct { 27 FuncName string 28 ErrorString string 29 Errno syscall.Errno 30 } 31 32 func ptyError(name string, err error) *PtyError { 33 return &PtyError{name, err.Error(), err.(syscall.Errno)} 34 } 35 36 func (e *PtyError) Error() string { 37 return fmt.Sprintf("%s: %s", e.FuncName, e.ErrorString) 38 } 39 40 func (e *PtyError) Unwrap() error { return e.Errno } 41 42 // Open returns a control pty and the name of the linked process tty. 43 func Open() (pty *os.File, processTTY string, err error) { 44 m, err := C.posix_openpt(C.O_RDWR) 45 if err != nil { 46 return nil, "", ptyError("posix_openpt", err) 47 } 48 if _, err := C.grantpt(m); err != nil { 49 C.close(m) 50 return nil, "", ptyError("grantpt", err) 51 } 52 if _, err := C.unlockpt(m); err != nil { 53 C.close(m) 54 return nil, "", ptyError("unlockpt", err) 55 } 56 processTTY = C.GoString(C.ptsname(m)) 57 return os.NewFile(uintptr(m), "pty"), processTTY, nil 58 }