aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ex_cmds.c10
-rw-r--r--src/fileio.c33
-rw-r--r--src/os/fs.c10
-rw-r--r--src/os/os.h1
-rw-r--r--test/unit/os/fs.moon18
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)