What version of Go are you using (go version)?

$ go version
go version go1.21.1 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Ayman\AppData\Local\go-build
set GOENV=C:\Users\Ayman\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\Ayman\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\Ayman\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.21.1
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\Ayman\AppData\Local\Temp\go-build1093290718=/tmp/go-build -gno-record-gcc-switches

What did you do?

Windows now supports creating pseudo consoles, ConPty, using their Console API. As of now, we cannot run a process on a ConPty using os/exec. That's due to the fact that ConPty requires updating the process attributes with the Pty handle and pseudoconsole attribute (PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016), and currently, there is no way to pass the Pty handle down to syscall.StartProcess.

See: https://learn.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session Related: https://github.com/golang/sys/pull/175

What did you expect to see?

The process runs on a ConPty session.

What did you see instead?

The process does not run on a ConPty session.

Comment From: seankhliao

is there a specific change that you're proposing that could make it work?

cc @golang/windows

Comment From: aymanbagabas

is there a specific change that you're proposing that could make it work?

cc @golang/windows

Yes, I just submitted https://github.com/golang/go/pull/62710 to fix this issue

Comment From: gopherbot

Change https://go.dev/cl/529315 mentions this issue: syscall: add SysProcAttr.PseudoConsole on Windows

Comment From: qmuntal

This proposal doesn't contain the necessary API changes to support ConPty. For what I can see in the associated CL 529315, it would only need this addition into syscall.SysProcAttr :

type SysProcAttr struct {
        ...
    PseudoConsole              Handle              // if non-zero, the new process will be attached to the console represented by this handle, any AdditionalInheritedHandles will be ignored, this implies NoInheritHandles
}

Reading the docs and peeking at some code samples out there, adding this new property seems like enough to creating pseudoconsole sessions. What I can't find is documentation about why it precludes inheriting additional handles. Could you help me understanding that?

Comment From: aymanbagabas

This proposal doesn't contain the necessary API changes to support ConPty. For what I can see in the associated CL 529315, it would only need this addition into syscall.SysProcAttr :

That's correct. This is where CL 528915 comes in place to add ConPty API to sys/windows. We need CL 529315 to support running processes on a ConPty.

Reading the docs and peeking at some code samples out there, adding this new property seems like enough to creating pseudoconsole sessions. What I can't find is documentation about why it precludes inheriting additional handles. Could you help me understanding that?

I couldn't find any info in the docs. All I found is this comment from hcsshim "If the client requested a pseudo console then there's nothing we need to do pipe wise, as the process inherits the other end of the pty's pipes."

EDIT: add node-pty and https://github.com/microsoft/node-pty/pull/334 for reference

Comment From: qmuntal

EDIT: add node-pty and https://github.com/microsoft/node-pty/pull/334 for reference

Thanks for the sources. What I understood is that ConPty has a bug that makes it misbehave when inheriting handles. As it makes no sense to do that anyway, then handle inheriting is disabled. Looks fuzzy, but convinced me.

Comment From: aymanbagabas

Any updates on this one? #62710 CR 529315 only needs one addition to syscall.SysProcAttr to make spawning processes on a ConPty possible

type SysProcAttr struct {
        ...
    PseudoConsole              Handle              // if non-zero, the new process will be attached to the console represented by this handle, any AdditionalInheritedHandles will be ignored, this implies NoInheritHandles
}

CC/ @bcmills @thanm @qmuntal

Comment From: qmuntal

Any updates on this one?

It still needs to complete the proposal process and get accepted. The next step is that this proposal is discussed by the proposals team, but it can take a while as the proposals queue is big.

Comment From: nichtverstehen

What is missing from this proposal? I see there is a decent CL provided with tests and stuff.

This change would be incredibly useful (currently we have to resort to forking the whole syscall.StartProcess into our codebase).