aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/CMakeLists.txt15
-rw-r--r--src/nvim/fileio.c44
-rw-r--r--src/nvim/main.c7
-rw-r--r--src/nvim/os/fs.c151
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(&params);
- if (GARGCOUNT > 0)
- fname = get_fname(&params);
+ if (GARGCOUNT > 0) {
+ fname = get_fname(&params, 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
+}