Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion std_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
package readline

func init() {
Stdin = NewRawReader()
// don't use RawReader if stdin is a pipe (see https://github.com/chzyer/readline/issues/229)
stdinType, _ := kernel.GetFileType(stdin)
if stdinType == FILE_TYPE_CHAR {
Stdin = NewRawReader()
}
Stdout = NewANSIWriter(Stdout)
Stderr = NewANSIWriter(Stderr)
}
53 changes: 28 additions & 25 deletions windows_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Kernel struct {
GetConsoleScreenBufferInfo,
GetConsoleCursorInfo,
GetStdHandle CallFunc
GetFileType CallFuncDword
}

type short int16
Expand All @@ -45,6 +46,7 @@ const (
EVENT_WINDOW_BUFFER_SIZE = 0x0004
EVENT_MENU = 0x0008
EVENT_FOCUS = 0x0010
FILE_TYPE_CHAR = 0x0002
)

type _KEY_EVENT_RECORD struct {
Expand Down Expand Up @@ -88,46 +90,47 @@ type _CONSOLE_CURSOR_INFO struct {
}

type CallFunc func(u ...uintptr) error
type CallFuncDword func(u ...uintptr) (uint32, error)

func NewKernel() *Kernel {
k := &Kernel{}
kernel32 := syscall.NewLazyDLL("kernel32.dll")
v := reflect.ValueOf(k).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
name := t.Field(i).Name
field := t.Field(i)
name := field.Name
f := kernel32.NewProc(name)
v.Field(i).Set(reflect.ValueOf(k.Wrap(f)))
v.Field(i).Set(reflect.ValueOf(k.Wrap(f, field.Type)))
}
return k
}

func (k *Kernel) Wrap(p *syscall.LazyProc) CallFunc {
return func(args ...uintptr) error {
var r0 uintptr
var e1 syscall.Errno
size := uintptr(len(args))
if len(args) <= 3 {
buf := make([]uintptr, 3)
copy(buf, args)
r0, _, e1 = syscall.Syscall(p.Addr(), size,
buf[0], buf[1], buf[2])
} else {
buf := make([]uintptr, 6)
copy(buf, args)
r0, _, e1 = syscall.Syscall6(p.Addr(), size,
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
)
}

if int(r0) == 0 {
func (k *Kernel) Wrap(p *syscall.LazyProc, fieldType reflect.Type) interface{} {
if fieldType == reflect.ValueOf(CallFuncDword(nil)).Type() {
return func(args ...uintptr) (uint32, error) {
var r0 uintptr
var e1 syscall.Errno
r0, _, e1 = syscall.SyscallN(p.Addr(), args...);
if e1 != 0 {
return error(e1)
} else {
return syscall.EINVAL
return 0, error(e1)
}
return uint32(r0), nil
}
} else {
return func(args ...uintptr) error {
var r0 uintptr
var e1 syscall.Errno
r0, _, e1 = syscall.SyscallN(p.Addr(), args...);
if int(r0) == 0 {
if e1 != 0 {
return error(e1)
} else {
return syscall.EINVAL
}
}
return nil
}
return nil
}

}
Expand Down