github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/homedir/homedir_linux.go (about)

     1  package homedir // import "github.com/demonoid81/moby/pkg/homedir"
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  )
     9  
    10  // GetRuntimeDir returns XDG_RUNTIME_DIR.
    11  // XDG_RUNTIME_DIR is typically configured via pam_systemd.
    12  // GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set.
    13  //
    14  // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
    15  func GetRuntimeDir() (string, error) {
    16  	if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {
    17  		return xdgRuntimeDir, nil
    18  	}
    19  	return "", errors.New("could not get XDG_RUNTIME_DIR")
    20  }
    21  
    22  // StickRuntimeDirContents sets the sticky bit on files that are under
    23  // XDG_RUNTIME_DIR, so that the files won't be periodically removed by the system.
    24  //
    25  // StickyRuntimeDir returns slice of sticked files.
    26  // StickyRuntimeDir returns nil error if XDG_RUNTIME_DIR is not set.
    27  //
    28  // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
    29  func StickRuntimeDirContents(files []string) ([]string, error) {
    30  	runtimeDir, err := GetRuntimeDir()
    31  	if err != nil {
    32  		// ignore error if runtimeDir is empty
    33  		return nil, nil
    34  	}
    35  	runtimeDir, err = filepath.Abs(runtimeDir)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	var sticked []string
    40  	for _, f := range files {
    41  		f, err = filepath.Abs(f)
    42  		if err != nil {
    43  			return sticked, err
    44  		}
    45  		if strings.HasPrefix(f, runtimeDir+"/") {
    46  			if err = stick(f); err != nil {
    47  				return sticked, err
    48  			}
    49  			sticked = append(sticked, f)
    50  		}
    51  	}
    52  	return sticked, nil
    53  }
    54  
    55  func stick(f string) error {
    56  	st, err := os.Stat(f)
    57  	if err != nil {
    58  		return err
    59  	}
    60  	m := st.Mode()
    61  	m |= os.ModeSticky
    62  	return os.Chmod(f, m)
    63  }
    64  
    65  // GetDataHome returns XDG_DATA_HOME.
    66  // GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set.
    67  //
    68  // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
    69  func GetDataHome() (string, error) {
    70  	if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" {
    71  		return xdgDataHome, nil
    72  	}
    73  	home := os.Getenv("HOME")
    74  	if home == "" {
    75  		return "", errors.New("could not get either XDG_DATA_HOME or HOME")
    76  	}
    77  	return filepath.Join(home, ".local", "share"), nil
    78  }
    79  
    80  // GetConfigHome returns XDG_CONFIG_HOME.
    81  // GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
    82  //
    83  // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
    84  func GetConfigHome() (string, error) {
    85  	if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
    86  		return xdgConfigHome, nil
    87  	}
    88  	home := os.Getenv("HOME")
    89  	if home == "" {
    90  		return "", errors.New("could not get either XDG_CONFIG_HOME or HOME")
    91  	}
    92  	return filepath.Join(home, ".config"), nil
    93  }