This commit is contained in:
Solomon Hykes 2013-03-09 19:44:09 -08:00
parent 754cf30b0e
commit 3de7ff271c
2 changed files with 86 additions and 90 deletions

View File

@ -1,8 +1,8 @@
package client package client
import ( import (
"github.com/dotcloud/docker/rcli"
"github.com/dotcloud/docker/future" "github.com/dotcloud/docker/future"
"github.com/dotcloud/docker/rcli"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
@ -112,7 +112,7 @@ func InteractiveMode(scripts ...string) error {
return err return err
} }
io.WriteString(rcfile, "enable -n help\n") io.WriteString(rcfile, "enable -n help\n")
os.Setenv("PATH", tmp + ":" + os.Getenv("PATH")) os.Setenv("PATH", tmp+":"+os.Getenv("PATH"))
os.Setenv("PS1", "\\h docker> ") os.Setenv("PS1", "\\h docker> ")
shell := exec.Command("/bin/bash", append([]string{"--rcfile", rcfile.Name()}, scripts...)...) shell := exec.Command("/bin/bash", append([]string{"--rcfile", rcfile.Name()}, scripts...)...)
shell.Stdin = os.Stdin shell.Stdin = os.Stdin

172
term.go
View File

@ -15,7 +15,6 @@ type Termios struct {
Ospeed uintptr Ospeed uintptr
} }
const ( const (
// Input flags // Input flags
inpck = 0x010 inpck = 0x010
@ -35,113 +34,110 @@ const (
) )
const ( const (
HUPCL = 0x4000 HUPCL = 0x4000
ICANON = 0x100 ICANON = 0x100
ICRNL = 0x100 ICRNL = 0x100
IEXTEN = 0x400 IEXTEN = 0x400
BRKINT = 0x2 BRKINT = 0x2
CFLUSH = 0xf CFLUSH = 0xf
CLOCAL = 0x8000 CLOCAL = 0x8000
CREAD = 0x800 CREAD = 0x800
CS5 = 0x0 CS5 = 0x0
CS6 = 0x100 CS6 = 0x100
CS7 = 0x200 CS7 = 0x200
CS8 = 0x300 CS8 = 0x300
CSIZE = 0x300 CSIZE = 0x300
CSTART = 0x11 CSTART = 0x11
CSTATUS = 0x14 CSTATUS = 0x14
CSTOP = 0x13 CSTOP = 0x13
CSTOPB = 0x400 CSTOPB = 0x400
CSUSP = 0x1a CSUSP = 0x1a
IGNBRK = 0x1 IGNBRK = 0x1
IGNCR = 0x80 IGNCR = 0x80
IGNPAR = 0x4 IGNPAR = 0x4
IMAXBEL = 0x2000 IMAXBEL = 0x2000
INLCR = 0x40 INLCR = 0x40
INPCK = 0x10 INPCK = 0x10
ISIG = 0x80 ISIG = 0x80
ISTRIP = 0x20 ISTRIP = 0x20
IUTF8 = 0x4000 IUTF8 = 0x4000
IXANY = 0x800 IXANY = 0x800
IXOFF = 0x400 IXOFF = 0x400
IXON = 0x200 IXON = 0x200
NOFLSH = 0x80000000 NOFLSH = 0x80000000
OCRNL = 0x10 OCRNL = 0x10
OFDEL = 0x20000 OFDEL = 0x20000
OFILL = 0x80 OFILL = 0x80
ONLCR = 0x2 ONLCR = 0x2
ONLRET = 0x40 ONLRET = 0x40
ONOCR = 0x20 ONOCR = 0x20
ONOEOT = 0x8 ONOEOT = 0x8
OPOST = 0x1 OPOST = 0x1
RENB = 0x1000 RENB = 0x1000
PARMRK = 0x8 PARMRK = 0x8
PARODD = 0x2000 PARODD = 0x2000
TOSTOP = 0x400000 TOSTOP = 0x400000
VDISCARD = 0xf VDISCARD = 0xf
VDSUSP = 0xb VDSUSP = 0xb
VEOF = 0x0 VEOF = 0x0
VEOL = 0x1 VEOL = 0x1
VEOL2 = 0x2 VEOL2 = 0x2
VERASE = 0x3 VERASE = 0x3
VINTR = 0x8 VINTR = 0x8
VKILL = 0x5 VKILL = 0x5
VLNEXT = 0xe VLNEXT = 0xe
VMIN = 0x10 VMIN = 0x10
VQUIT = 0x9 VQUIT = 0x9
VREPRINT = 0x6 VREPRINT = 0x6
VSTART = 0xc VSTART = 0xc
VSTATUS = 0x12 VSTATUS = 0x12
VSTOP = 0xd VSTOP = 0xd
VSUSP = 0xa VSUSP = 0xa
VT0 = 0x0 VT0 = 0x0
VT1 = 0x10000 VT1 = 0x10000
VTDLY = 0x10000 VTDLY = 0x10000
VTIME = 0x11 VTIME = 0x11
ECHO = 0x00000008 ECHO = 0x00000008
PENDIN = 0x20000000 PENDIN = 0x20000000
) )
type State struct { type State struct {
termios Termios termios Termios
} }
// IsTerminal returns true if the given file descriptor is a terminal. // IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool { func IsTerminal(fd int) bool {
var termios Termios var termios Termios
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&termios)), 0, 0, 0) _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
return err == 0 return err == 0
} }
// MakeRaw put the terminal connected to the given file descriptor into raw // 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 // mode and returns the previous state of the terminal so that it can be
// restored. // restored.
func MakeRaw(fd int) (*State, error) { func MakeRaw(fd int) (*State, error) {
var oldState State 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.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
return nil, err return nil, err
} }
newState := oldState.termios newState := oldState.termios
newState.Iflag &^= ISTRIP | INLCR | IGNCR | IXON | IXOFF newState.Iflag &^= ISTRIP | INLCR | IGNCR | IXON | IXOFF
newState.Iflag |= ICRNL newState.Iflag |= ICRNL
newState.Oflag |= ONLCR newState.Oflag |= ONLCR
newState.Lflag &^= ECHO | ICANON | ISIG 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 { if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
return nil, err return nil, err
} }
return &oldState, nil return &oldState, nil
} }
// Restore restores the terminal connected to the given file descriptor to a // Restore restores the terminal connected to the given file descriptor to a
// previous state. // previous state.
func Restore(fd int, state *State) error { func Restore(fd int, state *State) error {
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
return err return err
} }