OSDN Git Service

Bring over accumulated bug fixes from mainline.
[pf3gnuchains/gcc-fork.git] / libgo / go / os / user / lookup_unix.go
index 0f04012..ebc8684 100644 (file)
@@ -2,11 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build darwin freebsd linux
+// +build cgo
+
 package user
 
 import (
        "fmt"
-       "os"
+       "strconv"
        "strings"
        "syscall"
        "unsafe"
@@ -24,26 +27,45 @@ static int mygetpwuid_r(int uid, struct passwd *pwd,
 }
 */
 
-func libc_getpwnam_r(name *byte, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int __asm__ ("getpwnam_r")
-func libc_getpwuid_r(uid syscall.Uid_t, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int __asm__ ("getpwuid_r")
+//extern getpwnam_r
+func libc_getpwnam_r(name *byte, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int
+
+//extern getpwuid_r
+func libc_getpwuid_r(uid syscall.Uid_t, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int
+
+// bytePtrToString takes a NUL-terminated array of bytes and convert
+// it to a Go string.
+func bytePtrToString(p *byte) string {
+       a := (*[10000]byte)(unsafe.Pointer(p))
+       i := 0
+       for a[i] != 0 {
+               i++
+       }
+       return string(a[:i])
+}
 
-func init() {
-       implemented = true
+// Current returns the current user. 
+func Current() (*User, error) {
+       return lookup(syscall.Getuid(), "", false)
 }
 
 // Lookup looks up a user by username. If the user cannot be found,
 // the returned error is of type UnknownUserError.
-func Lookup(username string) (*User, os.Error) {
+func Lookup(username string) (*User, error) {
        return lookup(-1, username, true)
 }
 
 // LookupId looks up a user by userid. If the user cannot be found,
 // the returned error is of type UnknownUserIdError.
-func LookupId(uid int) (*User, os.Error) {
-       return lookup(uid, "", false)
+func LookupId(uid string) (*User, error) {
+       i, e := strconv.Atoi(uid)
+       if e != nil {
+               return nil, e
+       }
+       return lookup(i, "", false)
 }
 
-func lookup(uid int, username string, lookupByName bool) (*User, os.Error) {
+func lookup(uid int, username string, lookupByName bool) (*User, error) {
        var pwd syscall.Passwd
        var result *syscall.Passwd
 
@@ -51,36 +73,41 @@ func lookup(uid int, username string, lookupByName bool) (*User, os.Error) {
        const bufSize = 1024
        buf := make([]byte, bufSize)
        if lookupByName {
-               rv := libc_getpwnam_r(syscall.StringBytePtr(username),
+               p := syscall.StringBytePtr(username)
+               syscall.Entersyscall()
+               rv := libc_getpwnam_r(p,
                        &pwd,
                        &buf[0],
                        bufSize,
                        &result)
+               syscall.Exitsyscall()
                if rv != 0 {
-                       return nil, fmt.Errorf("user: lookup username %s: %s", username, os.Errno(syscall.GetErrno()))
+                       return nil, fmt.Errorf("user: lookup username %s: %s", username, syscall.GetErrno())
                }
                if result == nil {
                        return nil, UnknownUserError(username)
                }
        } else {
+               syscall.Entersyscall()
                rv := libc_getpwuid_r(syscall.Uid_t(uid),
                        &pwd,
                        &buf[0],
                        bufSize,
                        &result)
+               syscall.Exitsyscall()
                if rv != 0 {
-                       return nil, fmt.Errorf("user: lookup userid %d: %s", uid, os.Errno(syscall.GetErrno()))
+                       return nil, fmt.Errorf("user: lookup userid %d: %s", uid, syscall.GetErrno())
                }
                if result == nil {
                        return nil, UnknownUserIdError(uid)
                }
        }
        u := &User{
-               Uid:      int(pwd.Pw_uid),
-               Gid:      int(pwd.Pw_gid),
-               Username: syscall.BytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_name))),
-               Name:     syscall.BytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_gecos))),
-               HomeDir:  syscall.BytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_dir))),
+               Uid:      strconv.Itoa(int(pwd.Pw_uid)),
+               Gid:      strconv.Itoa(int(pwd.Pw_gid)),
+               Username: bytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_name))),
+               Name:     bytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_gecos))),
+               HomeDir:  bytePtrToString((*byte)(unsafe.Pointer(pwd.Pw_dir))),
        }
        // The pw_gecos field isn't quite standardized.  Some docs
        // say: "It is expected to be a comma separated list of