Merge pull request #792 from dotcloud/780-diff-fix

- Runtime: fix Path corruption in 'docker diff'
diff --git a/api_params.go b/api_params.go
index 1a24ab2..e18238b 100644
--- a/api_params.go
+++ b/api_params.go
@@ -3,7 +3,7 @@
 type ApiHistory struct {
 	Id        string
 	Created   int64
-	CreatedBy string
+	CreatedBy string `json:",omitempty"`
 }
 
 type ApiImages struct {
@@ -14,13 +14,13 @@
 }
 
 type ApiInfo struct {
-	Containers  int
-	Version     string
-	Images      int
 	Debug       bool
-	GoVersion   string
-	NFd         int `json:",omitempty"`
-	NGoroutines int `json:",omitempty"`
+	Containers  int
+	Images      int
+	NFd         int  `json:",omitempty"`
+	NGoroutines int  `json:",omitempty"`
+	MemoryLimit bool `json:",omitempty"`
+	SwapLimit   bool `json:",omitempty"`
 }
 
 type ApiContainers struct {
@@ -43,7 +43,7 @@
 
 type ApiRun struct {
 	Id       string
-	Warnings []string
+	Warnings []string `json:",omitempty"`
 }
 
 type ApiPort struct {
@@ -51,10 +51,9 @@
 }
 
 type ApiVersion struct {
-	Version     string
-	GitCommit   string
-	MemoryLimit bool
-	SwapLimit   bool
+	Version   string
+	GitCommit string `json:",omitempty"`
+	GoVersion string `json:",omitempty"`
 }
 
 type ApiWait struct {
diff --git a/api_test.go b/api_test.go
index f364c6c..9121167 100644
--- a/api_test.go
+++ b/api_test.go
@@ -106,8 +106,8 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if infos.Version != VERSION {
-		t.Errorf("Excepted version %s, %s found", VERSION, infos.Version)
+	if infos.Images != 1 {
+		t.Errorf("Excepted images: %d, %d found", 1, infos.Images)
 	}
 }
 
diff --git a/commands.go b/commands.go
index 76b70cd..ddb2c1a 100644
--- a/commands.go
+++ b/commands.go
@@ -392,15 +392,14 @@
 		utils.Debugf("Error unmarshal: body: %s, err: %s\n", body, err)
 		return err
 	}
-	fmt.Println("Version:", out.Version)
-	fmt.Println("Git Commit:", out.GitCommit)
-	if !out.MemoryLimit {
-		fmt.Println("WARNING: No memory limit support")
+	fmt.Println("Client version:", VERSION)
+	fmt.Println("Server version:", out.Version)
+	if out.GitCommit != "" {
+		fmt.Println("Git commit:", out.GitCommit)
 	}
-	if !out.SwapLimit {
-		fmt.Println("WARNING: No swap limit support")
+	if out.GoVersion != "" {
+		fmt.Println("Go version:", out.GoVersion)
 	}
-
 	return nil
 }
 
@@ -421,14 +420,23 @@
 	}
 
 	var out ApiInfo
-	err = json.Unmarshal(body, &out)
-	if err != nil {
+	if err := json.Unmarshal(body, &out); err != nil {
 		return err
 	}
-	fmt.Printf("containers: %d\nversion: %s\nimages: %d\nGo version: %s\n", out.Containers, out.Version, out.Images, out.GoVersion)
-	if out.Debug {
-		fmt.Println("debug mode enabled")
-		fmt.Printf("fds: %d\ngoroutines: %d\n", out.NFd, out.NGoroutines)
+
+	fmt.Printf("Containers: %d\n", out.Containers)
+	fmt.Printf("Images: %d\n", out.Images)
+	if out.Debug || os.Getenv("DEBUG") != "" {
+		fmt.Printf("Debug mode (server): %v\n", out.Debug)
+		fmt.Printf("Debug mode (client): %v\n", os.Getenv("DEBUG") != "")
+		fmt.Printf("Fds: %d\n", out.NFd)
+		fmt.Printf("Goroutines: %d\n", out.NGoroutines)
+	}
+	if !out.MemoryLimit {
+		fmt.Println("WARNING: No memory limit support")
+	}
+	if !out.SwapLimit {
+		fmt.Println("WARNING: No swap limit support")
 	}
 	return nil
 }
@@ -731,12 +739,6 @@
 		remote = remoteParts[0]
 	}
 
-	if strings.Contains(remote, "/") {
-		if _, err := cli.checkIfLogged(true, "pull"); err != nil {
-			return err
-		}
-	}
-
 	v := url.Values{}
 	v.Set("fromImage", remote)
 	v.Set("tag", *tag)
@@ -1414,7 +1416,7 @@
 		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 {
@@ -1433,7 +1435,7 @@
 		return err
 	}
 
-	if !term.IsTerminal(int(os.Stdin.Fd())) {
+	if !term.IsTerminal(os.Stdin.Fd()) {
 		if err := <-sendStdin; err != nil {
 			return err
 		}
diff --git a/docs/sources/api/docker_remote_api.rst b/docs/sources/api/docker_remote_api.rst
index 9087c21..dca4599 100644
--- a/docs/sources/api/docker_remote_api.rst
+++ b/docs/sources/api/docker_remote_api.rst
@@ -957,10 +957,12 @@
 
 	   {
 		"Containers":11,
-		"Version":"0.2.2",
 		"Images":16,
-		"GoVersion":"go1.0.3",
-		"Debug":false
+		"Debug":false,
+		"NFd": 11,
+		"NGoroutines":21,
+		"MemoryLimit":true,
+		"SwapLimit":false
 	   }
 
         :statuscode 200: no error
@@ -986,12 +988,11 @@
 
            HTTP/1.1 200 OK
 	   Content-Type: application/json
-	   
+
 	   {
 		"Version":"0.2.2",
 		"GitCommit":"5a2a5cc+CHANGES",
-		"MemoryLimit":true,
-		"SwapLimit":false
+		"GoVersion":"go1.0.3"
 	   }
 
         :statuscode 200: no error
diff --git a/server.go b/server.go
index 4c05a97..fa847b9 100644
--- a/server.go
+++ b/server.go
@@ -17,7 +17,11 @@
 )
 
 func (srv *Server) DockerVersion() ApiVersion {
-	return ApiVersion{VERSION, GIT_COMMIT, srv.runtime.capabilities.MemoryLimit, srv.runtime.capabilities.SwapLimit}
+	return ApiVersion{
+		Version:   VERSION,
+		GitCommit: GIT_COMMIT,
+		GoVersion: runtime.Version(),
+	}
 }
 
 func (srv *Server) ContainerKill(name string) error {
@@ -187,7 +191,7 @@
 	return outs, nil
 }
 
-func (srv *Server) DockerInfo() ApiInfo {
+func (srv *Server) DockerInfo() *ApiInfo {
 	images, _ := srv.runtime.graph.All()
 	var imgcount int
 	if images == nil {
@@ -195,17 +199,15 @@
 	} else {
 		imgcount = len(images)
 	}
-	var out ApiInfo
-	out.Containers = len(srv.runtime.List())
-	out.Version = VERSION
-	out.Images = imgcount
-	out.GoVersion = runtime.Version()
-	if os.Getenv("DEBUG") != "" {
-		out.Debug = true
-		out.NFd = utils.GetTotalUsedFds()
-		out.NGoroutines = runtime.NumGoroutine()
+	return &ApiInfo{
+		Containers:  len(srv.runtime.List()),
+		Images:      imgcount,
+		MemoryLimit: srv.runtime.capabilities.MemoryLimit,
+		SwapLimit:   srv.runtime.capabilities.SwapLimit,
+		Debug:       os.Getenv("DEBUG") != "",
+		NFd:         utils.GetTotalUsedFds(),
+		NGoroutines: runtime.NumGoroutine(),
 	}
-	return out
 }
 
 func (srv *Server) ImageHistory(name string) ([]ApiHistory, error) {
diff --git a/term/term.go b/term/term.go
index 290bf17..0cc91ea 100644
--- a/term/term.go
+++ b/term/term.go
@@ -7,104 +7,6 @@
 	"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 @@
 }
 
 // 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 @@
 	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)
 }
diff --git a/term/termios_darwin.go b/term/termios_darwin.go
index 7df54e7..ac18aab 100644
--- a/term/termios_darwin.go
+++ b/term/termios_darwin.go
@@ -8,23 +8,45 @@
 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
 	}
 
diff --git a/term/termios_linux.go b/term/termios_linux.go
index 92f21ed..4a717c8 100644
--- a/term/termios_linux.go
+++ b/term/termios_linux.go
@@ -5,54 +5,40 @@
 	"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))
+
+	newState := oldState.termios
+
+	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, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
+		return nil, err
+	}
 	return &oldState, nil
-
-	// FIXME: post on goland issues this: very same as the C function bug non-working
-
-	// 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
-
-	// if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&newState))); err != 0 {
-	// 	return nil, err
-	// }
-	// return &oldState, nil
 }