diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2022-06-30 13:16:46 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-30 04:16:46 -0700 |
commit | f50135a32e11c535e1dc3a8e9460c5b4e640ee86 (patch) | |
tree | 4531a75f5f099877cb8d672743abf03004171f4f /src/nvim/os | |
parent | 514e76e4b2903530922529c60bfbf32cadd257a3 (diff) | |
download | rneovim-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.c | 2 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 23 | ||||
-rw-r--r-- | src/nvim/os/stdpaths.c | 12 | ||||
-rw-r--r-- | src/nvim/os/users.c | 28 |
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) { |