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

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 c4b835aa75c1 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
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 // LookupId looks up a user by username. If the user isn't found,
r 2011/04/21 20:39:32 s/isn't/cannot be/ here and below
29 // os.ENOENT is returned.
r 2011/04/21 20:39:32 is this overspecifying the error return? we usual
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 isn't found,
35 // os.ENOENT is returned.
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 }
53 if bufSize <= 0 || bufSize > 1<<20 {
r 2011/04/21 20:39:32 this test can go up a line
54 return nil, fmt.Errorf("user: unreasonable _SC_GETPW_R_SIZE_MAX of %d", bufSize)
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 } else {
68 // mygetpwuid_r is a wrapper around getpwuid_r to
69 // to avoid using uid_t because C.uid_t(uid) for
70 // unknown reasons doesn't work on linux.
71 rv = C.mygetpwuid_r(C.int(uid),
72 &pwd,
73 (*C.char)(buf),
74 C.size_t(bufSize),
75 &result)
76 }
77 if rv != 0 {
78 return nil, fmt.Errorf("user: getpwuid_r returned %d", rv)
79 }
80 if result == nil {
81 return nil, os.ENOENT
82 }
83 u := &User{
84 Uid: int(pwd.pw_uid),
85 Gid: int(pwd.pw_gid),
86 Username: C.GoString(pwd.pw_name),
87 Name: C.GoString(pwd.pw_gecos),
88 HomeDirectory: C.GoString(pwd.pw_dir),
89 }
90 // The pw_gecos field isn't quite standardized. Some docs
91 // says: "It is expected to be a comma separated list of
92 // personal data where the first item is the full name of the
93 // user."
94 if strings.Contains(u.Name, ",") {
95 sp := strings.Split(u.Name, ",", 2)
96 u.Name = sp[0]
97 }
98 return u, nil
99 }
OLDNEW

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