diff options
-rw-r--r-- | src/nvim/os/fs.c | 9 | ||||
-rw-r--r-- | test/includes/pre/sys/errno.h | 4 | ||||
-rw-r--r-- | test/includes/pre/sys/fcntl.h | 7 | ||||
-rw-r--r-- | test/unit/os/fs.moon | 71 |
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) -> |