diff --git a/README.md b/README.md
index 291bd53..9ccfb62 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,7 @@ Sensible fallback locations are used for the folders which are not set.
| XDG_CONFIG_DIRS | /etc/xdg | ~/Library/Preferences
/Library/Application Support
/Library/Preferences
~/.config | /lib |
| XDG_STATE_HOME | ~/.local/state | ~/Library/Application Support | $home/lib/state |
| XDG_CACHE_HOME | ~/.cache | ~/Library/Caches | $home/lib/cache |
-| XDG_RUNTIME_DIR | /run/user/UID | ~/Library/Application Support | /tmp |
+| XDG_RUNTIME_DIR | /run/user/$UID | ~/Library/Application Support | /tmp |
| XDG_BIN_HOME | ~/.local/bin | ~/.local/bin | $home/bin |
diff --git a/base_dirs.go b/base_dirs.go
index fc482e2..0cdca02 100644
--- a/base_dirs.go
+++ b/base_dirs.go
@@ -1,6 +1,10 @@
package xdg
-import "github.com/adrg/xdg/internal/pathutil"
+import (
+ "os"
+
+ "github.com/adrg/xdg/internal/pathutil"
+)
// XDG Base Directory environment variables.
const (
@@ -48,7 +52,13 @@ func (bd baseDirectories) cacheFile(relPath string) (string, error) {
}
func (bd baseDirectories) runtimeFile(relPath string) (string, error) {
- return pathutil.Create(relPath, []string{bd.runtime})
+ var paths []string
+ for _, p := range pathutil.Unique([]string{bd.runtime, os.TempDir()}) {
+ if pathutil.Exists(p) {
+ paths = append(paths, p)
+ }
+ }
+ return pathutil.Create(relPath, paths)
}
func (bd baseDirectories) searchDataFile(relPath string) (string, error) {
diff --git a/internal/pathutil/pathutil.go b/internal/pathutil/pathutil.go
index 554eda6..981580d 100644
--- a/internal/pathutil/pathutil.go
+++ b/internal/pathutil/pathutil.go
@@ -4,7 +4,6 @@ import (
"fmt"
"os"
"path/filepath"
- "strings"
)
// Unique eliminates the duplicate paths from the provided slice and returns
@@ -52,7 +51,6 @@ func First(paths []string) string {
// relative to the selected parent path.
func Create(name string, paths []string) (string, error) {
searchedPaths := make([]string, 0, len(paths))
-
for _, p := range paths {
p = filepath.Join(p, name)
@@ -67,8 +65,8 @@ func Create(name string, paths []string) (string, error) {
searchedPaths = append(searchedPaths, dir)
}
- return "", fmt.Errorf("could not create any of the following paths: %s",
- strings.Join(searchedPaths, ", "))
+ return "", fmt.Errorf("could not create any of the following paths: %v",
+ searchedPaths)
}
// Search searches for the file with the specified `name` in the provided
@@ -76,7 +74,6 @@ func Create(name string, paths []string) (string, error) {
// but it can also contain a set of parent directories.
func Search(name string, paths []string) (string, error) {
searchedPaths := make([]string, 0, len(paths))
-
for _, p := range paths {
p = filepath.Join(p, name)
if Exists(p) {
@@ -86,8 +83,8 @@ func Search(name string, paths []string) (string, error) {
searchedPaths = append(searchedPaths, filepath.Dir(p))
}
- return "", fmt.Errorf("could not locate `%s` in any of the following paths: %s",
- filepath.Base(name), strings.Join(searchedPaths, ", "))
+ return "", fmt.Errorf("could not locate `%s` in any of the following paths: %v",
+ filepath.Base(name), searchedPaths)
}
// EnvPath returns the value of the environment variable with the specified
diff --git a/xdg.go b/xdg.go
index 654d1d7..059d695 100644
--- a/xdg.go
+++ b/xdg.go
@@ -161,8 +161,9 @@ func CacheFile(relPath string) (string, error) {
// The relPath parameter must contain the name of the runtime file, and
// optionally, a set of parent directories (e.g. appname/app.pid).
// If the specified directories do not exist, they will be created relative
-// to the base runtime directory. On failure, an error containing the
-// attempted paths is returned.
+// to the base runtime directory. If the base runtime directory does not exist,
+// the operating system's temporary directory is used as a fallback. On failure,
+// an error containing the attempted paths is returned.
func RuntimeFile(relPath string) (string, error) {
return baseDirs.runtimeFile(relPath)
}
diff --git a/xdg_test.go b/xdg_test.go
index 72e1910..53d0604 100644
--- a/xdg_test.go
+++ b/xdg_test.go
@@ -199,3 +199,20 @@ func TestInvalidPaths(t *testing.T) {
require.Error(t, err)
}
}
+
+func TestNonExistentRuntimeDir(t *testing.T) {
+ var (
+ envRuntimeDirVar = "XDG_RUNTIME_DIR"
+ originalRuntimeDir = xdg.RuntimeDir
+ nonExistentRuntimeDir = filepath.Join(xdg.Home, "runtime")
+ )
+ defer os.Setenv(envRuntimeDirVar, originalRuntimeDir)
+
+ require.NoError(t, os.Setenv(envRuntimeDirVar, nonExistentRuntimeDir))
+ xdg.Reload()
+ require.Equal(t, nonExistentRuntimeDir, xdg.RuntimeDir)
+
+ p, err := xdg.RuntimeFile("app.pid")
+ require.NoError(t, err)
+ require.Equal(t, filepath.Clean(os.TempDir()), filepath.Dir(p))
+}