diff options
-rw-r--r-- | src/ex_cmds.c | 10 | ||||
-rw-r--r-- | src/fileio.c | 33 | ||||
-rw-r--r-- | src/os/fs.c | 10 | ||||
-rw-r--r-- | src/os/os.h | 1 | ||||
-rw-r--r-- | test/unit/os/fs.moon | 18 |
5 files changed, 33 insertions, 39 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 3d177b86af..65c71cdcb2 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -2496,15 +2496,11 @@ int not_writing(void) */ static int check_readonly(int *forceit, buf_T *buf) { - struct stat st; - /* Handle a file being readonly when the 'readonly' option is set or when - * the file exists and permissions are read-only. - * We will send 0777 to check_file_readonly(), as the "perm" variable is - * important for device checks but not here. */ + * the file exists and permissions are read-only. */ if (!*forceit && (buf->b_p_ro - || (mch_stat((char *)buf->b_ffname, &st) >= 0 - && check_file_readonly(buf->b_ffname, 0777)))) { + || (os_file_exists(buf->b_ffname) + && os_file_is_readonly((char *)buf->b_ffname)))) { if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL) { char_u buff[DIALOG_MSG_SIZE]; diff --git a/src/fileio.c b/src/fileio.c index bf3a6dfb95..62e2b6fac1 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -71,9 +71,6 @@ static int crypt_seed_len[] = {0, 8}; #define CRYPT_SALT_LEN_MAX 8 #define CRYPT_SEED_LEN_MAX 8 -/* Is there any system that doesn't have access()? */ -#define USE_MCH_ACCESS - static char_u *next_fenc(char_u **pp); static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp); @@ -2443,34 +2440,6 @@ set_file_time ( } #endif /* UNIX */ - -/* - * Return TRUE if a file appears to be read-only from the file permissions. - */ -int -check_file_readonly ( - char_u *fname, /* full path to file */ - int perm /* known permissions on file */ -) -{ -#ifndef USE_MCH_ACCESS - int fd = 0; -#endif - - return -#ifdef USE_MCH_ACCESS -# ifdef UNIX - (perm & 0222) == 0 || -# endif - mch_access((char *)fname, W_OK) -#else - (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0 - ? TRUE : (close(fd), FALSE) -#endif - ; -} - - /* * buf_write() - write to file "fname" lines "start" through "end" * @@ -2887,7 +2856,7 @@ buf_write ( * Check if the file is really writable (when renaming the file to * make a backup we won't discover it later). */ - file_readonly = check_file_readonly(fname, (int)perm); + file_readonly = os_file_is_readonly((char *)fname); if (!forceit && file_readonly) { if (vim_strchr(p_cpo, CPO_FWRITE) != NULL) { diff --git a/src/os/fs.c b/src/os/fs.c index 711262740e..71dee4dd3d 100644 --- a/src/os/fs.c +++ b/src/os/fs.c @@ -278,3 +278,13 @@ int os_file_exists(const char_u *name) } } +// return TRUE if a file appears to be read-only from the file permissions. +int os_file_is_readonly(const char *name) +{ + if (mch_access(name, W_OK) == 0) { + return FALSE; + } else { + return TRUE; + } +} + diff --git a/src/os/os.h b/src/os/os.h index 6a5bb156cd..e4f5af5057 100644 --- a/src/os/os.h +++ b/src/os/os.h @@ -68,5 +68,6 @@ int os_get_usernames(garray_T *usernames); int os_get_user_name(char *s, size_t len); int os_get_uname(uid_t uid, char *s, size_t len); char *os_get_user_directory(const char *name); +int os_file_is_readonly(const char *name); #endif // NEOVIM_OS_OS_H diff --git a/test/unit/os/fs.moon b/test/unit/os/fs.moon index 44dd3a123e..82414186d9 100644 --- a/test/unit/os/fs.moon +++ b/test/unit/os/fs.moon @@ -19,6 +19,7 @@ int os_can_exe(char_u *name); int32_t os_getperm(char_u *name); int os_setperm(char_u *name, long perm); int os_file_exists(const char_u *name); +int os_file_is_readonly(char *fname); ]] -- import constants parsed by ffi @@ -282,6 +283,9 @@ describe 'fs function', -> os_setperm = (filename, perm) -> fs.os_setperm (to_cstr filename), perm + os_file_is_readonly = (filename) -> + fs.os_file_is_readonly (to_cstr filename) + bit_set = (number, check_bit) -> if 0 == (bit.band number, check_bit) then false else true @@ -322,6 +326,20 @@ describe 'fs function', -> perm = ffi.C.kS_IXUSR eq FAIL, (os_setperm 'non-existing-file', perm) + describe 'os_file_is_readonly', -> + it 'returns TRUE if the file is readonly', -> + perm = os_getperm 'unit-test-directory/test.file' + perm_orig = perm + perm = unset_bit perm, ffi.C.kS_IWUSR + perm = unset_bit perm, ffi.C.kS_IWGRP + perm = unset_bit perm, ffi.C.kS_IWOTH + eq OK, (os_setperm 'unit-test-directory/test.file', perm) + eq TRUE, os_file_is_readonly 'unit-test-directory/test.file' + eq OK, (os_setperm 'unit-test-directory/test.file', perm_orig) + + it 'returns FALSE if the file is writable', -> + eq FALSE, os_file_is_readonly 'unit-test-directory/test.file' + describe 'os_file_exists', -> os_file_exists = (filename) -> fs.os_file_exists (to_cstr filename) |