github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/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 "github.com/x04/go/src/C"
    20  
    21  import (
    22  	"github.com/x04/go/src/fmt"
    23  	"github.com/x04/go/src/os"
    24  	"github.com/x04/go/src/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  func (e *PtyError) Unwrap() error	{ return e.Errno }
    42  
    43  // Open returns a master pty and the name of the linked slave tty.
    44  func Open() (master *os.File, slave string, err error) {
    45  	m, err := C.posix_openpt(C.O_RDWR)
    46  	if err != nil {
    47  		return nil, "", ptyError("posix_openpt", err)
    48  	}
    49  	if _, err := C.grantpt(m); err != nil {
    50  		C.close(m)
    51  		return nil, "", ptyError("grantpt", err)
    52  	}
    53  	if _, err := C.unlockpt(m); err != nil {
    54  		C.close(m)
    55  		return nil, "", ptyError("unlockpt", err)
    56  	}
    57  	slave = C.GoString(C.ptsname(m))
    58  	return os.NewFile(uintptr(m), "pty-master"), slave, nil
    59  }