Update to go1.24.0
This commit is contained in:
@@ -1,52 +1,56 @@
|
||||
From f1f146d4534fc925bceffe523852fe2261841008 Mon Sep 17 00:00:00 2001
|
||||
From 8dea0c5555bd5f397aa11a4e052bbec0d71e6495 Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Sat, 21 Sep 2024 23:56:11 +1000
|
||||
Subject: [PATCH] Switch ProcessPrng back to RtlGenRandom (revert 693def1)
|
||||
Date: Fri, 14 Feb 2025 10:39:55 +0700
|
||||
Subject: [PATCH] Switch ProcessPrng back to RtlGenRandom
|
||||
|
||||
---
|
||||
src/crypto/internal/sysrand/rand_windows.go | 13 +++++++-
|
||||
src/crypto/rand/rand.go | 2 +-
|
||||
src/crypto/rand/rand_windows.go | 7 +++--
|
||||
.../syscall/windows/syscall_windows.go | 2 +-
|
||||
.../syscall/windows/zsyscall_windows.go | 7 ++---
|
||||
src/runtime/os_windows.go | 30 ++++++++++++-------
|
||||
5 files changed, 29 insertions(+), 19 deletions(-)
|
||||
5 files changed, 36 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go
|
||||
index 91f1490..d23f180 100644
|
||||
--- a/src/crypto/internal/sysrand/rand_windows.go
|
||||
+++ b/src/crypto/internal/sysrand/rand_windows.go
|
||||
@@ -7,5 +7,16 @@ package sysrand
|
||||
import "internal/syscall/windows"
|
||||
|
||||
func read(b []byte) error {
|
||||
- return windows.ProcessPrng(b)
|
||||
+ const maxChunk = 1<<31 - 1
|
||||
+ for len(b) > 0 {
|
||||
+ chunk := b
|
||||
+ if len(chunk) > maxChunk {
|
||||
+ chunk = chunk[:maxChunk]
|
||||
+ }
|
||||
+ if err := windows.RtlGenRandom(chunk); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ b = b[len(chunk):]
|
||||
+ }
|
||||
+ return nil
|
||||
}
|
||||
diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go
|
||||
index d16d7a1..cdfeb06 100644
|
||||
index 1ca16ca..7d5cea8 100644
|
||||
--- a/src/crypto/rand/rand.go
|
||||
+++ b/src/crypto/rand/rand.go
|
||||
@@ -16,7 +16,7 @@ import "io"
|
||||
// - On macOS and iOS, Reader uses arc4random_buf(3).
|
||||
// - On OpenBSD and NetBSD, Reader uses getentropy(2).
|
||||
// - On other Unix-like systems, Reader reads from /dev/urandom.
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
// - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use.
|
||||
// - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3).
|
||||
// - On NetBSD, Reader uses the kern.arandom sysctl.
|
||||
-// - On Windows, Reader uses the ProcessPrng API.
|
||||
+// - On Windows, Reader uses the RtlGenRandom API.
|
||||
// - On js/wasm, Reader uses the Web Crypto API.
|
||||
// - On wasip1/wasm, Reader uses random_get from wasi_snapshot_preview1.
|
||||
var Reader io.Reader
|
||||
diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go
|
||||
index 7380f1f..6c0655c 100644
|
||||
--- a/src/crypto/rand/rand_windows.go
|
||||
+++ b/src/crypto/rand/rand_windows.go
|
||||
@@ -15,8 +15,11 @@ func init() { Reader = &rngReader{} }
|
||||
|
||||
type rngReader struct{}
|
||||
|
||||
-func (r *rngReader) Read(b []byte) (int, error) {
|
||||
- if err := windows.ProcessPrng(b); err != nil {
|
||||
+func (r *rngReader) Read(b []byte) (n int, err error) {
|
||||
+ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at
|
||||
+ // most 1<<31-1 bytes at a time so that this works the same on 32-bit
|
||||
+ // and 64-bit systems.
|
||||
+ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(b), nil
|
||||
// - On wasip1/wasm, Reader uses random_get.
|
||||
//
|
||||
diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go
|
||||
index cc26a50..b0b5a64 100644
|
||||
index c848f92..715d072 100644
|
||||
--- a/src/internal/syscall/windows/syscall_windows.go
|
||||
+++ b/src/internal/syscall/windows/syscall_windows.go
|
||||
@@ -414,7 +414,7 @@ func ErrorLoadingGetTempPath2() error {
|
||||
@@ -416,7 +416,7 @@ func ErrorLoadingGetTempPath2() error {
|
||||
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
|
||||
//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW
|
||||
|
||||
@@ -56,7 +60,7 @@ index cc26a50..b0b5a64 100644
|
||||
type FILE_ID_BOTH_DIR_INFO struct {
|
||||
NextEntryOffset uint32
|
||||
diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go
|
||||
index 414ad26..062641c 100644
|
||||
index 6a6ea7b..9a096cf 100644
|
||||
--- a/src/internal/syscall/windows/zsyscall_windows.go
|
||||
+++ b/src/internal/syscall/windows/zsyscall_windows.go
|
||||
@@ -38,7 +38,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
@@ -67,7 +71,7 @@ index 414ad26..062641c 100644
|
||||
modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
|
||||
modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
|
||||
modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
|
||||
@@ -57,7 +56,7 @@ var (
|
||||
@@ -63,7 +62,7 @@ var (
|
||||
procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation")
|
||||
@@ -76,7 +80,7 @@ index 414ad26..062641c 100644
|
||||
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
|
||||
procCreateEventW = modkernel32.NewProc("CreateEventW")
|
||||
procGetACP = modkernel32.NewProc("GetACP")
|
||||
@@ -183,12 +182,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32
|
||||
@@ -236,12 +235,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32
|
||||
return
|
||||
}
|
||||
|
||||
@@ -92,10 +96,10 @@ index 414ad26..062641c 100644
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
|
||||
index 4aabc29..0273580 100644
|
||||
index 7183e79..fd65e34 100644
|
||||
--- a/src/runtime/os_windows.go
|
||||
+++ b/src/runtime/os_windows.go
|
||||
@@ -127,8 +127,15 @@ var (
|
||||
@@ -128,8 +128,15 @@ var (
|
||||
_WriteFile,
|
||||
_ stdFunction
|
||||
|
||||
@@ -113,7 +117,7 @@ index 4aabc29..0273580 100644
|
||||
|
||||
// Load ntdll.dll manually during startup, otherwise Mingw
|
||||
// links wrong printf function to cgo executable (see issue
|
||||
@@ -146,10 +153,11 @@ var (
|
||||
@@ -147,10 +154,11 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -129,7 +133,7 @@ index 4aabc29..0273580 100644
|
||||
)
|
||||
|
||||
// Function to be called by windows CreateThread
|
||||
@@ -263,11 +271,11 @@ func windows_QueryPerformanceFrequency() int64 {
|
||||
@@ -264,11 +272,11 @@ func windows_QueryPerformanceFrequency() int64 {
|
||||
}
|
||||
|
||||
func loadOptionalSyscalls() {
|
||||
@@ -145,7 +149,7 @@ index 4aabc29..0273580 100644
|
||||
|
||||
n32 := windowsLoadSystemLib(ntdlldll[:])
|
||||
if n32 == 0 {
|
||||
@@ -500,7 +508,7 @@ func osinit() {
|
||||
@@ -501,7 +509,7 @@ func osinit() {
|
||||
//go:nosplit
|
||||
func readRandom(r []byte) int {
|
||||
n := 0
|
||||
@@ -155,5 +159,5 @@ index 4aabc29..0273580 100644
|
||||
}
|
||||
return n
|
||||
--
|
||||
2.47.0
|
||||
2.39.5
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From d02338f60a2671b5d8f748956aa90cf7011b72e2 Mon Sep 17 00:00:00 2001
|
||||
From 6fb20b1b5f82c5eb0979157d3537b48e5956e723 Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Sun, 22 Sep 2024 00:23:47 +1000
|
||||
Subject: [PATCH] Restore GOPATH-mode get (revert de4d503)
|
||||
Date: Fri, 14 Feb 2025 11:33:18 +0700
|
||||
Subject: [PATCH] Restore GOPATH-mode get
|
||||
|
||||
---
|
||||
src/cmd/go/alldocs.go | 66 ++
|
||||
@@ -9,7 +9,9 @@ Subject: [PATCH] Restore GOPATH-mode get (revert de4d503)
|
||||
src/cmd/go/internal/get/get.go | 640 ++++++++++++++++++
|
||||
src/cmd/go/internal/get/tag_test.go | 100 +++
|
||||
src/cmd/go/internal/help/help.go | 7 +
|
||||
src/cmd/go/internal/load/pkg.go | 60 ++
|
||||
src/cmd/go/internal/modget/get.go | 17 +
|
||||
src/cmd/go/internal/vcs/vcs.go | 39 +-
|
||||
src/cmd/go/main.go | 10 +
|
||||
src/cmd/go/testdata/script/get_404_meta.txt | 3 +
|
||||
src/cmd/go/testdata/script/get_brace.txt | 51 ++
|
||||
@@ -48,7 +50,8 @@ Subject: [PATCH] Restore GOPATH-mode get (revert de4d503)
|
||||
.../script/vendor_list_issue11977.txt | 78 +--
|
||||
.../script/vendor_test_issue11864.txt | 79 +--
|
||||
.../script/vendor_test_issue14613.txt | 46 +-
|
||||
44 files changed, 1801 insertions(+), 191 deletions(-)
|
||||
src/cmd/internal/par/work.go | 38 ++
|
||||
47 files changed, 1934 insertions(+), 195 deletions(-)
|
||||
create mode 100644 src/cmd/go/internal/get/get.go
|
||||
create mode 100644 src/cmd/go/internal/get/tag_test.go
|
||||
create mode 100644 src/cmd/go/testdata/script/get_brace.txt
|
||||
@@ -82,11 +85,11 @@ Subject: [PATCH] Restore GOPATH-mode get (revert de4d503)
|
||||
create mode 100644 src/cmd/go/testdata/script/gopath_moved_repo.txt
|
||||
|
||||
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
|
||||
index 75e6d65..abbad2c 100644
|
||||
index 2220863..72df60d 100644
|
||||
--- a/src/cmd/go/alldocs.go
|
||||
+++ b/src/cmd/go/alldocs.go
|
||||
@@ -45,9 +45,11 @@
|
||||
// filetype file types
|
||||
@@ -47,9 +47,11 @@
|
||||
// goauth GOAUTH environment variable
|
||||
// go.mod the go.mod file
|
||||
// gopath GOPATH environment variable
|
||||
+// gopath-get legacy GOPATH go get
|
||||
@@ -97,7 +100,7 @@ index 75e6d65..abbad2c 100644
|
||||
// module-auth module authentication using go.sum
|
||||
// packages package lists and patterns
|
||||
// private configuration for downloading non-public code
|
||||
@@ -2661,6 +2663,70 @@
|
||||
@@ -2820,6 +2822,70 @@
|
||||
//
|
||||
// See https://golang.org/s/go15vendor for details.
|
||||
//
|
||||
@@ -169,10 +172,10 @@ index 75e6d65..abbad2c 100644
|
||||
//
|
||||
// A Go module proxy is any web server that can respond to GET requests for
|
||||
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
|
||||
index b45a905..b06fef6 100644
|
||||
index 1df7cf8..c92dcf2 100644
|
||||
--- a/src/cmd/go/go_test.go
|
||||
+++ b/src/cmd/go/go_test.go
|
||||
@@ -972,6 +972,77 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
|
||||
@@ -973,6 +973,77 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
|
||||
tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
|
||||
}
|
||||
|
||||
@@ -250,7 +253,7 @@ index b45a905..b06fef6 100644
|
||||
func TestPackageMainTestCompilerFlags(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
@@ -1292,6 +1363,35 @@ func TestDefaultGOPATH(t *testing.T) {
|
||||
@@ -1293,6 +1364,35 @@ func TestDefaultGOPATH(t *testing.T) {
|
||||
tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
|
||||
}
|
||||
|
||||
@@ -288,7 +291,7 @@ index b45a905..b06fef6 100644
|
||||
defer tg.cleanup()
|
||||
diff --git a/src/cmd/go/internal/get/get.go b/src/cmd/go/internal/get/get.go
|
||||
new file mode 100644
|
||||
index 0000000..06b567a
|
||||
index 0000000..16175a2
|
||||
--- /dev/null
|
||||
+++ b/src/cmd/go/internal/get/get.go
|
||||
@@ -0,0 +1,640 @@
|
||||
@@ -599,7 +602,7 @@ index 0000000..06b567a
|
||||
+ // Download if the package is missing, or update if we're using -u.
|
||||
+ if p.Dir == "" || *getU {
|
||||
+ // The actual download.
|
||||
+ stk.Push(arg)
|
||||
+ stk.Push(load.ImportInfo{Pkg: arg})
|
||||
+ err := downloadPackage(p)
|
||||
+ if err != nil {
|
||||
+ base.Errorf("%s", &load.PackageError{ImportStack: stk.Copy(), Err: err})
|
||||
@@ -664,7 +667,7 @@ index 0000000..06b567a
|
||||
+ if isWildcard {
|
||||
+ // Report both the real package and the
|
||||
+ // wildcard in any error message.
|
||||
+ stk.Push(p.ImportPath)
|
||||
+ stk.Push(load.ImportInfo{Pkg: p.ImportPath})
|
||||
+ }
|
||||
+
|
||||
+ // Process dependencies, now that we know what they are.
|
||||
@@ -687,7 +690,7 @@ index 0000000..06b567a
|
||||
+ orig = p.Internal.Build.Imports[i]
|
||||
+ }
|
||||
+ if j, ok := load.FindVendor(orig); ok {
|
||||
+ stk.Push(path)
|
||||
+ stk.Push(load.ImportInfo{Pkg: path})
|
||||
+ err := &load.PackageError{
|
||||
+ ImportStack: stk.Copy(),
|
||||
+ Err: load.ImportErrorf(path, "%s must be imported as %s", path, path[j+len("vendor/"):]),
|
||||
@@ -1063,11 +1066,96 @@ index 4f2607f..229ebc3 100644
|
||||
cmds = append(cmds, cmd)
|
||||
cmds = append(cmds, cmd.Commands...)
|
||||
}
|
||||
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
|
||||
index 15f6b2e..8f6fd27 100644
|
||||
--- a/src/cmd/go/internal/load/pkg.go
|
||||
+++ b/src/cmd/go/internal/load/pkg.go
|
||||
@@ -461,6 +461,7 @@ type PackageError struct {
|
||||
Pos string // position of error
|
||||
Err error // the error itself
|
||||
IsImportCycle bool // the error is an import cycle
|
||||
+ Hard bool // whether the error is soft or hard; soft errors are ignored in some places
|
||||
alwaysPrintStack bool // whether to always print the ImportStack
|
||||
}
|
||||
|
||||
@@ -640,6 +641,51 @@ func (sp *ImportStack) shorterThan(t []string) bool {
|
||||
// we return the same pointer each time.
|
||||
var packageCache = map[string]*Package{}
|
||||
|
||||
+// ClearPackageCache clears the in-memory package cache and the preload caches.
|
||||
+// It is only for use by GOPATH-based "go get".
|
||||
+// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
|
||||
+func ClearPackageCache() {
|
||||
+ clear(packageCache)
|
||||
+ resolvedImportCache.Clear()
|
||||
+ packageDataCache.Clear()
|
||||
+}
|
||||
+
|
||||
+// ClearPackageCachePartial clears packages with the given import paths from the
|
||||
+// in-memory package cache and the preload caches. It is only for use by
|
||||
+// GOPATH-based "go get".
|
||||
+// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
|
||||
+func ClearPackageCachePartial(args []string) {
|
||||
+ shouldDelete := make(map[string]bool)
|
||||
+ for _, arg := range args {
|
||||
+ shouldDelete[arg] = true
|
||||
+ if p := packageCache[arg]; p != nil {
|
||||
+ delete(packageCache, arg)
|
||||
+ }
|
||||
+ }
|
||||
+ resolvedImportCache.DeleteIf(func(key importSpec) bool {
|
||||
+ return shouldDelete[key.path]
|
||||
+ })
|
||||
+ packageDataCache.DeleteIf(func(key string) bool {
|
||||
+ return shouldDelete[key]
|
||||
+ })
|
||||
+}
|
||||
+
|
||||
+// ReloadPackageNoFlags is like LoadImport but makes sure
|
||||
+// not to use the package cache.
|
||||
+// It is only for use by GOPATH-based "go get".
|
||||
+// TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
|
||||
+func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
|
||||
+ p := packageCache[arg]
|
||||
+ if p != nil {
|
||||
+ delete(packageCache, arg)
|
||||
+ resolvedImportCache.DeleteIf(func(key importSpec) bool {
|
||||
+ return key.path == p.ImportPath
|
||||
+ })
|
||||
+ packageDataCache.Delete(p.ImportPath)
|
||||
+ }
|
||||
+ return LoadPackage(context.TODO(), PackageOpts{}, arg, base.Cwd(), stk, nil, 0)
|
||||
+}
|
||||
+
|
||||
// dirToImportPath returns the pseudo-import path we use for a package
|
||||
// outside the Go path. It begins with _/ and then contains the full path
|
||||
// to the directory. If the package lives in c:\home\gopher\my\pkg then
|
||||
@@ -691,6 +737,20 @@ const (
|
||||
cmdlinePkgLiteral
|
||||
)
|
||||
|
||||
+// LoadImport scans the directory named by path, which must be an import path,
|
||||
+// but possibly a local import path (an absolute file system path or one beginning
|
||||
+// with ./ or ../). A local relative path is interpreted relative to srcDir.
|
||||
+// It returns a *Package describing the package found in that directory.
|
||||
+// LoadImport does not set tool flags and should only be used by
|
||||
+// this package, as part of a bigger load operation, and by GOPATH-based "go get".
|
||||
+// TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
|
||||
+// The returned PackageError, if any, describes why parent is not allowed
|
||||
+// to import the named package, with the error referring to importPos.
|
||||
+// The PackageError can only be non-nil when parent is not nil.
|
||||
+func LoadImport(ctx context.Context, opts PackageOpts, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
|
||||
+ return loadImport(ctx, opts, nil, path, srcDir, parent, stk, importPos, mode)
|
||||
+}
|
||||
+
|
||||
// LoadPackage does Load import, but without a parent package load context
|
||||
func LoadPackage(ctx context.Context, opts PackageOpts, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {
|
||||
p, err := loadImport(ctx, opts, nil, path, srcDir, nil, stk, importPos, mode)
|
||||
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
|
||||
index 7343128..966c504 100644
|
||||
index 48ae12f..31407e2 100644
|
||||
--- a/src/cmd/go/internal/modget/get.go
|
||||
+++ b/src/cmd/go/internal/modget/get.go
|
||||
@@ -131,6 +131,23 @@ See also: go build, go install, go clean, go mod.
|
||||
@@ -129,6 +129,23 @@ See also: go build, go install, go clean, go mod.
|
||||
`,
|
||||
}
|
||||
|
||||
@@ -1091,8 +1179,82 @@ index 7343128..966c504 100644
|
||||
var HelpVCS = &base.Command{
|
||||
UsageLine: "vcs",
|
||||
Short: "controlling version control with GOVCS",
|
||||
diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go
|
||||
index 1d10c7f..8f2b8a2 100644
|
||||
--- a/src/cmd/go/internal/vcs/vcs.go
|
||||
+++ b/src/cmd/go/internal/vcs/vcs.go
|
||||
@@ -1021,11 +1021,11 @@ var defaultGOVCS = govcsConfig{
|
||||
{"public", []string{"git", "hg"}},
|
||||
}
|
||||
|
||||
-// checkGOVCS checks whether the policy defined by the environment variable
|
||||
+// CheckGOVCS checks whether the policy defined by the environment variable
|
||||
// GOVCS allows the given vcs command to be used with the given repository
|
||||
// root path. Note that root may not be a real package or module path; it's
|
||||
// the same as the root path in the go-import meta tag.
|
||||
-func checkGOVCS(vcs *Cmd, root string) error {
|
||||
+func CheckGOVCS(vcs *Cmd, root string) error {
|
||||
if vcs == vcsMod {
|
||||
// Direct module (proxy protocol) fetches don't
|
||||
// involve an external version control system
|
||||
@@ -1053,6 +1053,37 @@ func checkGOVCS(vcs *Cmd, root string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
+// CheckNested checks for an incorrectly-nested VCS-inside-VCS
|
||||
+// situation for dir, checking parents up until srcRoot.
|
||||
+func CheckNested(vcs *Cmd, dir, srcRoot string) error {
|
||||
+ if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
|
||||
+ return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
|
||||
+ }
|
||||
+
|
||||
+ otherDir := dir
|
||||
+ for len(otherDir) > len(srcRoot) {
|
||||
+ for _, otherVCS := range vcsList {
|
||||
+ if isVCSRoot(otherDir, otherVCS.RootNames) {
|
||||
+ // Allow expected vcs in original dir.
|
||||
+ if otherDir == dir && otherVCS == vcs {
|
||||
+ continue
|
||||
+ }
|
||||
+ // Otherwise, we have one VCS inside a different VCS.
|
||||
+ return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.Cmd, otherDir, otherVCS.Cmd)
|
||||
+ }
|
||||
+ }
|
||||
+ // Move to parent.
|
||||
+ newDir := filepath.Dir(otherDir)
|
||||
+ if len(newDir) >= len(otherDir) {
|
||||
+ // Shouldn't happen, but just in case, stop.
|
||||
+ break
|
||||
+ }
|
||||
+ otherDir = newDir
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
// RepoRoot describes the repository root for a tree of source code.
|
||||
type RepoRoot struct {
|
||||
Repo string // repository URL, including scheme
|
||||
@@ -1168,7 +1199,7 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths
|
||||
if vcs == nil {
|
||||
return nil, fmt.Errorf("unknown version control system %q", match["vcs"])
|
||||
}
|
||||
- if err := checkGOVCS(vcs, match["root"]); err != nil {
|
||||
+ if err := CheckGOVCS(vcs, match["root"]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var repoURL string
|
||||
@@ -1357,7 +1388,7 @@ func repoRootForImportDynamic(importPath string, mod ModuleMode, security web.Se
|
||||
}
|
||||
}
|
||||
|
||||
- if err := checkGOVCS(vcs, mmi.Prefix); err != nil {
|
||||
+ if err := CheckGOVCS(vcs, mmi.Prefix); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
|
||||
index 1c58232..722ab87 100644
|
||||
index e81969c..2246d11 100644
|
||||
--- a/src/cmd/go/main.go
|
||||
+++ b/src/cmd/go/main.go
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
@@ -1103,8 +1265,8 @@ index 1c58232..722ab87 100644
|
||||
"cmd/go/internal/help"
|
||||
"cmd/go/internal/list"
|
||||
"cmd/go/internal/modcmd"
|
||||
@@ -78,9 +79,11 @@ func init() {
|
||||
help.HelpFileType,
|
||||
@@ -80,9 +81,11 @@ func init() {
|
||||
help.HelpGoAuth,
|
||||
modload.HelpGoMod,
|
||||
help.HelpGopath,
|
||||
+ get.HelpGopathGet,
|
||||
@@ -1115,7 +1277,7 @@ index 1c58232..722ab87 100644
|
||||
modfetch.HelpModuleAuth,
|
||||
help.HelpPackages,
|
||||
modfetch.HelpPrivate,
|
||||
@@ -112,6 +115,13 @@ func main() {
|
||||
@@ -119,6 +122,13 @@ func main() {
|
||||
base.Usage()
|
||||
}
|
||||
|
||||
@@ -2451,6 +2613,52 @@ index d2f05c9..9535fc1 100644
|
||||
-
|
||||
-func main() {}
|
||||
-
|
||||
diff --git a/src/cmd/internal/par/work.go b/src/cmd/internal/par/work.go
|
||||
index 881b51b..3f1e69a 100644
|
||||
--- a/src/cmd/internal/par/work.go
|
||||
+++ b/src/cmd/internal/par/work.go
|
||||
@@ -180,3 +180,41 @@ func (c *Cache[K, V]) Get(key K) (V, bool) {
|
||||
}
|
||||
return e.result, true
|
||||
}
|
||||
+
|
||||
+// Clear removes all entries in the cache.
|
||||
+//
|
||||
+// Concurrent calls to Get may return old values. Concurrent calls to Do
|
||||
+// may return old values or store results in entries that have been deleted.
|
||||
+//
|
||||
+// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
+// in internal/load have been removed.
|
||||
+func (c *Cache[K, V]) Clear() {
|
||||
+ c.m.Clear()
|
||||
+}
|
||||
+
|
||||
+// Delete removes an entry from the map. It is safe to call Delete for an
|
||||
+// entry that does not exist. Delete will return quickly, even if the result
|
||||
+// for a key is still being computed; the computation will finish, but the
|
||||
+// result won't be accessible through the cache.
|
||||
+//
|
||||
+// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
+// in internal/load have been removed.
|
||||
+func (c *Cache[K, V]) Delete(key K) {
|
||||
+ c.m.Delete(key)
|
||||
+}
|
||||
+
|
||||
+// DeleteIf calls pred for each key in the map. If pred returns true for a key,
|
||||
+// DeleteIf removes the corresponding entry. If the result for a key is
|
||||
+// still being computed, DeleteIf will remove the entry without waiting for
|
||||
+// the computation to finish. The result won't be accessible through the cache.
|
||||
+//
|
||||
+// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
+// in internal/load have been removed.
|
||||
+func (c *Cache[K, V]) DeleteIf(pred func(key K) bool) {
|
||||
+ c.m.Range(func(key, _ any) bool {
|
||||
+ if key := key.(K); pred(key) {
|
||||
+ c.Delete(key)
|
||||
+ }
|
||||
+ return true
|
||||
+ })
|
||||
+}
|
||||
--
|
||||
2.47.0
|
||||
2.39.5
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
From 3e1a3a3c96117fd4d655dd85d2e2c807e691104e Mon Sep 17 00:00:00 2001
|
||||
From b832732b5d8509512c5021b5f4b1cf3e2ec6ea2c Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Tue, 24 Dec 2024 19:31:25 +0700
|
||||
Date: Fri, 14 Feb 2025 11:35:56 +0700
|
||||
Subject: [PATCH] Add back LoadLibraryA fallback
|
||||
|
||||
---
|
||||
@@ -14,10 +14,10 @@ Subject: [PATCH] Add back LoadLibraryA fallback
|
||||
7 files changed, 136 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/runtime/export_windows_test.go b/src/runtime/export_windows_test.go
|
||||
index 4880e62..8bfff0b 100644
|
||||
index 13d30d4..5ff5229 100644
|
||||
--- a/src/runtime/export_windows_test.go
|
||||
+++ b/src/runtime/export_windows_test.go
|
||||
@@ -36,3 +36,7 @@ func NewContextStub() *ContextStub {
|
||||
@@ -39,3 +39,7 @@ func NewContextStub() *ContextStub {
|
||||
ctx.set_fp(getcallerfp())
|
||||
return &ContextStub{ctx}
|
||||
}
|
||||
@@ -26,10 +26,10 @@ index 4880e62..8bfff0b 100644
|
||||
+ return useLoadLibraryEx, _LoadLibraryExW != nil, _AddDllDirectory != nil
|
||||
+}
|
||||
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
|
||||
index 0273580..c76df9d 100644
|
||||
index fd65e34..c85fab7 100644
|
||||
--- a/src/runtime/os_windows.go
|
||||
+++ b/src/runtime/os_windows.go
|
||||
@@ -41,6 +41,7 @@ const (
|
||||
@@ -42,6 +42,7 @@ const (
|
||||
//go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
|
||||
@@ -37,7 +37,7 @@ index 0273580..c76df9d 100644
|
||||
//go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll"
|
||||
@@ -74,6 +75,7 @@ var (
|
||||
@@ -75,6 +76,7 @@ var (
|
||||
// Following syscalls are available on every Windows PC.
|
||||
// All these variables are set by the Windows executable
|
||||
// loader before the Go program starts.
|
||||
@@ -45,7 +45,7 @@ index 0273580..c76df9d 100644
|
||||
_AddVectoredContinueHandler,
|
||||
_AddVectoredExceptionHandler,
|
||||
_CloseHandle,
|
||||
@@ -99,6 +101,7 @@ var (
|
||||
@@ -100,6 +102,7 @@ var (
|
||||
_SetThreadContext,
|
||||
_LoadLibraryExW,
|
||||
_LoadLibraryW,
|
||||
@@ -53,7 +53,7 @@ index 0273580..c76df9d 100644
|
||||
_PostQueuedCompletionStatus,
|
||||
_QueryPerformanceCounter,
|
||||
_QueryPerformanceFrequency,
|
||||
@@ -157,7 +160,6 @@ var (
|
||||
@@ -158,7 +161,6 @@ var (
|
||||
ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
|
||||
powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
|
||||
winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
|
||||
@@ -61,7 +61,7 @@ index 0273580..c76df9d 100644
|
||||
)
|
||||
|
||||
// Function to be called by windows CreateThread
|
||||
@@ -253,7 +255,36 @@ func windows_GetSystemDirectory() string {
|
||||
@@ -254,7 +256,36 @@ func windows_GetSystemDirectory() string {
|
||||
}
|
||||
|
||||
func windowsLoadSystemLib(name []uint16) uintptr {
|
||||
@@ -99,7 +99,7 @@ index 0273580..c76df9d 100644
|
||||
}
|
||||
|
||||
//go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter
|
||||
@@ -271,6 +302,15 @@ func windows_QueryPerformanceFrequency() int64 {
|
||||
@@ -272,6 +303,15 @@ func windows_QueryPerformanceFrequency() int64 {
|
||||
}
|
||||
|
||||
func loadOptionalSyscalls() {
|
||||
@@ -115,7 +115,7 @@ index 0273580..c76df9d 100644
|
||||
a32 := windowsLoadSystemLib(advapi32dll[:])
|
||||
if a32 == 0 {
|
||||
throw("advapi32.dll not found")
|
||||
@@ -365,6 +405,22 @@ const (
|
||||
@@ -366,6 +406,22 @@ const (
|
||||
// in sys_windows_386.s and sys_windows_amd64.s:
|
||||
func getlasterror() uint32
|
||||
|
||||
@@ -169,10 +169,10 @@ index 85b1b8c..eb808fe 100644
|
||||
err = 0
|
||||
}
|
||||
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
|
||||
index 156cf3e..2db5b61 100644
|
||||
index 01a9ca3..53f7110 100644
|
||||
--- a/src/runtime/syscall_windows_test.go
|
||||
+++ b/src/runtime/syscall_windows_test.go
|
||||
@@ -1166,7 +1166,10 @@ uintptr_t cfunc(void) {
|
||||
@@ -1160,7 +1160,10 @@ uintptr_t cfunc(void) {
|
||||
dll, err = syscall.LoadDLL(name)
|
||||
if err == nil {
|
||||
dll.Release()
|
||||
@@ -184,7 +184,7 @@ index 156cf3e..2db5b61 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1219,6 +1222,24 @@ func TestSyscallStackUsage(t *testing.T) {
|
||||
@@ -1213,6 +1216,24 @@ func TestSyscallStackUsage(t *testing.T) {
|
||||
syscall.Syscall18(procSetEvent.Addr(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ index 4e988c4..45b1908 100644
|
||||
// An access token contains the security information for a logon session.
|
||||
// The system creates an access token when a user logs on, and every
|
||||
diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
|
||||
index d8d8594..28369e3 100644
|
||||
index c0585a6..85c66de 100644
|
||||
--- a/src/syscall/zsyscall_windows.go
|
||||
+++ b/src/syscall/zsyscall_windows.go
|
||||
@@ -128,6 +128,7 @@ var (
|
||||
@@ -286,7 +286,7 @@ index d8d8594..28369e3 100644
|
||||
procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime")
|
||||
procGetTempPathW = modkernel32.NewProc("GetTempPathW")
|
||||
procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation")
|
||||
@@ -870,6 +871,15 @@ func GetStdHandle(stdhandle int) (handle Handle, err error) {
|
||||
@@ -871,6 +872,15 @@ func GetStdHandle(stdhandle int) (handle Handle, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
From 3593bfc89de341818aefadf365ca615b78a8c958 Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Sun, 22 Sep 2024 00:34:20 +1000
|
||||
Subject: [PATCH] Restore related GOPATH-mode go get functions
|
||||
|
||||
---
|
||||
src/cmd/go/internal/load/pkg.go | 59 +++++++++++++++++++++++++++++++++
|
||||
src/cmd/go/internal/par/work.go | 38 +++++++++++++++++++++
|
||||
src/cmd/go/internal/vcs/vcs.go | 39 +++++++++++++++++++---
|
||||
3 files changed, 132 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
|
||||
index 7c402b4..cb38b53 100644
|
||||
--- a/src/cmd/go/internal/load/pkg.go
|
||||
+++ b/src/cmd/go/internal/load/pkg.go
|
||||
@@ -604,6 +604,51 @@ func (sp *ImportStack) shorterThan(t []string) bool {
|
||||
// we return the same pointer each time.
|
||||
var packageCache = map[string]*Package{}
|
||||
|
||||
+// ClearPackageCache clears the in-memory package cache and the preload caches.
|
||||
+// It is only for use by GOPATH-based "go get".
|
||||
+// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
|
||||
+func ClearPackageCache() {
|
||||
+ clear(packageCache)
|
||||
+ resolvedImportCache.Clear()
|
||||
+ packageDataCache.Clear()
|
||||
+}
|
||||
+
|
||||
+// ClearPackageCachePartial clears packages with the given import paths from the
|
||||
+// in-memory package cache and the preload caches. It is only for use by
|
||||
+// GOPATH-based "go get".
|
||||
+// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
|
||||
+func ClearPackageCachePartial(args []string) {
|
||||
+ shouldDelete := make(map[string]bool)
|
||||
+ for _, arg := range args {
|
||||
+ shouldDelete[arg] = true
|
||||
+ if p := packageCache[arg]; p != nil {
|
||||
+ delete(packageCache, arg)
|
||||
+ }
|
||||
+ }
|
||||
+ resolvedImportCache.DeleteIf(func(key importSpec) bool {
|
||||
+ return shouldDelete[key.path]
|
||||
+ })
|
||||
+ packageDataCache.DeleteIf(func(key string) bool {
|
||||
+ return shouldDelete[key]
|
||||
+ })
|
||||
+}
|
||||
+
|
||||
+// ReloadPackageNoFlags is like LoadImport but makes sure
|
||||
+// not to use the package cache.
|
||||
+// It is only for use by GOPATH-based "go get".
|
||||
+// TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
|
||||
+func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
|
||||
+ p := packageCache[arg]
|
||||
+ if p != nil {
|
||||
+ delete(packageCache, arg)
|
||||
+ resolvedImportCache.DeleteIf(func(key importSpec) bool {
|
||||
+ return key.path == p.ImportPath
|
||||
+ })
|
||||
+ packageDataCache.Delete(p.ImportPath)
|
||||
+ }
|
||||
+ return LoadPackage(context.TODO(), PackageOpts{}, arg, base.Cwd(), stk, nil, 0)
|
||||
+}
|
||||
+
|
||||
// dirToImportPath returns the pseudo-import path we use for a package
|
||||
// outside the Go path. It begins with _/ and then contains the full path
|
||||
// to the directory. If the package lives in c:\home\gopher\my\pkg then
|
||||
@@ -655,6 +700,20 @@ const (
|
||||
cmdlinePkgLiteral
|
||||
)
|
||||
|
||||
+// LoadImport scans the directory named by path, which must be an import path,
|
||||
+// but possibly a local import path (an absolute file system path or one beginning
|
||||
+// with ./ or ../). A local relative path is interpreted relative to srcDir.
|
||||
+// It returns a *Package describing the package found in that directory.
|
||||
+// LoadImport does not set tool flags and should only be used by
|
||||
+// this package, as part of a bigger load operation, and by GOPATH-based "go get".
|
||||
+// TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
|
||||
+// The returned PackageError, if any, describes why parent is not allowed
|
||||
+// to import the named package, with the error referring to importPos.
|
||||
+// The PackageError can only be non-nil when parent is not nil.
|
||||
+func LoadImport(ctx context.Context, opts PackageOpts, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
|
||||
+ return loadImport(ctx, opts, nil, path, srcDir, parent, stk, importPos, mode)
|
||||
+}
|
||||
+
|
||||
// LoadPackage does Load import, but without a parent package load contezt
|
||||
func LoadPackage(ctx context.Context, opts PackageOpts, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {
|
||||
p, err := loadImport(ctx, opts, nil, path, srcDir, nil, stk, importPos, mode)
|
||||
diff --git a/src/cmd/go/internal/par/work.go b/src/cmd/go/internal/par/work.go
|
||||
index 881b51b..3f1e69a 100644
|
||||
--- a/src/cmd/go/internal/par/work.go
|
||||
+++ b/src/cmd/go/internal/par/work.go
|
||||
@@ -180,3 +180,41 @@ func (c *Cache[K, V]) Get(key K) (V, bool) {
|
||||
}
|
||||
return e.result, true
|
||||
}
|
||||
+
|
||||
+// Clear removes all entries in the cache.
|
||||
+//
|
||||
+// Concurrent calls to Get may return old values. Concurrent calls to Do
|
||||
+// may return old values or store results in entries that have been deleted.
|
||||
+//
|
||||
+// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
+// in internal/load have been removed.
|
||||
+func (c *Cache[K, V]) Clear() {
|
||||
+ c.m.Clear()
|
||||
+}
|
||||
+
|
||||
+// Delete removes an entry from the map. It is safe to call Delete for an
|
||||
+// entry that does not exist. Delete will return quickly, even if the result
|
||||
+// for a key is still being computed; the computation will finish, but the
|
||||
+// result won't be accessible through the cache.
|
||||
+//
|
||||
+// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
+// in internal/load have been removed.
|
||||
+func (c *Cache[K, V]) Delete(key K) {
|
||||
+ c.m.Delete(key)
|
||||
+}
|
||||
+
|
||||
+// DeleteIf calls pred for each key in the map. If pred returns true for a key,
|
||||
+// DeleteIf removes the corresponding entry. If the result for a key is
|
||||
+// still being computed, DeleteIf will remove the entry without waiting for
|
||||
+// the computation to finish. The result won't be accessible through the cache.
|
||||
+//
|
||||
+// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
+// in internal/load have been removed.
|
||||
+func (c *Cache[K, V]) DeleteIf(pred func(key K) bool) {
|
||||
+ c.m.Range(func(key, _ any) bool {
|
||||
+ if key := key.(K); pred(key) {
|
||||
+ c.Delete(key)
|
||||
+ }
|
||||
+ return true
|
||||
+ })
|
||||
+}
|
||||
diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go
|
||||
index 19a6a5e..044d02e 100644
|
||||
--- a/src/cmd/go/internal/vcs/vcs.go
|
||||
+++ b/src/cmd/go/internal/vcs/vcs.go
|
||||
@@ -1013,11 +1013,11 @@ var defaultGOVCS = govcsConfig{
|
||||
{"public", []string{"git", "hg"}},
|
||||
}
|
||||
|
||||
-// checkGOVCS checks whether the policy defined by the environment variable
|
||||
+// CheckGOVCS checks whether the policy defined by the environment variable
|
||||
// GOVCS allows the given vcs command to be used with the given repository
|
||||
// root path. Note that root may not be a real package or module path; it's
|
||||
// the same as the root path in the go-import meta tag.
|
||||
-func checkGOVCS(vcs *Cmd, root string) error {
|
||||
+func CheckGOVCS(vcs *Cmd, root string) error {
|
||||
if vcs == vcsMod {
|
||||
// Direct module (proxy protocol) fetches don't
|
||||
// involve an external version control system
|
||||
@@ -1045,6 +1045,37 @@ func checkGOVCS(vcs *Cmd, root string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
+// CheckNested checks for an incorrectly-nested VCS-inside-VCS
|
||||
+// situation for dir, checking parents up until srcRoot.
|
||||
+func CheckNested(vcs *Cmd, dir, srcRoot string) error {
|
||||
+ if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
|
||||
+ return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
|
||||
+ }
|
||||
+
|
||||
+ otherDir := dir
|
||||
+ for len(otherDir) > len(srcRoot) {
|
||||
+ for _, otherVCS := range vcsList {
|
||||
+ if isVCSRoot(otherDir, otherVCS.RootNames) {
|
||||
+ // Allow expected vcs in original dir.
|
||||
+ if otherDir == dir && otherVCS == vcs {
|
||||
+ continue
|
||||
+ }
|
||||
+ // Otherwise, we have one VCS inside a different VCS.
|
||||
+ return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.Cmd, otherDir, otherVCS.Cmd)
|
||||
+ }
|
||||
+ }
|
||||
+ // Move to parent.
|
||||
+ newDir := filepath.Dir(otherDir)
|
||||
+ if len(newDir) >= len(otherDir) {
|
||||
+ // Shouldn't happen, but just in case, stop.
|
||||
+ break
|
||||
+ }
|
||||
+ otherDir = newDir
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
// RepoRoot describes the repository root for a tree of source code.
|
||||
type RepoRoot struct {
|
||||
Repo string // repository URL, including scheme
|
||||
@@ -1160,7 +1191,7 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths
|
||||
if vcs == nil {
|
||||
return nil, fmt.Errorf("unknown version control system %q", match["vcs"])
|
||||
}
|
||||
- if err := checkGOVCS(vcs, match["root"]); err != nil {
|
||||
+ if err := CheckGOVCS(vcs, match["root"]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var repoURL string
|
||||
@@ -1349,7 +1380,7 @@ func repoRootForImportDynamic(importPath string, mod ModuleMode, security web.Se
|
||||
}
|
||||
}
|
||||
|
||||
- if err := checkGOVCS(vcs, mmi.Prefix); err != nil {
|
||||
+ if err := CheckGOVCS(vcs, mmi.Prefix); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
From 017970028ebf60ec44fd1b528b691a47f09ea3a6 Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Fri, 14 Feb 2025 12:13:28 +0700
|
||||
Subject: [PATCH] Add Windows 7 console and process handle workaround
|
||||
|
||||
---
|
||||
src/os/exec_windows.go | 11 ++++++++++
|
||||
src/syscall/exec_windows.go | 38 ++++++++++++++++++++++++++++++++-
|
||||
src/syscall/types_windows.go | 10 +++++++++
|
||||
src/syscall/zsyscall_windows.go | 7 ++++++
|
||||
4 files changed, 65 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/os/exec_windows.go b/src/os/exec_windows.go
|
||||
index ab2dae1..f5e3a4f 100644
|
||||
--- a/src/os/exec_windows.go
|
||||
+++ b/src/os/exec_windows.go
|
||||
@@ -44,6 +44,17 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
if e != nil {
|
||||
return nil, NewSyscallError("GetProcessTimes", e)
|
||||
}
|
||||
+
|
||||
+ // NOTE(brainman): It seems that sometimes process is not dead
|
||||
+ // when WaitForSingleObject returns. But we do not know any
|
||||
+ // other way to wait for it. Sleeping for a while seems to do
|
||||
+ // the trick sometimes.
|
||||
+ // See https://golang.org/issue/25965 for details.
|
||||
+ _, isWin10AndAbove := syscall.WindowsVersion()
|
||||
+ if !isWin10AndAbove {
|
||||
+ defer time.Sleep(5 * time.Millisecond)
|
||||
+ }
|
||||
+
|
||||
defer p.Release()
|
||||
return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
|
||||
}
|
||||
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
|
||||
index 1220de4..b4b846d 100644
|
||||
--- a/src/syscall/exec_windows.go
|
||||
+++ b/src/syscall/exec_windows.go
|
||||
@@ -254,6 +254,16 @@ type SysProcAttr struct {
|
||||
var zeroProcAttr ProcAttr
|
||||
var zeroSysProcAttr SysProcAttr
|
||||
|
||||
+// WindowsVersion returns whether the OS is Windows 7 (or earlier) and Windows 10 (or later)
|
||||
+func WindowsVersion() (isWin7, isWin10AndAbove bool) {
|
||||
+ info := _OSVERSIONINFOW{}
|
||||
+ info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
|
||||
+ rtlGetVersion(&info)
|
||||
+ isWin7 = info.majorVersion < 6 || (info.majorVersion == 6 && info.minorVersion <= 1)
|
||||
+ isWin10AndAbove = info.majorVersion >= 10
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
|
||||
if len(argv0) == 0 {
|
||||
return 0, 0, EWINDOWS
|
||||
@@ -317,6 +327,16 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
}
|
||||
}
|
||||
|
||||
+ isWin7, _ := WindowsVersion()
|
||||
+
|
||||
+ // NT kernel handles are divisible by 4, with the bottom 3 bits left as
|
||||
+ // a tag. The fully set tag correlates with the types of handles we're
|
||||
+ // concerned about here. Except, the kernel will interpret some
|
||||
+ // special handle values, like -1, -2, and so forth, so kernelbase.dll
|
||||
+ // checks to see that those bottom three bits are checked, but that top
|
||||
+ // bit is not checked.
|
||||
+ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 }
|
||||
+
|
||||
p, _ := GetCurrentProcess()
|
||||
parentProcess := p
|
||||
if sys.ParentProcess != 0 {
|
||||
@@ -325,7 +345,15 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
fd := make([]Handle, len(attr.Files))
|
||||
for i := range attr.Files {
|
||||
if attr.Files[i] > 0 {
|
||||
- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
|
||||
+ destinationProcessHandle := parentProcess
|
||||
+
|
||||
+ // On Windows 7, console handles aren't real handles, and can only be duplicated
|
||||
+ // into the current process, not a parent one, which amounts to the same thing.
|
||||
+ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) {
|
||||
+ destinationProcessHandle = p
|
||||
+ }
|
||||
+
|
||||
+ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
@@ -356,6 +384,14 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
|
||||
fd = append(fd, sys.AdditionalInheritedHandles...)
|
||||
|
||||
+ // On Windows 7, console handles aren't real handles, so don't pass them
|
||||
+ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
|
||||
+ for i := range fd {
|
||||
+ if isLegacyWin7ConsoleHandle(fd[i]) {
|
||||
+ fd[i] = 0
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST
|
||||
// to treat the entire list as empty, so remove NULL handles.
|
||||
j := 0
|
||||
diff --git a/src/syscall/types_windows.go b/src/syscall/types_windows.go
|
||||
index fa34053..f08ebe0 100644
|
||||
--- a/src/syscall/types_windows.go
|
||||
+++ b/src/syscall/types_windows.go
|
||||
@@ -1173,3 +1173,13 @@ const (
|
||||
)
|
||||
|
||||
const UNIX_PATH_MAX = 108 // defined in afunix.h
|
||||
+
|
||||
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfow
|
||||
+type _OSVERSIONINFOW struct {
|
||||
+ osVersionInfoSize uint32
|
||||
+ majorVersion uint32
|
||||
+ minorVersion uint32
|
||||
+ buildNumber uint32
|
||||
+ platformId uint32
|
||||
+ csdVersion [128]uint16
|
||||
+}
|
||||
diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
|
||||
index 85c66de..e58a384 100644
|
||||
--- a/src/syscall/zsyscall_windows.go
|
||||
+++ b/src/syscall/zsyscall_windows.go
|
||||
@@ -43,6 +43,7 @@ var (
|
||||
modkernel32 = NewLazyDLL(sysdll.Add("kernel32.dll"))
|
||||
modmswsock = NewLazyDLL(sysdll.Add("mswsock.dll"))
|
||||
modnetapi32 = NewLazyDLL(sysdll.Add("netapi32.dll"))
|
||||
+ modntdll = NewLazyDLL(sysdll.Add("ntdll.dll"))
|
||||
modsecur32 = NewLazyDLL(sysdll.Add("secur32.dll"))
|
||||
modshell32 = NewLazyDLL(sysdll.Add("shell32.dll"))
|
||||
moduserenv = NewLazyDLL(sysdll.Add("userenv.dll"))
|
||||
@@ -170,6 +171,7 @@ var (
|
||||
procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
|
||||
procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
|
||||
procGetUserNameExW = modsecur32.NewProc("GetUserNameExW")
|
||||
+ procRtlGetVersion = modntdll.NewProc("RtlGetVersion")
|
||||
procTranslateNameW = modsecur32.NewProc("TranslateNameW")
|
||||
procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW")
|
||||
procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
|
||||
@@ -1237,6 +1239,11 @@ func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err er
|
||||
return
|
||||
}
|
||||
|
||||
+func rtlGetVersion(info *_OSVERSIONINFOW) {
|
||||
+ Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0)
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
|
||||
r1, _, e1 := Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
|
||||
if r1&0xff == 0 {
|
||||
--
|
||||
2.39.5
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
From 60f9e8454df41affe07266e795f8a1d22567fd3e Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Sat, 5 Oct 2024 14:17:43 +1000
|
||||
Subject: [PATCH] Add Windows 7 console handle workaround (revert 48042aa)
|
||||
|
||||
---
|
||||
src/syscall/exec_windows.go | 29 ++++++++++++++++++++++++++++-
|
||||
1 file changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
|
||||
index 1220de4..815dfd6 100644
|
||||
--- a/src/syscall/exec_windows.go
|
||||
+++ b/src/syscall/exec_windows.go
|
||||
@@ -317,6 +317,17 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
}
|
||||
}
|
||||
|
||||
+ var maj, min, build uint32
|
||||
+ rtlGetNtVersionNumbers(&maj, &min, &build)
|
||||
+ isWin7 := maj < 6 || (maj == 6 && min <= 1)
|
||||
+ // NT kernel handles are divisible by 4, with the bottom 3 bits left as
|
||||
+ // a tag. The fully set tag correlates with the types of handles we're
|
||||
+ // concerned about here. Except, the kernel will interpret some
|
||||
+ // special handle values, like -1, -2, and so forth, so kernelbase.dll
|
||||
+ // checks to see that those bottom three bits are checked, but that top
|
||||
+ // bit is not checked.
|
||||
+ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 }
|
||||
+
|
||||
p, _ := GetCurrentProcess()
|
||||
parentProcess := p
|
||||
if sys.ParentProcess != 0 {
|
||||
@@ -325,7 +336,15 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
fd := make([]Handle, len(attr.Files))
|
||||
for i := range attr.Files {
|
||||
if attr.Files[i] > 0 {
|
||||
- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
|
||||
+ destinationProcessHandle := parentProcess
|
||||
+
|
||||
+ // On Windows 7, console handles aren't real handles, and can only be duplicated
|
||||
+ // into the current process, not a parent one, which amounts to the same thing.
|
||||
+ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) {
|
||||
+ destinationProcessHandle = p
|
||||
+ }
|
||||
+
|
||||
+ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
@@ -356,6 +375,14 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
|
||||
fd = append(fd, sys.AdditionalInheritedHandles...)
|
||||
|
||||
+ // On Windows 7, console handles aren't real handles, so don't pass them
|
||||
+ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
|
||||
+ for i := range fd {
|
||||
+ if isLegacyWin7ConsoleHandle(fd[i]) {
|
||||
+ fd[i] = 0
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST
|
||||
// to treat the entire list as empty, so remove NULL handles.
|
||||
j := 0
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0468b8b0addf825a274d81630087d62db495a562 Mon Sep 17 00:00:00 2001
|
||||
From b2a7b0bb30410c1f86e218119eb7501e252011b1 Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Sat, 5 Oct 2024 14:27:19 +1000
|
||||
Subject: [PATCH] Add sysSocket fallback (revert 7c1157f)
|
||||
Date: Fri, 14 Feb 2025 12:16:14 +0700
|
||||
Subject: [PATCH] Add sysSocket fallback
|
||||
|
||||
---
|
||||
src/net/hook_windows.go | 1 +
|
||||
@@ -161,7 +161,7 @@ index a519909..ebdf4c3 100644
|
||||
return syscall.InvalidHandle, os.NewSyscallError("socket", err)
|
||||
}
|
||||
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
|
||||
index 815dfd6..d197380 100644
|
||||
index b4b846d..27b4303 100644
|
||||
--- a/src/syscall/exec_windows.go
|
||||
+++ b/src/syscall/exec_windows.go
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
@@ -173,5 +173,5 @@ index 815dfd6..d197380 100644
|
||||
|
||||
// EscapeArg rewrites command line argument s as prescribed
|
||||
--
|
||||
2.47.0
|
||||
2.39.5
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
From d97201a53d5ec76fa81b091bc0d4d64f6ff6ff8c Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Sat, 5 Oct 2024 15:10:54 +1000
|
||||
Subject: [PATCH] Add Windows version info to syscall
|
||||
|
||||
---
|
||||
src/syscall/exec_windows.go | 7 ++++---
|
||||
src/syscall/types_windows.go | 10 ++++++++++
|
||||
src/syscall/zsyscall_windows.go | 7 +++++++
|
||||
3 files changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
|
||||
index d197380..f099a6f 100644
|
||||
--- a/src/syscall/exec_windows.go
|
||||
+++ b/src/syscall/exec_windows.go
|
||||
@@ -316,9 +316,10 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
}
|
||||
}
|
||||
|
||||
- var maj, min, build uint32
|
||||
- rtlGetNtVersionNumbers(&maj, &min, &build)
|
||||
- isWin7 := maj < 6 || (maj == 6 && min <= 1)
|
||||
+ info := _OSVERSIONINFOW{}
|
||||
+ info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
|
||||
+ rtlGetVersion(&info)
|
||||
+ isWin7 := info.majorVersion < 6 || (info.majorVersion == 6 && info.minorVersion <= 1)
|
||||
// NT kernel handles are divisible by 4, with the bottom 3 bits left as
|
||||
// a tag. The fully set tag correlates with the types of handles we're
|
||||
// concerned about here. Except, the kernel will interpret some
|
||||
diff --git a/src/syscall/types_windows.go b/src/syscall/types_windows.go
|
||||
index 6743675..37d0eff 100644
|
||||
--- a/src/syscall/types_windows.go
|
||||
+++ b/src/syscall/types_windows.go
|
||||
@@ -1169,3 +1169,13 @@ const (
|
||||
)
|
||||
|
||||
const UNIX_PATH_MAX = 108 // defined in afunix.h
|
||||
+
|
||||
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfow
|
||||
+type _OSVERSIONINFOW struct {
|
||||
+ osVersionInfoSize uint32
|
||||
+ majorVersion uint32
|
||||
+ minorVersion uint32
|
||||
+ buildNumber uint32
|
||||
+ platformId uint32
|
||||
+ csdVersion [128]uint16
|
||||
+}
|
||||
diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
|
||||
index 28369e3..a47b090 100644
|
||||
--- a/src/syscall/zsyscall_windows.go
|
||||
+++ b/src/syscall/zsyscall_windows.go
|
||||
@@ -43,6 +43,7 @@ var (
|
||||
modkernel32 = NewLazyDLL(sysdll.Add("kernel32.dll"))
|
||||
modmswsock = NewLazyDLL(sysdll.Add("mswsock.dll"))
|
||||
modnetapi32 = NewLazyDLL(sysdll.Add("netapi32.dll"))
|
||||
+ modntdll = NewLazyDLL(sysdll.Add("ntdll.dll"))
|
||||
modsecur32 = NewLazyDLL(sysdll.Add("secur32.dll"))
|
||||
modshell32 = NewLazyDLL(sysdll.Add("shell32.dll"))
|
||||
moduserenv = NewLazyDLL(sysdll.Add("userenv.dll"))
|
||||
@@ -169,6 +170,7 @@ var (
|
||||
procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
|
||||
procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
|
||||
procGetUserNameExW = modsecur32.NewProc("GetUserNameExW")
|
||||
+ procRtlGetVersion = modntdll.NewProc("RtlGetVersion")
|
||||
procTranslateNameW = modsecur32.NewProc("TranslateNameW")
|
||||
procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW")
|
||||
procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
|
||||
@@ -1228,6 +1230,11 @@ func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err er
|
||||
return
|
||||
}
|
||||
|
||||
+func rtlGetVersion(info *_OSVERSIONINFOW) {
|
||||
+ Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0)
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
|
||||
r1, _, e1 := Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
|
||||
if r1&0xff == 0 {
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
From cf3a4d4bb96092dcc87454133a9a77ea4454a60d Mon Sep 17 00:00:00 2001
|
||||
From: Vorapol Rinsatitnon <vorapol.r@pm.me>
|
||||
Date: Wed, 25 Dec 2024 14:16:56 +0700
|
||||
Subject: [PATCH] Add 5ms sleep on Windows 7/8 in (*Process).Wait
|
||||
|
||||
---
|
||||
src/os/exec_windows.go | 11 +++++++++++
|
||||
src/syscall/exec_windows.go | 16 ++++++++++++----
|
||||
2 files changed, 23 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/os/exec_windows.go b/src/os/exec_windows.go
|
||||
index ab2dae1..a2d7d34 100644
|
||||
--- a/src/os/exec_windows.go
|
||||
+++ b/src/os/exec_windows.go
|
||||
@@ -44,6 +44,17 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
if e != nil {
|
||||
return nil, NewSyscallError("GetProcessTimes", e)
|
||||
}
|
||||
+
|
||||
+ // NOTE(brainman): It seems that sometimes process is not dead
|
||||
+ // when WaitForSingleObject returns. But we do not know any
|
||||
+ // other way to wait for it. Sleeping for a while seems to do
|
||||
+ // the trick sometimes.
|
||||
+ // See https://golang.org/issue/25965 for details.
|
||||
+ _, isWin10AndAbove := syscall.WindowsVersion()
|
||||
+ if !isWin10AndAbove {
|
||||
+ defer time.Sleep(5 * time.Millisecond)
|
||||
+ }
|
||||
+
|
||||
defer p.Release()
|
||||
return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
|
||||
}
|
||||
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
|
||||
index f099a6f..27b4303 100644
|
||||
--- a/src/syscall/exec_windows.go
|
||||
+++ b/src/syscall/exec_windows.go
|
||||
@@ -253,6 +253,16 @@ type SysProcAttr struct {
|
||||
var zeroProcAttr ProcAttr
|
||||
var zeroSysProcAttr SysProcAttr
|
||||
|
||||
+// WindowsVersion returns whether the OS is Windows 7 (or earlier) and Windows 10 (or later)
|
||||
+func WindowsVersion() (isWin7, isWin10AndAbove bool) {
|
||||
+ info := _OSVERSIONINFOW{}
|
||||
+ info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
|
||||
+ rtlGetVersion(&info)
|
||||
+ isWin7 = info.majorVersion < 6 || (info.majorVersion == 6 && info.minorVersion <= 1)
|
||||
+ isWin10AndAbove = info.majorVersion >= 10
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
|
||||
if len(argv0) == 0 {
|
||||
return 0, 0, EWINDOWS
|
||||
@@ -316,10 +326,8 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
|
||||
}
|
||||
}
|
||||
|
||||
- info := _OSVERSIONINFOW{}
|
||||
- info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
|
||||
- rtlGetVersion(&info)
|
||||
- isWin7 := info.majorVersion < 6 || (info.majorVersion == 6 && info.minorVersion <= 1)
|
||||
+ isWin7, _ := WindowsVersion()
|
||||
+
|
||||
// NT kernel handles are divisible by 4, with the bottom 3 bits left as
|
||||
// a tag. The fully set tag correlates with the types of handles we're
|
||||
// concerned about here. Except, the kernel will interpret some
|
||||
--
|
||||
2.39.5
|
||||
|
||||
Reference in New Issue
Block a user