Skip to content

Commit 914b398

Browse files
committed
syscall: add SysProcAttr.PseudoConsole on Windows
This allows the user to pass a ConPty handle to run a process on a ConPty session. See: https://learn.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session Fixes: #62708
1 parent c631297 commit 914b398

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/syscall/exec_windows.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ type SysProcAttr struct {
251251
NoInheritHandles bool // if set, no handles are inherited by the new process, not even the standard handles, contained in ProcAttr.Files, nor the ones contained in AdditionalInheritedHandles
252252
AdditionalInheritedHandles []Handle // a list of additional handles, already marked as inheritable, that will be inherited by the new process
253253
ParentProcess Handle // if non-zero, the new process regards the process given by this handle as its parent process, and AdditionalInheritedHandles, if set, should exist in this parent process
254+
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
254255
}
255256

256257
var zeroProcAttr ProcAttr
@@ -371,9 +372,13 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
371372
return 0, 0, err
372373
}
373374
}
374-
si.StdInput = fd[0]
375-
si.StdOutput = fd[1]
376-
si.StdErr = fd[2]
375+
376+
// If a PseudoConsole is specified, then there is nothing we need to do with the handles since the process will inherit the other end of the PseudoConsole.
377+
if sys.PseudoConsole == 0 {
378+
si.StdInput = fd[0]
379+
si.StdOutput = fd[1]
380+
si.StdErr = fd[2]
381+
}
377382

378383
fd = append(fd, sys.AdditionalInheritedHandles...)
379384

@@ -396,7 +401,7 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
396401
}
397402
fd = fd[:j]
398403

399-
willInheritHandles := len(fd) > 0 && !sys.NoInheritHandles
404+
willInheritHandles := len(fd) > 0 && !sys.NoInheritHandles && sys.PseudoConsole == 0
400405

401406
// Do not accidentally inherit more than these handles.
402407
if willInheritHandles {
@@ -406,6 +411,13 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
406411
}
407412
}
408413

414+
if sys.PseudoConsole != 0 {
415+
err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, unsafe.Pointer(sys.PseudoConsole), unsafe.Sizeof(sys.PseudoConsole), nil, nil)
416+
if err != nil {
417+
return 0, 0, err
418+
}
419+
}
420+
409421
envBlock, err := createEnvBlock(attr.Env)
410422
if err != nil {
411423
return 0, 0, err

src/syscall/types_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ type _PROC_THREAD_ATTRIBUTE_LIST struct {
497497
const (
498498
_PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000
499499
_PROC_THREAD_ATTRIBUTE_HANDLE_LIST = 0x00020002
500+
_PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016
500501
)
501502

502503
type _STARTUPINFOEXW struct {

0 commit comments

Comments
 (0)