diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-04-09 16:43:22 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-04-09 16:43:22 +0000 |
commit | 9bafe5a81e42406b86a65ef14b011ed9acc96c5d (patch) | |
tree | 35478f4f4ff092374f748479debcda06b96dd6dd /libgo | |
parent | 10f47d3d1dc2e1267a32fa6459655b4645a9adad (diff) | |
parent | 3fa176b767e14e1d2491775978afac3e87892d1d (diff) | |
download | gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.zip gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.tar.gz gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.tar.bz2 |
Merge from trunk revision 270220.
From-SVN: r270233
Diffstat (limited to 'libgo')
49 files changed, 423 insertions, 289 deletions
diff --git a/libgo/MERGE b/libgo/MERGE index d456361..37b7480 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -0380c9ad38843d523d9c9804fe300cb7edd7cd3c +ac02fdec7cd16ea8d3de1fc33def9cfabec5170d The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/VERSION b/libgo/VERSION index f325447..b9c6439 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.12.1 +go1.12.2 diff --git a/libgo/go/archive/tar/stat_actime1.go b/libgo/go/archive/tar/stat_actime1.go index e2c79a5..2a7f7f3 100644 --- a/libgo/go/archive/tar/stat_actime1.go +++ b/libgo/go/archive/tar/stat_actime1.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build hurd linux dragonfly openbsd solaris +// +build aix hurd linux dragonfly openbsd solaris package tar diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index 543250e..5e511db 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -1184,6 +1184,36 @@ var cgoSyscallExclude = map[string]bool{ var foldPath = make(map[string]string) +// DefaultExecName returns the default executable name +// for a package with the import path importPath. +// +// The default executable name is the last element of the import path. +// In module-aware mode, an additional rule is used. If the last element +// is a vN path element specifying the major version, then the second last +// element of the import path is used instead. +func DefaultExecName(importPath string) string { + _, elem := pathpkg.Split(importPath) + if cfg.ModulesEnabled { + // If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2. + // See golang.org/issue/24667. + isVersion := func(v string) bool { + if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] { + return false + } + for i := 2; i < len(v); i++ { + if c := v[i]; c < '0' || '9' < c { + return false + } + } + return true + } + if isVersion(elem) { + _, elem = pathpkg.Split(pathpkg.Dir(importPath)) + } + } + return elem +} + // load populates p using information from bp, err, which should // be the result of calling build.Context.Import. func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { @@ -1226,7 +1256,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { } _, elem := filepath.Split(p.Dir) if cfg.ModulesEnabled { - // NOTE(rsc): Using p.ImportPath instead of p.Dir + // NOTE(rsc,dmitshur): Using p.ImportPath instead of p.Dir // makes sure we install a package in the root of a // cached module directory as that package name // not name@v1.2.3. @@ -1235,26 +1265,9 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // even for non-module-enabled code, // but I'm not brave enough to change the // non-module behavior this late in the - // release cycle. Maybe for Go 1.12. + // release cycle. Can be done for Go 1.13. // See golang.org/issue/26869. - _, elem = pathpkg.Split(p.ImportPath) - - // If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2. - // See golang.org/issue/24667. - isVersion := func(v string) bool { - if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] { - return false - } - for i := 2; i < len(v); i++ { - if c := v[i]; c < '0' || '9' < c { - return false - } - } - return true - } - if isVersion(elem) { - _, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath)) - } + elem = DefaultExecName(p.ImportPath) } full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH { diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go index c0e0667..7385c4e 100644 --- a/libgo/go/cmd/go/internal/load/test.go +++ b/libgo/go/cmd/go/internal/load/test.go @@ -268,17 +268,8 @@ func GetTestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Pac pmain.Imports = pmain.Imports[:w] pmain.Internal.RawImports = str.StringList(pmain.Imports) - if ptest != p { - // We have made modifications to the package p being tested - // and are rebuilding p (as ptest). - // Arrange to rebuild all packages q such that - // the test depends on q and q depends on p. - // This makes sure that q sees the modifications to p. - // Strictly speaking, the rebuild is only necessary if the - // modifications to p change its export metadata, but - // determining that is a bit tricky, so we rebuild always. - recompileForTest(pmain, p, ptest, pxtest) - } + // Replace pmain's transitive dependencies with test copies, as necessary. + recompileForTest(pmain, p, ptest, pxtest) // Should we apply coverage analysis locally, // only for this package and only for this test? @@ -325,6 +316,14 @@ Search: return stk } +// recompileForTest copies and replaces certain packages in pmain's dependency +// graph. This is necessary for two reasons. First, if ptest is different than +// preal, packages that import the package under test should get ptest instead +// of preal. This is particularly important if pxtest depends on functionality +// exposed in test sources in ptest. Second, if there is a main package +// (other than pmain) anywhere, we need to clear p.Internal.BuildInfo in +// the test copy to prevent link conflicts. This may happen if both -coverpkg +// and the command line patterns include multiple main packages. func recompileForTest(pmain, preal, ptest, pxtest *Package) { // The "test copy" of preal is ptest. // For each package that depends on preal, make a "test copy" @@ -367,7 +366,7 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) { // Don't compile build info from a main package. This can happen // if -coverpkg patterns include main packages, since those packages - // are imported by pmain. + // are imported by pmain. See golang.org/issue/30907. if p.Internal.BuildInfo != "" && p != pmain { split() } diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go index 2831975..a14362b 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go @@ -35,7 +35,9 @@ const ( writeLock lockType = syscall.F_WRLCK ) -type inode = uint64 // type of syscall.Stat_t.Ino +// type of syscall.Stat_t.Ino for 64 bits architectures. +// For 32 bits architecture, it's easier to cast it instead. +type inode = uint64 type inodeLock struct { owner File @@ -59,7 +61,7 @@ func lock(f File, lt lockType) (err error) { if err != nil { return err } - ino := fi.Sys().(*syscall.Stat_t).Ino + ino := uint64(fi.Sys().(*syscall.Stat_t).Ino) mu.Lock() if i, dup := inodes[f]; dup && i != ino { diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index 332f312..b72eace 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -805,7 +805,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin if p.ImportPath == "command-line-arguments" { elem = p.Name } else { - _, elem = path.Split(p.ImportPath) + elem = load.DefaultExecName(p.ImportPath) } testBinary := elem + ".test" diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go index 145b875..ed66df2 100644 --- a/libgo/go/cmd/go/internal/work/build.go +++ b/libgo/go/cmd/go/internal/work/build.go @@ -10,7 +10,6 @@ import ( "go/build" "os" "os/exec" - "path" "path/filepath" "runtime" "strings" @@ -285,7 +284,7 @@ func runBuild(cmd *base.Command, args []string) { pkgs := load.PackagesForBuild(args) if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" { - _, cfg.BuildO = path.Split(pkgs[0].ImportPath) + cfg.BuildO = load.DefaultExecName(pkgs[0].ImportPath) cfg.BuildO += cfg.ExeSuffix } @@ -518,7 +517,7 @@ func InstallPackages(patterns []string, pkgs []*load.Package) { if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" { // Compute file 'go build' would have created. // If it exists and is an executable file, remove it. - _, targ := filepath.Split(pkgs[0].ImportPath) + targ := load.DefaultExecName(pkgs[0].ImportPath) targ += cfg.ExeSuffix if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory fi, err := os.Stat(targ) diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index fc052b3..5302724 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -214,6 +214,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { if p.Internal.CoverMode != "" { fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover")) } + fmt.Fprintf(h, "modinfo %q\n", p.Internal.BuildInfo) // Configuration specific to compiler toolchain. switch cfg.BuildToolchainName { diff --git a/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt b/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt index cfa91f0..3acd637 100644 --- a/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt +++ b/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt @@ -13,3 +13,9 @@ import "rsc.io/quote" func main() { println(quote.Hello()) } +-- fortune_test.go -- +package main + +import "testing" + +func TestFortuneV2(t *testing.T) {} diff --git a/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt b/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt new file mode 100644 index 0000000..ab7cd66 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt @@ -0,0 +1,43 @@ +# This test checks that multiple main packages can be tested +# with -coverpkg=all without duplicate symbol errors. +# Verifies golang.org/issue/30374. + +env GO111MODULE=on + +[short] skip + +go test -coverpkg=all ./... + +-- go.mod -- +module example.com/cov + +-- mainonly/mainonly.go -- +package main + +func main() {} + +-- mainwithtest/mainwithtest.go -- +package main + +func main() {} + +func Foo() {} + +-- mainwithtest/mainwithtest_test.go -- +package main + +import "testing" + +func TestFoo(t *testing.T) { + Foo() +} + +-- xtest/x.go -- +package x + +-- xtest/x_test.go -- +package x_test + +import "testing" + +func TestX(t *testing.T) {} diff --git a/libgo/go/internal/poll/fd_windows.go b/libgo/go/internal/poll/fd_windows.go index 19d9a12..f860b82 100644 --- a/libgo/go/internal/poll/fd_windows.go +++ b/libgo/go/internal/poll/fd_windows.go @@ -660,6 +660,10 @@ func (fd *FD) Write(buf []byte) (int, error) { return 0, err } defer fd.writeUnlock() + if fd.isFile || fd.isDir || fd.isConsole { + fd.l.Lock() + defer fd.l.Unlock() + } ntotal := 0 for len(buf) > 0 { @@ -670,8 +674,6 @@ func (fd *FD) Write(buf []byte) (int, error) { var n int var err error if fd.isFile || fd.isDir || fd.isConsole { - fd.l.Lock() - defer fd.l.Unlock() if fd.isConsole { n, err = fd.writeConsole(b) } else { diff --git a/libgo/go/internal/syscall/unix/at_largefile.go b/libgo/go/internal/syscall/unix/at_largefile.go index 5318d23..82e0dcf 100644 --- a/libgo/go/internal/syscall/unix/at_largefile.go +++ b/libgo/go/internal/syscall/unix/at_largefile.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix hurd linux solaris,386 solaris,sparc +// +build hurd linux solaris,386 solaris,sparc package unix diff --git a/libgo/go/internal/syscall/unix/at_regfile.go b/libgo/go/internal/syscall/unix/at_regfile.go index 004c801..14fdb70 100644 --- a/libgo/go/internal/syscall/unix/at_regfile.go +++ b/libgo/go/internal/syscall/unix/at_regfile.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !aix // +build !hurd // +build !linux // +build !solaris !386 diff --git a/libgo/go/internal/syscall/unix/ioctl_aix.go b/libgo/go/internal/syscall/unix/ioctl_aix.go index 19d56c3..af105d6 100644 --- a/libgo/go/internal/syscall/unix/ioctl_aix.go +++ b/libgo/go/internal/syscall/unix/ioctl_aix.go @@ -9,17 +9,12 @@ import ( "unsafe" ) -//go:cgo_import_dynamic libc_ioctl ioctl "libc.a/shr_64.o" -//go:linkname libc_ioctl libc_ioctl -var libc_ioctl uintptr - -// Implemented in syscall/syscall_aix.go. -func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +//extern __go_ioctl_ptr +func ioctl(int32, int32, unsafe.Pointer) int32 func Ioctl(fd int, cmd int, args uintptr) (err error) { - _, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_ioctl)), 3, uintptr(fd), uintptr(cmd), uintptr(args), 0, 0, 0) - if e1 != 0 { - err = e1 + if ioctl(int32(fd), int32(cmd), unsafe.Pointer(args)) < 0 { + return syscall.GetErrno() } return } diff --git a/libgo/go/net/http/httputil/reverseproxy.go b/libgo/go/net/http/httputil/reverseproxy.go index 4e10bf3..4b165d6 100644 --- a/libgo/go/net/http/httputil/reverseproxy.go +++ b/libgo/go/net/http/httputil/reverseproxy.go @@ -389,6 +389,11 @@ func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval latency: flushInterval, } defer mlw.stop() + + // set up initial timer so headers get flushed even if body writes are delayed + mlw.flushPending = true + mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush) + dst = mlw } } diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go index 5edefa0..367ba73 100644 --- a/libgo/go/net/http/httputil/reverseproxy_test.go +++ b/libgo/go/net/http/httputil/reverseproxy_test.go @@ -9,6 +9,7 @@ package httputil import ( "bufio" "bytes" + "context" "errors" "fmt" "io" @@ -317,6 +318,47 @@ func TestReverseProxyFlushInterval(t *testing.T) { } } +func TestReverseProxyFlushIntervalHeaders(t *testing.T) { + const expected = "hi" + stopCh := make(chan struct{}) + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("MyHeader", expected) + w.WriteHeader(200) + w.(http.Flusher).Flush() + <-stopCh + })) + defer backend.Close() + defer close(stopCh) + + backendURL, err := url.Parse(backend.URL) + if err != nil { + t.Fatal(err) + } + + proxyHandler := NewSingleHostReverseProxy(backendURL) + proxyHandler.FlushInterval = time.Microsecond + + frontend := httptest.NewServer(proxyHandler) + defer frontend.Close() + + req, _ := http.NewRequest("GET", frontend.URL, nil) + req.Close = true + + ctx, cancel := context.WithTimeout(req.Context(), 10*time.Second) + defer cancel() + req = req.WithContext(ctx) + + res, err := frontend.Client().Do(req) + if err != nil { + t.Fatalf("Get: %v", err) + } + defer res.Body.Close() + + if res.Header.Get("MyHeader") != expected { + t.Errorf("got header %q; expected %q", res.Header.Get("MyHeader"), expected) + } +} + func TestReverseProxyCancelation(t *testing.T) { const backendResponse = "I am the backend" diff --git a/libgo/go/net/interface_aix.go b/libgo/go/net/interface_aix.go index 9a8b5bb..1fe9bba 100644 --- a/libgo/go/net/interface_aix.go +++ b/libgo/go/net/interface_aix.go @@ -32,6 +32,8 @@ const _RTAX_NETMASK = 2 const _RTAX_IFA = 5 const _RTAX_MAX = 8 +const _SIOCGIFMTU = -0x3fd796aa + func getIfList() ([]byte, error) { needed, err := syscall.Getkerninfo(_KINFO_RT_IFLIST, 0, 0, 0) if err != nil { @@ -62,7 +64,7 @@ func interfaceTable(ifindex int) ([]Interface, error) { } if ifm.Type == syscall.RTM_IFINFO { if ifindex == 0 || ifindex == int(ifm.Index) { - sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[syscall.SizeofIfMsghdr])) + sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[unsafe.Sizeof(syscall.IfMsgHdr)])) ifi := &Interface{Index: int(ifm.Index), Flags: linkFlags(ifm.Flags)} ifi.Name = string(sdl.Data[:sdl.Nlen]) @@ -75,7 +77,7 @@ func interfaceTable(ifindex int) ([]Interface, error) { if err != nil { return nil, err } - err = unix.Ioctl(sock, syscall.SIOCGIFMTU, uintptr(unsafe.Pointer(ifr))) + err = unix.Ioctl(sock, _SIOCGIFMTU, uintptr(unsafe.Pointer(ifr))) if err != nil { return nil, err } @@ -131,7 +133,7 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) { if ifm.Type == syscall.RTM_NEWADDR { if ifi == nil || ifi.Index == int(ifm.Index) { mask := ifm.Addrs - off := uint(syscall.SizeofIfMsghdr) + off := uint(unsafe.Sizeof(syscall.IfMsgHdr)) var iprsa, nmrsa *syscall.RawSockaddr for i := uint(0); i < _RTAX_MAX; i++ { diff --git a/libgo/go/net/interface_stub.go b/libgo/go/net/interface_stub.go index 0b3580e..d8afd5e 100644 --- a/libgo/go/net/interface_stub.go +++ b/libgo/go/net/interface_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix nacl hurd js,wasm +// +build nacl hurd js,wasm package net diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go index e108893..08e8d01 100644 --- a/libgo/go/net/lookup.go +++ b/libgo/go/net/lookup.go @@ -262,8 +262,9 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP // only the values in context. See Issue 28600. lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx)) + lookupKey := network + "\000" + host dnsWaitGroup.Add(1) - ch, called := r.getLookupGroup().DoChan(host, func() (interface{}, error) { + ch, called := r.getLookupGroup().DoChan(lookupKey, func() (interface{}, error) { defer dnsWaitGroup.Done() return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host) }) @@ -280,7 +281,7 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP // let the lookup continue uncanceled, and let later // lookups with the same key share the result. // See issues 8602, 20703, 22724. - if r.getLookupGroup().ForgetUnshared(host) { + if r.getLookupGroup().ForgetUnshared(lookupKey) { lookupGroupCancel() } else { go func() { diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go index 85bcb2b..28a895e 100644 --- a/libgo/go/net/lookup_test.go +++ b/libgo/go/net/lookup_test.go @@ -16,6 +16,7 @@ import ( "sort" "strings" "sync" + "sync/atomic" "testing" "time" ) @@ -253,14 +254,11 @@ func TestLookupGmailTXT(t *testing.T) { } } -var lookupGooglePublicDNSAddrTests = []struct { - addr, name string -}{ - {"8.8.8.8", ".google.com."}, - {"8.8.4.4", ".google.com."}, - - {"2001:4860:4860::8888", ".google.com."}, - {"2001:4860:4860::8844", ".google.com."}, +var lookupGooglePublicDNSAddrTests = []string{ + "8.8.8.8", + "8.8.4.4", + "2001:4860:4860::8888", + "2001:4860:4860::8844", } func TestLookupGooglePublicDNSAddr(t *testing.T) { @@ -272,8 +270,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) { defer dnsWaitGroup.Wait() - for _, tt := range lookupGooglePublicDNSAddrTests { - names, err := LookupAddr(tt.addr) + for _, ip := range lookupGooglePublicDNSAddrTests { + names, err := LookupAddr(ip) if err != nil { t.Fatal(err) } @@ -281,8 +279,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) { t.Error("got no record") } for _, name := range names { - if !strings.HasSuffix(name, tt.name) { - t.Errorf("got %s; want a record containing %s", name, tt.name) + if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") { + t.Errorf("got %q; want a record ending in .google.com. or .google.", name) } } } @@ -658,8 +656,8 @@ func testDots(t *testing.T, mode string) { t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode) } else { for _, name := range names { - if !strings.HasSuffix(name, ".google.com.") { - t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names, mode) + if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") { + t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com or .google with trailing dot (mode=%v)", names, mode) break } } @@ -1096,6 +1094,69 @@ func TestLookupIPAddrPreservesContextValues(t *testing.T) { } } +// Issue 30521: The lookup group should call the resolver for each network. +func TestLookupIPAddrConcurrentCallsForNetworks(t *testing.T) { + origTestHookLookupIP := testHookLookupIP + defer func() { testHookLookupIP = origTestHookLookupIP }() + + queries := [][]string{ + {"udp", "golang.org"}, + {"udp4", "golang.org"}, + {"udp6", "golang.org"}, + {"udp", "golang.org"}, + {"udp", "golang.org"}, + } + results := map[[2]string][]IPAddr{ + {"udp", "golang.org"}: { + {IP: IPv4(127, 0, 0, 1)}, + {IP: IPv6loopback}, + }, + {"udp4", "golang.org"}: { + {IP: IPv4(127, 0, 0, 1)}, + }, + {"udp6", "golang.org"}: { + {IP: IPv6loopback}, + }, + } + calls := int32(0) + waitCh := make(chan struct{}) + testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) { + // We'll block until this is called one time for each different + // expected result. This will ensure that the lookup group would wait + // for the existing call if it was to be reused. + if atomic.AddInt32(&calls, 1) == int32(len(results)) { + close(waitCh) + } + select { + case <-waitCh: + case <-ctx.Done(): + return nil, ctx.Err() + } + return results[[2]string{network, host}], nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + wg := sync.WaitGroup{} + for _, q := range queries { + network := q[0] + host := q[1] + wg.Add(1) + go func() { + defer wg.Done() + gotIPs, err := DefaultResolver.lookupIPAddr(ctx, network, host) + if err != nil { + t.Errorf("lookupIPAddr(%v, %v): unexpected error: %v", network, host, err) + } + wantIPs := results[[2]string{network, host}] + if !reflect.DeepEqual(gotIPs, wantIPs) { + t.Errorf("lookupIPAddr(%v, %v): mismatched IPAddr results\n\tGot: %v\n\tWant: %v", network, host, gotIPs, wantIPs) + } + }() + } + wg.Wait() +} + func TestWithUnexpiredValuesPreserved(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/libgo/go/net/sockoptip_aix.go b/libgo/go/net/sockoptip_aix.go deleted file mode 100644 index 1e28fe6..0000000 --- a/libgo/go/net/sockoptip_aix.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package net - -import "syscall" - -func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { - return syscall.ENOPROTOOPT -} - -func setIPv4MulticastLoopback(fd *netFD, v bool) error { - return syscall.ENOPROTOOPT -} diff --git a/libgo/go/os/dir_gccgo.go b/libgo/go/os/dir_gccgo.go index 60f70aa..ad77a40 100644 --- a/libgo/go/os/dir_gccgo.go +++ b/libgo/go/os/dir_gccgo.go @@ -16,9 +16,6 @@ import ( //extern pathconf func libc_pathconf(*byte, int) int -//extern fdopendir -func libc_fdopendir(int32) *syscall.DIR - func clen(n []byte) int { for i := 0; i < len(n); i++ { if n[i] == 0 { diff --git a/libgo/go/os/dir_libc64_gccgo.go b/libgo/go/os/dir_libc64_gccgo.go index dc3ba7f..3582243 100644 --- a/libgo/go/os/dir_libc64_gccgo.go +++ b/libgo/go/os/dir_libc64_gccgo.go @@ -10,3 +10,6 @@ import "syscall" //extern closedir64 func libc_closedir(*syscall.DIR) int + +//extern fdopendir64 +func libc_fdopendir(int32) *syscall.DIR diff --git a/libgo/go/os/dir_libc_gccgo.go b/libgo/go/os/dir_libc_gccgo.go index b46eb4c..a3be43b 100644 --- a/libgo/go/os/dir_libc_gccgo.go +++ b/libgo/go/os/dir_libc_gccgo.go @@ -10,3 +10,6 @@ import "syscall" //extern closedir func libc_closedir(*syscall.DIR) int + +//extern fdopendir +func libc_fdopendir(int32) *syscall.DIR diff --git a/libgo/go/os/path.go b/libgo/go/os/path.go index 104b7ce..ba43ea3 100644 --- a/libgo/go/os/path.go +++ b/libgo/go/os/path.go @@ -62,6 +62,7 @@ func MkdirAll(path string, perm FileMode) error { // It removes everything it can but returns the first error // it encounters. If the path does not exist, RemoveAll // returns nil (no error). +// If there is an error, it will be of type *PathError. func RemoveAll(path string) error { return removeAll(path) } diff --git a/libgo/go/os/path_unix.go b/libgo/go/os/path_unix.go index e55301f..4864989 100644 --- a/libgo/go/os/path_unix.go +++ b/libgo/go/os/path_unix.go @@ -51,7 +51,7 @@ func splitPath(path string) (string, string) { // Remove leading directory path for i--; i >= 0; i-- { if path[i] == '/' { - dirname = path[:i+1] + dirname = path[:i] basename = path[i+1:] break } diff --git a/libgo/go/os/removeall_at.go b/libgo/go/os/removeall_at.go index 512a891..6fdd7e8 100644 --- a/libgo/go/os/removeall_at.go +++ b/libgo/go/os/removeall_at.go @@ -46,13 +46,20 @@ func removeAll(path string) error { } defer parent.Close() - return removeAllFrom(parent, base) + if err := removeAllFrom(parent, base); err != nil { + if pathErr, ok := err.(*PathError); ok { + pathErr.Path = parentDir + string(PathSeparator) + pathErr.Path + err = pathErr + } + return err + } + return nil } -func removeAllFrom(parent *File, path string) error { +func removeAllFrom(parent *File, base string) error { parentFd := int(parent.Fd()) // Simple case: if Unlink (aka remove) works, we're done. - err := unix.Unlinkat(parentFd, path, 0) + err := unix.Unlinkat(parentFd, base, 0) if err == nil || IsNotExist(err) { return nil } @@ -64,21 +71,21 @@ func removeAllFrom(parent *File, path string) error { // whose contents need to be removed. // Otherwise just return the error. if err != syscall.EISDIR && err != syscall.EPERM && err != syscall.EACCES { - return err + return &PathError{"unlinkat", base, err} } // Is this a directory we need to recurse into? var statInfo syscall.Stat_t - statErr := unix.Fstatat(parentFd, path, &statInfo, unix.AT_SYMLINK_NOFOLLOW) + statErr := unix.Fstatat(parentFd, base, &statInfo, unix.AT_SYMLINK_NOFOLLOW) if statErr != nil { if IsNotExist(statErr) { return nil } - return statErr + return &PathError{"fstatat", base, statErr} } if statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR { - // Not a directory; return the error from the Remove. - return err + // Not a directory; return the error from the unix.Unlinkat. + return &PathError{"unlinkat", base, err} } // Remove the directory's entries. @@ -87,12 +94,12 @@ func removeAllFrom(parent *File, path string) error { const request = 1024 // Open the directory to recurse into - file, err := openFdAt(parentFd, path) + file, err := openFdAt(parentFd, base) if err != nil { if IsNotExist(err) { return nil } - recurseErr = err + recurseErr = &PathError{"openfdat", base, err} break } @@ -103,12 +110,15 @@ func removeAllFrom(parent *File, path string) error { if IsNotExist(readErr) { return nil } - return readErr + return &PathError{"readdirnames", base, readErr} } for _, name := range names { err := removeAllFrom(file, name) if err != nil { + if pathErr, ok := err.(*PathError); ok { + pathErr.Path = base + string(PathSeparator) + pathErr.Path + } recurseErr = err } } @@ -127,7 +137,7 @@ func removeAllFrom(parent *File, path string) error { } // Remove the directory itself. - unlinkError := unix.Unlinkat(parentFd, path, unix.AT_REMOVEDIR) + unlinkError := unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR) if unlinkError == nil || IsNotExist(unlinkError) { return nil } @@ -135,7 +145,7 @@ func removeAllFrom(parent *File, path string) error { if recurseErr != nil { return recurseErr } - return unlinkError + return &PathError{"unlinkat", base, unlinkError} } // openFdAt opens path relative to the directory in fd. @@ -157,7 +167,7 @@ func openFdAt(dirfd int, name string) (*File, error) { continue } - return nil, &PathError{"openat", name, e} + return nil, e } if !supportsCloseOnExec { diff --git a/libgo/go/os/removeall_test.go b/libgo/go/os/removeall_test.go index 21371d8..945a38e 100644 --- a/libgo/go/os/removeall_test.go +++ b/libgo/go/os/removeall_test.go @@ -294,7 +294,7 @@ func TestRemoveReadOnlyDir(t *testing.T) { } // Issue #29983. -func TestRemoveAllButReadOnly(t *testing.T) { +func TestRemoveAllButReadOnlyAndPathError(t *testing.T) { switch runtime.GOOS { case "nacl", "js", "windows": t.Skipf("skipping test on %s", runtime.GOOS) @@ -355,10 +355,21 @@ func TestRemoveAllButReadOnly(t *testing.T) { defer Chmod(d, 0777) } - if err := RemoveAll(tempDir); err == nil { + err = RemoveAll(tempDir) + if err == nil { t.Fatal("RemoveAll succeeded unexpectedly") } + // The error should be of type *PathError. + // see issue 30491 for details. + if pathErr, ok := err.(*PathError); ok { + if g, w := pathErr.Path, filepath.Join(tempDir, "b", "y"); g != w { + t.Errorf("got %q, expected pathErr.path %q", g, w) + } + } else { + t.Errorf("got %T, expected *os.PathError", err) + } + for _, dir := range dirs { _, err := Stat(filepath.Join(tempDir, dir)) if inReadonly(dir) { diff --git a/libgo/go/os/sys_aix.go b/libgo/go/os/sys_aix.go deleted file mode 100644 index 53a40f2..0000000 --- a/libgo/go/os/sys_aix.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package os - -import "syscall" - -// gethostname syscall cannot be used because it also returns the domain. -// Therefore, hostname is retrieve with uname syscall and the Nodename field. - -func hostname() (name string, err error) { - var u syscall.Utsname - if errno := syscall.Uname(&u); errno != nil { - return "", NewSyscallError("uname", errno) - } - b := make([]byte, len(u.Nodename)) - i := 0 - for ; i < len(u.Nodename); i++ { - if u.Nodename[i] == 0 { - break - } - b[i] = byte(u.Nodename[i]) - } - return string(b[:i]), nil -} diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index b6a7ee1..c0b4caa 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -218,7 +218,7 @@ const ( // we further limit it to 31 bits. // // WebAssembly currently has a limit of 4GB linear memory. - heapAddrBits = (_64bit*(1-sys.GoarchWasm)*(1-sys.GoosAix))*48 + (1-_64bit+sys.GoarchWasm)*(32-(sys.GoarchMips+sys.GoarchMipsle)) + 60*sys.GoosAix + heapAddrBits = (_64bit*(1-sys.GoarchWasm)*(1-sys.GoosAix))*48 + (1-_64bit+sys.GoarchWasm)*(32-(sys.GoarchMips+sys.GoarchMipsle)) + 60*(sys.GoosAix*_64bit) // maxAlloc is the maximum size of an allocation. On 64-bit, // it's theoretically possible to allocate 1<<heapAddrBits bytes. On @@ -259,7 +259,7 @@ const ( // logHeapArenaBytes is log_2 of heapArenaBytes. For clarity, // prefer using heapArenaBytes where possible (we need the // constant to compute some other constants). - logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoosAix)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (8+20)*sys.GoosAix + logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoosAix)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (8+20)*(sys.GoosAix*_64bit) // heapArenaBitmapBytes is the size of each heap arena's bitmap. heapArenaBitmapBytes = heapArenaBytes / (sys.PtrSize * 8 / 2) @@ -282,7 +282,7 @@ const ( // // We use the L1 map on aix/ppc64 to keep the same L2 value // as on Linux. - arenaL1Bits = 6*(_64bit*sys.GoosWindows) + 12*sys.GoosAix + arenaL1Bits = 6*(_64bit*sys.GoosWindows) + 12*(sys.GoosAix*_64bit) // arenaL2Bits is the number of bits of the arena number // covered by the second level arena index. diff --git a/libgo/go/runtime/mem_gccgo.go b/libgo/go/runtime/mem_gccgo.go index 44f4648..9874678 100644 --- a/libgo/go/runtime/mem_gccgo.go +++ b/libgo/go/runtime/mem_gccgo.go @@ -187,6 +187,11 @@ func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer { func sysMap(v unsafe.Pointer, n uintptr, sysStat *uint64) { mSysStatInc(sysStat, n) + if GOOS == "aix" { + // AIX does not allow mapping a range that is already mapped. + // So always unmap first even if it is already unmapped. + munmap(v, n) + } p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, mmapFD, 0) if err == _ENOMEM { throw("runtime: out of memory") diff --git a/libgo/go/runtime/netpoll_aix.go b/libgo/go/runtime/netpoll_aix.go index 86c3e96..70bf9eb 100644 --- a/libgo/go/runtime/netpoll_aix.go +++ b/libgo/go/runtime/netpoll_aix.go @@ -37,7 +37,6 @@ const _POLLIN = 0x0001 const _POLLOUT = 0x0002 const _POLLHUP = 0x2000 const _POLLERR = 0x4000 -const _O_NONBLOCK = 0x4 var ( pfds []pollfd diff --git a/libgo/go/runtime/os_aix.go b/libgo/go/runtime/os_aix.go index 1003616..9211f21 100644 --- a/libgo/go/runtime/os_aix.go +++ b/libgo/go/runtime/os_aix.go @@ -62,12 +62,19 @@ func semasleep(ns int64) int32 { if clock_gettime(_CLOCK_REALTIME, &ts) != 0 { throw("clock_gettime") } - ts.tv_sec += ns / 1e9 - ts.tv_nsec += ns % 1e9 - if ts.tv_nsec >= 1e9 { - ts.tv_sec++ - ts.tv_nsec -= 1e9 + + sec := int64(ts.tv_sec) + ns/1e9 + nsec := int64(ts.tv_nsec) + ns%1e9 + if nsec >= 1e9 { + sec++ + nsec -= 1e9 + } + if sec != int64(timespec_sec_t(sec)) { + // Handle overflows (timespec_sec_t is 32-bit in 32-bit applications) + sec = 1<<31 - 1 } + ts.tv_sec = timespec_sec_t(sec) + ts.tv_nsec = timespec_nsec_t(nsec) if sem_timedwait((*semt)(unsafe.Pointer(_m_.mos.waitsema)), &ts) != 0 { err := errno() diff --git a/libgo/go/runtime/runtime-lldb_test.go b/libgo/go/runtime/runtime-lldb_test.go index fe3a0eb..08d6a34 100644 --- a/libgo/go/runtime/runtime-lldb_test.go +++ b/libgo/go/runtime/runtime-lldb_test.go @@ -139,6 +139,7 @@ func TestLldbPython(t *testing.T) { if final := os.Getenv("GOROOT_FINAL"); final != "" && runtime.GOROOT() != final { t.Skip("gdb test can fail with GOROOT_FINAL pending") } + testenv.SkipFlaky(t, 31188) checkLldbPython(t) diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go index 335532d..9137951 100644 --- a/libgo/go/runtime/slice.go +++ b/libgo/go/runtime/slice.go @@ -77,31 +77,31 @@ func makeslice64(et *_type, len64, cap64 int64) unsafe.Pointer { // and it returns a new slice with at least that capacity, with the old data // copied into it. // The new slice's length is set to the requested capacity. -func growslice(et *_type, old slice, cap int) slice { +func growslice(et *_type, oldarray unsafe.Pointer, oldlen, oldcap, cap int) slice { if raceenabled { callerpc := getcallerpc() - racereadrangepc(old.array, uintptr(old.len*int(et.size)), callerpc, funcPC(growslice)) + racereadrangepc(oldarray, uintptr(oldlen*int(et.size)), callerpc, funcPC(growslice)) } if msanenabled { - msanread(old.array, uintptr(old.len*int(et.size))) + msanread(oldarray, uintptr(oldlen*int(et.size))) } - if cap < old.cap { + if cap < oldcap { panic(errorString("growslice: cap out of range")) } if et.size == 0 { // append should not create a slice with nil pointer but non-zero len. - // We assume that append doesn't need to preserve old.array in this case. + // We assume that append doesn't need to preserve oldarray in this case. return slice{unsafe.Pointer(&zerobase), cap, cap} } - newcap := old.cap + newcap := oldcap doublecap := newcap + newcap if cap > doublecap { newcap = cap } else { - if old.len < 1024 { + if oldlen < 1024 { newcap = doublecap } else { // Check 0 < newcap to detect overflow @@ -125,13 +125,13 @@ func growslice(et *_type, old slice, cap int) slice { // For powers of 2, use a variable shift. switch { case et.size == 1: - lenmem = uintptr(old.len) + lenmem = uintptr(oldlen) newlenmem = uintptr(cap) capmem = roundupsize(uintptr(newcap)) overflow = uintptr(newcap) > maxAlloc newcap = int(capmem) case et.size == sys.PtrSize: - lenmem = uintptr(old.len) * sys.PtrSize + lenmem = uintptr(oldlen) * sys.PtrSize newlenmem = uintptr(cap) * sys.PtrSize capmem = roundupsize(uintptr(newcap) * sys.PtrSize) overflow = uintptr(newcap) > maxAlloc/sys.PtrSize @@ -144,13 +144,13 @@ func growslice(et *_type, old slice, cap int) slice { } else { shift = uintptr(sys.Ctz32(uint32(et.size))) & 31 } - lenmem = uintptr(old.len) << shift + lenmem = uintptr(oldlen) << shift newlenmem = uintptr(cap) << shift capmem = roundupsize(uintptr(newcap) << shift) overflow = uintptr(newcap) > (maxAlloc >> shift) newcap = int(capmem >> shift) default: - lenmem = uintptr(old.len) * et.size + lenmem = uintptr(oldlen) * et.size newlenmem = uintptr(cap) * et.size capmem, overflow = math.MulUintptr(et.size, uintptr(newcap)) capmem = roundupsize(capmem) @@ -177,19 +177,19 @@ func growslice(et *_type, old slice, cap int) slice { var p unsafe.Pointer if et.kind&kindNoPointers != 0 { p = mallocgc(capmem, nil, false) - // The append() that calls growslice is going to overwrite from old.len to cap (which will be the new length). + // The append() that calls growslice is going to overwrite from oldlen to cap (which will be the new length). // Only clear the part that will not be overwritten. memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem) } else { // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory. p = mallocgc(capmem, et, true) if writeBarrier.enabled { - // Only shade the pointers in old.array since we know the destination slice p + // Only shade the pointers in oldarray since we know the destination slice p // only contains nil pointers because it has been cleared during alloc. - bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(old.array), lenmem) + bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldarray), lenmem) } } - memmove(p, old.array, lenmem) + memmove(p, oldarray, lenmem) return slice{p, cap, newcap} } diff --git a/libgo/go/runtime/stubs2.go b/libgo/go/runtime/stubs2.go index 304c8e4..1cb910c 100644 --- a/libgo/go/runtime/stubs2.go +++ b/libgo/go/runtime/stubs2.go @@ -7,7 +7,6 @@ // +build !nacl // +build !js // +build !darwin -// +build !aix package runtime diff --git a/libgo/go/runtime/timestub2.go b/libgo/go/runtime/timestub2.go index 00c2c55..7a28603 100644 --- a/libgo/go/runtime/timestub2.go +++ b/libgo/go/runtime/timestub2.go @@ -5,8 +5,6 @@ // +build !darwin // +build !windows // +build !freebsd -// +build !aix - package runtime func walltime() (sec int64, nsec int32) diff --git a/libgo/go/syscall/exec_aix_test.go b/libgo/go/syscall/exec_aix_test.go deleted file mode 100644 index 22b752c..0000000 --- a/libgo/go/syscall/exec_aix_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build aix - -package syscall - -import "unsafe" - -//go:cgo_import_dynamic libc_Getpgid getpgid "libc.a/shr_64.o" -//go:cgo_import_dynamic libc_Getpgrp getpgrp "libc.a/shr_64.o" - -//go:linkname libc_Getpgid libc_Getpgid -//go:linkname libc_Getpgrp libc_Getpgrp - -var ( - libc_Getpgid, - libc_Getpgrp libcFunc -) - -func Getpgid(pid int) (pgid int, err error) { - r0, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_Getpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0) - pgid = int(r0) - if e1 != 0 { - err = e1 - } - return -} - -func Getpgrp() (pgrp int) { - r0, _, _ := syscall6(uintptr(unsafe.Pointer(&libc_Getpgrp)), 0, 0, 0, 0, 0, 0, 0) - pgrp = int(r0) - return -} - -var Ioctl = ioctl diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go index bad2ce4..ec21f80 100644 --- a/libgo/go/syscall/exec_unix.go +++ b/libgo/go/syscall/exec_unix.go @@ -299,7 +299,6 @@ func runtime_AfterExec() // execveLibc is non-nil on OS using libc syscall, set to execve in exec_libc.go; this // avoids a build dependency for other platforms. -var execveLibc func(path uintptr, argv uintptr, envp uintptr) Errno var execveDarwin func(path *byte, argv **byte, envp **byte) error // Exec invokes the execve(2) system call. @@ -321,10 +320,7 @@ func Exec(argv0 string, argv []string, envv []string) (err error) { var err1 error if runtime.GOOS == "solaris" || runtime.GOOS == "aix" || runtime.GOOS == "hurd" { // RawSyscall should never be used on Solaris or AIX. - err1 = execveLibc( - uintptr(unsafe.Pointer(argv0p)), - uintptr(unsafe.Pointer(&argvp[0])), - uintptr(unsafe.Pointer(&envvp[0]))) + err1 = raw_execve(argv0p, &argvp[0], &envvp[0]) } else if runtime.GOOS == "darwin" { // Similarly on Darwin. err1 = execveDarwin(argv0p, &argvp[0], &envvp[0]) diff --git a/libgo/go/syscall/flock_aix.go b/libgo/go/syscall/flock_aix.go deleted file mode 100644 index c9eab43..0000000 --- a/libgo/go/syscall/flock_aix.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package syscall - -import "unsafe" - -// On AIX, there is no flock() system call. - -// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. -func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) { - _, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/libgo/go/syscall/libcall_aix.go b/libgo/go/syscall/libcall_aix.go index 072f92a..8d9f59e 100644 --- a/libgo/go/syscall/libcall_aix.go +++ b/libgo/go/syscall/libcall_aix.go @@ -10,6 +10,9 @@ import ( "unsafe" ) +// For exec_unix.go. +const SYS_EXECVE = 0 + //sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) //open64at(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int @@ -139,3 +142,6 @@ func ReadDirent(fd int, buf []byte) (n int, err error) { func Unlinkat(dirfd int, path string) (err error) { return unlinkat(dirfd, path, 0) } + +//sys Getkerninfo(op int32, where uintptr, size uintptr, arg int64) (i int32, err error) +//getkerninfo(op _C_int, where *byte, size *byte, arg _C_long) _C_int diff --git a/libgo/go/syscall/security_windows.go b/libgo/go/syscall/security_windows.go index ae8b3a1..db80d98 100644 --- a/libgo/go/syscall/security_windows.go +++ b/libgo/go/syscall/security_windows.go @@ -290,6 +290,7 @@ type Tokenprimarygroup struct { //sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken //sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation //sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW +//sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW // 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/libgo/go/syscall/syscall_funcs.go b/libgo/go/syscall/syscall_funcs.go new file mode 100644 index 0000000..4b1ee32 --- /dev/null +++ b/libgo/go/syscall/syscall_funcs.go @@ -0,0 +1,45 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd hurd linux netbsd openbsd solaris + +package syscall + +//extern __go_syscall6 +func syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) uintptr + +// Do a system call. We look at the size of uintptr to see how to pass +// the arguments, so that we don't pass a 64-bit value when the function +// expects a 32-bit one. +func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { + Entersyscall() + SetErrno(0) + r := syscall6(trap, a1, a2, a3, 0, 0, 0) + err = GetErrno() + Exitsyscall() + return r, 0, err +} + +func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { + Entersyscall() + SetErrno(0) + r := syscall6(trap, a1, a2, a3, a4, a5, a6) + err = GetErrno() + Exitsyscall() + return r, 0, err +} + +func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { + SetErrno(0) + r := syscall6(trap, a1, a2, a3, 0, 0, 0) + err = GetErrno() + return r, 0, err +} + +func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { + SetErrno(0) + r := syscall6(trap, a1, a2, a3, a4, a5, a6) + err = GetErrno() + return r, 0, err +} diff --git a/libgo/go/syscall/syscall_funcs_stubs.go b/libgo/go/syscall/syscall_funcs_stubs.go new file mode 100644 index 0000000..c68ab26 --- /dev/null +++ b/libgo/go/syscall/syscall_funcs_stubs.go @@ -0,0 +1,29 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix rtems + +// These are stubs. + +package syscall + +func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { + z := -1 + return uintptr(z), 0, ENOSYS +} + +func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { + z := -1 + return uintptr(z), 0, ENOSYS +} + +func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { + z := -1 + return uintptr(z), 0, ENOSYS +} + +func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { + z := -1 + return uintptr(z), 0, ENOSYS +} diff --git a/libgo/go/syscall/syscall_stubs.go b/libgo/go/syscall/syscall_stubs.go deleted file mode 100644 index 00288ee..0000000 --- a/libgo/go/syscall/syscall_stubs.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build rtems - -// These are stubs. - -package syscall - -func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { - z := -1 - return uintptr(z), 0, uintptr(ENOSYS) -} - -func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { - z := -1 - return uintptr(z), 0, uintptr(ENOSYS) -} - -func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { - z := -1 - return uintptr(z), 0, uintptr(ENOSYS) -} - -func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { - z := -1 - return uintptr(z), 0, uintptr(ENOSYS) -} diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go index b786dc5..ec8f343 100644 --- a/libgo/go/syscall/syscall_unix.go +++ b/libgo/go/syscall/syscall_unix.go @@ -19,9 +19,6 @@ var ( Stderr = 2 ) -//extern __go_syscall6 -func syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) uintptr - const ( darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8 @@ -29,41 +26,6 @@ const ( solaris64Bit = runtime.GOOS == "solaris" && sizeofPtr == 8 ) -// Do a system call. We look at the size of uintptr to see how to pass -// the arguments, so that we don't pass a 64-bit value when the function -// expects a 32-bit one. -func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { - Entersyscall() - SetErrno(0) - r := syscall6(trap, a1, a2, a3, 0, 0, 0) - err = GetErrno() - Exitsyscall() - return r, 0, err -} - -func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { - Entersyscall() - SetErrno(0) - r := syscall6(trap, a1, a2, a3, a4, a5, a6) - err = GetErrno() - Exitsyscall() - return r, 0, err -} - -func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { - SetErrno(0) - r := syscall6(trap, a1, a2, a3, 0, 0, 0) - err = GetErrno() - return r, 0, err -} - -func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { - SetErrno(0) - r := syscall6(trap, a1, a2, a3, a4, a5, a6) - err = GetErrno() - return r, 0, err -} - // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. func clen(n []byte) int { for i := 0; i < len(n); i++ { diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index 418ba2c..c9dd8d4 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -1024,6 +1024,18 @@ grep '^type _ifinfomsg ' gen-sysinfo.go | \ -e 's/ifi_change/Change/' \ >> ${OUT} +# The if_msghdr struct. +grep '^type _if_msghdr ' gen-sysinfo.go | \ + sed -e 's/_if_msghdr/IfMsgHdr/' \ + -e 's/ifm_msglen/Msglen/' \ + -e 's/ifm_version/Version/' \ + -e 's/ifm_type/Type/' \ + -e 's/ifm_addrs/Addrs/' \ + -e 's/ifm_flags/Flags/' \ + -e 's/ifm_index/Index/' \ + -e 's/ifm_addrlen/Addrlen/' \ + >> ${OUT} + # The interface information types and flags. grep '^const _IFA' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(IFA[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} diff --git a/libgo/runtime/go-varargs.c b/libgo/runtime/go-varargs.c index cf033af..2b186ef 100644 --- a/libgo/runtime/go-varargs.c +++ b/libgo/runtime/go-varargs.c @@ -96,6 +96,8 @@ __go_openat (int fd, char *path, int flags, mode_t mode) #endif +#ifdef HAVE_SYSCALL + // __go_syscall6 is called by both the runtime and syscall packages. // We use uintptr_t to make sure that the types match, since the Go // and C "int" types are not the same. @@ -106,3 +108,5 @@ __go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3, { return syscall (flag, a1, a2, a3, a4, a5, a6); } + +#endif |