github.com/neugram/ng@v0.0.0-20180309130942-d472ff93d872/eval/shell/ioctl.go (about)

     1  // Copyright 2015 The Neugram 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 !windows
     6  
     7  package shell
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"syscall"
    13  	"unsafe"
    14  )
    15  
    16  func ioctl(fd uintptr, request ioctlRequest, argp unsafe.Pointer) error {
    17  	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, uintptr(request), uintptr(argp), 0, 0, 0)
    18  	if err != 0 {
    19  		return os.NewSyscallError(fmt.Sprintf("ioctl %s", request), err)
    20  	}
    21  	return nil
    22  }
    23  
    24  type ioctlRequest uintptr
    25  
    26  const (
    27  	_TIOCSPGRP  = ioctlRequest(syscall.TIOCSPGRP)
    28  	_TIOCGPGRP  = ioctlRequest(syscall.TIOCGPGRP)
    29  	_TIOCGWINSZ = ioctlRequest(syscall.TIOCGWINSZ)
    30  )
    31  
    32  var ioctlRequests = map[ioctlRequest]string{
    33  	_TIOCGETS:   "TIOCGETS",
    34  	_TIOCSETS:   "TIOCSETS",
    35  	_TIOCSPGRP:  "TIOCSPGRP",
    36  	_TIOCGWINSZ: "TIOCGWINSZ",
    37  }
    38  
    39  func (r ioctlRequest) String() string {
    40  	s := ioctlRequests[r]
    41  	if s == "" {
    42  		s = "Unknown"
    43  	}
    44  	return fmt.Sprintf("%s(0x%x)", s, uintptr(r))
    45  }
    46  
    47  func tcgetattr(fd uintptr) (syscall.Termios, error) {
    48  	var termios syscall.Termios
    49  	return termios, ioctl(fd, _TIOCGETS, unsafe.Pointer(&termios))
    50  }
    51  
    52  func tcsetattr(fd uintptr, termios *syscall.Termios) error {
    53  	return ioctl(fd, _TIOCSETS, unsafe.Pointer(termios))
    54  }
    55  
    56  func tcsetpgrp(fd uintptr, pgrp int) error {
    57  	pgid := int32(pgrp) // TODO: uintptr?
    58  	return ioctl(fd, _TIOCSPGRP, unsafe.Pointer(&pgid))
    59  }
    60  
    61  func tcgetpgrp(fd uintptr) (int, error) {
    62  	var pgid int64
    63  	err := ioctl(fd, _TIOCGPGRP, unsafe.Pointer(&pgid))
    64  	return int(pgid), err
    65  }
    66  
    67  func WindowSize(fd uintptr) (rows, cols int, err error) {
    68  	var sz struct{ rows, cols, _, _ uint16 }
    69  	if err := ioctl(fd, _TIOCGWINSZ, unsafe.Pointer(&sz)); err != nil {
    70  		return 0, 0, err
    71  	}
    72  	return int(sz.rows), int(sz.cols), nil
    73  }