浏览代码

Merge pull request #784 from dotcloud/remove_cgo_dependency

* Runtime: Remove cgo dependency
Guillaume J. Charmes 12 年之前
父节点
当前提交
2b1b3c1270
共有 4 个文件被更改,包括 58 次插入148 次删除
  1. 2 2
      commands.go
  2. 7 105
      term/term.go
  3. 27 5
      term/termios_darwin.go
  4. 22 36
      term/termios_linux.go

+ 2 - 2
commands.go

@@ -1422,7 +1422,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.Fi
 		return err
 	})
 
-	if in != nil && setRawTerminal && term.IsTerminal(int(in.Fd())) && os.Getenv("NORAW") == "" {
+	if in != nil && setRawTerminal && term.IsTerminal(in.Fd()) && os.Getenv("NORAW") == "" {
 		if oldState, err := term.SetRawTerminal(); err != nil {
 			return err
 		} else {
@@ -1441,7 +1441,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.Fi
 		return err
 	}
 
-	if !term.IsTerminal(int(os.Stdin.Fd())) {
+	if !term.IsTerminal(os.Stdin.Fd()) {
 		if err := <-sendStdin; err != nil {
 			return err
 		}

+ 7 - 105
term/term.go

@@ -7,104 +7,6 @@ import (
 	"unsafe"
 )
 
-type Termios struct {
-	Iflag  uintptr
-	Oflag  uintptr
-	Cflag  uintptr
-	Lflag  uintptr
-	Cc     [20]byte
-	Ispeed uintptr
-	Ospeed uintptr
-}
-
-const (
-	// Input flags
-	inpck  = 0x010
-	istrip = 0x020
-	icrnl  = 0x100
-	ixon   = 0x200
-
-	// Output flags
-	opost = 0x1
-
-	// Control flags
-	cs8 = 0x300
-
-	// Local flags
-	icanon = 0x100
-	iexten = 0x400
-)
-
-const (
-	HUPCL   = 0x4000
-	ICANON  = 0x100
-	ICRNL   = 0x100
-	IEXTEN  = 0x400
-	BRKINT  = 0x2
-	CFLUSH  = 0xf
-	CLOCAL  = 0x8000
-	CREAD   = 0x800
-	CS5     = 0x0
-	CS6     = 0x100
-	CS7     = 0x200
-	CS8     = 0x300
-	CSIZE   = 0x300
-	CSTART  = 0x11
-	CSTATUS = 0x14
-	CSTOP   = 0x13
-	CSTOPB  = 0x400
-	CSUSP   = 0x1a
-	IGNBRK  = 0x1
-	IGNCR   = 0x80
-	IGNPAR  = 0x4
-	IMAXBEL = 0x2000
-	INLCR   = 0x40
-	INPCK   = 0x10
-	ISIG    = 0x80
-	ISTRIP  = 0x20
-	IUTF8   = 0x4000
-	IXANY   = 0x800
-	IXOFF   = 0x400
-	IXON    = 0x200
-	NOFLSH  = 0x80000000
-	OCRNL   = 0x10
-	OFDEL   = 0x20000
-	OFILL   = 0x80
-	ONLCR   = 0x2
-	ONLRET  = 0x40
-	ONOCR   = 0x20
-	ONOEOT  = 0x8
-	OPOST   = 0x1
-	RENB    = 0x1000
-	PARMRK  = 0x8
-	PARODD  = 0x2000
-
-	TOSTOP   = 0x400000
-	VDISCARD = 0xf
-	VDSUSP   = 0xb
-	VEOF     = 0x0
-	VEOL     = 0x1
-	VEOL2    = 0x2
-	VERASE   = 0x3
-	VINTR    = 0x8
-	VKILL    = 0x5
-	VLNEXT   = 0xe
-	VMIN     = 0x10
-	VQUIT    = 0x9
-	VREPRINT = 0x6
-	VSTART   = 0xc
-	VSTATUS  = 0x12
-	VSTOP    = 0xd
-	VSUSP    = 0xa
-	VT0      = 0x0
-	VT1      = 0x10000
-	VTDLY    = 0x10000
-	VTIME    = 0x11
-	ECHO     = 0x00000008
-
-	PENDIN = 0x20000000
-)
-
 type State struct {
 	termios Termios
 }
@@ -128,21 +30,21 @@ func SetWinsize(fd uintptr, ws *Winsize) error {
 }
 
 // IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
+func IsTerminal(fd uintptr) bool {
 	var termios Termios
-	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&termios)))
+	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&termios)))
 	return err == 0
 }
 
 // Restore restores the terminal connected to the given file descriptor to a
 // previous state.
-func Restore(fd int, state *State) error {
-	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)))
+func Restore(fd uintptr, state *State) error {
+	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)))
 	return err
 }
 
 func SetRawTerminal() (*State, error) {
-	oldState, err := MakeRaw(int(os.Stdin.Fd()))
+	oldState, err := MakeRaw(os.Stdin.Fd())
 	if err != nil {
 		return nil, err
 	}
@@ -150,12 +52,12 @@ func SetRawTerminal() (*State, error) {
 	signal.Notify(c, os.Interrupt)
 	go func() {
 		_ = <-c
-		Restore(int(os.Stdin.Fd()), oldState)
+		Restore(os.Stdin.Fd(), oldState)
 		os.Exit(0)
 	}()
 	return oldState, err
 }
 
 func RestoreTerminal(state *State) {
-	Restore(int(os.Stdin.Fd()), state)
+	Restore(os.Stdin.Fd(), state)
 }

+ 27 - 5
term/termios_darwin.go

@@ -8,23 +8,45 @@ import (
 const (
 	getTermios = syscall.TIOCGETA
 	setTermios = syscall.TIOCSETA
+
+	ECHO    = 0x00000008
+	ONLCR   = 0x2
+	ISTRIP  = 0x20
+	INLCR   = 0x40
+	ISIG    = 0x80
+	IGNCR   = 0x80
+	ICANON  = 0x100
+	ICRNL   = 0x100
+	IXOFF   = 0x400
+	IXON    = 0x200
 )
 
+type Termios struct {
+	Iflag  uint64
+	Oflag  uint64
+	Cflag  uint64
+	Lflag  uint64
+	Cc     [20]byte
+	Ispeed uint64
+	Ospeed uint64
+}
+
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // mode and returns the previous state of the terminal so that it can be
 // restored.
-func MakeRaw(fd int) (*State, error) {
+func MakeRaw(fd uintptr) (*State, error) {
 	var oldState State
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
 		return nil, err
 	}
 
 	newState := oldState.termios
-	newState.Iflag &^= ISTRIP | INLCR | IGNCR | IXON | IXOFF
+	newState.Iflag &^= (ISTRIP | INLCR | IGNCR | IXON | IXOFF)
 	newState.Iflag |= ICRNL
 	newState.Oflag |= ONLCR
-	newState.Lflag &^= ECHO | ICANON | ISIG
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+	newState.Lflag &^= (ECHO | ICANON | ISIG)
+
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
 		return nil, err
 	}
 

+ 22 - 36
term/termios_linux.go

@@ -5,54 +5,40 @@ import (
 	"unsafe"
 )
 
-// #include <termios.h>
-// #include <sys/ioctl.h>
-/*
-void MakeRaw(int fd) {
-  struct termios t;
-
-  // FIXME: Handle errors?
-  ioctl(fd, TCGETS, &t);
-
-  t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
-  t.c_oflag &= ~OPOST;
-  t.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
-  t.c_cflag &= ~(CSIZE | PARENB);
-  t.c_cflag |= CS8;
-
-  ioctl(fd, TCSETS, &t);
-}
-*/
-import "C"
-
 const (
 	getTermios = syscall.TCGETS
 	setTermios = syscall.TCSETS
 )
 
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [20]byte
+	Ispeed uint32
+	Ospeed uint32
+}
+
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // mode and returns the previous state of the terminal so that it can be
 // restored.
-func MakeRaw(fd int) (*State, error) {
+func MakeRaw(fd uintptr) (*State, error) {
 	var oldState State
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
 		return nil, err
 	}
-	C.MakeRaw(C.int(fd))
-	return &oldState, nil
-
-	// FIXME: post on goland issues this: very same as the C function bug non-working
 
-	// newState := oldState.termios
+	newState := oldState.termios
 
-	// newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
-	// newState.Oflag &^= OPOST
-	// newState.Lflag &^= (ECHO | syscall.ECHONL | ICANON | ISIG | IEXTEN)
-	// newState.Cflag &^= (CSIZE | syscall.PARENB)
-	// newState.Cflag |= CS8
+	newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
+	newState.Oflag &^= syscall.OPOST
+	newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
+	newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
+	newState.Cflag |= syscall.CS8
 
-	// if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&newState))); err != 0 {
-	// 	return nil, err
-	// }
-	// return &oldState, nil
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
+		return nil, err
+	}
+	return &oldState, nil
 }