Skip to content

Instantly share code, notes, and snippets.

@SCP002
Last active November 1, 2022 20:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SCP002/097d77724aabe45deda3b880276a2e27 to your computer and use it in GitHub Desktop.
Save SCP002/097d77724aabe45deda3b880276a2e27 to your computer and use it in GitHub Desktop.
Golang: Initialize console handlers after AttachConsole or AllocConsole on Windows.
// 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