1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
20 #include <sys/types.h>
24 static int mygetpwuid_r(int uid, struct passwd *pwd,
25 char *buf, size_t buflen, struct passwd **result) {
26 return getpwuid_r(uid, pwd, buf, buflen, result);
30 // bytePtrToString takes a NUL-terminated array of bytes and convert
32 func bytePtrToString(p
*byte) string {
33 a
:= (*[10000]byte)(unsafe
.Pointer(p
))
41 func current() (*User
, error
) {
42 return lookupUnix(syscall
.Getuid(), "", false)
45 func lookup(username
string) (*User
, error
) {
46 return lookupUnix(-1, username
, true)
49 func lookupId(uid
string) (*User
, error
) {
50 i
, e
:= strconv
.Atoi(uid
)
54 return lookupUnix(i
, "", false)
57 func lookupUnix(uid
int, username
string, lookupByName
bool) (*User
, error
) {
58 var pwd syscall
.Passwd
59 var result
*syscall
.Passwd
61 // FIXME: Should let buf grow if necessary.
63 buf
:= make([]byte, bufSize
)
65 p
:= syscall
.StringBytePtr(username
)
66 syscall
.Entersyscall()
67 rv
:= libc_getpwnam_r(p
,
74 return nil, fmt
.Errorf("user: lookup username %s: %s", username
, syscall
.GetErrno())
77 return nil, UnknownUserError(username
)
80 syscall
.Entersyscall()
81 rv
:= libc_getpwuid_r(syscall
.Uid_t(uid
),
88 return nil, fmt
.Errorf("user: lookup userid %d: %s", uid
, syscall
.GetErrno())
91 return nil, UnknownUserIdError(uid
)
95 Uid
: strconv
.Itoa(int(pwd
.Pw_uid
)),
96 Gid
: strconv
.Itoa(int(pwd
.Pw_gid
)),
97 Username
: bytePtrToString((*byte)(unsafe
.Pointer(pwd
.Pw_name
))),
98 Name
: bytePtrToString((*byte)(unsafe
.Pointer(pwd
.Pw_gecos
))),
99 HomeDir
: bytePtrToString((*byte)(unsafe
.Pointer(pwd
.Pw_dir
))),
101 // The pw_gecos field isn't quite standardized. Some docs
102 // say: "It is expected to be a comma separated list of
103 // personal data where the first item is the full name of the
105 if i
:= strings
.Index(u
.Name
, ","); i
>= 0 {