Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1246)

Side by Side Diff: src/pkg/os/user/lookup_unix.go

Issue 4440057: code review 4440057: os/user: new package to look up users (Closed)
Patch Set: diff -r 76be0b3eee98 https://go.googlecode.com/hg/ Created 13 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/os/user/lookup_stubs.go ('k') | src/pkg/os/user/user.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 package user
6
7 import (
8 "fmt"
9 "os"
10 "runtime"
11 "strings"
12 "unsafe"
13 )
14
15 /*
16 #include <unistd.h>
17 #include <sys/types.h>
18 #include <pwd.h>
19 #include <stdlib.h>
20
21 static int mygetpwuid_r(int uid, struct passwd *pwd,
22 char *buf, size_t buflen, struct passwd **result) {
23 return getpwuid_r(uid, pwd, buf, buflen, result);
24 }
25 */
26 import "C"
27
28 // Lookup looks up a user by username. If the user cannot be found,
29 // the returned error is of type UnknownUserError.
30 func Lookup(username string) (*User, os.Error) {
31 return lookup(-1, username, true)
32 }
33
34 // LookupId looks up a user by userid. If the user cannot be found,
35 // the returned error is of type UnknownUserIdError.
36 func LookupId(uid int) (*User, os.Error) {
37 return lookup(uid, "", false)
38 }
39
40 func lookup(uid int, username string, lookupByName bool) (*User, os.Error) {
41 var pwd C.struct_passwd
42 var result *C.struct_passwd
43
44 var bufSize C.long
45 if runtime.GOOS == "freebsd" {
46 // FreeBSD doesn't have _SC_GETPW_R_SIZE_MAX
47 // and just returns -1. So just use the same
48 // size that Linux returns
49 bufSize = 1024
50 } else {
51 bufSize = C.sysconf(C._SC_GETPW_R_SIZE_MAX)
52 if bufSize <= 0 || bufSize > 1<<20 {
53 return nil, fmt.Errorf("user: unreasonable _SC_GETPW_R_S IZE_MAX of %d", bufSize)
54 }
55 }
56 buf := C.malloc(C.size_t(bufSize))
57 defer C.free(buf)
58 var rv C.int
59 if lookupByName {
60 nameC := C.CString(username)
61 defer C.free(unsafe.Pointer(nameC))
62 rv = C.getpwnam_r(nameC,
63 &pwd,
64 (*C.char)(buf),
65 C.size_t(bufSize),
66 &result)
67 if rv != 0 {
68 return nil, fmt.Errorf("user: lookup username %s: %s", u sername, os.Errno(rv))
69 }
70 if result == nil {
71 return nil, UnknownUserError(username)
72 }
73 } else {
74 // mygetpwuid_r is a wrapper around getpwuid_r to
75 // to avoid using uid_t because C.uid_t(uid) for
76 // unknown reasons doesn't work on linux.
77 rv = C.mygetpwuid_r(C.int(uid),
78 &pwd,
79 (*C.char)(buf),
80 C.size_t(bufSize),
81 &result)
82 if rv != 0 {
83 return nil, fmt.Errorf("user: lookup userid %d: %s", uid , os.Errno(rv))
84 }
85 if result == nil {
86 return nil, UnknownUserIdError(uid)
87 }
88 }
89 u := &User{
90 Uid: int(pwd.pw_uid),
91 Gid: int(pwd.pw_gid),
92 Username: C.GoString(pwd.pw_name),
93 Name: C.GoString(pwd.pw_gecos),
94 HomeDir: C.GoString(pwd.pw_dir),
95 }
96 // The pw_gecos field isn't quite standardized. Some docs
97 // say: "It is expected to be a comma separated list of
98 // personal data where the first item is the full name of the
99 // user."
100 if i := strings.Index(u.Name, ","); i >= 0 {
101 u.Name = u.Name[:i]
102 }
103 return u, nil
104 }
OLDNEW
« no previous file with comments | « src/pkg/os/user/lookup_stubs.go ('k') | src/pkg/os/user/user.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b