Source file src/pkg/os/user/lookup_unix.go
1
2
3
4
5
6
7
8 package user
9
10 import (
11 "fmt"
12 "runtime"
13 "strconv"
14 "strings"
15 "syscall"
16 "unsafe"
17 )
18
19 20 21 22 23 24 25 26 27 28 29
30 import "C"
31
32 func current() (*User, error) {
33 return lookupUnix(syscall.Getuid(), "", false)
34 }
35
36 func lookup(username string) (*User, error) {
37 return lookupUnix(-1, username, true)
38 }
39
40 func lookupId(uid string) (*User, error) {
41 i, e := strconv.Atoi(uid)
42 if e != nil {
43 return nil, e
44 }
45 return lookupUnix(i, "", false)
46 }
47
48 func lookupUnix(uid int, username string, lookupByName bool) (*User, error) {
49 var pwd C.struct_passwd
50 var result *C.struct_passwd
51
52 var bufSize C.long
53 if runtime.GOOS == "freebsd" {
54
55
56
57 bufSize = 1024
58 } else {
59 bufSize = C.sysconf(C._SC_GETPW_R_SIZE_MAX)
60 if bufSize <= 0 || bufSize > 1<<20 {
61 return nil, fmt.Errorf("user: unreasonable _SC_GETPW_R_SIZE_MAX of %d", bufSize)
62 }
63 }
64 buf := C.malloc(C.size_t(bufSize))
65 defer C.free(buf)
66 var rv C.int
67 if lookupByName {
68 nameC := C.CString(username)
69 defer C.free(unsafe.Pointer(nameC))
70 rv = C.getpwnam_r(nameC,
71 &pwd,
72 (*C.char)(buf),
73 C.size_t(bufSize),
74 &result)
75 if rv != 0 {
76 return nil, fmt.Errorf("user: lookup username %s: %s", username, syscall.Errno(rv))
77 }
78 if result == nil {
79 return nil, UnknownUserError(username)
80 }
81 } else {
82
83
84
85 rv = C.mygetpwuid_r(C.int(uid),
86 &pwd,
87 (*C.char)(buf),
88 C.size_t(bufSize),
89 &result)
90 if rv != 0 {
91 return nil, fmt.Errorf("user: lookup userid %d: %s", uid, syscall.Errno(rv))
92 }
93 if result == nil {
94 return nil, UnknownUserIdError(uid)
95 }
96 }
97 u := &User{
98 Uid: strconv.Itoa(int(pwd.pw_uid)),
99 Gid: strconv.Itoa(int(pwd.pw_gid)),
100 Username: C.GoString(pwd.pw_name),
101 Name: C.GoString(pwd.pw_gecos),
102 HomeDir: C.GoString(pwd.pw_dir),
103 }
104
105
106
107
108 if i := strings.Index(u.Name, ","); i >= 0 {
109 u.Name = u.Name[:i]
110 }
111 return u, nil
112 }
View as plain text