diff --git a/platform/winproc.go b/platform/winproc.go index cbee5f3..71ba07b 100644 --- a/platform/winproc.go +++ b/platform/winproc.go @@ -68,7 +68,7 @@ package platform // return 0; // } // -// DWORD createGuestProcHelper( uintptr_t hpc, LPCWSTR imagePath, uintptr_t * hProcess ) +// DWORD createGuestProcHelper( uintptr_t hpc, LPCWSTR imagePath, uintptr_t * hProcess, DWORD * dwProcessID ) // { // STARTUPINFOEXW_copy si; // ZeroMemory( &si, sizeof(si) ); @@ -132,6 +132,7 @@ package platform // } // // *hProcess = (uintptr_t) pi.hProcess; +// *dwProcessID = pi.dwProcessId; // // HeapFree(GetProcessHeap(), 0, si.lpAttributeList); // HeapFree(GetProcessHeap(), 0, cmdLineMutable); @@ -154,10 +155,11 @@ func init() { } type winProcess struct { - hproc uintptr + hproc uintptr + processID uint32 } -func createPtyChildProcess(imagePath string, hcon uintptr) (Process, error) { +func createPtyChildProcess(imagePath string, hcon uintptr) (*winProcess, error) { path16 := utf16.Encode([]rune(imagePath)) cpath16 := C.calloc(C.size_t(len(path16)+1), 2) @@ -165,8 +167,9 @@ func createPtyChildProcess(imagePath string, hcon uintptr) (Process, error) { copy(pp[:], path16) hproc := C.uintptr_t(0) + dwProcessID := C.DWORD(0) - hr := C.createGuestProcHelper(C.uintptr_t(hcon), (C.LPCWSTR)(cpath16), &hproc) + hr := C.createGuestProcHelper(C.uintptr_t(hcon), (C.LPCWSTR)(cpath16), &hproc, &dwProcessID) C.free(cpath16) @@ -175,7 +178,8 @@ func createPtyChildProcess(imagePath string, hcon uintptr) (Process, error) { } return &winProcess{ - hproc: uintptr(hproc), + hproc: uintptr(hproc), + processID: uint32(dwProcessID), }, nil } diff --git a/platform/winpty.go b/platform/winpty.go index ffbed82..020975d 100644 --- a/platform/winpty.go +++ b/platform/winpty.go @@ -5,6 +5,7 @@ package platform import ( "errors" "syscall" + "time" "github.com/MaxRis/w32" ) @@ -132,7 +133,42 @@ func (pty *winConPty) Close() error { } func (pty *winConPty) CreateGuestProcess(imagePath string) (Process, error) { - return createPtyChildProcess(imagePath, pty.hcon) + process, err := createPtyChildProcess(imagePath, pty.hcon) + + if err == nil { + setupChildConsole(C.DWORD(process.processID), C.STD_OUTPUT_HANDLE, C.ENABLE_PROCESSED_OUTPUT|C.ENABLE_WRAP_AT_EOL_OUTPUT) + } + + return process, err +} + +func setupChildConsole(processID C.DWORD, nStdHandle C.DWORD, mode uint) bool { + C.FreeConsole() + defer C.AttachConsole(^C.DWORD(0)) // attach to parent process console + + // process may not be ready so we'll do retries + const maxWaitMilliSeconds = 5000 + const waitStepMilliSeconds = 200 + count := maxWaitMilliSeconds / waitStepMilliSeconds + + for { + if r := C.AttachConsole(processID); r != 0 { + break // success + } + lastError := C.GetLastError() + if lastError != C.ERROR_GEN_FAILURE || count <= 0 { + return false + } + + time.Sleep(time.Millisecond * time.Duration(waitStepMilliSeconds)) + count-- + } + + h := C.GetStdHandle(nStdHandle) + C.SetConsoleMode(h, C.DWORD(mode)) + C.FreeConsole() + + return true } func (pty *winConPty) Resize(x, y int) error { diff --git a/terminal/sixel.go b/terminal/sixel.go index 476046d..1faefbd 100644 --- a/terminal/sixel.go +++ b/terminal/sixel.go @@ -17,7 +17,10 @@ func sixelHandler(pty chan rune, terminal *Terminal) error { for { b := <-pty if b == 0x1b { // terminated by ESC bell or ESC \ - _ = <-pty // swallow \ or bell + t := <-pty + if t != 0x07 && t != 0x5c { + return fmt.Errorf("Incorrect terminator in sixel sequence: 0x%02X [%c]", t, t) + } break } if b >= 33 {