aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/os/fs.c9
-rw-r--r--test/includes/pre/sys/errno.h4
-rw-r--r--test/includes/pre/sys/fcntl.h7
-rw-r--r--test/unit/os/fs.moon71
4 files changed, 77 insertions, 14 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index ff8b8557de..dce95eb3c9 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -11,7 +11,6 @@
#include "nvim/misc2.h"
#include "nvim/path.h"
#include "nvim/strings.h"
-#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/fs.c.generated.h"
@@ -156,16 +155,16 @@ static bool is_executable_in_path(const char_u *name)
/// calls (read, write, lseek, fcntl, etc.). If the operation fails, `-errno`
/// is returned, and no file is created or modified.
///
-/// @param flags bitwise OR of flags defined in <fcntl.h>
-/// @param mode permissions for the newly-created file (IGNORED if 'flags' is
-/// not `O_CREAT` or `O_TMPFILE`)
+/// @param flags Bitwise OR of flags defined in <fcntl.h>
+/// @param mode Permissions for the newly-created file (IGNORED if 'flags' is
+/// not `O_CREAT` or `O_TMPFILE`), subject to the current umask
/// @return file descriptor, or negative `errno` on failure
int os_open(const char* path, int flags, int mode)
{
uv_fs_t open_req;
int r = uv_fs_open(uv_default_loop(), &open_req, path, flags, mode, NULL);
uv_fs_req_cleanup(&open_req);
- //`r` is the same as open_req.result, except when OOM. So just use `r`.
+ // r is the same as open_req.result (except for OOM: then only r is set).
return r;
}
diff --git a/test/includes/pre/sys/errno.h b/test/includes/pre/sys/errno.h
new file mode 100644
index 0000000000..0b8934d33e
--- /dev/null
+++ b/test/includes/pre/sys/errno.h
@@ -0,0 +1,4 @@
+#include <sys/errno.h>
+
+static const int kENOENT = ENOENT;
+static const int kEEXIST = EEXIST;
diff --git a/test/includes/pre/sys/fcntl.h b/test/includes/pre/sys/fcntl.h
new file mode 100644
index 0000000000..767c97a631
--- /dev/null
+++ b/test/includes/pre/sys/fcntl.h
@@ -0,0 +1,7 @@
+#include <sys/fcntl.h>
+
+static const mode_t kO_RDONLY = O_RDONLY;
+static const mode_t kO_WRONLY = O_WRONLY;
+static const mode_t kO_RDWR = O_RDWR;
+static const mode_t kO_CREAT = O_CREAT;
+static const mode_t kO_EXCL = O_EXCL;
diff --git a/test/unit/os/fs.moon b/test/unit/os/fs.moon
index 1d4d7448f5..a1445aeb0c 100644
--- a/test/unit/os/fs.moon
+++ b/test/unit/os/fs.moon
@@ -9,6 +9,14 @@ FAIL = 0
OK = 1
cppimport 'sys/stat.h'
+cppimport 'sys/fcntl.h'
+cppimport 'sys/errno.h'
+
+assert_file_exists = (filepath) ->
+ eq false, nil == (lfs.attributes filepath, 'r')
+
+assert_file_does_not_exist = (filepath) ->
+ eq true, nil == (lfs.attributes filepath, 'r')
describe 'fs function', ->
setup ->
@@ -217,12 +225,6 @@ describe 'fs function', ->
eq 2, os_file_is_writable 'unit-test-directory'
describe 'file operations', ->
- setup ->
- (io.open 'unit-test-directory/test_remove.file', 'w').close!
-
- teardown ->
- os.remove 'unit-test-directory/test_remove.file'
-
os_file_exists = (filename) ->
fs.os_file_exists (to_cstr filename)
@@ -232,6 +234,9 @@ describe 'fs function', ->
os_remove = (path) ->
fs.os_remove (to_cstr path)
+ os_open = (path, flags, mode) ->
+ fs.os_open (to_cstr path), flags, mode
+
describe 'os_file_exists', ->
it 'returns false when given a non-existing file', ->
eq false, (os_file_exists 'non-existing-file')
@@ -267,13 +272,61 @@ describe 'fs function', ->
file\close!
describe 'os_remove', ->
+ before_each ->
+ (io.open 'unit-test-directory/test_remove.file', 'w').close!
+ after_each ->
+ os.remove 'unit-test-directory/test_remove.file'
+
it 'returns non-zero when given a non-existing file', ->
neq 0, (os_remove 'non-existing-file')
it 'removes the given file and returns 0', ->
- eq true, (os_file_exists 'unit-test-directory/test_remove.file')
- eq 0, (os_remove 'unit-test-directory/test_remove.file')
- eq false, (os_file_exists 'unit-test-directory/test_remove.file')
+ f = 'unit-test-directory/test_remove.file'
+ assert_file_exists f
+ eq 0, (os_remove f)
+ assert_file_does_not_exist f
+
+ describe 'os_open', ->
+ before_each ->
+ (io.open 'unit-test-directory/test_existing.file', 'w').close!
+ after_each ->
+ os.remove 'unit-test-directory/test_existing.file'
+ os.remove 'test_new_file'
+
+ new_file = 'test_new_file'
+ existing_file = 'unit-test-directory/test_existing.file'
+
+ it 'returns -ENOENT for O_RDWR on a non-existing file', ->
+ eq -ffi.C.kENOENT, (os_open 'non-existing-file', ffi.C.kO_RDWR, 0)
+
+ it 'returns non-negative for O_CREAT on a non-existing file', ->
+ assert_file_does_not_exist new_file
+ assert.is_true 0 <= (os_open new_file, ffi.C.kO_CREAT, 0)
+
+ it 'returns non-negative for O_CREAT on a existing file', ->
+ assert_file_exists existing_file
+ assert.is_true 0 <= (os_open existing_file, ffi.C.kO_CREAT, 0)
+
+ it 'returns -EEXIST for O_CREAT|O_EXCL on a existing file', ->
+ assert_file_exists existing_file
+ eq -ffi.C.kEEXIST, (os_open existing_file, (bit.bor ffi.C.kO_CREAT, ffi.C.kO_EXCL), 0)
+
+ it 'sets `rwx` permissions for O_CREAT 700', ->
+ assert_file_does_not_exist new_file
+ --create the file
+ os_open new_file, ffi.C.kO_CREAT, tonumber("700", 8)
+ --verify permissions
+ eq 'rwx------', lfs.attributes(new_file)['permissions']
+
+ it 'sets `rw` permissions for O_CREAT 600', ->
+ assert_file_does_not_exist new_file
+ --create the file
+ os_open new_file, ffi.C.kO_CREAT, tonumber("600", 8)
+ --verify permissions
+ eq 'rw-------', lfs.attributes(new_file)['permissions']
+
+ it 'returns a non-negative file descriptor for an existing file', ->
+ assert.is_true 0 <= (os_open existing_file, ffi.C.kO_RDWR, 0)
describe 'folder operations', ->
os_mkdir = (path, mode) ->