summaryrefslogtreecommitdiff
path: root/go/golang/gocache/66/66fc8816e54b731ce80418edca379a32d7c7d17de1cc960a413b621623aee3ea-d
diff options
context:
space:
mode:
Diffstat (limited to 'go/golang/gocache/66/66fc8816e54b731ce80418edca379a32d7c7d17de1cc960a413b621623aee3ea-d')
-rw-r--r--go/golang/gocache/66/66fc8816e54b731ce80418edca379a32d7c7d17de1cc960a413b621623aee3ea-d282
1 files changed, 282 insertions, 0 deletions
diff --git a/go/golang/gocache/66/66fc8816e54b731ce80418edca379a32d7c7d17de1cc960a413b621623aee3ea-d b/go/golang/gocache/66/66fc8816e54b731ce80418edca379a32d7c7d17de1cc960a413b621623aee3ea-d
new file mode 100644
index 00000000..4904bc02
--- /dev/null
+++ b/go/golang/gocache/66/66fc8816e54b731ce80418edca379a32d7c7d17de1cc960a413b621623aee3ea-d
@@ -0,0 +1,282 @@
+// Code generated by cmd/cgo; DO NOT EDIT.
+
+//line /workdir/go/src/os/user/cgo_lookup_unix.go:1:1
+// Copyright 2011 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 !android,linux netbsd openbsd solaris
+// +build cgo,!osusergo
+
+package user; import _cgo_unsafe "unsafe"
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+/*
+#cgo solaris CFLAGS: -D_POSIX_PTHREAD_SEMANTICS
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdlib.h>
+
+static int mygetpwuid_r(int uid, struct passwd *pwd,
+ char *buf, size_t buflen, struct passwd **result) {
+ return getpwuid_r(uid, pwd, buf, buflen, result);
+}
+
+static int mygetpwnam_r(const char *name, struct passwd *pwd,
+ char *buf, size_t buflen, struct passwd **result) {
+ return getpwnam_r(name, pwd, buf, buflen, result);
+}
+
+static int mygetgrgid_r(int gid, struct group *grp,
+ char *buf, size_t buflen, struct group **result) {
+ return getgrgid_r(gid, grp, buf, buflen, result);
+}
+
+static int mygetgrnam_r(const char *name, struct group *grp,
+ char *buf, size_t buflen, struct group **result) {
+ return getgrnam_r(name, grp, buf, buflen, result);
+}
+*/
+import _ "unsafe"
+
+func current() (*User, error) {
+ return lookupUnixUid(syscall.Getuid())
+}
+
+func lookupUser(username string) (*User, error) {
+ var pwd _Ctype_struct_passwd
+ var result *_Ctype_struct_passwd
+ nameC := make([]byte, len(username)+1)
+ copy(nameC, username)
+
+ buf := alloc(userBuffer)
+ defer buf.free()
+
+ err := retryWithBuffer(buf, func() syscall.Errno {
+ // mygetpwnam_r is a wrapper around getpwnam_r to avoid
+ // passing a size_t to getpwnam_r, because for unknown
+ // reasons passing a size_t to getpwnam_r doesn't work on
+ // Solaris.
+ return syscall.Errno(func(_cgo0 *_Ctype_char, _cgo1 *_Ctype_struct_passwd, _cgo2 *_Ctype_char, _cgo3 _Ctype_size_t, _cgo4 **_Ctype_struct_passwd) _Ctype_int {; _cgoCheckPointer(_cgo1, true); _cgoCheckPointer(_cgo4, true); return (_Cfunc_mygetpwnam_r)(_cgo0, _cgo1, _cgo2, _cgo3, _cgo4);}((*_Ctype_char)(unsafe.Pointer(&nameC[0])),
+ &pwd,
+ (*_Ctype_char)(buf.ptr),
+ _Ctype_size_t(buf.size),
+ &result))
+ })
+ if err != nil {
+ return nil, fmt.Errorf("user: lookup username %s: %v", username, err)
+ }
+ if result == nil {
+ return nil, UnknownUserError(username)
+ }
+ return buildUser(&pwd), err
+}
+
+func lookupUserId(uid string) (*User, error) {
+ i, e := strconv.Atoi(uid)
+ if e != nil {
+ return nil, e
+ }
+ return lookupUnixUid(i)
+}
+
+func lookupUnixUid(uid int) (*User, error) {
+ var pwd _Ctype_struct_passwd
+ var result *_Ctype_struct_passwd
+
+ buf := alloc(userBuffer)
+ defer buf.free()
+
+ err := retryWithBuffer(buf, func() syscall.Errno {
+ // mygetpwuid_r is a wrapper around getpwuid_r to
+ // to avoid using uid_t because C.uid_t(uid) for
+ // unknown reasons doesn't work on linux.
+ return syscall.Errno(func(_cgo0 _Ctype_int, _cgo1 *_Ctype_struct_passwd, _cgo2 *_Ctype_char, _cgo3 _Ctype_size_t, _cgo4 **_Ctype_struct_passwd) _Ctype_int {; _cgoCheckPointer(_cgo1, true); _cgoCheckPointer(_cgo4, true); return (_Cfunc_mygetpwuid_r)(_cgo0, _cgo1, _cgo2, _cgo3, _cgo4);}(_Ctype_int(uid),
+ &pwd,
+ (*_Ctype_char)(buf.ptr),
+ _Ctype_size_t(buf.size),
+ &result))
+ })
+ if err != nil {
+ return nil, fmt.Errorf("user: lookup userid %d: %v", uid, err)
+ }
+ if result == nil {
+ return nil, UnknownUserIdError(uid)
+ }
+ return buildUser(&pwd), nil
+}
+
+func buildUser(pwd *_Ctype_struct_passwd) *User {
+ u := &User{
+ Uid: strconv.FormatUint(uint64(pwd.pw_uid), 10),
+ Gid: strconv.FormatUint(uint64(pwd.pw_gid), 10),
+ Username: (_Cfunc_GoString)(pwd.pw_name),
+ Name: (_Cfunc_GoString)(pwd.pw_gecos),
+ HomeDir: (_Cfunc_GoString)(pwd.pw_dir),
+ }
+ // The pw_gecos field isn't quite standardized. Some docs
+ // say: "It is expected to be a comma separated list of
+ // personal data where the first item is the full name of the
+ // user."
+ if i := strings.Index(u.Name, ","); i >= 0 {
+ u.Name = u.Name[:i]
+ }
+ return u
+}
+
+func currentGroup() (*Group, error) {
+ return lookupUnixGid(syscall.Getgid())
+}
+
+func lookupGroup(groupname string) (*Group, error) {
+ var grp _Ctype_struct_group
+ var result *_Ctype_struct_group
+
+ buf := alloc(groupBuffer)
+ defer buf.free()
+ cname := make([]byte, len(groupname)+1)
+ copy(cname, groupname)
+
+ err := retryWithBuffer(buf, func() syscall.Errno {
+ return syscall.Errno(func(_cgo0 *_Ctype_char, _cgo1 *_Ctype_struct_group, _cgo2 *_Ctype_char, _cgo3 _Ctype_size_t, _cgo4 **_Ctype_struct_group) _Ctype_int {; _cgoCheckPointer(_cgo1, true); _cgoCheckPointer(_cgo4, true); return (_Cfunc_mygetgrnam_r)(_cgo0, _cgo1, _cgo2, _cgo3, _cgo4);}((*_Ctype_char)(unsafe.Pointer(&cname[0])),
+ &grp,
+ (*_Ctype_char)(buf.ptr),
+ _Ctype_size_t(buf.size),
+ &result))
+ })
+ if err != nil {
+ return nil, fmt.Errorf("user: lookup groupname %s: %v", groupname, err)
+ }
+ if result == nil {
+ return nil, UnknownGroupError(groupname)
+ }
+ return buildGroup(&grp), nil
+}
+
+func lookupGroupId(gid string) (*Group, error) {
+ i, e := strconv.Atoi(gid)
+ if e != nil {
+ return nil, e
+ }
+ return lookupUnixGid(i)
+}
+
+func lookupUnixGid(gid int) (*Group, error) {
+ var grp _Ctype_struct_group
+ var result *_Ctype_struct_group
+
+ buf := alloc(groupBuffer)
+ defer buf.free()
+
+ err := retryWithBuffer(buf, func() syscall.Errno {
+ // mygetgrgid_r is a wrapper around getgrgid_r to
+ // to avoid using gid_t because C.gid_t(gid) for
+ // unknown reasons doesn't work on linux.
+ return syscall.Errno(func(_cgo0 _Ctype_int, _cgo1 *_Ctype_struct_group, _cgo2 *_Ctype_char, _cgo3 _Ctype_size_t, _cgo4 **_Ctype_struct_group) _Ctype_int {; _cgoCheckPointer(_cgo1, true); _cgoCheckPointer(_cgo4, true); return (_Cfunc_mygetgrgid_r)(_cgo0, _cgo1, _cgo2, _cgo3, _cgo4);}(_Ctype_int(gid),
+ &grp,
+ (*_Ctype_char)(buf.ptr),
+ _Ctype_size_t(buf.size),
+ &result))
+ })
+ if err != nil {
+ return nil, fmt.Errorf("user: lookup groupid %d: %v", gid, err)
+ }
+ if result == nil {
+ return nil, UnknownGroupIdError(strconv.Itoa(gid))
+ }
+ return buildGroup(&grp), nil
+}
+
+func buildGroup(grp *_Ctype_struct_group) *Group {
+ g := &Group{
+ Gid: strconv.Itoa(int(grp.gr_gid)),
+ Name: (_Cfunc_GoString)(grp.gr_name),
+ }
+ return g
+}
+
+type bufferKind _Ctype_int
+
+const (
+ userBuffer = bufferKind((_Ciconst__SC_GETPW_R_SIZE_MAX))
+ groupBuffer = bufferKind((_Ciconst__SC_GETGR_R_SIZE_MAX))
+)
+
+func (k bufferKind) initialSize() _Ctype_size_t {
+ sz := (_Cfunc_sysconf)(_Ctype_int(k))
+ if sz == -1 {
+ // DragonFly and FreeBSD do not have _SC_GETPW_R_SIZE_MAX.
+ // Additionally, not all Linux systems have it, either. For
+ // example, the musl libc returns -1.
+ return 1024
+ }
+ if !isSizeReasonable(int64(sz)) {
+ // Truncate. If this truly isn't enough, retryWithBuffer will error on the first run.
+ return maxBufferSize
+ }
+ return _Ctype_size_t(sz)
+}
+
+type memBuffer struct {
+ ptr unsafe.Pointer
+ size _Ctype_size_t
+}
+
+func alloc(kind bufferKind) *memBuffer {
+ sz := kind.initialSize()
+ return &memBuffer{
+ ptr: (_Cfunc__CMalloc)(sz),
+ size: sz,
+ }
+}
+
+func (mb *memBuffer) resize(newSize _Ctype_size_t) {
+ mb.ptr = func(_cgo0 _cgo_unsafe.Pointer, _cgo1 _Ctype_size_t) _cgo_unsafe.Pointer {; _cgoCheckPointer(_cgo0); return (_Cfunc_realloc)(_cgo0, _cgo1);}(mb.ptr, newSize)
+ mb.size = newSize
+}
+
+func (mb *memBuffer) free() {
+ func(_cgo0 _cgo_unsafe.Pointer) {; _cgoCheckPointer(_cgo0); (_Cfunc_free)(_cgo0);}(mb.ptr)
+}
+
+// retryWithBuffer repeatedly calls f(), increasing the size of the
+// buffer each time, until f succeeds, fails with a non-ERANGE error,
+// or the buffer exceeds a reasonable limit.
+func retryWithBuffer(buf *memBuffer, f func() syscall.Errno) error {
+ for {
+ errno := f()
+ if errno == 0 {
+ return nil
+ } else if errno != syscall.ERANGE {
+ return errno
+ }
+ newSize := buf.size * 2
+ if !isSizeReasonable(int64(newSize)) {
+ return fmt.Errorf("internal buffer exceeds %d bytes", maxBufferSize)
+ }
+ buf.resize(newSize)
+ }
+}
+
+const maxBufferSize = 1 << 20
+
+func isSizeReasonable(sz int64) bool {
+ return sz > 0 && sz <= maxBufferSize
+}
+
+// Because we can't use cgo in tests:
+func structPasswdForNegativeTest() _Ctype_struct_passwd {
+ sp := _Ctype_struct_passwd{}
+ sp.pw_uid = 1<<32 - 2
+ sp.pw_gid = 1<<32 - 3
+ return sp
+}