removed auth in pull
This commit is contained in:
commit
7e59b83053
11 changed files with 156 additions and 225 deletions
12
api.go
12
api.go
|
@ -327,17 +327,7 @@ func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *ht
|
|||
sf := utils.NewStreamFormatter(version > 1.0)
|
||||
if image != "" { //pull
|
||||
registry := r.Form.Get("registry")
|
||||
authConfig := &auth.AuthConfig{}
|
||||
if version > 1.1 {
|
||||
json.NewDecoder(r.Body).Decode(authConfig)
|
||||
} else {
|
||||
localAuthConfig, err := auth.LoadConfig(srv.runtime.root)
|
||||
if err != nil && err != auth.ErrConfigFileMissing {
|
||||
return err
|
||||
}
|
||||
authConfig = localAuthConfig
|
||||
}
|
||||
if err := srv.ImagePull(image, tag, registry, w, sf, authConfig); err != nil {
|
||||
if err := srv.ImagePull(image, tag, registry, w, sf, &auth.AuthConfig{}); err != nil {
|
||||
if sf.Used() {
|
||||
w.Write(sf.FormatError(err))
|
||||
return nil
|
||||
|
|
|
@ -3,7 +3,7 @@ package docker
|
|||
type ApiHistory struct {
|
||||
Id string
|
||||
Created int64
|
||||
CreatedBy string
|
||||
CreatedBy string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ApiImages struct {
|
||||
|
@ -14,13 +14,13 @@ type ApiImages struct {
|
|||
}
|
||||
|
||||
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 ApiId struct {
|
|||
|
||||
type ApiRun struct {
|
||||
Id string
|
||||
Warnings []string
|
||||
Warnings []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ApiPort struct {
|
||||
|
@ -51,10 +51,9 @@ type ApiPort struct {
|
|||
}
|
||||
|
||||
type ApiVersion struct {
|
||||
Version string
|
||||
GitCommit string
|
||||
MemoryLimit bool
|
||||
SwapLimit bool
|
||||
Version string
|
||||
GitCommit string `json:",omitempty"`
|
||||
GoVersion string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ApiWait struct {
|
||||
|
|
|
@ -99,8 +99,8 @@ func TestGetInfo(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ func Changes(layers []string, rw string) ([]Change, error) {
|
|||
file := filepath.Base(path)
|
||||
// If there is a whiteout, then the file was removed
|
||||
if strings.HasPrefix(file, ".wh.") {
|
||||
originalFile := strings.TrimLeft(file, ".wh.")
|
||||
originalFile := strings.TrimPrefix(file, ".wh.")
|
||||
change.Path = filepath.Join(filepath.Dir(path), originalFile)
|
||||
change.Kind = ChangeDelete
|
||||
} else {
|
||||
|
|
51
commands.go
51
commands.go
|
@ -383,15 +383,14 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
|
|||
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
|
||||
}
|
||||
|
||||
|
@ -412,14 +411,23 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -693,9 +701,14 @@ func (cli *DockerCli) CmdPush(args ...string) error {
|
|||
return fmt.Errorf("Impossible to push a \"root\" repository. Please rename your repository in <user>/<repo> (ex: %s/%s)", cli.authConfig.Username, name)
|
||||
}
|
||||
|
||||
buf, err := json.Marshal(cli.authConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("registry", *registry)
|
||||
if err := cli.stream("POST", "/images/"+name+"/push?"+v.Encode(), nil, os.Stdout); err != nil {
|
||||
if err := cli.stream("POST", "/images/"+name+"/push?"+v.Encode(), bytes.NewBuffer(buf), os.Stdout); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -721,12 +734,6 @@ func (cli *DockerCli) CmdPull(args ...string) error {
|
|||
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)
|
||||
|
@ -1383,7 +1390,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 {
|
||||
|
@ -1402,7 +1409,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
|
||||
}
|
||||
|
|
|
@ -217,6 +217,37 @@ func TestDiff(t *testing.T) {
|
|||
t.Fatalf("/etc/passwd should not be present in the diff after commit.")
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new containere
|
||||
container3, err := builder.Create(
|
||||
&Config{
|
||||
Image: GetTestImage(runtime).Id,
|
||||
Cmd: []string{"rm", "/bin/httpd"},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer runtime.Destroy(container3)
|
||||
|
||||
if err := container3.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check the changelog
|
||||
c, err = container3.Changes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
success = false
|
||||
for _, elem := range c {
|
||||
if elem.Path == "/bin/httpd" && elem.Kind == 2 {
|
||||
success = true
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
t.Fatalf("/bin/httpd should be present in the diff after commit.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitAutoRun(t *testing.T) {
|
||||
|
|
|
@ -14,7 +14,7 @@ Docker Remote API
|
|||
- The Remote API is replacing rcli
|
||||
- Default port in the docker deamon is 4243
|
||||
- The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr
|
||||
- Since API version 1.2, the auth configuration is now handled client side, so the client has to send the authConfig as POST in /images/create and /images/<name>/pull
|
||||
- Since API version 1.2, the auth configuration is now handled client side, so the client has to send the authConfig as POST in /images/create
|
||||
|
||||
2. Version
|
||||
==========
|
||||
|
@ -551,19 +551,12 @@ Create an image
|
|||
|
||||
Create an image, either by pull it from the registry or by importing it
|
||||
|
||||
**Example request v1.0**:
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /images/create?fromImage=base HTTP/1.1
|
||||
|
||||
**Example request v1.2**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /images/create?fromImage=base HTTP/1.1
|
||||
{{ authConfig }}
|
||||
|
||||
**Example response v1.1**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
@ -972,10 +965,12 @@ Display system-wide information
|
|||
|
||||
{
|
||||
"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
|
||||
|
@ -1001,12 +996,11 @@ Show the docker version information
|
|||
|
||||
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
|
||||
|
|
28
server.go
28
server.go
|
@ -17,7 +17,11 @@ import (
|
|||
)
|
||||
|
||||
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 @@ func (srv *Server) Images(all bool, filter string) ([]ApiImages, error) {
|
|||
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 @@ func (srv *Server) DockerInfo() ApiInfo {
|
|||
} 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) {
|
||||
|
@ -395,7 +397,6 @@ func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, remote, a
|
|||
}
|
||||
|
||||
func (srv *Server) ImagePull(name, tag, endpoint string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig) error {
|
||||
utils.Debugf("ImagePull from <%s>", authConfig.Username)
|
||||
r := registry.NewRegistry(srv.runtime.root, authConfig)
|
||||
out = utils.NewWriteFlusher(out)
|
||||
if endpoint != "" {
|
||||
|
@ -578,7 +579,6 @@ func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgId,
|
|||
}
|
||||
|
||||
func (srv *Server) ImagePush(name, endpoint string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig) error {
|
||||
utils.Debugf("ImagePush from <%s>", authConfig.Username)
|
||||
out = utils.NewWriteFlusher(out)
|
||||
img, err := srv.runtime.graph.Get(name)
|
||||
r := registry.NewRegistry(srv.runtime.root, authConfig)
|
||||
|
|
112
term/term.go
112
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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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.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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue