github.com/devdivbcp/moby@v17.12.0-ce-rc1.0.20200726071732-2d4bfdc789ad+incompatible/pkg/homedir/homedir_linux.go (about) 1 package homedir // import "github.com/docker/docker/pkg/homedir" 2 3 import ( 4 "errors" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/docker/docker/pkg/idtools" 10 ) 11 12 // GetStatic returns the home directory for the current user without calling 13 // os/user.Current(). This is useful for static-linked binary on glibc-based 14 // system, because a call to os/user.Current() in a static binary leads to 15 // segfault due to a glibc issue that won't be fixed in a short term. 16 // (#29344, golang/go#13470, https://sourceware.org/bugzilla/show_bug.cgi?id=19341) 17 func GetStatic() (string, error) { 18 uid := os.Getuid() 19 usr, err := idtools.LookupUID(uid) 20 if err != nil { 21 return "", err 22 } 23 return usr.Home, nil 24 } 25 26 // GetRuntimeDir returns XDG_RUNTIME_DIR. 27 // XDG_RUNTIME_DIR is typically configured via pam_systemd. 28 // GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set. 29 // 30 // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html 31 func GetRuntimeDir() (string, error) { 32 if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" { 33 return xdgRuntimeDir, nil 34 } 35 return "", errors.New("could not get XDG_RUNTIME_DIR") 36 } 37 38 // StickRuntimeDirContents sets the sticky bit on files that are under 39 // XDG_RUNTIME_DIR, so that the files won't be periodically removed by the system. 40 // 41 // StickyRuntimeDir returns slice of sticked files. 42 // StickyRuntimeDir returns nil error if XDG_RUNTIME_DIR is not set. 43 // 44 // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html 45 func StickRuntimeDirContents(files []string) ([]string, error) { 46 runtimeDir, err := GetRuntimeDir() 47 if err != nil { 48 // ignore error if runtimeDir is empty 49 return nil, nil 50 } 51 runtimeDir, err = filepath.Abs(runtimeDir) 52 if err != nil { 53 return nil, err 54 } 55 var sticked []string 56 for _, f := range files { 57 f, err = filepath.Abs(f) 58 if err != nil { 59 return sticked, err 60 } 61 if strings.HasPrefix(f, runtimeDir+"/") { 62 if err = stick(f); err != nil { 63 return sticked, err 64 } 65 sticked = append(sticked, f) 66 } 67 } 68 return sticked, nil 69 } 70 71 func stick(f string) error { 72 st, err := os.Stat(f) 73 if err != nil { 74 return err 75 } 76 m := st.Mode() 77 m |= os.ModeSticky 78 return os.Chmod(f, m) 79 } 80 81 // GetDataHome returns XDG_DATA_HOME. 82 // GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set. 83 // 84 // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html 85 func GetDataHome() (string, error) { 86 if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" { 87 return xdgDataHome, nil 88 } 89 home := os.Getenv("HOME") 90 if home == "" { 91 return "", errors.New("could not get either XDG_DATA_HOME or HOME") 92 } 93 return filepath.Join(home, ".local", "share"), nil 94 } 95 96 // GetConfigHome returns XDG_CONFIG_HOME. 97 // GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set. 98 // 99 // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html 100 func GetConfigHome() (string, error) { 101 if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { 102 return xdgConfigHome, nil 103 } 104 home := os.Getenv("HOME") 105 if home == "" { 106 return "", errors.New("could not get either XDG_CONFIG_HOME or HOME") 107 } 108 return filepath.Join(home, ".config"), nil 109 }