Last active
November 1, 2022 20:42
-
-
Save SCP002/097d77724aabe45deda3b880276a2e27 to your computer and use it in GitHub Desktop.
Golang: Initialize console handlers after AttachConsole or AllocConsole on Windows.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Used in https://github.com/SCP002/terminator. | |
package main | |
import ( | |
"errors" | |
"os" | |
"golang.org/x/sys/windows" | |
) | |
// InitConsoleHandles initializes standard IO handles for the current console. | |
// | |
// Useful to call after AttachConsole or AllocConsole. | |
func InitConsoleHandles() error { | |
// Retrieve standard handles. | |
hIn, err := windows.GetStdHandle(windows.STD_INPUT_HANDLE) | |
if err != nil { | |
return errors.New("Failed to retrieve standard input handler.") | |
} | |
hOut, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) | |
if err != nil { | |
return errors.New("Failed to retrieve standard output handler.") | |
} | |
hErr, err := windows.GetStdHandle(windows.STD_ERROR_HANDLE) | |
if err != nil { | |
return errors.New("Failed to retrieve standard error handler.") | |
} | |
// Wrap handles in files. /dev/ prefix just to make it conventional. | |
stdInF := os.NewFile(uintptr(hIn), "/dev/stdin") | |
if stdInF == nil { | |
return errors.New("Failed to create a new file for standard input.") | |
} | |
stdOutF := os.NewFile(uintptr(hOut), "/dev/stdout") | |
if stdOutF == nil { | |
return errors.New("Failed to create a new file for standard output.") | |
} | |
stdErrF := os.NewFile(uintptr(hErr), "/dev/stderr") | |
if stdErrF == nil { | |
return errors.New("Failed to create a new file for standard error.") | |
} | |
// Set handles for standard input, output and error devices. | |
err = windows.SetStdHandle(windows.STD_INPUT_HANDLE, windows.Handle(stdInF.Fd())) | |
if err != nil { | |
return errors.New("Failed to set standard input handler.") | |
} | |
err = windows.SetStdHandle(windows.STD_OUTPUT_HANDLE, windows.Handle(stdOutF.Fd())) | |
if err != nil { | |
return errors.New("Failed to set standard output handler.") | |
} | |
err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(stdErrF.Fd())) | |
if err != nil { | |
return errors.New("Failed to set standard error handler.") | |
} | |
// Update golang standard IO file descriptors. | |
os.Stdin = stdInF | |
os.Stdout = stdOutF | |
os.Stderr = stdErrF | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment