aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2022-06-30 13:16:46 +0200
committerGitHub <noreply@github.com>2022-06-30 04:16:46 -0700
commitf50135a32e11c535e1dc3a8e9460c5b4e640ee86 (patch)
tree4531a75f5f099877cb8d672743abf03004171f4f /src/nvim/os
parent514e76e4b2903530922529c60bfbf32cadd257a3 (diff)
downloadrneovim-f50135a32e11c535e1dc3a8e9460c5b4e640ee86.tar.gz
rneovim-f50135a32e11c535e1dc3a8e9460c5b4e640ee86.tar.bz2
rneovim-f50135a32e11c535e1dc3a8e9460c5b4e640ee86.zip
feat: stdpath('run'), /tmp/nvim.user/ #18993
Problem: - Since c57f6b28d71d #8519, sockets are created in ~/.local/… but XDG spec says: "XDG_RUNTIME_DIR: Must be on the local filesystem", which implies that XDG_STATE_DIR is potentially non-local. - Not easy to inspect Nvim-created temp files (for debugging etc). Solution: - Store sockets in stdpath('run') ($XDG_RUNTIME_DIR). - Establish "/tmp/nvim.user/" as the tempdir root shared by all Nvims. - Make ok() actually useful. - Introduce assert_nolog(). closes #3517 closes #17093
Diffstat (limited to 'src/nvim/os')
-rw-r--r--src/nvim/os/env.c2
-rw-r--r--src/nvim/os/fs.c23
-rw-r--r--src/nvim/os/stdpaths.c12
-rw-r--r--src/nvim/os/users.c28
4 files changed, 50 insertions, 15 deletions
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 3a213605dc..2a7f7a221f 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -663,7 +663,7 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
// Get the user directory. If this fails the shell is used to expand
// ~user, which is slower and may fail on old versions of /bin/sh.
var = (*dst == NUL) ? NULL
- : (char_u *)os_get_user_directory((char *)dst + 1);
+ : (char_u *)os_get_userdir((char *)dst + 1);
mustfree = true;
if (var == NULL) {
expand_T xpc;
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 68da53c476..7c5e4f31d7 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -126,7 +126,7 @@ bool os_isrealdir(const char *name)
}
}
-/// Check if the given path is a directory or not.
+/// Check if the given path exists and is a directory.
///
/// @return `true` if `name` is a directory.
bool os_isdir(const char_u *name)
@@ -791,6 +791,27 @@ int os_setperm(const char *const name, int perm)
return (r == kLibuvSuccess ? OK : FAIL);
}
+#ifdef UNIX
+/// Checks if the current user owns a file.
+///
+/// Uses both uv_fs_stat() and uv_fs_lstat() via os_fileinfo() and
+/// os_fileinfo_link() respectively for extra security.
+bool os_file_owned(const char *fname)
+ FUNC_ATTR_NONNULL_ALL
+{
+ uid_t uid = getuid();
+ FileInfo finfo;
+ bool file_owned = os_fileinfo(fname, &finfo) && finfo.stat.st_uid == uid;
+ bool link_owned = os_fileinfo_link(fname, &finfo) && finfo.stat.st_uid == uid;
+ return file_owned && link_owned;
+}
+#else
+bool os_file_owned(const char *fname)
+{
+ return true; // TODO(justinmk): Windows. #8244
+}
+#endif
+
/// Changes the owner and group of a file, like chown(2).
///
/// @return 0 on success, or libuv error code on failure.
diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c
index a382392bd3..5576e7ba07 100644
--- a/src/nvim/os/stdpaths.c
+++ b/src/nvim/os/stdpaths.c
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include "nvim/ascii.h"
+#include "nvim/fileio.h"
#include "nvim/memory.h"
#include "nvim/os/os.h"
#include "nvim/os/stdpaths_defs.h"
@@ -26,7 +27,7 @@ static const char *const xdg_defaults_env_vars[] = {
[kXDGDataHome] = "LOCALAPPDATA",
[kXDGCacheHome] = "TEMP",
[kXDGStateHome] = "LOCALAPPDATA",
- [kXDGRuntimeDir] = NULL,
+ [kXDGRuntimeDir] = NULL, // Decided by vim_mktempdir().
[kXDGConfigDirs] = NULL,
[kXDGDataDirs] = NULL,
};
@@ -41,7 +42,7 @@ static const char *const xdg_defaults[] = {
[kXDGDataHome] = "~\\AppData\\Local",
[kXDGCacheHome] = "~\\AppData\\Local\\Temp",
[kXDGStateHome] = "~\\AppData\\Local",
- [kXDGRuntimeDir] = NULL,
+ [kXDGRuntimeDir] = NULL, // Decided by vim_mktempdir().
[kXDGConfigDirs] = NULL,
[kXDGDataDirs] = NULL,
#else
@@ -49,7 +50,7 @@ static const char *const xdg_defaults[] = {
[kXDGDataHome] = "~/.local/share",
[kXDGCacheHome] = "~/.cache",
[kXDGStateHome] = "~/.local/state",
- [kXDGRuntimeDir] = NULL,
+ [kXDGRuntimeDir] = NULL, // Decided by vim_mktempdir().
[kXDGConfigDirs] = "/etc/xdg/",
[kXDGDataDirs] = "/usr/local/share/:/usr/share/",
#endif
@@ -83,6 +84,11 @@ char *stdpaths_get_xdg_var(const XDGVarType idx)
ret = xstrdup(env_val);
} else if (fallback) {
ret = expand_env_save((char *)fallback);
+ } else if (idx == kXDGRuntimeDir) {
+ // Special-case: stdpath('run') is defined at startup.
+ ret = vim_gettempdir();
+ size_t len = strlen(ret);
+ ret = xstrndup(ret, len >= 2 ? len - 1 : 0); // Trim trailing slash.
}
return ret;
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index 9fe97dd5e4..bd34e917b2 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.c
@@ -112,9 +112,13 @@ int os_get_usernames(garray_T *users)
return OK;
}
-// Insert user name in s[len].
-// Return OK if a name found.
-int os_get_user_name(char *s, size_t len)
+/// Gets the username that owns the current Nvim process.
+///
+/// @param s[out] Username.
+/// @param len Length of `s`.
+///
+/// @return OK if a name found.
+int os_get_username(char *s, size_t len)
{
#ifdef UNIX
return os_get_uname((uv_uid_t)getuid(), s, len);
@@ -124,9 +128,13 @@ int os_get_user_name(char *s, size_t len)
#endif
}
-// Insert user name for "uid" in s[len].
-// Return OK if a name found.
-// If the name is not found, write the uid into s[len] and return FAIL.
+/// Gets the username associated with `uid`.
+///
+/// @param uid User id.
+/// @param s[out] Username, or `uid` on failure.
+/// @param len Length of `s`.
+///
+/// @return OK if a username was found, else FAIL.
int os_get_uname(uv_uid_t uid, char *s, size_t len)
{
#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
@@ -142,10 +150,10 @@ int os_get_uname(uv_uid_t uid, char *s, size_t len)
return FAIL; // a number is not a name
}
-// Returns the user directory for the given username.
-// The caller has to free() the returned string.
-// If the username is not found, NULL is returned.
-char *os_get_user_directory(const char *name)
+/// Gets the user directory for the given username, or NULL on failure.
+///
+/// Caller must free() the returned string.
+char *os_get_userdir(const char *name)
{
#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
if (name == NULL || *name == NUL) {