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
7package user
8
9import (
10	"fmt"
11	"os"
12	"runtime"
13	"strconv"
14)
15
16var (
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
23func 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
68func 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
78func currentGID() string {
79	if id := os.Getgid(); id >= 0 {
80		return strconv.Itoa(id)
81	}
82	return ""
83}
84