aboutsummaryrefslogtreecommitdiff
path: root/src/os
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2022-12-07 09:18:11 -0500
committerGopher Robot <gobot@golang.org>2022-12-07 16:09:09 +0000
commit7ed50cfd09ba3d51c673fc782c6ad2b715a46bc2 (patch)
tree5eabbd313e552a8197bd3f442b1b595e982c9d8a /src/os
parenta4a86c7b2441d2777beb2377acfa3d9d7b1fc4ee (diff)
downloadgo-7ed50cfd09ba3d51c673fc782c6ad2b715a46bc2.tar.xz
os/user: fix buffer retry loop on macOS
getpwnam_r and friends return the errno as the result, not in the global errno. The code changes in CL 449316 inadvertently started using the global errno. So if a lookup didn't fit in the first buffer size, it was treated as not found instead of growing the buffer. Fixes #56942. Change-Id: Ic5904fbeb31161bccd858e5adb987e919fb3e9d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/455815 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Bryan Mills <bcmills@google.com> Auto-Submit: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/os')
-rw-r--r--src/os/user/cgo_lookup_unix.go2
-rw-r--r--src/os/user/lookup_plan9.go7
-rw-r--r--src/os/user/lookup_stubs.go7
-rw-r--r--src/os/user/lookup_windows.go7
-rw-r--r--src/os/user/user_test.go10
5 files changed, 32 insertions, 1 deletions
diff --git a/src/os/user/cgo_lookup_unix.go b/src/os/user/cgo_lookup_unix.go
index 81787fee2b..b745ffd9cf 100644
--- a/src/os/user/cgo_lookup_unix.go
+++ b/src/os/user/cgo_lookup_unix.go
@@ -141,7 +141,7 @@ func buildGroup(grp *_C_struct_group) *Group {
type bufferKind _C_int
-const (
+var (
userBuffer = bufferKind(_C__SC_GETPW_R_SIZE_MAX)
groupBuffer = bufferKind(_C__SC_GETGR_R_SIZE_MAX)
)
diff --git a/src/os/user/lookup_plan9.go b/src/os/user/lookup_plan9.go
index dcc9319268..c2aabd504c 100644
--- a/src/os/user/lookup_plan9.go
+++ b/src/os/user/lookup_plan9.go
@@ -20,6 +20,13 @@ func init() {
groupListImplemented = false
}
+var (
+ // unused variables (in this implementation)
+ // modified during test to exercise code paths in the cgo implementation.
+ userBuffer = 0
+ groupBuffer = 0
+)
+
func current() (*User, error) {
ubytes, err := os.ReadFile("/dev/user")
if err != nil {
diff --git a/src/os/user/lookup_stubs.go b/src/os/user/lookup_stubs.go
index b02c1ffa28..89dfe455b5 100644
--- a/src/os/user/lookup_stubs.go
+++ b/src/os/user/lookup_stubs.go
@@ -13,6 +13,13 @@ import (
"strconv"
)
+var (
+ // unused variables (in this implementation)
+ // modified during test to exercise code paths in the cgo implementation.
+ userBuffer = 0
+ groupBuffer = 0
+)
+
func current() (*User, error) {
uid := currentUID()
// $USER and /etc/passwd may disagree; prefer the latter if we can get it.
diff --git a/src/os/user/lookup_windows.go b/src/os/user/lookup_windows.go
index f65773ced3..e64b8ae028 100644
--- a/src/os/user/lookup_windows.go
+++ b/src/os/user/lookup_windows.go
@@ -192,6 +192,13 @@ func newUser(uid, gid, dir, username, domain string) (*User, error) {
return u, nil
}
+var (
+ // unused variables (in this implementation)
+ // modified during test to exercise code paths in the cgo implementation.
+ userBuffer = 0
+ groupBuffer = 0
+)
+
func current() (*User, error) {
t, e := syscall.OpenCurrentProcessToken()
if e != nil {
diff --git a/src/os/user/user_test.go b/src/os/user/user_test.go
index 80251749a7..0fa963dae0 100644
--- a/src/os/user/user_test.go
+++ b/src/os/user/user_test.go
@@ -16,6 +16,11 @@ func checkUser(t *testing.T) {
}
func TestCurrent(t *testing.T) {
+ old := userBuffer
+ defer func() {
+ userBuffer = old
+ }()
+ userBuffer = 1 // force use of retry code
u, err := Current()
if err != nil {
t.Fatalf("Current: %v (got %#v)", err, u)
@@ -91,6 +96,11 @@ func checkGroup(t *testing.T) {
}
func TestLookupGroup(t *testing.T) {
+ old := groupBuffer
+ defer func() {
+ groupBuffer = old
+ }()
+ groupBuffer = 1 // force use of retry code
checkGroup(t)
user, err := Current()
if err != nil {