2018-02-05 16:05:59 -05:00
|
|
|
package homedir // import "github.com/docker/docker/pkg/homedir"
|
2016-12-16 04:50:14 -05:00
|
|
|
|
|
|
|
import (
|
2018-10-15 03:52:53 -04:00
|
|
|
"errors"
|
2016-12-16 04:50:14 -05:00
|
|
|
"os"
|
2018-10-15 03:52:53 -04:00
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2016-12-16 04:50:14 -05:00
|
|
|
|
|
|
|
"github.com/docker/docker/pkg/idtools"
|
|
|
|
)
|
|
|
|
|
|
|
|
// GetStatic returns the home directory for the current user without calling
|
|
|
|
// os/user.Current(). This is useful for static-linked binary on glibc-based
|
|
|
|
// system, because a call to os/user.Current() in a static binary leads to
|
|
|
|
// segfault due to a glibc issue that won't be fixed in a short term.
|
|
|
|
// (#29344, golang/go#13470, https://sourceware.org/bugzilla/show_bug.cgi?id=19341)
|
|
|
|
func GetStatic() (string, error) {
|
|
|
|
uid := os.Getuid()
|
|
|
|
usr, err := idtools.LookupUID(uid)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return usr.Home, nil
|
|
|
|
}
|
2018-10-15 03:52:53 -04:00
|
|
|
|
|
|
|
// GetRuntimeDir returns XDG_RUNTIME_DIR.
|
|
|
|
// XDG_RUNTIME_DIR is typically configured via pam_systemd.
|
|
|
|
// GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set.
|
|
|
|
//
|
|
|
|
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
|
|
|
|
func GetRuntimeDir() (string, error) {
|
|
|
|
if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {
|
|
|
|
return xdgRuntimeDir, nil
|
|
|
|
}
|
|
|
|
return "", errors.New("could not get XDG_RUNTIME_DIR")
|
|
|
|
}
|
|
|
|
|
|
|
|
// StickRuntimeDirContents sets the sticky bit on files that are under
|
|
|
|
// XDG_RUNTIME_DIR, so that the files won't be periodically removed by the system.
|
|
|
|
//
|
|
|
|
// StickyRuntimeDir returns slice of sticked files.
|
|
|
|
// StickyRuntimeDir returns nil error if XDG_RUNTIME_DIR is not set.
|
|
|
|
//
|
|
|
|
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
|
|
|
|
func StickRuntimeDirContents(files []string) ([]string, error) {
|
|
|
|
runtimeDir, err := GetRuntimeDir()
|
|
|
|
if err != nil {
|
|
|
|
// ignore error if runtimeDir is empty
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
runtimeDir, err = filepath.Abs(runtimeDir)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var sticked []string
|
|
|
|
for _, f := range files {
|
|
|
|
f, err = filepath.Abs(f)
|
|
|
|
if err != nil {
|
|
|
|
return sticked, err
|
|
|
|
}
|
|
|
|
if strings.HasPrefix(f, runtimeDir+"/") {
|
|
|
|
if err = stick(f); err != nil {
|
|
|
|
return sticked, err
|
|
|
|
}
|
|
|
|
sticked = append(sticked, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sticked, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func stick(f string) error {
|
|
|
|
st, err := os.Stat(f)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
m := st.Mode()
|
|
|
|
m |= os.ModeSticky
|
|
|
|
return os.Chmod(f, m)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetDataHome returns XDG_DATA_HOME.
|
|
|
|
// GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set.
|
|
|
|
//
|
|
|
|
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
|
|
|
|
func GetDataHome() (string, error) {
|
|
|
|
if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" {
|
|
|
|
return xdgDataHome, nil
|
|
|
|
}
|
|
|
|
home := os.Getenv("HOME")
|
|
|
|
if home == "" {
|
|
|
|
return "", errors.New("could not get either XDG_DATA_HOME or HOME")
|
|
|
|
}
|
|
|
|
return filepath.Join(home, ".local", "share"), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetConfigHome returns XDG_CONFIG_HOME.
|
|
|
|
// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
|
|
|
|
//
|
|
|
|
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
|
|
|
|
func GetConfigHome() (string, error) {
|
|
|
|
if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
|
|
|
|
return xdgConfigHome, nil
|
|
|
|
}
|
|
|
|
home := os.Getenv("HOME")
|
|
|
|
if home == "" {
|
|
|
|
return "", errors.New("could not get either XDG_CONFIG_HOME or HOME")
|
|
|
|
}
|
|
|
|
return filepath.Join(home, ".config"), nil
|
|
|
|
}
|