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 //go:build (!cgo && !darwin && !windows && !plan9) || android || (osusergo && !windows && !plan9)
6 7 package user
8 9 import (
10 "fmt"
11 "os"
12 "runtime"
13 "strconv"
14 )
15 16 var (
17 // unused variables (in this implementation)
18 // modified during test to exercise code paths in the cgo implementation.
19 userBuffer = 0
20 groupBuffer = 0
21 )
22 23 func current() (*User, error) {
24 uid := currentUID()
25 // $USER and /etc/passwd may disagree; prefer the latter if we can get it.
26 // See issue 27524 for more information.
27 u, err := lookupUserId(uid)
28 if err == nil {
29 return u, nil
30 }
31 32 homeDir, _ := os.UserHomeDir()
33 u = &User{
34 Uid: uid,
35 Gid: currentGID(),
36 Username: os.Getenv("USER"),
37 Name: "", // ignored
38 HomeDir: homeDir,
39 }
40 // On Android, return a dummy user instead of failing.
41 switch runtime.GOOS {
42 case "android":
43 if u.Uid == "" {
44 u.Uid = "1"
45 }
46 if u.Username == "" {
47 u.Username = "android"
48 }
49 }
50 // cgo isn't available, but if we found the minimum information
51 // without it, use it:
52 if u.Uid != "" && u.Username != "" && u.HomeDir != "" {
53 return u, nil
54 }
55 var missing string
56 if u.Username == "" {
57 missing = "$USER"
58 }
59 if u.HomeDir == "" {
60 if missing != "" {
61 missing += ", "
62 }
63 missing += "$HOME"
64 }
65 return u, fmt.Errorf("user: Current requires cgo or %s set in environment", missing)
66 }
67 68 func currentUID() string {
69 if id := os.Getuid(); id >= 0 {
70 return strconv.Itoa(id)
71 }
72 // Note: Windows returns -1, but this file isn't used on
73 // Windows anyway, so this empty return path shouldn't be
74 // used.
75 return ""
76 }
77 78 func currentGID() string {
79 if id := os.Getgid(); id >= 0 {
80 return strconv.Itoa(id)
81 }
82 return ""
83 }
84