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  }