diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2014-08-22 03:15:00 +0000 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2016-04-29 00:22:43 -0400 |
commit | 7db4a15e95337fc9afe4b8d60ae14a62bebcc2d8 (patch) | |
tree | 300039cad6d5f92237108168cbf322fab20b458c | |
parent | 43e7c40051e9a3914ea280759982df6da2bfd526 (diff) | |
download | rneovim-7db4a15e95337fc9afe4b8d60ae14a62bebcc2d8.tar.gz rneovim-7db4a15e95337fc9afe4b8d60ae14a62bebcc2d8.tar.bz2 rneovim-7db4a15e95337fc9afe4b8d60ae14a62bebcc2d8.zip |
os_nodetype: impl with libuv
-rw-r--r-- | src/nvim/fileio.c | 6 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 67 | ||||
-rw-r--r-- | src/nvim/os/fs_defs.h | 6 | ||||
-rw-r--r-- | src/nvim/os_unix.c | 20 | ||||
-rw-r--r-- | src/nvim/os_unix.h | 6 |
5 files changed, 75 insertions, 30 deletions
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index c431f721dd..b9d9ea5457 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -2576,7 +2576,7 @@ buf_write ( errmsg = (char_u *)_("is a directory"); goto fail; } - if (mch_nodetype(fname) != NODE_WRITABLE) { + if (os_nodetype((char *)fname) != NODE_WRITABLE) { errnum = (char_u *)"E503: "; errmsg = (char_u *)_("is not a file or writable device"); goto fail; @@ -2588,11 +2588,11 @@ buf_write ( perm = -1; } } -#else /* !UNIX */ +#else /* win32 */ /* * Check for a writable device name. */ - c = mch_nodetype(fname); + c = os_nodetype((char *)fname); if (c == NODE_OTHER) { errnum = (char_u *)"E503: "; errmsg = (char_u *)_("is not a file or writable device"); diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index bc2d37764d..3d5281a636 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -94,9 +94,74 @@ bool os_isdir(const char_u *name) return true; } +/// Check what `name` is: +/// @return NODE_NORMAL: file or directory (or doesn't exist) +/// NODE_WRITABLE: writable device, socket, fifo, etc. +/// NODE_OTHER: non-writable things +int os_nodetype(const char *name) +{ +#ifdef WIN32 + // Edge case from Vim os_win32.c: + // We can't open a file with a name "\\.\con" or "\\.\prn", trying to read + // from it later will cause Vim to hang. Thus return NODE_WRITABLE here. + if (STRNCMP(name, "\\\\.\\", 4) == 0) { + return NODE_WRITABLE; + } +#endif + + uv_stat_t statbuf; + if (os_stat(name, &statbuf) == 0) { + return NODE_NORMAL; + } + +#ifndef WIN32 + // libuv does not handle BLK and DIR in uv_handle_type. + // Related: https://github.com/joyent/libuv/pull/1421 + if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode)) { + return NODE_NORMAL; + } + if (S_ISBLK(statbuf.st_mode)) { // block device isn't writable + return NODE_OTHER; + } +#endif + + // Vim os_win32.c:mch_nodetype does this (since patch 7.4.015): + // if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { + // wn = enc_to_utf16(name, NULL); + // hFile = CreatFile(wn, ...) + // to get a HANDLE. But libuv just calls win32's _get_osfhandle() on the fd we + // give it. uv_fs_open calls fs__capture_path which does a similar dance and + // saves us the hassle. + + int nodetype = NODE_WRITABLE; + int fd = os_open(name, O_RDONLY, 0); + switch(uv_guess_handle(fd)) { + case UV_TTY: // FILE_TYPE_CHAR + nodetype = NODE_WRITABLE; + break; + case UV_FILE: // FILE_TYPE_DISK + nodetype = NODE_NORMAL; + break; + case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c + case UV_UDP: // unix only + case UV_TCP: // unix only + case UV_UNKNOWN_HANDLE: + default: +#ifdef WIN32 + nodetype = NODE_OTHER; +#else + nodetype = NODE_WRITABLE; // Everything else is writable? +#endif + break; + } + + close(fd); + return nodetype; +} + /// Checks if the given path represents an executable file. /// -/// @param[in] name The name of the executable. +/// @param[in] name Name of the executable. /// @param[out] abspath Path of the executable, if found and not `NULL`. /// /// @return `true` if `name` is executable and diff --git a/src/nvim/os/fs_defs.h b/src/nvim/os/fs_defs.h index 52b2841514..0bd9c37750 100644 --- a/src/nvim/os/fs_defs.h +++ b/src/nvim/os/fs_defs.h @@ -26,4 +26,10 @@ typedef struct { /// negative libuv error codes are returned by a number of os functions. #define os_strerror uv_strerror +// Values returned by os_nodetype() +#define NODE_NORMAL 0 // file or directory, check with os_isdir() +#define NODE_WRITABLE 1 // something we can write to (character + // device, fifo, socket, ..) +#define NODE_OTHER 2 // non-writable thing (e.g., block device) + #endif // NVIM_OS_FS_DEFS_H diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 2a859a0f7a..63a3dbc054 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -136,26 +136,6 @@ void mch_free_acl(vim_acl_T aclent) } #endif -/* - * Check what "name" is: - * NODE_NORMAL: file or directory (or doesn't exist) - * NODE_WRITABLE: writable device, socket, fifo, etc. - * NODE_OTHER: non-writable things - */ -int mch_nodetype(char_u *name) -{ - struct stat st; - - if (stat((char *)name, &st)) - return NODE_NORMAL; - if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) - return NODE_NORMAL; - if (S_ISBLK(st.st_mode)) /* block device isn't writable */ - return NODE_OTHER; - /* Everything else is writable? */ - return NODE_WRITABLE; -} - void mch_exit(int r) { exiting = true; diff --git a/src/nvim/os_unix.h b/src/nvim/os_unix.h index 5a3eb84ba4..d627b16ec0 100644 --- a/src/nvim/os_unix.h +++ b/src/nvim/os_unix.h @@ -4,12 +4,6 @@ #include "nvim/types.h" // for vim_acl_T #include "nvim/os/shell.h" -/* Values returned by mch_nodetype() */ -#define NODE_NORMAL 0 /* file or directory, check with os_isdir()*/ -#define NODE_WRITABLE 1 /* something we can write to (character - device, fifo, socket, ..) */ -#define NODE_OTHER 2 /* non-writable thing (e.g., block device) */ - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os_unix.h.generated.h" #endif |