Skip to content

Commit 4c8f48e

Browse files
committed
syscall: do not change stdio handle inheritance
Before the CL 288297 all Go process handles had to be made non-inheritable - otherwise they would escape into the child process. But now this is not necessary. This CL stops changing inheritance flag of stdint, stdout and stderr handles. Fixes #44876 Change-Id: Ib8fcf8066c30282293d96c34486b01b4c04f7116 Reviewed-on: https://go-review.googlesource.com/c/go/+/316269 Trust: Alex Brainman <[email protected]> Trust: Jason A. Donenfeld <[email protected]> Run-TryBot: Alex Brainman <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Jason A. Donenfeld <[email protected]>
1 parent 9d0819b commit 4c8f48e

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

src/syscall/syscall_windows.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,6 @@ var (
472472

473473
func getStdHandle(h int) (fd Handle) {
474474
r, _ := GetStdHandle(h)
475-
CloseOnExec(r)
476475
return r
477476
}
478477

src/syscall/syscall_windows_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
package syscall_test
66

77
import (
8+
"fmt"
9+
"internal/testenv"
810
"os"
11+
"os/exec"
912
"path/filepath"
13+
"strings"
1014
"syscall"
1115
"testing"
1216
)
@@ -71,3 +75,64 @@ func TestTOKEN_ALL_ACCESS(t *testing.T) {
7175
t.Errorf("TOKEN_ALL_ACCESS = %x, want 0xF01FF", syscall.TOKEN_ALL_ACCESS)
7276
}
7377
}
78+
79+
func TestStdioAreInheritable(t *testing.T) {
80+
testenv.MustHaveGoBuild(t)
81+
testenv.MustHaveExecPath(t, "gcc")
82+
83+
tmpdir := t.TempDir()
84+
85+
// build go dll
86+
const dlltext = `
87+
package main
88+
89+
import "C"
90+
import (
91+
"fmt"
92+
)
93+
94+
//export HelloWorld
95+
func HelloWorld() {
96+
fmt.Println("Hello World")
97+
}
98+
99+
func main() {}
100+
`
101+
dllsrc := filepath.Join(tmpdir, "helloworld.go")
102+
err := os.WriteFile(dllsrc, []byte(dlltext), 0644)
103+
if err != nil {
104+
t.Fatal(err)
105+
}
106+
dll := filepath.Join(tmpdir, "helloworld.dll")
107+
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "-buildmode", "c-shared", dllsrc)
108+
out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
109+
if err != nil {
110+
t.Fatalf("failed to build go library: %s\n%s", err, out)
111+
}
112+
113+
// run powershell script
114+
psscript := fmt.Sprintf(`
115+
hostname;
116+
$signature = " [DllImport("%q")] public static extern void HelloWorld(); ";
117+
Add-Type -MemberDefinition $signature -Name World -Namespace Hello;
118+
[Hello.World]::HelloWorld();
119+
hostname;
120+
`, dll)
121+
psscript = strings.ReplaceAll(psscript, "\n", "")
122+
out, err = exec.Command("powershell", "-Command", psscript).CombinedOutput()
123+
if err != nil {
124+
t.Fatalf("Powershell command failed: %v: %v", err, string(out))
125+
}
126+
127+
hostname, err := os.Hostname()
128+
if err != nil {
129+
t.Fatal(err)
130+
}
131+
132+
have := strings.ReplaceAll(string(out), "\n", "")
133+
have = strings.ReplaceAll(have, "\r", "")
134+
want := fmt.Sprintf("%sHello World%s", hostname, hostname)
135+
if have != want {
136+
t.Fatalf("Powershell command output is wrong: got %q, want %q", have, want)
137+
}
138+
}

0 commit comments

Comments
 (0)