diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/fileio.c | 148 | ||||
-rw-r--r-- | src/nvim/lua/vim.lua | 13 | ||||
-rw-r--r-- | src/nvim/memfile.c | 3 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 35 | ||||
-rw-r--r-- | src/nvim/os_unix.c | 53 | ||||
-rw-r--r-- | src/nvim/undo.c | 4 |
6 files changed, 70 insertions, 186 deletions
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 8e4a210b66..b468b7bb8c 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -2781,20 +2781,12 @@ buf_write ( else backup_ext = p_bex; - if (backup_copy && (fd = os_open((char *)fname, O_RDONLY, 0)) >= 0) { - int bfd; - char_u *copybuf, *wp; - int some_error = FALSE; + if (backup_copy) { + char_u *wp; + int some_error = false; char_u *dirp; char_u *rootname; - copybuf = verbose_try_malloc(BUFSIZE + 1); - if (copybuf == NULL) { - // out of memory - some_error = TRUE; - goto nobackup; - } - /* * Try to make the backup in each directory in the 'bdir' option. * @@ -2812,8 +2804,8 @@ buf_write ( /* * Isolate one directory name, using an entry in 'bdir'. */ - (void)copy_option_part(&dirp, copybuf, BUFSIZE, ","); - rootname = get_file_in_dir(fname, copybuf); + (void)copy_option_part(&dirp, IObuff, IOSIZE, ","); + rootname = get_file_in_dir(fname, IObuff); if (rootname == NULL) { some_error = TRUE; /* out of memory */ goto nobackup; @@ -2875,87 +2867,44 @@ buf_write ( if (backup != NULL) { /* remove old backup, if present */ os_remove((char *)backup); - /* Open with O_EXCL to avoid the file being created while - * we were sleeping (symlink hacker attack?) */ - bfd = os_open((char *)backup, - O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW, - perm & 0777); - if (bfd < 0) { - xfree(backup); - backup = NULL; - } else { - // set file protection same as original file, but - // strip s-bit. - (void)os_setperm((const char *)backup, perm & 0777); + + // set file protection same as original file, but + // strip s-bit. + (void)os_setperm((const char *)backup, perm & 0777); #ifdef UNIX - /* - * Try to set the group of the backup same as the - * original file. If this fails, set the protection - * bits for the group same as the protection bits for - * others. - */ - if (file_info_new.stat.st_gid != file_info_old.stat.st_gid - && os_fchown(bfd, -1, file_info_old.stat.st_gid) != 0) { - os_setperm((const char *)backup, - (perm & 0707) | ((perm & 07) << 3)); - } -# ifdef HAVE_SELINUX - mch_copy_sec(fname, backup); -# endif + // + // Try to set the group of the backup same as the original file. If + // this fails, set the protection bits for the group same as the + // protection bits for others. + // + if (file_info_new.stat.st_gid != file_info_old.stat.st_gid + && os_chown((char *)backup, -1, file_info_old.stat.st_gid) != 0) { + os_setperm((const char *)backup, + (perm & 0707) | ((perm & 07) << 3)); + } #endif - /* - * copy the file. - */ - write_info.bw_fd = bfd; - write_info.bw_buf = copybuf; -#ifdef HAS_BW_FLAGS - write_info.bw_flags = FIO_NOCONVERT; -#endif - while ((write_info.bw_len = read_eintr(fd, copybuf, - BUFSIZE)) > 0) { - if (buf_write_bytes(&write_info) == FAIL) { - SET_ERRMSG(_( - "E506: Can't write to backup file (add ! to override)")); - break; - } - os_breakcheck(); - if (got_int) { - SET_ERRMSG(_(e_interr)); - break; - } - } + // copy the file + if (os_copy((char *)fname, (char *)backup, UV_FS_COPYFILE_FICLONE) + != 0) { + SET_ERRMSG(_("E506: Can't write to backup file " + "(add ! to override)")); + } - int error; - if ((error = os_close(bfd)) != 0 && errmsg == NULL) { - SET_ERRMSG_ARG(_("E507: Close error for backup file " - "(add ! to override): %s"), - error); - } - if (write_info.bw_len < 0) { - SET_ERRMSG(_( - "E508: Can't read file for backup (add ! to override)")); - } #ifdef UNIX - set_file_time(backup, - file_info_old.stat.st_atim.tv_sec, - file_info_old.stat.st_mtim.tv_sec); + set_file_time(backup, + file_info_old.stat.st_atim.tv_sec, + file_info_old.stat.st_mtim.tv_sec); #endif #ifdef HAVE_ACL - mch_set_acl(backup, acl); -#endif -#ifdef HAVE_SELINUX - mch_copy_sec(fname, backup); + mch_set_acl(backup, acl); #endif - break; - } + break; } } -nobackup: - os_close(fd); // Ignore errors for closing read file. - xfree(copybuf); +nobackup: if (backup == NULL && errmsg == NULL) { SET_ERRMSG(_( "E509: Cannot create backup file (add ! to override)")); @@ -3433,13 +3382,6 @@ restore_backup: end = 0; } -#ifdef HAVE_SELINUX - // Probably need to set the security context. - if (!backup_copy) { - mch_copy_sec(backup, wfname); - } -#endif - #ifdef UNIX // When creating a new file, set its owner/group to that of the original // file. Get the new device and inode number. @@ -3537,28 +3479,11 @@ restore_backup: MSG(_(e_interr)); ui_flush(); } - if ((fd = os_open((char *)backup, O_RDONLY, 0)) >= 0) { - if ((write_info.bw_fd = os_open((char *)fname, - O_WRONLY | O_CREAT | O_TRUNC, - perm & 0777)) >= 0) { - // copy the file. - write_info.bw_buf = smallbuf; -#ifdef HAS_BW_FLAGS - write_info.bw_flags = FIO_NOCONVERT; -#endif - while ((write_info.bw_len = read_eintr(fd, smallbuf, - SMBUFSIZE)) > 0) { - if (buf_write_bytes(&write_info) == FAIL) { - break; - } - } - if (close(write_info.bw_fd) >= 0 - && write_info.bw_len == 0) { - end = 1; // success - } - } - close(fd); // ignore errors for closing read file + // copy the file. + if (os_copy((char *)backup, (char *)fname, UV_FS_COPYFILE_FICLONE) + == 0) { + end = 1; // success } } else { if (vim_rename(backup, fname) == 0) { @@ -4825,9 +4750,6 @@ int vim_rename(const char_u *from, const char_u *to) mch_set_acl(to, acl); mch_free_acl(acl); #endif -#ifdef HAVE_SELINUX - mch_copy_sec(from, to); -#endif if (errmsg != NULL) { EMSG2(errmsg, to); return -1; diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 38a8795680..848bccaae6 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -154,15 +154,11 @@ local function _update_package_paths() last_nvim_paths = cur_nvim_paths end ---- Trim whitespace (Lua pattern "%%s") from both sides of a string. +--- Return a human-readable representation of the given object. --- ---@see https://www.lua.org/pil/20.2.html ---@param s String to trim ---@returns String with whitespace removed from its beginning and end -local function trim(s) - assert(type(s) == 'string', 'Only strings can be trimmed') - local result = s:gsub('^%s+', ''):gsub('%s+$', '') - return result +--@see https://github.com/kikito/inspect.lua +local function inspect(object, options) -- luacheck: no unused + error(object, options) -- Stub for gen_vimdoc.py end local function __index(t, key) @@ -181,7 +177,6 @@ local module = { _os_proc_children = _os_proc_children, _os_proc_info = _os_proc_info, _system = _system, - trim = trim, } setmetatable(module, { diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 0a16f8aafb..5a64c82e0e 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -785,9 +785,6 @@ static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags) } (void)os_set_cloexec(mfp->mf_fd); -#ifdef HAVE_SELINUX - mch_copy_sec(fname, mfp->mf_fname); -#endif return true; } diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 8d9de1253e..d5500b230c 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -643,6 +643,21 @@ ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, return (ptrdiff_t)written_bytes; } +/// Copies a file from `path` to `new_path`. +/// +/// @see http://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_copyfile +/// +/// @param path Path of file to be copied +/// @param path_new Path of new file +/// @param flags Bitwise OR of flags defined in <uv.h> +/// @return 0 on success, or libuv error code on failure. +int os_copy(const char *path, const char *new_path, int flags) +{ + int r; + RUN_UV_FS_FUNC(r, uv_fs_copyfile, path, new_path, flags, NULL); + return r; +} + /// Flushes file modifications to disk. /// /// @param fd the file descriptor of the file to flush to disk. @@ -697,12 +712,24 @@ int os_setperm(const char *const name, int perm) return (r == kLibuvSuccess ? OK : FAIL); } -/// Changes the ownership of the file referred to by the open file descriptor. +/// Changes the owner and group of a file, like chown(2). /// -/// @return `0` on success, a libuv error code on failure. +/// @return 0 on success, or libuv error code on failure. +/// +/// @note If `owner` or `group` is -1, then that ID is not changed. +int os_chown(const char *path, uv_uid_t owner, uv_gid_t group) +{ + int r; + RUN_UV_FS_FUNC(r, uv_fs_chown, path, owner, group, NULL); + return r; +} + +/// Changes the owner and group of the file referred to by the open file +/// descriptor, like fchown(2). +/// +/// @return 0 on success, or libuv error code on failure. /// -/// @note If the `owner` or `group` is specified as `-1`, then that ID is not -/// changed. +/// @note If `owner` or `group` is -1, then that ID is not changed. int os_fchown(int fd, uv_uid_t owner, uv_gid_t group) { int r; diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 351350d939..8180a2e8ac 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -45,12 +45,6 @@ #include "nvim/os/signal.h" #include "nvim/msgpack_rpc/helpers.h" -#ifdef HAVE_SELINUX -# include <selinux/selinux.h> -static int selinux_enabled = -1; -#endif - - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os_unix.c.generated.h" #endif @@ -64,53 +58,6 @@ static int selinux_enabled = -1; # endif -#if defined(HAVE_SELINUX) -// Copy security info from "from_file" to "to_file". -void mch_copy_sec(char_u *from_file, char_u *to_file) -{ - if (from_file == NULL) - return; - - if (selinux_enabled == -1) - selinux_enabled = is_selinux_enabled(); - - if (selinux_enabled > 0) { - security_context_t from_context = NULL; - security_context_t to_context = NULL; - - if (getfilecon((char *)from_file, &from_context) < 0) { - // If the filesystem doesn't support extended attributes, - // the original had no special security context and the - // target cannot have one either. - if (errno == EOPNOTSUPP) { - return; - } - - MSG_PUTS(_("\nCould not get security context for ")); - msg_outtrans(from_file); - msg_putchar('\n'); - return; - } - if (getfilecon((char *)to_file, &to_context) < 0) { - MSG_PUTS(_("\nCould not get security context for ")); - msg_outtrans(to_file); - msg_putchar('\n'); - freecon (from_context); - return; - } - if (strcmp(from_context, to_context) != 0) { - if (setfilecon((char *)to_file, from_context) < 0) { - MSG_PUTS(_("\nCould not set security context for ")); - msg_outtrans(to_file); - msg_putchar('\n'); - } - } - freecon(to_context); - freecon(from_context); - } -} -#endif // HAVE_SELINUX - // Return a pointer to the ACL of file "fname" in allocated memory. // Return NULL if the ACL is not available for whatever reason. vim_acl_T mch_get_acl(const char_u *fname) diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 10996d99d5..2cc3e928f7 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1169,10 +1169,6 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, && os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) { os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3)); } -# ifdef HAVE_SELINUX - if (buf->b_ffname != NULL) - mch_copy_sec(buf->b_ffname, file_name); -# endif #endif fp = fdopen(fd, "w"); |