diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/CMakeLists.txt | 15 | ||||
-rw-r--r-- | src/nvim/fileio.c | 44 | ||||
-rw-r--r-- | src/nvim/main.c | 7 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 151 |
4 files changed, 164 insertions, 53 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index d80add2835..5c4df1be0b 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -259,6 +259,21 @@ add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) install_helper(TARGETS nvim) +if(WIN32) + # Copy DLLs to bin/ and install them along with nvim + add_custom_target(nvim_dll_deps ALL DEPENDS nvim + COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps + COMMAND ${CMAKE_COMMAND} + "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" + -DBINARY="${PROJECT_BINARY_DIR}/bin/nvim${CMAKE_EXECUTABLE_SUFFIX}" + -DDST=${PROJECT_BINARY_DIR}/windows_runtime_deps + -P ${PROJECT_SOURCE_DIR}/cmake/WindowsDllCopy.cmake + COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps/ + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + install(DIRECTORY ${PROJECT_BINARY_DIR}/windows_runtime_deps/ + DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() + if(CLANG_ASAN_UBSAN) message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.") check_c_compiler_flag(-fno-sanitize-recover=all SANITIZE_RECOVER_ALL) diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 3b598bd64b..e0b6ae1215 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -282,11 +282,9 @@ readfile ( int error = FALSE; /* errors encountered */ int ff_error = EOL_UNKNOWN; /* file format with errors */ long linerest = 0; /* remaining chars in line */ -#ifdef UNIX int perm = 0; +#ifdef UNIX int swap_mode = -1; /* protection bits for swap file */ -#else - int perm; #endif int fileformat = 0; /* end-of-line format */ int keep_fileformat = FALSE; @@ -418,23 +416,21 @@ readfile ( } } - if (!read_stdin && !read_buffer) { -#ifdef UNIX - /* - * On Unix it is possible to read a directory, so we have to - * check for it before os_open(). - */ + if (!read_buffer && !read_stdin) { perm = os_getperm(fname); - if (perm >= 0 && !S_ISREG(perm) /* not a regular file ... */ +#ifdef UNIX + // On Unix it is possible to read a directory, so we have to + // check for it before os_open(). + if (perm >= 0 && !S_ISREG(perm) // not a regular file ... # ifdef S_ISFIFO - && !S_ISFIFO(perm) /* ... or fifo */ + && !S_ISFIFO(perm) // ... or fifo # endif # ifdef S_ISSOCK - && !S_ISSOCK(perm) /* ... or socket */ + && !S_ISSOCK(perm) // ... or socket # endif # ifdef OPEN_CHR_FILES && !(S_ISCHR(perm) && is_dev_fd_file(fname)) - /* ... or a character special file named /dev/fd/<n> */ + // ... or a character special file named /dev/fd/<n> # endif ) { if (S_ISDIR(perm)) @@ -503,26 +499,21 @@ readfile ( fd = os_open((char *)fname, O_RDONLY, 0); } - if (fd < 0) { /* cannot open at all */ + if (fd < 0) { // cannot open at all msg_scroll = msg_save; #ifndef UNIX - /* - * On non-unix systems we can't open a directory, check here. - */ - perm = os_getperm(fname); /* check if the file exists */ + // On non-unix systems we can't open a directory, check here. if (os_isdir(fname)) { filemess(curbuf, sfname, (char_u *)_("is a directory"), 0); - curbuf->b_p_ro = TRUE; /* must use "w!" now */ - } else + curbuf->b_p_ro = true; // must use "w!" now + } else { #endif if (!newfile) { return FAIL; } - if (perm == UV_ENOENT) { - /* - * Set the 'new-file' flag, so that when the file has - * been created by someone else, a ":w" will complain. - */ + if (perm == UV_ENOENT) { // check if the file exists + // Set the 'new-file' flag, so that when the file has + // been created by someone else, a ":w" will complain. curbuf->b_flags |= BF_NEW; /* Create a swap file now, so that other Vims are warned @@ -573,6 +564,9 @@ readfile ( return FAIL; } +#ifndef UNIX + } +#endif /* * Only set the 'ro' flag for readonly files the first time they are diff --git a/src/nvim/main.c b/src/nvim/main.c index e052d0d315..b5c51e3444 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -251,8 +251,9 @@ int main(int argc, char **argv) */ command_line_scan(¶ms); - if (GARGCOUNT > 0) - fname = get_fname(¶ms); + if (GARGCOUNT > 0) { + fname = get_fname(¶ms, cwd); + } TIME_MSG("expanding arguments"); @@ -1196,7 +1197,7 @@ static void check_and_set_isatty(mparm_T *paramp) /* * Get filename from command line, given that there is one. */ -static char_u *get_fname(mparm_T *parmp) +static char_u *get_fname(mparm_T *parmp, char_u *cwd) { #if !defined(UNIX) /* diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index cd943c4843..e63b8b6793 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -399,14 +399,7 @@ ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf, assert(read_bytes <= size); } if (cur_read_bytes < 0) { -#ifdef HAVE_UV_TRANSLATE_SYS_ERROR - const int error = uv_translate_sys_error(errno); -#else - const int error = -errno; - STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes"); - STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes"); - STATIC_ASSERT(-ENOMEM == UV_ENOMEM, "Need to translate error codes"); -#endif + const int error = os_translate_sys_error(errno); errno = 0; if (error == UV_EINTR || error == UV_EAGAIN) { continue; @@ -469,14 +462,7 @@ ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size) } } } else if (cur_read_bytes < 0) { -#ifdef HAVE_UV_TRANSLATE_SYS_ERROR - const int error = uv_translate_sys_error(errno); -#else - const int error = -errno; - STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes"); - STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes"); - STATIC_ASSERT(-ENOMEM == UV_ENOMEM, "Need to translate error codes"); -#endif + const int error = os_translate_sys_error(errno); errno = 0; if (error == UV_EINTR || error == UV_EAGAIN) { continue; @@ -515,15 +501,7 @@ ptrdiff_t os_write(const int fd, const char *const buf, const size_t size) written_bytes += (size_t)cur_written_bytes; } if (cur_written_bytes < 0) { -#ifdef HAVE_UV_TRANSLATE_SYS_ERROR - const int error = uv_translate_sys_error(errno); -#else - const int error = -errno; - STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes"); - STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes"); - // According to the man page open() may fail with ENOMEM, but write() - // can’t. -#endif + const int error = os_translate_sys_error(errno); errno = 0; if (error == UV_EINTR || error == UV_EAGAIN) { continue; @@ -1023,3 +1001,126 @@ shortcut_end: } #endif + +int os_translate_sys_error(int sys_errno) { +#ifdef HAVE_UV_TRANSLATE_SYS_ERROR + return uv_translate_sys_error(sys_errno); +#elif WIN32 + // TODO(equalsraf): libuv does not yet expose uv_translate_sys_error() + // in its public API, include a version here until it can be used. + // See https://github.com/libuv/libuv/issues/79 +# ifndef ERROR_SYMLINK_NOT_SUPPORTED +# define ERROR_SYMLINK_NOT_SUPPORTED 1464 +# endif + + if (sys_errno <= 0) { + return sys_errno; // If < 0 then it's already a libuv error + } + + switch (sys_errno) { + case ERROR_NOACCESS: return UV_EACCES; + case WSAEACCES: return UV_EACCES; + case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE; + case WSAEADDRINUSE: return UV_EADDRINUSE; + case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL; + case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT; + case WSAEWOULDBLOCK: return UV_EAGAIN; + case WSAEALREADY: return UV_EALREADY; + case ERROR_INVALID_FLAGS: return UV_EBADF; + case ERROR_INVALID_HANDLE: return UV_EBADF; + case ERROR_LOCK_VIOLATION: return UV_EBUSY; + case ERROR_PIPE_BUSY: return UV_EBUSY; + case ERROR_SHARING_VIOLATION: return UV_EBUSY; + case ERROR_OPERATION_ABORTED: return UV_ECANCELED; + case WSAEINTR: return UV_ECANCELED; + case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET; + case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED; + case WSAECONNABORTED: return UV_ECONNABORTED; + case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED; + case WSAECONNREFUSED: return UV_ECONNREFUSED; + case ERROR_NETNAME_DELETED: return UV_ECONNRESET; + case WSAECONNRESET: return UV_ECONNRESET; + case ERROR_ALREADY_EXISTS: return UV_EEXIST; + case ERROR_FILE_EXISTS: return UV_EEXIST; + case ERROR_BUFFER_OVERFLOW: return UV_EFAULT; + case WSAEFAULT: return UV_EFAULT; + case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH; + case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; + case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL; + case ERROR_INVALID_DATA: return UV_EINVAL; + case ERROR_INVALID_PARAMETER: return UV_EINVAL; + case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL; + case WSAEINVAL: return UV_EINVAL; + case WSAEPFNOSUPPORT: return UV_EINVAL; + case WSAESOCKTNOSUPPORT: return UV_EINVAL; + case ERROR_BEGINNING_OF_MEDIA: return UV_EIO; + case ERROR_BUS_RESET: return UV_EIO; + case ERROR_CRC: return UV_EIO; + case ERROR_DEVICE_DOOR_OPEN: return UV_EIO; + case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO; + case ERROR_DISK_CORRUPT: return UV_EIO; + case ERROR_EOM_OVERFLOW: return UV_EIO; + case ERROR_FILEMARK_DETECTED: return UV_EIO; + case ERROR_GEN_FAILURE: return UV_EIO; + case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO; + case ERROR_IO_DEVICE: return UV_EIO; + case ERROR_NO_DATA_DETECTED: return UV_EIO; + case ERROR_NO_SIGNAL_SENT: return UV_EIO; + case ERROR_OPEN_FAILED: return UV_EIO; + case ERROR_SETMARK_DETECTED: return UV_EIO; + case ERROR_SIGNAL_REFUSED: return UV_EIO; + case WSAEISCONN: return UV_EISCONN; + case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP; + case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; + case WSAEMFILE: return UV_EMFILE; + case WSAEMSGSIZE: return UV_EMSGSIZE; + case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG; + case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH; + case WSAENETUNREACH: return UV_ENETUNREACH; + case WSAENOBUFS: return UV_ENOBUFS; + case ERROR_BAD_PATHNAME: return UV_ENOENT; + case ERROR_DIRECTORY: return UV_ENOENT; + case ERROR_FILE_NOT_FOUND: return UV_ENOENT; + case ERROR_INVALID_NAME: return UV_ENOENT; + case ERROR_INVALID_DRIVE: return UV_ENOENT; + case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT; + case ERROR_MOD_NOT_FOUND: return UV_ENOENT; + case ERROR_PATH_NOT_FOUND: return UV_ENOENT; + case WSAHOST_NOT_FOUND: return UV_ENOENT; + case WSANO_DATA: return UV_ENOENT; + case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM; + case ERROR_OUTOFMEMORY: return UV_ENOMEM; + case ERROR_CANNOT_MAKE: return UV_ENOSPC; + case ERROR_DISK_FULL: return UV_ENOSPC; + case ERROR_EA_TABLE_FULL: return UV_ENOSPC; + case ERROR_END_OF_MEDIA: return UV_ENOSPC; + case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC; + case ERROR_NOT_CONNECTED: return UV_ENOTCONN; + case WSAENOTCONN: return UV_ENOTCONN; + case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY; + case WSAENOTSOCK: return UV_ENOTSOCK; + case ERROR_NOT_SUPPORTED: return UV_ENOTSUP; + case ERROR_BROKEN_PIPE: return UV_EOF; + case ERROR_ACCESS_DENIED: return UV_EPERM; + case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM; + case ERROR_BAD_PIPE: return UV_EPIPE; + case ERROR_NO_DATA: return UV_EPIPE; + case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE; + case WSAESHUTDOWN: return UV_EPIPE; + case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT; + case ERROR_WRITE_PROTECT: return UV_EROFS; + case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT; + case WSAETIMEDOUT: return UV_ETIMEDOUT; + case ERROR_NOT_SAME_DEVICE: return UV_EXDEV; + case ERROR_INVALID_FUNCTION: return UV_EISDIR; + case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG; + default: return UV_UNKNOWN; + } +#else + const int error = -errno; + STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes"); + STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes"); + STATIC_ASSERT(-ENOMEM == UV_ENOMEM, "Need to translate error codes"); + return error; +#endif +} |