Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: syscall: make use of StartupInfo.Reserved2 on Windows #53686

Open
ZekeLu opened this issue Jul 5, 2022 · 1 comment · May be fixed by #53687
Open

proposal: syscall: make use of StartupInfo.Reserved2 on Windows #53686

ZekeLu opened this issue Jul 5, 2022 · 1 comment · May be fixed by #53687

Comments

@ZekeLu
Copy link
Contributor

ZekeLu commented Jul 5, 2022

Background

This is a follow-up of #21085. The inheritance part of that issue has been addressed by #44011. But the discovery part remains. This proposal tries to address the discovery part of that issue.

The Proposal

On Windows, it's a de facto to use _get_osfhandle to discover the inherited file descriptors in the child process. For example, Chromium uses it to support its --remote-debugging-pipe option (see devtools_pipe_handler.cc). This C Runtime function depends on the information passed by the lpReserved2 field of the STARTUPINFOW struct. The MSDN just states that this field is Reserved for use by the C Run-time; must be NULL. Luckily, the implementation can be found at least in two projects:

As of now, the corresponding field in Go is omitted. So I propose to make use of this field to make the inherited file descriptors discoverable by the child process. Here is the change to the StartupInfo struct:

 type StartupInfo struct {
    Cb            uint32
    _             *uint16
    Desktop       *uint16
    Title         *uint16
    X             uint32
    Y             uint32
    XSize         uint32
    YSize         uint32
    XCountChars   uint32
    YCountChars   uint32
    FillAttribute uint32
    Flags         uint32
    ShowWindow    uint16
-   _             uint16
-   _             *byte
+   CbReserved2   uint16
+   Reserved2     *byte
    StdInput      Handle
    StdOutput     Handle
    StdErr        Handle
 }

I will send a CL to show the implementation later. If the CL is landed, the child process can get the inherited file descriptor like this (taking from the test in the upcoming CL):

func cmdCRTPipeHandle(args ...string) {
	get_osfhandle := syscall.NewLazyDLL("msvcrt.dll").NewProc("_get_osfhandle")

	h3, _, _ := get_osfhandle.Call(3)
	if h3 == uintptr(syscall.InvalidHandle) {
		fmt.Fprintf(os.Stderr, "_get_osfhandle: pipe 3 is invalid\n")
		os.Exit(1)
	}
	pipe3 := os.NewFile(h3, "in")
	defer pipe3.Close()

	h4, _, _ := get_osfhandle.Call(4)
	if h4 == uintptr(syscall.InvalidHandle) {
		fmt.Fprintf(os.Stderr, "_get_osfhandle: pipe 4 is invalid\n")
		os.Exit(1)
	}
	pipe4 := os.NewFile(h4, "out")
	defer pipe4.Close()

	// use the pipes, truncated
}

Credits

The idea is inspired by the comments in #21085. Thank you @zombiezen @alexbrainman @glasser @tv42 and all others who were taking part in the discussion!

@ZekeLu ZekeLu added the Proposal label Jul 5, 2022
@gopherbot gopherbot added this to the Proposal milestone Jul 5, 2022
@ZekeLu ZekeLu linked a pull request Jul 5, 2022 that will close this issue
@gopherbot
Copy link

gopherbot commented Jul 5, 2022

Change https://go.dev/cl/415995 mentions this issue: syscall: make use of StartupInfo.Reserved2 on Windows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Incoming
Development

Successfully merging a pull request may close this issue.

3 participants