mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
os_nodetype: impl with libuv
This commit is contained in:
@@ -2576,7 +2576,7 @@ buf_write (
|
|||||||
errmsg = (char_u *)_("is a directory");
|
errmsg = (char_u *)_("is a directory");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (mch_nodetype(fname) != NODE_WRITABLE) {
|
if (os_nodetype((char *)fname) != NODE_WRITABLE) {
|
||||||
errnum = (char_u *)"E503: ";
|
errnum = (char_u *)"E503: ";
|
||||||
errmsg = (char_u *)_("is not a file or writable device");
|
errmsg = (char_u *)_("is not a file or writable device");
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -2588,11 +2588,11 @@ buf_write (
|
|||||||
perm = -1;
|
perm = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* !UNIX */
|
#else /* win32 */
|
||||||
/*
|
/*
|
||||||
* Check for a writable device name.
|
* Check for a writable device name.
|
||||||
*/
|
*/
|
||||||
c = mch_nodetype(fname);
|
c = os_nodetype((char *)fname);
|
||||||
if (c == NODE_OTHER) {
|
if (c == NODE_OTHER) {
|
||||||
errnum = (char_u *)"E503: ";
|
errnum = (char_u *)"E503: ";
|
||||||
errmsg = (char_u *)_("is not a file or writable device");
|
errmsg = (char_u *)_("is not a file or writable device");
|
||||||
|
@@ -94,9 +94,74 @@ bool os_isdir(const char_u *name)
|
|||||||
return true;
|
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.
|
/// 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`.
|
/// @param[out] abspath Path of the executable, if found and not `NULL`.
|
||||||
///
|
///
|
||||||
/// @return `true` if `name` is executable and
|
/// @return `true` if `name` is executable and
|
||||||
|
@@ -26,4 +26,10 @@ typedef struct {
|
|||||||
/// negative libuv error codes are returned by a number of os functions.
|
/// negative libuv error codes are returned by a number of os functions.
|
||||||
#define os_strerror uv_strerror
|
#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
|
#endif // NVIM_OS_FS_DEFS_H
|
||||||
|
@@ -136,26 +136,6 @@ void mch_free_acl(vim_acl_T aclent)
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
void mch_exit(int r)
|
||||||
{
|
{
|
||||||
exiting = true;
|
exiting = true;
|
||||||
|
@@ -4,12 +4,6 @@
|
|||||||
#include "nvim/types.h" // for vim_acl_T
|
#include "nvim/types.h" // for vim_acl_T
|
||||||
#include "nvim/os/shell.h"
|
#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
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os_unix.h.generated.h"
|
# include "os_unix.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user