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 freebsd linux
19 #include <sys/types.h>
23 static int mygetpwuid_r(int uid, struct passwd *pwd,
24 char *buf, size_t buflen, struct passwd **result) {
25 return getpwuid_r(uid, pwd, buf, buflen, result);
29 func libc_getpwnam_r(name *byte, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int __asm__ ("getpwnam_r")
30 func libc_getpwuid_r(uid syscall.Uid_t, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int __asm__ ("getpwuid_r")
32 // bytePtrToString takes a NUL-terminated array of bytes and convert
34 func bytePtrToString(p *byte) string {
35 a := (*[10000]byte)(unsafe.Pointer(p))
47 // Lookup looks up a user by username. If the user cannot be found,
48 // the returned error is of type UnknownUserError.
49 func Lookup(username string) (*User, os.Error) {
50 return lookup(-1, username, true)
53 // LookupId looks up a user by userid. If the user cannot be found,
54 // the returned error is of type UnknownUserIdError.
55 func LookupId(uid int) (*User, os.Error) {
56 return lookup(uid, "", false)
59 func lookup(uid int, username string, lookupByName bool) (*User, os.Error) {
60 var pwd syscall.Passwd
61 var result *syscall.Passwd
63 // FIXME: Should let buf grow if necessary.
65 buf := make([]byte, bufSize)
67 rv := libc_getpwnam_r(syscall.StringBytePtr(username),
73 return nil, fmt.Errorf("user: lookup username %s: %s", username, os.Errno(syscall.GetErrno()))
76 return nil, UnknownUserError(username)
79 rv := libc_getpwuid_r(syscall.Uid_t(uid),
85 return nil, fmt.Errorf("user: lookup userid %d: %s", uid, os.Errno(syscall.GetErrno()))
88 return nil, UnknownUserIdError(uid)
94 Username: bytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_name))),
95 Name: bytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_gecos))),
96 HomeDir: bytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_dir))),
98 // The pw_gecos field isn't quite standardized. Some docs
99 // say: "It is expected to be a comma separated list of
100 // personal data where the first item is the full name of the
102 if i := strings.Index(u.Name, ","); i >= 0 {