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