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 +}  | 
