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  }