github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/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 // +build aix darwin dragonfly freebsd linux,!android netbsd openbsd 7 // +build cgo 8 9 // Package pty is a simple pseudo-terminal package for Unix systems, 10 // implemented by calling C functions via cgo. 11 // This is only used for testing the os/signal package. 12 package pty 13 14 /* 15 #define _XOPEN_SOURCE 600 16 #include <fcntl.h> 17 #include <stdlib.h> 18 #include <unistd.h> 19 */ 20 import "C" 21 22 import ( 23 "fmt" 24 "os" 25 "syscall" 26 ) 27 28 type PtyError struct { 29 FuncName string 30 ErrorString string 31 Errno syscall.Errno 32 } 33 34 func ptyError(name string, err error) *PtyError { 35 return &PtyError{name, err.Error(), err.(syscall.Errno)} 36 } 37 38 func (e *PtyError) Error() string { 39 return fmt.Sprintf("%s: %s", e.FuncName, e.ErrorString) 40 } 41 42 func (e *PtyError) Unwrap() error { return e.Errno } 43 44 // Open returns a control pty and the name of the linked process tty. 45 func Open() (pty *os.File, processTTY string, err error) { 46 m, err := C.posix_openpt(C.O_RDWR) 47 if err != nil { 48 return nil, "", ptyError("posix_openpt", err) 49 } 50 if _, err := C.grantpt(m); err != nil { 51 C.close(m) 52 return nil, "", ptyError("grantpt", err) 53 } 54 if _, err := C.unlockpt(m); err != nil { 55 C.close(m) 56 return nil, "", ptyError("unlockpt", err) 57 } 58 processTTY = C.GoString(C.ptsname(m)) 59 return os.NewFile(uintptr(m), "pty"), processTTY, nil 60 }