How to disable ENABLE_LINE_INPUT in ConPTY? How to call GetConsoleMode for a PseudoConsole? #13257
-
Windows Terminal version1.12.10982.0 Windows build number10.0.19043.0 Other Softwarehttps://github.com/UserExistsError/conpty v0.1.0 Is it similar to https://stackoverflow.com/a/11439517/7696611 ? Steps to reproduce
package main
import (
"bufio"
"context"
"fmt"
"strings"
"github.com/UserExistsError/conpty"
)
func main() {
cpty, err := conpty.Start("python3 -c \"import sys; s = sys.stdin.readline(); print(len(s))\"")
if err != nil {
fmt.Printf("Failed to spawn a pty: %v", err)
return
}
defer cpty.Close()
go func() {
cpty.Write([]byte(strings.Repeat("A", 3000) + "\r\n"))
scanner := bufio.NewScanner(cpty)
for scanner.Scan() {
// Should output 3001.
// But output 511 in cmd, output 2510 in MSYS2.
fmt.Printf("Output: %s\n", scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}()
if _, err := cpty.Wait(context.Background()); err != nil {
fmt.Printf("Error: %v", err)
}
} Expected BehaviorOutput: 3001 Actual BehaviorOutput: 511 |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
If disable But I can't change the child process to disable Is there a way to disable
package main
import (
"bufio"
"fmt"
"os"
"golang.org/x/sys/windows"
)
func main() {
var st uint32
if err := windows.GetConsoleMode(windows.Handle(os.Stdin.Fd()), &st); err != nil {
fmt.Println(err)
return
}
// disable ENABLE_LINE_INPUT
raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
fmt.Printf("st: %#x, raw: %#x\n", st, raw)
if err := windows.SetConsoleMode(windows.Handle(os.Stdin.Fd()), raw); err != nil {
fmt.Println(err)
return
}
// reset console mode
defer func() {
if err := windows.SetConsoleMode(windows.Handle(os.Stdin.Fd()), st); err != nil {
fmt.Println(err)
return
}
}()
// read line
line, err := bufio.NewReader(os.Stdin).ReadBytes('\r')
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("\nLength: %d\r\n", len(line))
}
package main
import (
"bufio"
"context"
"fmt"
"strings"
"time"
"github.com/UserExistsError/conpty"
)
func main() {
cpty, err := conpty.Start("readline.exe") // The child process have to disable ENABLE_LINE_INPUT first
if err != nil {
fmt.Printf("Failed to spawn a pty: %v", err)
return
}
defer cpty.Close()
go func() {
time.Sleep(1 * time.Second) // Wait the child process disable ENABLE_LINE_INPUT first
cpty.Write([]byte(strings.Repeat("A", 5000) + "\r\n"))
scanner := bufio.NewScanner(cpty)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}()
if _, err := cpty.Wait(context.Background()); err != nil {
fmt.Printf("Error: %v", err)
}
} |
Beta Was this translation helpful? Give feedback.
-
Huh. I think you might be stuck here then. I don't think we provide any sort of way to call the console APIs on a conpty you create. There might be some trickery possible. You might be able to attach some other helper |
Beta Was this translation helpful? Give feedback.
-
Thanks for your help. I tried it before, it works. I disabled the Btw, the |
Beta Was this translation helpful? Give feedback.
Huh. I think you might be stuck here then. I don't think we provide any sort of way to call the console APIs on a conpty you create. There might be some trickery possible. You might be able to attach some other helper
disable-line-input.exe
to the same conpty, which just calls that API, and have it magically work. IIRC input mode is a global state, so multiple attached clients can mess with each other's state. But, I'd also caution that's definitely a hack and one we're intending to fix (#4954)