Browse Source

libuv 2018-05-06 (bf605bd7)

Code extracted from:

    https://github.com/libuv/libuv.git

at commit bf605bd7d0dd5660663e8e2eb44d63aa3355e268 (v1.x).
libuv upstream 7 years ago
parent
commit
c8b67ea119
61 changed files with 990 additions and 751 deletions
  1. 69 63
      include/uv-errno.h
  2. 1 1
      include/uv-os390.h
  3. 1 1
      include/uv-unix.h
  4. 2 2
      include/uv-version.h
  5. 18 3
      include/uv.h
  6. 13 13
      src/unix/aix-common.c
  7. 23 23
      src/unix/aix.c
  8. 4 4
      src/unix/async.c
  9. 2 2
      src/unix/bsd-ifaddrs.c
  10. 56 69
      src/unix/core.c
  11. 1 1
      src/unix/cygwin.c
  12. 8 5
      src/unix/darwin-proctitle.c
  13. 12 12
      src/unix/darwin.c
  14. 17 17
      src/unix/freebsd.c
  15. 69 36
      src/unix/fs.c
  16. 13 13
      src/unix/fsevents.c
  17. 5 5
      src/unix/getaddrinfo.c
  18. 1 1
      src/unix/getnameinfo.c
  19. 1 1
      src/unix/ibmi.c
  20. 14 1
      src/unix/internal.h
  21. 4 4
      src/unix/kqueue.c
  22. 17 17
      src/unix/linux-core.c
  23. 5 5
      src/unix/linux-inotify.c
  24. 1 1
      src/unix/loop-watcher.c
  25. 2 1
      src/unix/loop.c
  26. 14 14
      src/unix/netbsd.c
  27. 3 3
      src/unix/no-fsevents.c
  28. 1 1
      src/unix/no-proctitle.c
  29. 16 16
      src/unix/openbsd.c
  30. 2 0
      src/unix/os390-syscalls.c
  31. 19 19
      src/unix/os390.c
  32. 34 29
      src/unix/pipe.c
  33. 2 2
      src/unix/poll.c
  34. 14 4
      src/unix/posix-poll.c
  35. 27 30
      src/unix/process.c
  36. 2 2
      src/unix/procfs-exepath.c
  37. 2 2
      src/unix/proctitle.c
  38. 2 2
      src/unix/signal.c
  39. 51 39
      src/unix/stream.c
  40. 21 21
      src/unix/sunos.c
  41. 32 34
      src/unix/tcp.c
  42. 174 82
      src/unix/thread.c
  43. 2 2
      src/unix/timer.c
  44. 8 8
      src/unix/tty.c
  45. 38 38
      src/unix/udp.c
  46. 1 1
      src/uv-common.c
  47. 9 3
      src/uv-common.h
  48. 3 3
      src/win/core.c
  49. 27 2
      src/win/fs-event.c
  50. 13 2
      src/win/fs.c
  51. 8 2
      src/win/getaddrinfo.c
  52. 8 2
      src/win/internal.h
  53. 8 0
      src/win/pipe.c
  54. 8 3
      src/win/process.c
  55. 5 5
      src/win/stream-inl.h
  56. 8 7
      src/win/tcp.c
  57. 8 2
      src/win/tty.c
  58. 31 68
      src/win/util.c
  59. 11 0
      src/win/winapi.c
  60. 15 0
      src/win/winapi.h
  61. 4 2
      src/win/winsock.c

+ 69 - 63
include/uv-errno.h

@@ -23,6 +23,11 @@
 #define UV_ERRNO_H_
 #define UV_ERRNO_H_
 
 
 #include <errno.h>
 #include <errno.h>
+#if EDOM > 0
+# define UV__ERR(x) (-(x))
+#else
+# define UV__ERR(x) (x)
+#endif
 
 
 #define UV__EOF     (-4095)
 #define UV__EOF     (-4095)
 #define UV__UNKNOWN (-4094)
 #define UV__UNKNOWN (-4094)
@@ -46,355 +51,355 @@
  * a fairly common practice for Windows programmers to redefine errno codes.
  * a fairly common practice for Windows programmers to redefine errno codes.
  */
  */
 #if defined(E2BIG) && !defined(_WIN32)
 #if defined(E2BIG) && !defined(_WIN32)
-# define UV__E2BIG (-E2BIG)
+# define UV__E2BIG UV__ERR(E2BIG)
 #else
 #else
 # define UV__E2BIG (-4093)
 # define UV__E2BIG (-4093)
 #endif
 #endif
 
 
 #if defined(EACCES) && !defined(_WIN32)
 #if defined(EACCES) && !defined(_WIN32)
-# define UV__EACCES (-EACCES)
+# define UV__EACCES UV__ERR(EACCES)
 #else
 #else
 # define UV__EACCES (-4092)
 # define UV__EACCES (-4092)
 #endif
 #endif
 
 
 #if defined(EADDRINUSE) && !defined(_WIN32)
 #if defined(EADDRINUSE) && !defined(_WIN32)
-# define UV__EADDRINUSE (-EADDRINUSE)
+# define UV__EADDRINUSE UV__ERR(EADDRINUSE)
 #else
 #else
 # define UV__EADDRINUSE (-4091)
 # define UV__EADDRINUSE (-4091)
 #endif
 #endif
 
 
 #if defined(EADDRNOTAVAIL) && !defined(_WIN32)
 #if defined(EADDRNOTAVAIL) && !defined(_WIN32)
-# define UV__EADDRNOTAVAIL (-EADDRNOTAVAIL)
+# define UV__EADDRNOTAVAIL UV__ERR(EADDRNOTAVAIL)
 #else
 #else
 # define UV__EADDRNOTAVAIL (-4090)
 # define UV__EADDRNOTAVAIL (-4090)
 #endif
 #endif
 
 
 #if defined(EAFNOSUPPORT) && !defined(_WIN32)
 #if defined(EAFNOSUPPORT) && !defined(_WIN32)
-# define UV__EAFNOSUPPORT (-EAFNOSUPPORT)
+# define UV__EAFNOSUPPORT UV__ERR(EAFNOSUPPORT)
 #else
 #else
 # define UV__EAFNOSUPPORT (-4089)
 # define UV__EAFNOSUPPORT (-4089)
 #endif
 #endif
 
 
 #if defined(EAGAIN) && !defined(_WIN32)
 #if defined(EAGAIN) && !defined(_WIN32)
-# define UV__EAGAIN (-EAGAIN)
+# define UV__EAGAIN UV__ERR(EAGAIN)
 #else
 #else
 # define UV__EAGAIN (-4088)
 # define UV__EAGAIN (-4088)
 #endif
 #endif
 
 
 #if defined(EALREADY) && !defined(_WIN32)
 #if defined(EALREADY) && !defined(_WIN32)
-# define UV__EALREADY (-EALREADY)
+# define UV__EALREADY UV__ERR(EALREADY)
 #else
 #else
 # define UV__EALREADY (-4084)
 # define UV__EALREADY (-4084)
 #endif
 #endif
 
 
 #if defined(EBADF) && !defined(_WIN32)
 #if defined(EBADF) && !defined(_WIN32)
-# define UV__EBADF (-EBADF)
+# define UV__EBADF UV__ERR(EBADF)
 #else
 #else
 # define UV__EBADF (-4083)
 # define UV__EBADF (-4083)
 #endif
 #endif
 
 
 #if defined(EBUSY) && !defined(_WIN32)
 #if defined(EBUSY) && !defined(_WIN32)
-# define UV__EBUSY (-EBUSY)
+# define UV__EBUSY UV__ERR(EBUSY)
 #else
 #else
 # define UV__EBUSY (-4082)
 # define UV__EBUSY (-4082)
 #endif
 #endif
 
 
 #if defined(ECANCELED) && !defined(_WIN32)
 #if defined(ECANCELED) && !defined(_WIN32)
-# define UV__ECANCELED (-ECANCELED)
+# define UV__ECANCELED UV__ERR(ECANCELED)
 #else
 #else
 # define UV__ECANCELED (-4081)
 # define UV__ECANCELED (-4081)
 #endif
 #endif
 
 
 #if defined(ECHARSET) && !defined(_WIN32)
 #if defined(ECHARSET) && !defined(_WIN32)
-# define UV__ECHARSET (-ECHARSET)
+# define UV__ECHARSET UV__ERR(ECHARSET)
 #else
 #else
 # define UV__ECHARSET (-4080)
 # define UV__ECHARSET (-4080)
 #endif
 #endif
 
 
 #if defined(ECONNABORTED) && !defined(_WIN32)
 #if defined(ECONNABORTED) && !defined(_WIN32)
-# define UV__ECONNABORTED (-ECONNABORTED)
+# define UV__ECONNABORTED UV__ERR(ECONNABORTED)
 #else
 #else
 # define UV__ECONNABORTED (-4079)
 # define UV__ECONNABORTED (-4079)
 #endif
 #endif
 
 
 #if defined(ECONNREFUSED) && !defined(_WIN32)
 #if defined(ECONNREFUSED) && !defined(_WIN32)
-# define UV__ECONNREFUSED (-ECONNREFUSED)
+# define UV__ECONNREFUSED UV__ERR(ECONNREFUSED)
 #else
 #else
 # define UV__ECONNREFUSED (-4078)
 # define UV__ECONNREFUSED (-4078)
 #endif
 #endif
 
 
 #if defined(ECONNRESET) && !defined(_WIN32)
 #if defined(ECONNRESET) && !defined(_WIN32)
-# define UV__ECONNRESET (-ECONNRESET)
+# define UV__ECONNRESET UV__ERR(ECONNRESET)
 #else
 #else
 # define UV__ECONNRESET (-4077)
 # define UV__ECONNRESET (-4077)
 #endif
 #endif
 
 
 #if defined(EDESTADDRREQ) && !defined(_WIN32)
 #if defined(EDESTADDRREQ) && !defined(_WIN32)
-# define UV__EDESTADDRREQ (-EDESTADDRREQ)
+# define UV__EDESTADDRREQ UV__ERR(EDESTADDRREQ)
 #else
 #else
 # define UV__EDESTADDRREQ (-4076)
 # define UV__EDESTADDRREQ (-4076)
 #endif
 #endif
 
 
 #if defined(EEXIST) && !defined(_WIN32)
 #if defined(EEXIST) && !defined(_WIN32)
-# define UV__EEXIST (-EEXIST)
+# define UV__EEXIST UV__ERR(EEXIST)
 #else
 #else
 # define UV__EEXIST (-4075)
 # define UV__EEXIST (-4075)
 #endif
 #endif
 
 
 #if defined(EFAULT) && !defined(_WIN32)
 #if defined(EFAULT) && !defined(_WIN32)
-# define UV__EFAULT (-EFAULT)
+# define UV__EFAULT UV__ERR(EFAULT)
 #else
 #else
 # define UV__EFAULT (-4074)
 # define UV__EFAULT (-4074)
 #endif
 #endif
 
 
 #if defined(EHOSTUNREACH) && !defined(_WIN32)
 #if defined(EHOSTUNREACH) && !defined(_WIN32)
-# define UV__EHOSTUNREACH (-EHOSTUNREACH)
+# define UV__EHOSTUNREACH UV__ERR(EHOSTUNREACH)
 #else
 #else
 # define UV__EHOSTUNREACH (-4073)
 # define UV__EHOSTUNREACH (-4073)
 #endif
 #endif
 
 
 #if defined(EINTR) && !defined(_WIN32)
 #if defined(EINTR) && !defined(_WIN32)
-# define UV__EINTR (-EINTR)
+# define UV__EINTR UV__ERR(EINTR)
 #else
 #else
 # define UV__EINTR (-4072)
 # define UV__EINTR (-4072)
 #endif
 #endif
 
 
 #if defined(EINVAL) && !defined(_WIN32)
 #if defined(EINVAL) && !defined(_WIN32)
-# define UV__EINVAL (-EINVAL)
+# define UV__EINVAL UV__ERR(EINVAL)
 #else
 #else
 # define UV__EINVAL (-4071)
 # define UV__EINVAL (-4071)
 #endif
 #endif
 
 
 #if defined(EIO) && !defined(_WIN32)
 #if defined(EIO) && !defined(_WIN32)
-# define UV__EIO (-EIO)
+# define UV__EIO UV__ERR(EIO)
 #else
 #else
 # define UV__EIO (-4070)
 # define UV__EIO (-4070)
 #endif
 #endif
 
 
 #if defined(EISCONN) && !defined(_WIN32)
 #if defined(EISCONN) && !defined(_WIN32)
-# define UV__EISCONN (-EISCONN)
+# define UV__EISCONN UV__ERR(EISCONN)
 #else
 #else
 # define UV__EISCONN (-4069)
 # define UV__EISCONN (-4069)
 #endif
 #endif
 
 
 #if defined(EISDIR) && !defined(_WIN32)
 #if defined(EISDIR) && !defined(_WIN32)
-# define UV__EISDIR (-EISDIR)
+# define UV__EISDIR UV__ERR(EISDIR)
 #else
 #else
 # define UV__EISDIR (-4068)
 # define UV__EISDIR (-4068)
 #endif
 #endif
 
 
 #if defined(ELOOP) && !defined(_WIN32)
 #if defined(ELOOP) && !defined(_WIN32)
-# define UV__ELOOP (-ELOOP)
+# define UV__ELOOP UV__ERR(ELOOP)
 #else
 #else
 # define UV__ELOOP (-4067)
 # define UV__ELOOP (-4067)
 #endif
 #endif
 
 
 #if defined(EMFILE) && !defined(_WIN32)
 #if defined(EMFILE) && !defined(_WIN32)
-# define UV__EMFILE (-EMFILE)
+# define UV__EMFILE UV__ERR(EMFILE)
 #else
 #else
 # define UV__EMFILE (-4066)
 # define UV__EMFILE (-4066)
 #endif
 #endif
 
 
 #if defined(EMSGSIZE) && !defined(_WIN32)
 #if defined(EMSGSIZE) && !defined(_WIN32)
-# define UV__EMSGSIZE (-EMSGSIZE)
+# define UV__EMSGSIZE UV__ERR(EMSGSIZE)
 #else
 #else
 # define UV__EMSGSIZE (-4065)
 # define UV__EMSGSIZE (-4065)
 #endif
 #endif
 
 
 #if defined(ENAMETOOLONG) && !defined(_WIN32)
 #if defined(ENAMETOOLONG) && !defined(_WIN32)
-# define UV__ENAMETOOLONG (-ENAMETOOLONG)
+# define UV__ENAMETOOLONG UV__ERR(ENAMETOOLONG)
 #else
 #else
 # define UV__ENAMETOOLONG (-4064)
 # define UV__ENAMETOOLONG (-4064)
 #endif
 #endif
 
 
 #if defined(ENETDOWN) && !defined(_WIN32)
 #if defined(ENETDOWN) && !defined(_WIN32)
-# define UV__ENETDOWN (-ENETDOWN)
+# define UV__ENETDOWN UV__ERR(ENETDOWN)
 #else
 #else
 # define UV__ENETDOWN (-4063)
 # define UV__ENETDOWN (-4063)
 #endif
 #endif
 
 
 #if defined(ENETUNREACH) && !defined(_WIN32)
 #if defined(ENETUNREACH) && !defined(_WIN32)
-# define UV__ENETUNREACH (-ENETUNREACH)
+# define UV__ENETUNREACH UV__ERR(ENETUNREACH)
 #else
 #else
 # define UV__ENETUNREACH (-4062)
 # define UV__ENETUNREACH (-4062)
 #endif
 #endif
 
 
 #if defined(ENFILE) && !defined(_WIN32)
 #if defined(ENFILE) && !defined(_WIN32)
-# define UV__ENFILE (-ENFILE)
+# define UV__ENFILE UV__ERR(ENFILE)
 #else
 #else
 # define UV__ENFILE (-4061)
 # define UV__ENFILE (-4061)
 #endif
 #endif
 
 
 #if defined(ENOBUFS) && !defined(_WIN32)
 #if defined(ENOBUFS) && !defined(_WIN32)
-# define UV__ENOBUFS (-ENOBUFS)
+# define UV__ENOBUFS UV__ERR(ENOBUFS)
 #else
 #else
 # define UV__ENOBUFS (-4060)
 # define UV__ENOBUFS (-4060)
 #endif
 #endif
 
 
 #if defined(ENODEV) && !defined(_WIN32)
 #if defined(ENODEV) && !defined(_WIN32)
-# define UV__ENODEV (-ENODEV)
+# define UV__ENODEV UV__ERR(ENODEV)
 #else
 #else
 # define UV__ENODEV (-4059)
 # define UV__ENODEV (-4059)
 #endif
 #endif
 
 
 #if defined(ENOENT) && !defined(_WIN32)
 #if defined(ENOENT) && !defined(_WIN32)
-# define UV__ENOENT (-ENOENT)
+# define UV__ENOENT UV__ERR(ENOENT)
 #else
 #else
 # define UV__ENOENT (-4058)
 # define UV__ENOENT (-4058)
 #endif
 #endif
 
 
 #if defined(ENOMEM) && !defined(_WIN32)
 #if defined(ENOMEM) && !defined(_WIN32)
-# define UV__ENOMEM (-ENOMEM)
+# define UV__ENOMEM UV__ERR(ENOMEM)
 #else
 #else
 # define UV__ENOMEM (-4057)
 # define UV__ENOMEM (-4057)
 #endif
 #endif
 
 
 #if defined(ENONET) && !defined(_WIN32)
 #if defined(ENONET) && !defined(_WIN32)
-# define UV__ENONET (-ENONET)
+# define UV__ENONET UV__ERR(ENONET)
 #else
 #else
 # define UV__ENONET (-4056)
 # define UV__ENONET (-4056)
 #endif
 #endif
 
 
 #if defined(ENOSPC) && !defined(_WIN32)
 #if defined(ENOSPC) && !defined(_WIN32)
-# define UV__ENOSPC (-ENOSPC)
+# define UV__ENOSPC UV__ERR(ENOSPC)
 #else
 #else
 # define UV__ENOSPC (-4055)
 # define UV__ENOSPC (-4055)
 #endif
 #endif
 
 
 #if defined(ENOSYS) && !defined(_WIN32)
 #if defined(ENOSYS) && !defined(_WIN32)
-# define UV__ENOSYS (-ENOSYS)
+# define UV__ENOSYS UV__ERR(ENOSYS)
 #else
 #else
 # define UV__ENOSYS (-4054)
 # define UV__ENOSYS (-4054)
 #endif
 #endif
 
 
 #if defined(ENOTCONN) && !defined(_WIN32)
 #if defined(ENOTCONN) && !defined(_WIN32)
-# define UV__ENOTCONN (-ENOTCONN)
+# define UV__ENOTCONN UV__ERR(ENOTCONN)
 #else
 #else
 # define UV__ENOTCONN (-4053)
 # define UV__ENOTCONN (-4053)
 #endif
 #endif
 
 
 #if defined(ENOTDIR) && !defined(_WIN32)
 #if defined(ENOTDIR) && !defined(_WIN32)
-# define UV__ENOTDIR (-ENOTDIR)
+# define UV__ENOTDIR UV__ERR(ENOTDIR)
 #else
 #else
 # define UV__ENOTDIR (-4052)
 # define UV__ENOTDIR (-4052)
 #endif
 #endif
 
 
 #if defined(ENOTEMPTY) && !defined(_WIN32)
 #if defined(ENOTEMPTY) && !defined(_WIN32)
-# define UV__ENOTEMPTY (-ENOTEMPTY)
+# define UV__ENOTEMPTY UV__ERR(ENOTEMPTY)
 #else
 #else
 # define UV__ENOTEMPTY (-4051)
 # define UV__ENOTEMPTY (-4051)
 #endif
 #endif
 
 
 #if defined(ENOTSOCK) && !defined(_WIN32)
 #if defined(ENOTSOCK) && !defined(_WIN32)
-# define UV__ENOTSOCK (-ENOTSOCK)
+# define UV__ENOTSOCK UV__ERR(ENOTSOCK)
 #else
 #else
 # define UV__ENOTSOCK (-4050)
 # define UV__ENOTSOCK (-4050)
 #endif
 #endif
 
 
 #if defined(ENOTSUP) && !defined(_WIN32)
 #if defined(ENOTSUP) && !defined(_WIN32)
-# define UV__ENOTSUP (-ENOTSUP)
+# define UV__ENOTSUP UV__ERR(ENOTSUP)
 #else
 #else
 # define UV__ENOTSUP (-4049)
 # define UV__ENOTSUP (-4049)
 #endif
 #endif
 
 
 #if defined(EPERM) && !defined(_WIN32)
 #if defined(EPERM) && !defined(_WIN32)
-# define UV__EPERM (-EPERM)
+# define UV__EPERM UV__ERR(EPERM)
 #else
 #else
 # define UV__EPERM (-4048)
 # define UV__EPERM (-4048)
 #endif
 #endif
 
 
 #if defined(EPIPE) && !defined(_WIN32)
 #if defined(EPIPE) && !defined(_WIN32)
-# define UV__EPIPE (-EPIPE)
+# define UV__EPIPE UV__ERR(EPIPE)
 #else
 #else
 # define UV__EPIPE (-4047)
 # define UV__EPIPE (-4047)
 #endif
 #endif
 
 
 #if defined(EPROTO) && !defined(_WIN32)
 #if defined(EPROTO) && !defined(_WIN32)
-# define UV__EPROTO (-EPROTO)
+# define UV__EPROTO UV__ERR(EPROTO)
 #else
 #else
-# define UV__EPROTO (-4046)
+# define UV__EPROTO UV__ERR(4046)
 #endif
 #endif
 
 
 #if defined(EPROTONOSUPPORT) && !defined(_WIN32)
 #if defined(EPROTONOSUPPORT) && !defined(_WIN32)
-# define UV__EPROTONOSUPPORT (-EPROTONOSUPPORT)
+# define UV__EPROTONOSUPPORT UV__ERR(EPROTONOSUPPORT)
 #else
 #else
 # define UV__EPROTONOSUPPORT (-4045)
 # define UV__EPROTONOSUPPORT (-4045)
 #endif
 #endif
 
 
 #if defined(EPROTOTYPE) && !defined(_WIN32)
 #if defined(EPROTOTYPE) && !defined(_WIN32)
-# define UV__EPROTOTYPE (-EPROTOTYPE)
+# define UV__EPROTOTYPE UV__ERR(EPROTOTYPE)
 #else
 #else
 # define UV__EPROTOTYPE (-4044)
 # define UV__EPROTOTYPE (-4044)
 #endif
 #endif
 
 
 #if defined(EROFS) && !defined(_WIN32)
 #if defined(EROFS) && !defined(_WIN32)
-# define UV__EROFS (-EROFS)
+# define UV__EROFS UV__ERR(EROFS)
 #else
 #else
 # define UV__EROFS (-4043)
 # define UV__EROFS (-4043)
 #endif
 #endif
 
 
 #if defined(ESHUTDOWN) && !defined(_WIN32)
 #if defined(ESHUTDOWN) && !defined(_WIN32)
-# define UV__ESHUTDOWN (-ESHUTDOWN)
+# define UV__ESHUTDOWN UV__ERR(ESHUTDOWN)
 #else
 #else
 # define UV__ESHUTDOWN (-4042)
 # define UV__ESHUTDOWN (-4042)
 #endif
 #endif
 
 
 #if defined(ESPIPE) && !defined(_WIN32)
 #if defined(ESPIPE) && !defined(_WIN32)
-# define UV__ESPIPE (-ESPIPE)
+# define UV__ESPIPE UV__ERR(ESPIPE)
 #else
 #else
 # define UV__ESPIPE (-4041)
 # define UV__ESPIPE (-4041)
 #endif
 #endif
 
 
 #if defined(ESRCH) && !defined(_WIN32)
 #if defined(ESRCH) && !defined(_WIN32)
-# define UV__ESRCH (-ESRCH)
+# define UV__ESRCH UV__ERR(ESRCH)
 #else
 #else
 # define UV__ESRCH (-4040)
 # define UV__ESRCH (-4040)
 #endif
 #endif
 
 
 #if defined(ETIMEDOUT) && !defined(_WIN32)
 #if defined(ETIMEDOUT) && !defined(_WIN32)
-# define UV__ETIMEDOUT (-ETIMEDOUT)
+# define UV__ETIMEDOUT UV__ERR(ETIMEDOUT)
 #else
 #else
 # define UV__ETIMEDOUT (-4039)
 # define UV__ETIMEDOUT (-4039)
 #endif
 #endif
 
 
 #if defined(ETXTBSY) && !defined(_WIN32)
 #if defined(ETXTBSY) && !defined(_WIN32)
-# define UV__ETXTBSY (-ETXTBSY)
+# define UV__ETXTBSY UV__ERR(ETXTBSY)
 #else
 #else
 # define UV__ETXTBSY (-4038)
 # define UV__ETXTBSY (-4038)
 #endif
 #endif
 
 
 #if defined(EXDEV) && !defined(_WIN32)
 #if defined(EXDEV) && !defined(_WIN32)
-# define UV__EXDEV (-EXDEV)
+# define UV__EXDEV UV__ERR(EXDEV)
 #else
 #else
 # define UV__EXDEV (-4037)
 # define UV__EXDEV (-4037)
 #endif
 #endif
 
 
 #if defined(EFBIG) && !defined(_WIN32)
 #if defined(EFBIG) && !defined(_WIN32)
-# define UV__EFBIG (-EFBIG)
+# define UV__EFBIG UV__ERR(EFBIG)
 #else
 #else
 # define UV__EFBIG (-4036)
 # define UV__EFBIG (-4036)
 #endif
 #endif
 
 
 #if defined(ENOPROTOOPT) && !defined(_WIN32)
 #if defined(ENOPROTOOPT) && !defined(_WIN32)
-# define UV__ENOPROTOOPT (-ENOPROTOOPT)
+# define UV__ENOPROTOOPT UV__ERR(ENOPROTOOPT)
 #else
 #else
 # define UV__ENOPROTOOPT (-4035)
 # define UV__ENOPROTOOPT (-4035)
 #endif
 #endif
 
 
 #if defined(ERANGE) && !defined(_WIN32)
 #if defined(ERANGE) && !defined(_WIN32)
-# define UV__ERANGE (-ERANGE)
+# define UV__ERANGE UV__ERR(ERANGE)
 #else
 #else
 # define UV__ERANGE (-4034)
 # define UV__ERANGE (-4034)
 #endif
 #endif
 
 
 #if defined(ENXIO) && !defined(_WIN32)
 #if defined(ENXIO) && !defined(_WIN32)
-# define UV__ENXIO (-ENXIO)
+# define UV__ENXIO UV__ERR(ENXIO)
 #else
 #else
 # define UV__ENXIO (-4033)
 # define UV__ENXIO (-4033)
 #endif
 #endif
 
 
 #if defined(EMLINK) && !defined(_WIN32)
 #if defined(EMLINK) && !defined(_WIN32)
-# define UV__EMLINK (-EMLINK)
+# define UV__EMLINK UV__ERR(EMLINK)
 #else
 #else
 # define UV__EMLINK (-4032)
 # define UV__EMLINK (-4032)
 #endif
 #endif
@@ -404,7 +409,7 @@
  * icky to hard-code it.
  * icky to hard-code it.
  */
  */
 #if defined(EHOSTDOWN) && !defined(_WIN32)
 #if defined(EHOSTDOWN) && !defined(_WIN32)
-# define UV__EHOSTDOWN (-EHOSTDOWN)
+# define UV__EHOSTDOWN UV__ERR(EHOSTDOWN)
 #elif defined(__APPLE__) || \
 #elif defined(__APPLE__) || \
       defined(__DragonFly__) || \
       defined(__DragonFly__) || \
       defined(__FreeBSD__) || \
       defined(__FreeBSD__) || \
@@ -417,15 +422,16 @@
 #endif
 #endif
 
 
 #if defined(EREMOTEIO) && !defined(_WIN32)
 #if defined(EREMOTEIO) && !defined(_WIN32)
-# define UV__EREMOTEIO (-EREMOTEIO)
+# define UV__EREMOTEIO UV__ERR(EREMOTEIO)
 #else
 #else
 # define UV__EREMOTEIO (-4030)
 # define UV__EREMOTEIO (-4030)
 #endif
 #endif
 
 
 #if defined(ENOTTY) && !defined(_WIN32)
 #if defined(ENOTTY) && !defined(_WIN32)
-# define UV__ENOTTY (-ENOTTY)
+# define UV__ENOTTY UV__ERR(ENOTTY)
 #else
 #else
 # define UV__ENOTTY (-4029)
 # define UV__ENOTTY (-4029)
 #endif
 #endif
 
 
+
 #endif /* UV_ERRNO_H_ */
 #endif /* UV_ERRNO_H_ */

+ 1 - 1
include/uv-os390.h

@@ -22,7 +22,7 @@
 #ifndef UV_MVS_H
 #ifndef UV_MVS_H
 #define UV_MVS_H
 #define UV_MVS_H
 
 
-#define UV_PLATFORM_SEM_T int
+#define UV_PLATFORM_SEM_T long
 
 
 #define UV_PLATFORM_LOOP_FIELDS                                               \
 #define UV_PLATFORM_LOOP_FIELDS                                               \
   void* ep;                                                                   \
   void* ep;                                                                   \

+ 1 - 1
include/uv-unix.h

@@ -48,7 +48,7 @@
 # include "uv-linux.h"
 # include "uv-linux.h"
 #elif defined (__MVS__)
 #elif defined (__MVS__)
 # include "uv-os390.h"
 # include "uv-os390.h"
-#elif defined(_PASE)
+#elif defined(__PASE__)
 # include "uv-posix.h"
 # include "uv-posix.h"
 #elif defined(_AIX)
 #elif defined(_AIX)
 # include "uv-aix.h"
 # include "uv-aix.h"

+ 2 - 2
include/uv-version.h

@@ -31,8 +31,8 @@
  */
  */
 
 
 #define UV_VERSION_MAJOR 1
 #define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 19
-#define UV_VERSION_PATCH 1
+#define UV_VERSION_MINOR 20
+#define UV_VERSION_PATCH 3
 #define UV_VERSION_IS_RELEASE 0
 #define UV_VERSION_IS_RELEASE 0
 #define UV_VERSION_SUFFIX "dev"
 #define UV_VERSION_SUFFIX "dev"
 
 

+ 18 - 3
include/uv.h

@@ -378,8 +378,7 @@ UV_EXTERN const char* uv_err_name(int err);
   /* read-only */                                                             \
   /* read-only */                                                             \
   uv_req_type type;                                                           \
   uv_req_type type;                                                           \
   /* private */                                                               \
   /* private */                                                               \
-  void* active_queue[2];                                                      \
-  void* reserved[4];                                                          \
+  void* reserved[6];                                                          \
   UV_REQ_PRIVATE_FIELDS                                                       \
   UV_REQ_PRIVATE_FIELDS                                                       \
 
 
 /* Abstract base class of all requests. */
 /* Abstract base class of all requests. */
@@ -1191,6 +1190,18 @@ UV_EXTERN int uv_fs_write(uv_loop_t* loop,
  */
  */
 #define UV_FS_COPYFILE_EXCL   0x0001
 #define UV_FS_COPYFILE_EXCL   0x0001
 
 
+/*
+ * This flag can be used with uv_fs_copyfile() to attempt to create a reflink.
+ * If copy-on-write is not supported, a fallback copy mechanism is used.
+ */
+#define UV_FS_COPYFILE_FICLONE 0x0002
+
+/*
+ * This flag can be used with uv_fs_copyfile() to attempt to create a reflink.
+ * If copy-on-write is not supported, an error is returned.
+ */
+#define UV_FS_COPYFILE_FICLONE_FORCE 0x0004
+
 UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop,
 UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop,
                              uv_fs_t* req,
                              uv_fs_t* req,
                              const char* path,
                              const char* path,
@@ -1531,7 +1542,10 @@ struct uv_loop_s {
   /* Loop reference counting. */
   /* Loop reference counting. */
   unsigned int active_handles;
   unsigned int active_handles;
   void* handle_queue[2];
   void* handle_queue[2];
-  void* active_reqs[2];
+  union {
+    void* unused[2];
+    unsigned int count;
+  } active_reqs;
   /* Internal flag to signal loop stop. */
   /* Internal flag to signal loop stop. */
   unsigned int stop_flag;
   unsigned int stop_flag;
   UV_LOOP_PRIVATE_FIELDS
   UV_LOOP_PRIVATE_FIELDS
@@ -1559,6 +1573,7 @@ UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data);
 #undef UV_SIGNAL_PRIVATE_FIELDS
 #undef UV_SIGNAL_PRIVATE_FIELDS
 #undef UV_LOOP_PRIVATE_FIELDS
 #undef UV_LOOP_PRIVATE_FIELDS
 #undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
 #undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
+#undef UV__ERR
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 13 - 13
src/unix/aix-common.c

@@ -83,12 +83,12 @@ int uv_exepath(char* buffer, size_t* size) {
   struct procsinfo pi;
   struct procsinfo pi;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   pi.pi_pid = getpid();
   pi.pi_pid = getpid();
   res = getargs(&pi, sizeof(pi), args, sizeof(args));
   res = getargs(&pi, sizeof(pi), args, sizeof(args));
   if (res < 0)
   if (res < 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   /*
   /*
    * Possibilities for args:
    * Possibilities for args:
@@ -101,7 +101,7 @@ int uv_exepath(char* buffer, size_t* size) {
   /* Case i) and ii) absolute or relative paths */
   /* Case i) and ii) absolute or relative paths */
   if (strchr(args, '/') != NULL) {
   if (strchr(args, '/') != NULL) {
     if (realpath(args, abspath) != abspath)
     if (realpath(args, abspath) != abspath)
-      return -errno;
+      return UV__ERR(errno);
 
 
     abspath_size = strlen(abspath);
     abspath_size = strlen(abspath);
 
 
@@ -121,11 +121,11 @@ int uv_exepath(char* buffer, size_t* size) {
     char *path = getenv("PATH");
     char *path = getenv("PATH");
 
 
     if (path == NULL)
     if (path == NULL)
-      return -EINVAL;
+      return UV_EINVAL;
 
 
     clonedpath = uv__strdup(path);
     clonedpath = uv__strdup(path);
     if (clonedpath == NULL)
     if (clonedpath == NULL)
-      return -ENOMEM;
+      return UV_ENOMEM;
 
 
     token = strtok(clonedpath, ":");
     token = strtok(clonedpath, ":");
     while (token != NULL) {
     while (token != NULL) {
@@ -151,7 +151,7 @@ int uv_exepath(char* buffer, size_t* size) {
     uv__free(clonedpath);
     uv__free(clonedpath);
 
 
     /* Out of tokens (path entries), and no match found */
     /* Out of tokens (path entries), and no match found */
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 }
 }
 
 
@@ -177,19 +177,19 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
   *count = 0;
   *count = 0;
 
 
   if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
   if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
   if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   ifc.ifc_req = (struct ifreq*)uv__malloc(size);
   ifc.ifc_req = (struct ifreq*)uv__malloc(size);
   ifc.ifc_len = size;
   ifc.ifc_len = size;
   if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
   if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
 #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
 #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
@@ -208,7 +208,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
       uv__close(sockfd);
       uv__close(sockfd);
-      return -errno;
+      return UV__ERR(errno);
     }
     }
 
 
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@@ -221,7 +221,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
   *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
   *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
   if (!(*addresses)) {
   if (!(*addresses)) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
   address = *addresses;
   address = *addresses;
 
 
@@ -240,7 +240,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
       uv__close(sockfd);
       uv__close(sockfd);
-      return -ENOSYS;
+      return UV_ENOSYS;
     }
     }
 
 
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@@ -260,7 +260,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
 
 
     if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
     if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
       uv__close(sockfd);
       uv__close(sockfd);
-      return -ENOSYS;
+      return UV_ENOSYS;
     }
     }
 
 
     if (inet6)
     if (inet6)

+ 23 - 23
src/unix/aix.c

@@ -119,7 +119,7 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
   pc.fd = fd;
   pc.fd = fd;
 
 
   if (pollset_ctl(loop->backend_fd, &pc, 1))
   if (pollset_ctl(loop->backend_fd, &pc, 1))
-    return -errno;
+    return UV__ERR(errno);
 
 
   pc.cmd = PS_DELETE;
   pc.cmd = PS_DELETE;
   if (pollset_ctl(loop->backend_fd, &pc, 1))
   if (pollset_ctl(loop->backend_fd, &pc, 1))
@@ -409,22 +409,22 @@ static int uv__is_ahafs_mounted(void){
 
 
   p = uv__malloc(siz);
   p = uv__malloc(siz);
   if (p == NULL)
   if (p == NULL)
-    return -errno;
+    return UV__ERR(errno);
 
 
   /* Retrieve all mounted filesystems */
   /* Retrieve all mounted filesystems */
   rv = mntctl(MCTL_QUERY, siz, (char*)p);
   rv = mntctl(MCTL_QUERY, siz, (char*)p);
   if (rv < 0)
   if (rv < 0)
-    return -errno;
+    return UV__ERR(errno);
   if (rv == 0) {
   if (rv == 0) {
     /* buffer was not large enough, reallocate to correct size */
     /* buffer was not large enough, reallocate to correct size */
     siz = *(int*)p;
     siz = *(int*)p;
     uv__free(p);
     uv__free(p);
     p = uv__malloc(siz);
     p = uv__malloc(siz);
     if (p == NULL)
     if (p == NULL)
-      return -errno;
+      return UV__ERR(errno);
     rv = mntctl(MCTL_QUERY, siz, (char*)p);
     rv = mntctl(MCTL_QUERY, siz, (char*)p);
     if (rv < 0)
     if (rv < 0)
-      return -errno;
+      return UV__ERR(errno);
   }
   }
 
 
   /* Look for dev in filesystems mount info */
   /* Look for dev in filesystems mount info */
@@ -495,7 +495,7 @@ static int uv__make_subdirs_p(const char *filename) {
   rc = uv__makedir_p(cmd);
   rc = uv__makedir_p(cmd);
 
 
   if (rc == -1 && errno != EEXIST){
   if (rc == -1 && errno != EEXIST){
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   return rc;
   return rc;
@@ -522,7 +522,7 @@ static int uv__setup_ahafs(const char* filename, int *fd) {
     sprintf(mon_file, "/aha/fs/modFile.monFactory");
     sprintf(mon_file, "/aha/fs/modFile.monFactory");
 
 
   if ((strlen(mon_file) + strlen(filename) + 5) > PATH_MAX)
   if ((strlen(mon_file) + strlen(filename) + 5) > PATH_MAX)
-    return -ENAMETOOLONG;
+    return UV_ENAMETOOLONG;
 
 
   /* Make the necessary subdirectories for the monitor file */
   /* Make the necessary subdirectories for the monitor file */
   rc = uv__make_subdirs_p(filename);
   rc = uv__make_subdirs_p(filename);
@@ -537,7 +537,7 @@ static int uv__setup_ahafs(const char* filename, int *fd) {
   /* Open the monitor file, creating it if necessary */
   /* Open the monitor file, creating it if necessary */
   *fd = open(mon_file, O_CREAT|O_RDWR);
   *fd = open(mon_file, O_CREAT|O_RDWR);
   if (*fd < 0)
   if (*fd < 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   /* Write out the monitoring specifications.
   /* Write out the monitoring specifications.
    * In this case, we are monitoring for a state change event type
    * In this case, we are monitoring for a state change event type
@@ -558,7 +558,7 @@ static int uv__setup_ahafs(const char* filename, int *fd) {
 
 
   rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1);
   rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1);
   if (rc < 0)
   if (rc < 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -716,7 +716,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
   uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
   uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
   return 0;
   return 0;
 #else
 #else
-  return -ENOSYS;
+  return UV_ENOSYS;
 #endif
 #endif
 }
 }
 
 
@@ -771,7 +771,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
 
 
   return 0;
   return 0;
 #else
 #else
-  return -ENOSYS;
+  return UV_ENOSYS;
 #endif
 #endif
 }
 }
 
 
@@ -796,7 +796,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
 
 
   return 0;
   return 0;
 #else
 #else
-  return -ENOSYS;
+  return UV_ENOSYS;
 #endif
 #endif
 }
 }
 
 
@@ -861,7 +861,7 @@ int uv_set_process_title(const char* title) {
    */
    */
   new_title = uv__strdup(title);
   new_title = uv__strdup(title);
   if (new_title == NULL)
   if (new_title == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_mutex_lock(&process_title_mutex);
   uv_mutex_lock(&process_title_mutex);
@@ -888,9 +888,9 @@ int uv_get_process_title(char* buffer, size_t size) {
   size_t len;
   size_t len;
   len = strlen(process_argv[0]);
   len = strlen(process_argv[0]);
   if (buffer == NULL || size == 0)
   if (buffer == NULL || size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
   else if (size <= len)
   else if (size <= len)
-    return -ENOBUFS;
+    return UV_ENOBUFS;
 
 
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_mutex_lock(&process_title_mutex);
   uv_mutex_lock(&process_title_mutex);
@@ -919,10 +919,10 @@ int uv_resident_set_memory(size_t* rss) {
 
 
   fd = open(pp, O_RDONLY);
   fd = open(pp, O_RDONLY);
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   /* FIXME(bnoordhuis) Handle EINTR. */
   /* FIXME(bnoordhuis) Handle EINTR. */
-  err = -EINVAL;
+  err = UV_EINVAL;
   if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
   if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
     *rss = (size_t)psinfo.pr_rssize * 1024;
     *rss = (size_t)psinfo.pr_rssize * 1024;
     err = 0;
     err = 0;
@@ -953,7 +953,7 @@ int uv_uptime(double* uptime) {
   endutent();
   endutent();
 
 
   if (boot_time == 0)
   if (boot_time == 0)
-    return -ENOSYS;
+    return UV_ENOSYS;
 
 
   *uptime = time(NULL) - boot_time;
   *uptime = time(NULL) - boot_time;
   return 0;
   return 0;
@@ -969,30 +969,30 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
 
   result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
   result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
   if (result == -1) {
   if (result == -1) {
-    return -ENOSYS;
+    return UV_ENOSYS;
   }
   }
 
 
   ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
   ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
   if (result == -1) {
   if (result == -1) {
-    return -ENOSYS;
+    return UV_ENOSYS;
   }
   }
 
 
   ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t));
   ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t));
   if (!ps_cpus) {
   if (!ps_cpus) {
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   strcpy(cpu_id.name, FIRST_CPU);
   strcpy(cpu_id.name, FIRST_CPU);
   result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
   result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
   if (result == -1) {
   if (result == -1) {
     uv__free(ps_cpus);
     uv__free(ps_cpus);
-    return -ENOSYS;
+    return UV_ENOSYS;
   }
   }
 
 
   *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t));
   *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t));
   if (!*cpu_infos) {
   if (!*cpu_infos) {
     uv__free(ps_cpus);
     uv__free(ps_cpus);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   *count = ncpus;
   *count = ncpus;

+ 4 - 4
src/unix/async.c

@@ -166,7 +166,7 @@ static int uv__async_start(uv_loop_t* loop) {
     pipefd[0] = err;
     pipefd[0] = err;
     pipefd[1] = -1;
     pipefd[1] = -1;
   }
   }
-  else if (err == -ENOSYS) {
+  else if (err == UV_ENOSYS) {
     err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
     err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
 #if defined(__linux__)
 #if defined(__linux__)
     /* Save a file descriptor by opening one of the pipe descriptors as
     /* Save a file descriptor by opening one of the pipe descriptors as
@@ -240,7 +240,7 @@ static int uv__async_eventfd(void) {
     return fd;
     return fd;
 
 
   if (errno != ENOSYS)
   if (errno != ENOSYS)
-    return -errno;
+    return UV__ERR(errno);
 
 
   no_eventfd2 = 1;
   no_eventfd2 = 1;
 
 
@@ -257,7 +257,7 @@ skip_eventfd2:
   }
   }
 
 
   if (errno != ENOSYS)
   if (errno != ENOSYS)
-    return -errno;
+    return UV__ERR(errno);
 
 
   no_eventfd = 1;
   no_eventfd = 1;
 
 
@@ -265,5 +265,5 @@ skip_eventfd:
 
 
 #endif
 #endif
 
 
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }

+ 2 - 2
src/unix/bsd-ifaddrs.c

@@ -70,7 +70,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
   int i;
   int i;
 
 
   if (getifaddrs(&addrs) != 0)
   if (getifaddrs(&addrs) != 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   *count = 0;
   *count = 0;
 
 
@@ -85,7 +85,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
 
 
   if (*addresses == NULL) {
   if (*addresses == NULL) {
     freeifaddrs(addrs);
     freeifaddrs(addrs);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   address = *addresses;
   address = *addresses;

+ 56 - 69
src/unix/core.c

@@ -191,14 +191,14 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
   socklen_t len;
   socklen_t len;
 
 
   if (handle == NULL || value == NULL)
   if (handle == NULL || value == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
   if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
     fd = uv__stream_fd((uv_stream_t*) handle);
     fd = uv__stream_fd((uv_stream_t*) handle);
   else if (handle->type == UV_UDP)
   else if (handle->type == UV_UDP)
     fd = ((uv_udp_t *) handle)->io_watcher.fd;
     fd = ((uv_udp_t *) handle)->io_watcher.fd;
   else
   else
-    return -ENOTSUP;
+    return UV_ENOTSUP;
 
 
   len = sizeof(*value);
   len = sizeof(*value);
 
 
@@ -208,7 +208,7 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
     r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len);
     r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len);
 
 
   if (r < 0)
   if (r < 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -418,12 +418,12 @@ int uv__socket(int domain, int type, int protocol) {
     return sockfd;
     return sockfd;
 
 
   if (errno != EINVAL)
   if (errno != EINVAL)
-    return -errno;
+    return UV__ERR(errno);
 #endif
 #endif
 
 
   sockfd = socket(domain, type, protocol);
   sockfd = socket(domain, type, protocol);
   if (sockfd == -1)
   if (sockfd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   err = uv__nonblock(sockfd, 1);
   err = uv__nonblock(sockfd, 1);
   if (err == 0)
   if (err == 0)
@@ -487,7 +487,7 @@ int uv__accept(int sockfd) {
       continue;
       continue;
 
 
     if (errno != ENOSYS)
     if (errno != ENOSYS)
-      return -errno;
+      return UV__ERR(errno);
 
 
     no_accept4 = 1;
     no_accept4 = 1;
 skip:
 skip:
@@ -497,7 +497,7 @@ skip:
     if (peerfd == -1) {
     if (peerfd == -1) {
       if (errno == EINTR)
       if (errno == EINTR)
         continue;
         continue;
-      return -errno;
+      return UV__ERR(errno);
     }
     }
 
 
     err = uv__cloexec(peerfd, 1);
     err = uv__cloexec(peerfd, 1);
@@ -523,8 +523,8 @@ int uv__close_nocheckstdio(int fd) {
   saved_errno = errno;
   saved_errno = errno;
   rc = close(fd);
   rc = close(fd);
   if (rc == -1) {
   if (rc == -1) {
-    rc = -errno;
-    if (rc == -EINTR || rc == -EINPROGRESS)
+    rc = UV__ERR(errno);
+    if (rc == UV_EINTR || rc == UV__ERR(EINPROGRESS))
       rc = 0;    /* The close is in progress, not an error. */
       rc = 0;    /* The close is in progress, not an error. */
     errno = saved_errno;
     errno = saved_errno;
   }
   }
@@ -536,7 +536,7 @@ int uv__close_nocheckstdio(int fd) {
 int uv__close(int fd) {
 int uv__close(int fd) {
   assert(fd > STDERR_FILENO);  /* Catch stdio close bugs. */
   assert(fd > STDERR_FILENO);  /* Catch stdio close bugs. */
 #if defined(__MVS__)
 #if defined(__MVS__)
-  epoll_file_close(fd);
+  SAVE_ERRNO(epoll_file_close(fd));
 #endif
 #endif
   return uv__close_nocheckstdio(fd);
   return uv__close_nocheckstdio(fd);
 }
 }
@@ -550,7 +550,7 @@ int uv__nonblock_ioctl(int fd, int set) {
   while (r == -1 && errno == EINTR);
   while (r == -1 && errno == EINTR);
 
 
   if (r)
   if (r)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -565,7 +565,7 @@ int uv__cloexec_ioctl(int fd, int set) {
   while (r == -1 && errno == EINTR);
   while (r == -1 && errno == EINTR);
 
 
   if (r)
   if (r)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -581,7 +581,7 @@ int uv__nonblock_fcntl(int fd, int set) {
   while (r == -1 && errno == EINTR);
   while (r == -1 && errno == EINTR);
 
 
   if (r == -1)
   if (r == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   /* Bail out now if already set/clear. */
   /* Bail out now if already set/clear. */
   if (!!(r & O_NONBLOCK) == !!set)
   if (!!(r & O_NONBLOCK) == !!set)
@@ -597,7 +597,7 @@ int uv__nonblock_fcntl(int fd, int set) {
   while (r == -1 && errno == EINTR);
   while (r == -1 && errno == EINTR);
 
 
   if (r)
   if (r)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -612,7 +612,7 @@ int uv__cloexec_fcntl(int fd, int set) {
   while (r == -1 && errno == EINTR);
   while (r == -1 && errno == EINTR);
 
 
   if (r == -1)
   if (r == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   /* Bail out now if already set/clear. */
   /* Bail out now if already set/clear. */
   if (!!(r & FD_CLOEXEC) == !!set)
   if (!!(r & FD_CLOEXEC) == !!set)
@@ -628,7 +628,7 @@ int uv__cloexec_fcntl(int fd, int set) {
   while (r == -1 && errno == EINTR);
   while (r == -1 && errno == EINTR);
 
 
   if (r)
   if (r)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -643,7 +643,7 @@ int uv__dup(int fd) {
   fd = dup(fd);
   fd = dup(fd);
 
 
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   err = uv__cloexec(fd, 1);
   err = uv__cloexec(fd, 1);
   if (err) {
   if (err) {
@@ -667,10 +667,10 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
     if (rc != -1)
     if (rc != -1)
       return rc;
       return rc;
     if (errno != EINVAL)
     if (errno != EINVAL)
-      return -errno;
+      return UV__ERR(errno);
     rc = recvmsg(fd, msg, flags);
     rc = recvmsg(fd, msg, flags);
     if (rc == -1)
     if (rc == -1)
-      return -errno;
+      return UV__ERR(errno);
     no_msg_cmsg_cloexec = 1;
     no_msg_cmsg_cloexec = 1;
   } else {
   } else {
     rc = recvmsg(fd, msg, flags);
     rc = recvmsg(fd, msg, flags);
@@ -679,7 +679,7 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
   rc = recvmsg(fd, msg, flags);
   rc = recvmsg(fd, msg, flags);
 #endif
 #endif
   if (rc == -1)
   if (rc == -1)
-    return -errno;
+    return UV__ERR(errno);
   if (msg->msg_controllen == 0)
   if (msg->msg_controllen == 0)
     return rc;
     return rc;
   for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
   for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
@@ -695,10 +695,10 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
 
 
 int uv_cwd(char* buffer, size_t* size) {
 int uv_cwd(char* buffer, size_t* size) {
   if (buffer == NULL || size == NULL)
   if (buffer == NULL || size == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (getcwd(buffer, *size) == NULL)
   if (getcwd(buffer, *size) == NULL)
-    return -errno;
+    return UV__ERR(errno);
 
 
   *size = strlen(buffer);
   *size = strlen(buffer);
   if (*size > 1 && buffer[*size - 1] == '/') {
   if (*size > 1 && buffer[*size - 1] == '/') {
@@ -712,7 +712,7 @@ int uv_cwd(char* buffer, size_t* size) {
 
 
 int uv_chdir(const char* dir) {
 int uv_chdir(const char* dir) {
   if (chdir(dir))
   if (chdir(dir))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -749,11 +749,11 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
     break;
     break;
 
 
   default:
   default:
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 
 
   if (uv__is_closing(handle) || fd_out == -1)
   if (uv__is_closing(handle) || fd_out == -1)
-    return -EBADF;
+    return UV_EBADF;
 
 
   *fd = fd_out;
   *fd = fd_out;
   return 0;
   return 0;
@@ -931,7 +931,7 @@ int uv_getrusage(uv_rusage_t* rusage) {
   struct rusage usage;
   struct rusage usage;
 
 
   if (getrusage(RUSAGE_SELF, &usage))
   if (getrusage(RUSAGE_SELF, &usage))
-    return -errno;
+    return UV__ERR(errno);
 
 
   rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec;
   rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec;
   rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec;
   rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec;
@@ -973,7 +973,7 @@ int uv__open_cloexec(const char* path, int flags) {
       return fd;
       return fd;
 
 
     if (errno != EINVAL)
     if (errno != EINVAL)
-      return -errno;
+      return UV__ERR(errno);
 
 
     /* O_CLOEXEC not supported. */
     /* O_CLOEXEC not supported. */
     no_cloexec = 1;
     no_cloexec = 1;
@@ -982,7 +982,7 @@ int uv__open_cloexec(const char* path, int flags) {
 
 
   fd = open(path, flags);
   fd = open(path, flags);
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   err = uv__cloexec(fd, 1);
   err = uv__cloexec(fd, 1);
   if (err) {
   if (err) {
@@ -999,14 +999,14 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
 #if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__)
 #if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__)
   r = dup3(oldfd, newfd, O_CLOEXEC);
   r = dup3(oldfd, newfd, O_CLOEXEC);
   if (r == -1)
   if (r == -1)
-    return -errno;
+    return UV__ERR(errno);
   return r;
   return r;
 #elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC)
 #elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC)
   r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
   r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
   if (r != -1)
   if (r != -1)
     return r;
     return r;
   if (errno != EINVAL)
   if (errno != EINVAL)
-    return -errno;
+    return UV__ERR(errno);
   /* Fall through. */
   /* Fall through. */
 #elif defined(__linux__)
 #elif defined(__linux__)
   static int no_dup3;
   static int no_dup3;
@@ -1017,7 +1017,7 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
     if (r != -1)
     if (r != -1)
       return r;
       return r;
     if (errno != ENOSYS)
     if (errno != ENOSYS)
-      return -errno;
+      return UV__ERR(errno);
     /* Fall through. */
     /* Fall through. */
     no_dup3 = 1;
     no_dup3 = 1;
   }
   }
@@ -1033,7 +1033,7 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
 #endif
 #endif
 
 
     if (r == -1)
     if (r == -1)
-      return -errno;
+      return UV__ERR(errno);
 
 
     err = uv__cloexec(newfd, 1);
     err = uv__cloexec(newfd, 1);
     if (err) {
     if (err) {
@@ -1048,29 +1048,16 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
 
 
 int uv_os_homedir(char* buffer, size_t* size) {
 int uv_os_homedir(char* buffer, size_t* size) {
   uv_passwd_t pwd;
   uv_passwd_t pwd;
-  char* buf;
   size_t len;
   size_t len;
   int r;
   int r;
 
 
-  if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
-
-  /* Check if the HOME environment variable is set first */
-  buf = getenv("HOME");
-
-  if (buf != NULL) {
-    len = strlen(buf);
-
-    if (len >= *size) {
-      *size = len + 1;
-      return -ENOBUFS;
-    }
-
-    memcpy(buffer, buf, len + 1);
-    *size = len;
+  /* Check if the HOME environment variable is set first. The task of
+     performing input validation on buffer and size is taken care of by
+     uv_os_getenv(). */
+  r = uv_os_getenv("HOME", buffer, size);
 
 
-    return 0;
-  }
+  if (r != UV_ENOENT)
+    return r;
 
 
   /* HOME is not set, so call uv__getpwuid_r() */
   /* HOME is not set, so call uv__getpwuid_r() */
   r = uv__getpwuid_r(&pwd);
   r = uv__getpwuid_r(&pwd);
@@ -1084,7 +1071,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
   if (len >= *size) {
   if (len >= *size) {
     *size = len + 1;
     *size = len + 1;
     uv_os_free_passwd(&pwd);
     uv_os_free_passwd(&pwd);
-    return -ENOBUFS;
+    return UV_ENOBUFS;
   }
   }
 
 
   memcpy(buffer, pwd.homedir, len + 1);
   memcpy(buffer, pwd.homedir, len + 1);
@@ -1100,7 +1087,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
   size_t len;
   size_t len;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
 #define CHECK_ENV_VAR(name)                                                   \
 #define CHECK_ENV_VAR(name)                                                   \
   do {                                                                        \
   do {                                                                        \
@@ -1130,7 +1117,7 @@ return_buffer:
 
 
   if (len >= *size) {
   if (len >= *size) {
     *size = len + 1;
     *size = len + 1;
-    return -ENOBUFS;
+    return UV_ENOBUFS;
   }
   }
 
 
   /* The returned directory should not have a trailing slash. */
   /* The returned directory should not have a trailing slash. */
@@ -1162,11 +1149,11 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
 
 
   getpwuid_r = dlsym(RTLD_DEFAULT, "getpwuid_r");
   getpwuid_r = dlsym(RTLD_DEFAULT, "getpwuid_r");
   if (getpwuid_r == NULL)
   if (getpwuid_r == NULL)
-    return -ENOSYS;
+    return UV_ENOSYS;
 #endif
 #endif
 
 
   if (pwd == NULL)
   if (pwd == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   initsize = sysconf(_SC_GETPW_R_SIZE_MAX);
   initsize = sysconf(_SC_GETPW_R_SIZE_MAX);
 
 
@@ -1183,7 +1170,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
     buf = uv__malloc(bufsize);
     buf = uv__malloc(bufsize);
 
 
     if (buf == NULL)
     if (buf == NULL)
-      return -ENOMEM;
+      return UV_ENOMEM;
 
 
     r = getpwuid_r(uid, &pw, buf, bufsize, &result);
     r = getpwuid_r(uid, &pw, buf, bufsize, &result);
 
 
@@ -1200,7 +1187,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
 
 
   if (result == NULL) {
   if (result == NULL) {
     uv__free(buf);
     uv__free(buf);
-    return -ENOENT;
+    return UV_ENOENT;
   }
   }
 
 
   /* Allocate memory for the username, shell, and home directory */
   /* Allocate memory for the username, shell, and home directory */
@@ -1211,7 +1198,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
 
 
   if (pwd->username == NULL) {
   if (pwd->username == NULL) {
     uv__free(buf);
     uv__free(buf);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   /* Copy the username */
   /* Copy the username */
@@ -1267,18 +1254,18 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
   size_t len;
   size_t len;
 
 
   if (name == NULL || buffer == NULL || size == NULL || *size == 0)
   if (name == NULL || buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   var = getenv(name);
   var = getenv(name);
 
 
   if (var == NULL)
   if (var == NULL)
-    return -ENOENT;
+    return UV_ENOENT;
 
 
   len = strlen(var);
   len = strlen(var);
 
 
   if (len >= *size) {
   if (len >= *size) {
     *size = len + 1;
     *size = len + 1;
-    return -ENOBUFS;
+    return UV_ENOBUFS;
   }
   }
 
 
   memcpy(buffer, var, len + 1);
   memcpy(buffer, var, len + 1);
@@ -1290,10 +1277,10 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
 
 
 int uv_os_setenv(const char* name, const char* value) {
 int uv_os_setenv(const char* name, const char* value) {
   if (name == NULL || value == NULL)
   if (name == NULL || value == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (setenv(name, value, 1) != 0)
   if (setenv(name, value, 1) != 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -1301,10 +1288,10 @@ int uv_os_setenv(const char* name, const char* value) {
 
 
 int uv_os_unsetenv(const char* name) {
 int uv_os_unsetenv(const char* name) {
   if (name == NULL)
   if (name == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (unsetenv(name) != 0)
   if (unsetenv(name) != 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -1321,17 +1308,17 @@ int uv_os_gethostname(char* buffer, size_t* size) {
   size_t len;
   size_t len;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (gethostname(buf, sizeof(buf)) != 0)
   if (gethostname(buf, sizeof(buf)) != 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
   buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
   len = strlen(buf);
   len = strlen(buf);
 
 
   if (len >= *size) {
   if (len >= *size) {
     *size = len + 1;
     *size = len + 1;
-    return -ENOBUFS;
+    return UV_ENOBUFS;
   }
   }
 
 
   memcpy(buffer, buf, len + 1);
   memcpy(buffer, buf, len + 1);

+ 1 - 1
src/unix/cygwin.c

@@ -29,7 +29,7 @@ int uv_uptime(double* uptime) {
   struct sysinfo info;
   struct sysinfo info;
 
 
   if (sysinfo(&info) < 0)
   if (sysinfo(&info) < 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   *uptime = info.uptime;
   *uptime = info.uptime;
   return 0;
   return 0;

+ 8 - 5
src/unix/darwin-proctitle.c

@@ -18,6 +18,9 @@
  * IN THE SOFTWARE.
  * IN THE SOFTWARE.
  */
  */
 
 
+#include "uv.h"
+#include "internal.h"
+
 #include <dlfcn.h>
 #include <dlfcn.h>
 #include <errno.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -41,14 +44,14 @@ static int uv__pthread_setname_np(const char* name) {
       dlsym(RTLD_DEFAULT, "pthread_setname_np");
       dlsym(RTLD_DEFAULT, "pthread_setname_np");
 
 
   if (dynamic_pthread_setname_np == NULL)
   if (dynamic_pthread_setname_np == NULL)
-    return -ENOSYS;
+    return UV_ENOSYS;
 
 
   strncpy(namebuf, name, sizeof(namebuf) - 1);
   strncpy(namebuf, name, sizeof(namebuf) - 1);
   namebuf[sizeof(namebuf) - 1] = '\0';
   namebuf[sizeof(namebuf) - 1] = '\0';
 
 
   err = dynamic_pthread_setname_np(namebuf);
   err = dynamic_pthread_setname_np(namebuf);
   if (err)
   if (err)
-    return -err;
+    return UV__ERR(err);
 
 
   return 0;
   return 0;
 }
 }
@@ -84,7 +87,7 @@ int uv__set_process_title(const char* title) {
   CFTypeRef asn;
   CFTypeRef asn;
   int err;
   int err;
 
 
-  err = -ENOENT;
+  err = UV_ENOENT;
   application_services_handle = dlopen("/System/Library/Frameworks/"
   application_services_handle = dlopen("/System/Library/Frameworks/"
                                        "ApplicationServices.framework/"
                                        "ApplicationServices.framework/"
                                        "Versions/A/ApplicationServices",
                                        "Versions/A/ApplicationServices",
@@ -151,7 +154,7 @@ int uv__set_process_title(const char* title) {
   /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
   /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
   hi_services_bundle =
   hi_services_bundle =
       pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
       pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
-  err = -ENOENT;
+  err = UV_ENOENT;
   if (hi_services_bundle == NULL)
   if (hi_services_bundle == NULL)
     goto out;
     goto out;
 
 
@@ -182,7 +185,7 @@ int uv__set_process_title(const char* title) {
 
 
   asn = pLSGetCurrentApplicationASN();
   asn = pLSGetCurrentApplicationASN();
 
 
-  err = -EINVAL;
+  err = UV_EINVAL;
   if (pLSSetApplicationInformationItem(-2,  /* Magic value. */
   if (pLSSetApplicationInformationItem(-2,  /* Magic value. */
                                        asn,
                                        asn,
                                        *display_name_key,
                                        *display_name_key,

+ 12 - 12
src/unix/darwin.c

@@ -37,7 +37,7 @@ int uv__platform_loop_init(uv_loop_t* loop) {
   loop->cf_state = NULL;
   loop->cf_state = NULL;
 
 
   if (uv__kqueue_init(loop))
   if (uv__kqueue_init(loop))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -68,18 +68,18 @@ int uv_exepath(char* buffer, size_t* size) {
   size_t abspath_size;
   size_t abspath_size;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   exepath_size = sizeof(exepath);
   exepath_size = sizeof(exepath);
   if (_NSGetExecutablePath(exepath, &exepath_size))
   if (_NSGetExecutablePath(exepath, &exepath_size))
-    return -EIO;
+    return UV_EIO;
 
 
   if (realpath(exepath, abspath) != abspath)
   if (realpath(exepath, abspath) != abspath)
-    return -errno;
+    return UV__ERR(errno);
 
 
   abspath_size = strlen(abspath);
   abspath_size = strlen(abspath);
   if (abspath_size == 0)
   if (abspath_size == 0)
-    return -EIO;
+    return UV_EIO;
 
 
   *size -= 1;
   *size -= 1;
   if (*size > abspath_size)
   if (*size > abspath_size)
@@ -98,7 +98,7 @@ uint64_t uv_get_free_memory(void) {
 
 
   if (host_statistics(mach_host_self(), HOST_VM_INFO,
   if (host_statistics(mach_host_self(), HOST_VM_INFO,
                       (host_info_t)&info, &count) != KERN_SUCCESS) {
                       (host_info_t)&info, &count) != KERN_SUCCESS) {
-    return -EINVAL;  /* FIXME(bnoordhuis) Translate error. */
+    return UV_EINVAL;  /* FIXME(bnoordhuis) Translate error. */
   }
   }
 
 
   return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE);
   return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE);
@@ -111,7 +111,7 @@ uint64_t uv_get_total_memory(void) {
   size_t size = sizeof(info);
   size_t size = sizeof(info);
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return (uint64_t) info;
   return (uint64_t) info;
 }
 }
@@ -158,7 +158,7 @@ int uv_uptime(double* uptime) {
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   now = time(NULL);
   now = time(NULL);
   *uptime = now - info.tv_sec;
   *uptime = now - info.tv_sec;
@@ -181,23 +181,23 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   size = sizeof(model);
   size = sizeof(model);
   if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) &&
   if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) &&
       sysctlbyname("hw.model", &model, &size, NULL, 0)) {
       sysctlbyname("hw.model", &model, &size, NULL, 0)) {
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   size = sizeof(cpuspeed);
   size = sizeof(cpuspeed);
   if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0))
   if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus,
   if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus,
                           (processor_info_array_t*)&info,
                           (processor_info_array_t*)&info,
                           &msg_type) != KERN_SUCCESS) {
                           &msg_type) != KERN_SUCCESS) {
-    return -EINVAL;  /* FIXME(bnoordhuis) Translate error. */
+    return UV_EINVAL;  /* FIXME(bnoordhuis) Translate error. */
   }
   }
 
 
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos)) {
   if (!(*cpu_infos)) {
     vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
     vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   *count = numcpus;
   *count = numcpus;

+ 17 - 17
src/unix/freebsd.c

@@ -72,11 +72,11 @@ int uv_exepath(char* buffer, size_t* size) {
   ssize_t abspath_size;
   ssize_t abspath_size;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   abspath_size = readlink("/proc/curproc/file", abspath, sizeof(abspath));
   abspath_size = readlink("/proc/curproc/file", abspath, sizeof(abspath));
   if (abspath_size < 0)
   if (abspath_size < 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   assert(abspath_size > 0);
   assert(abspath_size > 0);
   *size -= 1;
   *size -= 1;
@@ -96,7 +96,7 @@ int uv_exepath(char* buffer, size_t* size) {
   size_t abspath_size;
   size_t abspath_size;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   mib[0] = CTL_KERN;
   mib[0] = CTL_KERN;
   mib[1] = KERN_PROC;
   mib[1] = KERN_PROC;
@@ -105,7 +105,7 @@ int uv_exepath(char* buffer, size_t* size) {
 
 
   abspath_size = sizeof abspath;
   abspath_size = sizeof abspath;
   if (sysctl(mib, 4, abspath, &abspath_size, NULL, 0))
   if (sysctl(mib, 4, abspath, &abspath_size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   assert(abspath_size > 0);
   assert(abspath_size > 0);
   abspath_size -= 1;
   abspath_size -= 1;
@@ -126,7 +126,7 @@ uint64_t uv_get_free_memory(void) {
   size_t size = sizeof(freecount);
   size_t size = sizeof(freecount);
 
 
   if (sysctlbyname("vm.stats.vm.v_free_count", &freecount, &size, NULL, 0))
   if (sysctlbyname("vm.stats.vm.v_free_count", &freecount, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return (uint64_t) freecount * sysconf(_SC_PAGESIZE);
   return (uint64_t) freecount * sysconf(_SC_PAGESIZE);
 
 
@@ -140,7 +140,7 @@ uint64_t uv_get_total_memory(void) {
   size_t size = sizeof(info);
   size_t size = sizeof(info);
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return (uint64_t) info;
   return (uint64_t) info;
 }
 }
@@ -176,7 +176,7 @@ int uv_set_process_title(const char* title) {
 
 
   if (process_title == NULL) {
   if (process_title == NULL) {
     uv_mutex_unlock(&process_title_mutex);
     uv_mutex_unlock(&process_title_mutex);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   uv__free(process_title);
   uv__free(process_title);
@@ -204,7 +204,7 @@ int uv_get_process_title(char* buffer, size_t size) {
   size_t len;
   size_t len;
 
 
   if (buffer == NULL || size == 0)
   if (buffer == NULL || size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_mutex_lock(&process_title_mutex);
   uv_mutex_lock(&process_title_mutex);
@@ -214,7 +214,7 @@ int uv_get_process_title(char* buffer, size_t size) {
 
 
     if (size < len) {
     if (size < len) {
       uv_mutex_unlock(&process_title_mutex);
       uv_mutex_unlock(&process_title_mutex);
-      return -ENOBUFS;
+      return UV_ENOBUFS;
     }
     }
 
 
     memcpy(buffer, process_title, len);
     memcpy(buffer, process_title, len);
@@ -243,7 +243,7 @@ int uv_resident_set_memory(size_t* rss) {
   kinfo_size = sizeof(kinfo);
   kinfo_size = sizeof(kinfo);
 
 
   if (sysctl(mib, 4, &kinfo, &kinfo_size, NULL, 0))
   if (sysctl(mib, 4, &kinfo, &kinfo_size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   page_size = getpagesize();
   page_size = getpagesize();
 
 
@@ -262,7 +262,7 @@ int uv_uptime(double* uptime) {
   struct timespec sp;
   struct timespec sp;
   r = clock_gettime(CLOCK_MONOTONIC, &sp);
   r = clock_gettime(CLOCK_MONOTONIC, &sp);
   if (r)
   if (r)
-    return -errno;
+    return UV__ERR(errno);
 
 
   *uptime = sp.tv_sec;
   *uptime = sp.tv_sec;
   return 0;
   return 0;
@@ -309,15 +309,15 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
 
   size = sizeof(model);
   size = sizeof(model);
   if (sysctlbyname(model_key, &model, &size, NULL, 0))
   if (sysctlbyname(model_key, &model, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   size = sizeof(numcpus);
   size = sizeof(numcpus);
   if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
   if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos))
   if (!(*cpu_infos))
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   *count = numcpus;
   *count = numcpus;
 
 
@@ -327,7 +327,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   size = sizeof(maxcpus);
   size = sizeof(maxcpus);
   if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) {
   if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) {
     uv__free(*cpu_infos);
     uv__free(*cpu_infos);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   size = maxcpus * CPUSTATES * sizeof(long);
   size = maxcpus * CPUSTATES * sizeof(long);
@@ -335,13 +335,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   cp_times = uv__malloc(size);
   cp_times = uv__malloc(size);
   if (cp_times == NULL) {
   if (cp_times == NULL) {
     uv__free(*cpu_infos);
     uv__free(*cpu_infos);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) {
   if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) {
     uv__free(cp_times);
     uv__free(cp_times);
     uv__free(*cpu_infos);
     uv__free(*cpu_infos);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   for (i = 0; i < numcpus; i++) {
   for (i = 0; i < numcpus; i++) {

+ 69 - 36
src/unix/fs.c

@@ -62,21 +62,23 @@
 
 
 #if defined(__APPLE__)
 #if defined(__APPLE__)
 # include <copyfile.h>
 # include <copyfile.h>
+#elif defined(__linux__) && !defined(FICLONE)
+# include <sys/ioctl.h>
+# define FICLONE _IOW(0x94, 9, int)
 #endif
 #endif
 
 
 #define INIT(subtype)                                                         \
 #define INIT(subtype)                                                         \
   do {                                                                        \
   do {                                                                        \
     if (req == NULL)                                                          \
     if (req == NULL)                                                          \
-      return -EINVAL;                                                         \
-    req->type = UV_FS;                                                        \
-    if (cb != NULL)                                                           \
-      uv__req_init(loop, req, UV_FS);                                         \
+      return UV_EINVAL;                                                       \
+    UV_REQ_INIT(req, UV_FS);                                                  \
     req->fs_type = UV_FS_ ## subtype;                                         \
     req->fs_type = UV_FS_ ## subtype;                                         \
     req->result = 0;                                                          \
     req->result = 0;                                                          \
     req->ptr = NULL;                                                          \
     req->ptr = NULL;                                                          \
     req->loop = loop;                                                         \
     req->loop = loop;                                                         \
     req->path = NULL;                                                         \
     req->path = NULL;                                                         \
     req->new_path = NULL;                                                     \
     req->new_path = NULL;                                                     \
+    req->bufs = NULL;                                                         \
     req->cb = cb;                                                             \
     req->cb = cb;                                                             \
   }                                                                           \
   }                                                                           \
   while (0)
   while (0)
@@ -88,10 +90,8 @@
       req->path = path;                                                       \
       req->path = path;                                                       \
     } else {                                                                  \
     } else {                                                                  \
       req->path = uv__strdup(path);                                           \
       req->path = uv__strdup(path);                                           \
-      if (req->path == NULL) {                                                \
-        uv__req_unregister(loop, req);                                        \
-        return -ENOMEM;                                                       \
-      }                                                                       \
+      if (req->path == NULL)                                                  \
+        return UV_ENOMEM;                                                     \
     }                                                                         \
     }                                                                         \
   }                                                                           \
   }                                                                           \
   while (0)
   while (0)
@@ -107,10 +107,8 @@
       path_len = strlen(path) + 1;                                            \
       path_len = strlen(path) + 1;                                            \
       new_path_len = strlen(new_path) + 1;                                    \
       new_path_len = strlen(new_path) + 1;                                    \
       req->path = uv__malloc(path_len + new_path_len);                        \
       req->path = uv__malloc(path_len + new_path_len);                        \
-      if (req->path == NULL) {                                                \
-        uv__req_unregister(loop, req);                                        \
-        return -ENOMEM;                                                       \
-      }                                                                       \
+      if (req->path == NULL)                                                  \
+        return UV_ENOMEM;                                                     \
       req->new_path = req->path + path_len;                                   \
       req->new_path = req->path + path_len;                                   \
       memcpy((void*) req->path, path, path_len);                              \
       memcpy((void*) req->path, path, path_len);                              \
       memcpy((void*) req->new_path, new_path, new_path_len);                  \
       memcpy((void*) req->new_path, new_path, new_path_len);                  \
@@ -121,6 +119,7 @@
 #define POST                                                                  \
 #define POST                                                                  \
   do {                                                                        \
   do {                                                                        \
     if (cb != NULL) {                                                         \
     if (cb != NULL) {                                                         \
+      uv__req_register(loop, req);                                            \
       uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done);        \
       uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done);        \
       return 0;                                                               \
       return 0;                                                               \
     }                                                                         \
     }                                                                         \
@@ -794,6 +793,19 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
   if (req->flags & UV_FS_COPYFILE_EXCL)
   if (req->flags & UV_FS_COPYFILE_EXCL)
     flags |= COPYFILE_EXCL;
     flags |= COPYFILE_EXCL;
 
 
+#ifdef COPYFILE_CLONE
+  if (req->flags & UV_FS_COPYFILE_FICLONE)
+    flags |= COPYFILE_CLONE;
+#endif
+
+  if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
+#ifdef COPYFILE_CLONE_FORCE
+    flags |= COPYFILE_CLONE_FORCE;
+#else
+    return UV_ENOSYS;
+#endif
+  }
+
   return copyfile(req->path, req->new_path, NULL, flags);
   return copyfile(req->path, req->new_path, NULL, flags);
 #else
 #else
   uv_fs_t fs_req;
   uv_fs_t fs_req;
@@ -818,7 +830,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
 
 
   /* Get the source file's mode. */
   /* Get the source file's mode. */
   if (fstat(srcfd, &statsbuf)) {
   if (fstat(srcfd, &statsbuf)) {
-    err = -errno;
+    err = UV__ERR(errno);
     goto out;
     goto out;
   }
   }
 
 
@@ -842,9 +854,32 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
   }
   }
 
 
   if (fchmod(dstfd, statsbuf.st_mode) == -1) {
   if (fchmod(dstfd, statsbuf.st_mode) == -1) {
-    err = -errno;
+    err = UV__ERR(errno);
+    goto out;
+  }
+
+#ifdef FICLONE
+  if (req->flags & UV_FS_COPYFILE_FICLONE ||
+      req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
+    if (ioctl(dstfd, FICLONE, srcfd) == -1) {
+      /* If an error occurred that the sendfile fallback also won't handle, or
+         this is a force clone then exit. Otherwise, fall through to try using
+         sendfile(). */
+      if ((errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) ||
+          req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
+        err = -errno;
+        goto out;
+      }
+    } else {
+      goto out;
+    }
+  }
+#else
+  if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
+    err = UV_ENOSYS;
     goto out;
     goto out;
   }
   }
+#endif
 
 
   bytes_to_send = statsbuf.st_size;
   bytes_to_send = statsbuf.st_size;
   in_offset = 0;
   in_offset = 0;
@@ -1107,7 +1142,7 @@ static void uv__fs_work(struct uv__work* w) {
   } while (r == -1 && errno == EINTR && retry_on_eintr);
   } while (r == -1 && errno == EINTR && retry_on_eintr);
 
 
   if (r == -1)
   if (r == -1)
-    req->result = -errno;
+    req->result = UV__ERR(errno);
   else
   else
     req->result = r;
     req->result = r;
 
 
@@ -1125,9 +1160,9 @@ static void uv__fs_done(struct uv__work* w, int status) {
   req = container_of(w, uv_fs_t, work_req);
   req = container_of(w, uv_fs_t, work_req);
   uv__req_unregister(req->loop, req);
   uv__req_unregister(req->loop, req);
 
 
-  if (status == -ECANCELED) {
+  if (status == UV_ECANCELED) {
     assert(req->result == 0);
     assert(req->result == 0);
-    req->result = -ECANCELED;
+    req->result = UV_ECANCELED;
   }
   }
 
 
   req->cb(req);
   req->cb(req);
@@ -1288,11 +1323,8 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
                   uv_fs_cb cb) {
                   uv_fs_cb cb) {
   INIT(MKDTEMP);
   INIT(MKDTEMP);
   req->path = uv__strdup(tpl);
   req->path = uv__strdup(tpl);
-  if (req->path == NULL) {
-    if (cb != NULL)
-      uv__req_unregister(loop, req);
-    return -ENOMEM;
-  }
+  if (req->path == NULL)
+    return UV_ENOMEM;
   POST;
   POST;
 }
 }
 
 
@@ -1320,7 +1352,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
   INIT(READ);
   INIT(READ);
 
 
   if (bufs == NULL || nbufs == 0)
   if (bufs == NULL || nbufs == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   req->file = file;
   req->file = file;
 
 
@@ -1329,11 +1361,8 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
   if (nbufs > ARRAY_SIZE(req->bufsml))
   if (nbufs > ARRAY_SIZE(req->bufsml))
     req->bufs = uv__malloc(nbufs * sizeof(*bufs));
     req->bufs = uv__malloc(nbufs * sizeof(*bufs));
 
 
-  if (req->bufs == NULL) {
-    if (cb != NULL)
-      uv__req_unregister(loop, req);
-    return -ENOMEM;
-  }
+  if (req->bufs == NULL)
+    return UV_ENOMEM;
 
 
   memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
   memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
 
 
@@ -1459,7 +1488,7 @@ int uv_fs_write(uv_loop_t* loop,
   INIT(WRITE);
   INIT(WRITE);
 
 
   if (bufs == NULL || nbufs == 0)
   if (bufs == NULL || nbufs == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   req->file = file;
   req->file = file;
 
 
@@ -1468,11 +1497,8 @@ int uv_fs_write(uv_loop_t* loop,
   if (nbufs > ARRAY_SIZE(req->bufsml))
   if (nbufs > ARRAY_SIZE(req->bufsml))
     req->bufs = uv__malloc(nbufs * sizeof(*bufs));
     req->bufs = uv__malloc(nbufs * sizeof(*bufs));
 
 
-  if (req->bufs == NULL) {
-    if (cb != NULL)
-      uv__req_unregister(loop, req);
-    return -ENOMEM;
-  }
+  if (req->bufs == NULL)
+    return UV_ENOMEM;
 
 
   memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
   memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
 
 
@@ -1499,6 +1525,10 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
   if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
   if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
     uv__fs_scandir_cleanup(req);
     uv__fs_scandir_cleanup(req);
 
 
+  if (req->bufs != req->bufsml)
+    uv__free(req->bufs);
+  req->bufs = NULL;
+
   if (req->ptr != &req->statbuf)
   if (req->ptr != &req->statbuf)
     uv__free(req->ptr);
     uv__free(req->ptr);
   req->ptr = NULL;
   req->ptr = NULL;
@@ -1513,8 +1543,11 @@ int uv_fs_copyfile(uv_loop_t* loop,
                    uv_fs_cb cb) {
                    uv_fs_cb cb) {
   INIT(COPYFILE);
   INIT(COPYFILE);
 
 
-  if (flags & ~UV_FS_COPYFILE_EXCL)
-    return -EINVAL;
+  if (flags & ~(UV_FS_COPYFILE_EXCL |
+                UV_FS_COPYFILE_FICLONE |
+                UV_FS_COPYFILE_FICLONE_FORCE)) {
+    return UV_EINVAL;
+  }
 
 
   PATH2;
   PATH2;
   req->flags = flags;
   req->flags = flags;

+ 13 - 13
src/unix/fsevents.c

@@ -379,7 +379,7 @@ static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) {
   if (!pFSEventStreamStart(ref)) {
   if (!pFSEventStreamStart(ref)) {
     pFSEventStreamInvalidate(ref);
     pFSEventStreamInvalidate(ref);
     pFSEventStreamRelease(ref);
     pFSEventStreamRelease(ref);
-    return -EMFILE;
+    return UV_EMFILE;
   }
   }
 
 
   state->fsevent_stream = ref;
   state->fsevent_stream = ref;
@@ -440,7 +440,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle,
   uv__fsevents_destroy_stream(handle->loop);
   uv__fsevents_destroy_stream(handle->loop);
 
 
   /* Any failure below will be a memory failure */
   /* Any failure below will be a memory failure */
-  err = -ENOMEM;
+  err = UV_ENOMEM;
 
 
   /* Create list of all watched paths */
   /* Create list of all watched paths */
   uv_mutex_lock(&state->fsevent_mutex);
   uv_mutex_lock(&state->fsevent_mutex);
@@ -474,7 +474,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle,
     /* Create new FSEventStream */
     /* Create new FSEventStream */
     cf_paths = pCFArrayCreate(NULL, (const void**) paths, path_count, NULL);
     cf_paths = pCFArrayCreate(NULL, (const void**) paths, path_count, NULL);
     if (cf_paths == NULL) {
     if (cf_paths == NULL) {
-      err = -ENOMEM;
+      err = UV_ENOMEM;
       goto final;
       goto final;
     }
     }
     err = uv__fsevents_create_stream(handle->loop, cf_paths);
     err = uv__fsevents_create_stream(handle->loop, cf_paths);
@@ -528,7 +528,7 @@ static int uv__fsevents_global_init(void) {
    * but if it ever becomes one, we can turn the dynamic library handles into
    * but if it ever becomes one, we can turn the dynamic library handles into
    * per-event loop properties and have the dynamic linker keep track for us.
    * per-event loop properties and have the dynamic linker keep track for us.
    */
    */
-  err = -ENOSYS;
+  err = UV_ENOSYS;
   core_foundation_handle = dlopen("/System/Library/Frameworks/"
   core_foundation_handle = dlopen("/System/Library/Frameworks/"
                                   "CoreFoundation.framework/"
                                   "CoreFoundation.framework/"
                                   "Versions/A/CoreFoundation",
                                   "Versions/A/CoreFoundation",
@@ -543,7 +543,7 @@ static int uv__fsevents_global_init(void) {
   if (core_services_handle == NULL)
   if (core_services_handle == NULL)
     goto out;
     goto out;
 
 
-  err = -ENOENT;
+  err = UV_ENOENT;
 #define V(handle, symbol)                                                     \
 #define V(handle, symbol)                                                     \
   do {                                                                        \
   do {                                                                        \
     *(void **)(&p ## symbol) = dlsym((handle), #symbol);                      \
     *(void **)(&p ## symbol) = dlsym((handle), #symbol);                      \
@@ -607,7 +607,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
 
 
   state = uv__calloc(1, sizeof(*state));
   state = uv__calloc(1, sizeof(*state));
   if (state == NULL)
   if (state == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   err = uv_mutex_init(&loop->cf_mutex);
   err = uv_mutex_init(&loop->cf_mutex);
   if (err)
   if (err)
@@ -636,7 +636,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
   ctx.perform = uv__cf_loop_cb;
   ctx.perform = uv__cf_loop_cb;
   state->signal_source = pCFRunLoopSourceCreate(NULL, 0, &ctx);
   state->signal_source = pCFRunLoopSourceCreate(NULL, 0, &ctx);
   if (state->signal_source == NULL) {
   if (state->signal_source == NULL) {
-    err = -ENOMEM;
+    err = UV_ENOMEM;
     goto fail_signal_source_create;
     goto fail_signal_source_create;
   }
   }
 
 
@@ -655,7 +655,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
   loop->cf_state = state;
   loop->cf_state = state;
 
 
   /* uv_thread_t is an alias for pthread_t. */
   /* uv_thread_t is an alias for pthread_t. */
-  err = -pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop);
+  err = UV__ERR(pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop));
 
 
   if (attr != NULL)
   if (attr != NULL)
     pthread_attr_destroy(attr);
     pthread_attr_destroy(attr);
@@ -787,7 +787,7 @@ int uv__cf_loop_signal(uv_loop_t* loop,
 
 
   item = uv__malloc(sizeof(*item));
   item = uv__malloc(sizeof(*item));
   if (item == NULL)
   if (item == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   item->handle = handle;
   item->handle = handle;
   item->type = type;
   item->type = type;
@@ -817,7 +817,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
   /* Get absolute path to file */
   /* Get absolute path to file */
   handle->realpath = realpath(handle->path, NULL);
   handle->realpath = realpath(handle->path, NULL);
   if (handle->realpath == NULL)
   if (handle->realpath == NULL)
-    return -errno;
+    return UV__ERR(errno);
   handle->realpath_len = strlen(handle->realpath);
   handle->realpath_len = strlen(handle->realpath);
 
 
   /* Initialize event queue */
   /* Initialize event queue */
@@ -830,7 +830,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
    */
    */
   handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb));
   handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb));
   if (handle->cf_cb == NULL) {
   if (handle->cf_cb == NULL) {
-    err = -ENOMEM;
+    err = UV_ENOMEM;
     goto fail_cf_cb_malloc;
     goto fail_cf_cb_malloc;
   }
   }
 
 
@@ -881,7 +881,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
   uv__cf_loop_state_t* state;
   uv__cf_loop_state_t* state;
 
 
   if (handle->cf_cb == NULL)
   if (handle->cf_cb == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   /* Remove handle from  the list */
   /* Remove handle from  the list */
   state = handle->loop->cf_state;
   state = handle->loop->cf_state;
@@ -895,7 +895,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
   assert(handle != NULL);
   assert(handle != NULL);
   err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalClosing);
   err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalClosing);
   if (err)
   if (err)
-    return -err;
+    return UV__ERR(err);
 
 
   /* Wait for deinitialization */
   /* Wait for deinitialization */
   uv_sem_wait(&state->fsevent_sem);
   uv_sem_wait(&state->fsevent_sem);

+ 5 - 5
src/unix/getaddrinfo.c

@@ -86,7 +86,7 @@ int uv__getaddrinfo_translate_error(int sys_err) {
   case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
   case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
 #endif
 #endif
 #if defined(EAI_SYSTEM)
 #if defined(EAI_SYSTEM)
-  case EAI_SYSTEM: return -errno;
+  case EAI_SYSTEM: return UV__ERR(errno);
 #endif
 #endif
   }
   }
   assert(!"unknown EAI_* error code");
   assert(!"unknown EAI_* error code");
@@ -125,7 +125,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
   req->service = NULL;
   req->service = NULL;
   req->hostname = NULL;
   req->hostname = NULL;
 
 
-  if (status == -ECANCELED) {
+  if (status == UV_ECANCELED) {
     assert(req->retcode == 0);
     assert(req->retcode == 0);
     req->retcode = UV_EAI_CANCELED;
     req->retcode = UV_EAI_CANCELED;
   }
   }
@@ -148,7 +148,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
   char* buf;
   char* buf;
 
 
   if (req == NULL || (hostname == NULL && service == NULL))
   if (req == NULL || (hostname == NULL && service == NULL))
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   hostname_len = hostname ? strlen(hostname) + 1 : 0;
   hostname_len = hostname ? strlen(hostname) + 1 : 0;
   service_len = service ? strlen(service) + 1 : 0;
   service_len = service ? strlen(service) + 1 : 0;
@@ -156,7 +156,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
   buf = uv__malloc(hostname_len + service_len + hints_len);
   buf = uv__malloc(hostname_len + service_len + hints_len);
 
 
   if (buf == NULL)
   if (buf == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   uv__req_init(loop, req, UV_GETADDRINFO);
   uv__req_init(loop, req, UV_GETADDRINFO);
   req->loop = loop;
   req->loop = loop;
@@ -211,7 +211,7 @@ int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) {
     return UV_EINVAL;
     return UV_EINVAL;
 
 
   if (if_indextoname(ifindex, ifname_buf) == NULL)
   if (if_indextoname(ifindex, ifname_buf) == NULL)
-    return -errno;
+    return UV__ERR(errno);
 
 
   len = strnlen(ifname_buf, sizeof(ifname_buf));
   len = strnlen(ifname_buf, sizeof(ifname_buf));
 
 

+ 1 - 1
src/unix/getnameinfo.c

@@ -61,7 +61,7 @@ static void uv__getnameinfo_done(struct uv__work* w, int status) {
   uv__req_unregister(req->loop, req);
   uv__req_unregister(req->loop, req);
   host = service = NULL;
   host = service = NULL;
 
 
-  if (status == -ECANCELED) {
+  if (status == UV_ECANCELED) {
     assert(req->retcode == 0);
     assert(req->retcode == 0);
     req->retcode = UV_EAI_CANCELED;
     req->retcode = UV_EAI_CANCELED;
   } else if (req->retcode == 0) {
   } else if (req->retcode == 0) {

+ 1 - 1
src/unix/ibmi.c

@@ -92,7 +92,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
 
   *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t));
   *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t));
   if (!*cpu_infos) {
   if (!*cpu_infos) {
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   cpu_info = *cpu_infos;
   cpu_info = *cpu_infos;

+ 14 - 1
src/unix/internal.h

@@ -29,6 +29,7 @@
 #include <string.h> /* strrchr */
 #include <string.h> /* strrchr */
 #include <fcntl.h>  /* O_CLOEXEC, may be */
 #include <fcntl.h>  /* O_CLOEXEC, may be */
 #include <stdio.h>
 #include <stdio.h>
+#include <errno.h>
 
 
 #if defined(__STRICT_ANSI__)
 #if defined(__STRICT_ANSI__)
 # define inline __inline
 # define inline __inline
@@ -184,12 +185,24 @@ struct uv__stream_queued_fds_s {
 #define uv__nonblock uv__nonblock_fcntl
 #define uv__nonblock uv__nonblock_fcntl
 #endif
 #endif
 
 
+/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute
+ * when O_NDELAY is not equal to O_NONBLOCK.  Case in point: linux/sparc32
+ * and linux/sparc64, where O_NDELAY is O_NONBLOCK + another bit.
+ *
+ * Libuv uses uv__nonblock_fcntl() directly sometimes so ensure that it
+ * commutes with uv__nonblock().
+ */
+#if defined(__linux__) && O_NDELAY != O_NONBLOCK
+#undef uv__nonblock
+#define uv__nonblock uv__nonblock_fcntl
+#endif
+
 /* core */
 /* core */
 int uv__cloexec_ioctl(int fd, int set);
 int uv__cloexec_ioctl(int fd, int set);
 int uv__cloexec_fcntl(int fd, int set);
 int uv__cloexec_fcntl(int fd, int set);
 int uv__nonblock_ioctl(int fd, int set);
 int uv__nonblock_ioctl(int fd, int set);
 int uv__nonblock_fcntl(int fd, int set);
 int uv__nonblock_fcntl(int fd, int set);
-int uv__close(int fd);
+int uv__close(int fd); /* preserves errno */
 int uv__close_nocheckstdio(int fd);
 int uv__close_nocheckstdio(int fd);
 int uv__socket(int domain, int type, int protocol);
 int uv__socket(int domain, int type, int protocol);
 int uv__dup(int fd);
 int uv__dup(int fd);

+ 4 - 4
src/unix/kqueue.c

@@ -51,7 +51,7 @@ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
 int uv__kqueue_init(uv_loop_t* loop) {
 int uv__kqueue_init(uv_loop_t* loop) {
   loop->backend_fd = kqueue();
   loop->backend_fd = kqueue();
   if (loop->backend_fd == -1)
   if (loop->backend_fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   uv__cloexec(loop->backend_fd, 1);
   uv__cloexec(loop->backend_fd, 1);
 
 
@@ -98,7 +98,7 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
   rc = 0;
   rc = 0;
   EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
   EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
   if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
   if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
-    rc = -errno;
+    rc = UV__ERR(errno);
 
 
   EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
   EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
   if (rc == 0)
   if (rc == 0)
@@ -458,12 +458,12 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   int fd;
   int fd;
 
 
   if (uv__is_active(handle))
   if (uv__is_active(handle))
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   /* TODO open asynchronously - but how do we report back errors? */
   /* TODO open asynchronously - but how do we report back errors? */
   fd = open(path, O_RDONLY);
   fd = open(path, O_RDONLY);
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   uv__handle_start(handle);
   uv__handle_start(handle);
   uv__io_init(&handle->event_watcher, uv__fs_event, fd);
   uv__io_init(&handle->event_watcher, uv__fs_event, fd);

+ 17 - 17
src/unix/linux-core.c

@@ -101,7 +101,7 @@ int uv__platform_loop_init(uv_loop_t* loop) {
   loop->inotify_watchers = NULL;
   loop->inotify_watchers = NULL;
 
 
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -175,7 +175,7 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
   rc = 0;
   rc = 0;
   if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_ADD, fd, &e))
   if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_ADD, fd, &e))
     if (errno != EEXIST)
     if (errno != EEXIST)
-      rc = -errno;
+      rc = UV__ERR(errno);
 
 
   if (rc == 0)
   if (rc == 0)
     if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &e))
     if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &e))
@@ -485,7 +485,7 @@ int uv_resident_set_memory(size_t* rss) {
   while (fd == -1 && errno == EINTR);
   while (fd == -1 && errno == EINTR);
 
 
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   do
   do
     n = read(fd, buf, sizeof(buf) - 1);
     n = read(fd, buf, sizeof(buf) - 1);
@@ -493,7 +493,7 @@ int uv_resident_set_memory(size_t* rss) {
 
 
   uv__close(fd);
   uv__close(fd);
   if (n == -1)
   if (n == -1)
-    return -errno;
+    return UV__ERR(errno);
   buf[n] = '\0';
   buf[n] = '\0';
 
 
   s = strchr(buf, ' ');
   s = strchr(buf, ' ');
@@ -525,7 +525,7 @@ int uv_resident_set_memory(size_t* rss) {
   return 0;
   return 0;
 
 
 err:
 err:
-  return -EINVAL;
+  return UV_EINVAL;
 }
 }
 
 
 
 
@@ -547,7 +547,7 @@ int uv_uptime(double* uptime) {
   }
   }
 
 
   if (r)
   if (r)
-    return -errno;
+    return UV__ERR(errno);
 
 
   *uptime = now.tv_sec;
   *uptime = now.tv_sec;
   return 0;
   return 0;
@@ -559,7 +559,7 @@ static int uv__cpu_num(FILE* statfile_fp, unsigned int* numcpus) {
   char buf[1024];
   char buf[1024];
 
 
   if (!fgets(buf, sizeof(buf), statfile_fp))
   if (!fgets(buf, sizeof(buf), statfile_fp))
-    return -EIO;
+    return UV_EIO;
 
 
   num = 0;
   num = 0;
   while (fgets(buf, sizeof(buf), statfile_fp)) {
   while (fgets(buf, sizeof(buf), statfile_fp)) {
@@ -569,7 +569,7 @@ static int uv__cpu_num(FILE* statfile_fp, unsigned int* numcpus) {
   }
   }
 
 
   if (num == 0)
   if (num == 0)
-    return -EIO;
+    return UV_EIO;
 
 
   *numcpus = num;
   *numcpus = num;
   return 0;
   return 0;
@@ -587,13 +587,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
 
   statfile_fp = uv__open_file("/proc/stat");
   statfile_fp = uv__open_file("/proc/stat");
   if (statfile_fp == NULL)
   if (statfile_fp == NULL)
-    return -errno;
+    return UV__ERR(errno);
 
 
   err = uv__cpu_num(statfile_fp, &numcpus);
   err = uv__cpu_num(statfile_fp, &numcpus);
   if (err < 0)
   if (err < 0)
     goto out;
     goto out;
 
 
-  err = -ENOMEM;
+  err = UV_ENOMEM;
   ci = uv__calloc(numcpus, sizeof(*ci));
   ci = uv__calloc(numcpus, sizeof(*ci));
   if (ci == NULL)
   if (ci == NULL)
     goto out;
     goto out;
@@ -667,7 +667,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
     defined(__x86_64__)
     defined(__x86_64__)
   fp = uv__open_file("/proc/cpuinfo");
   fp = uv__open_file("/proc/cpuinfo");
   if (fp == NULL)
   if (fp == NULL)
-    return -errno;
+    return UV__ERR(errno);
 
 
   while (fgets(buf, sizeof(buf), fp)) {
   while (fgets(buf, sizeof(buf), fp)) {
     if (model_idx < numcpus) {
     if (model_idx < numcpus) {
@@ -676,7 +676,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
         model = uv__strndup(model, strlen(model) - 1);  /* Strip newline. */
         model = uv__strndup(model, strlen(model) - 1);  /* Strip newline. */
         if (model == NULL) {
         if (model == NULL) {
           fclose(fp);
           fclose(fp);
-          return -ENOMEM;
+          return UV_ENOMEM;
         }
         }
         ci[model_idx++].model = model;
         ci[model_idx++].model = model;
         continue;
         continue;
@@ -695,7 +695,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
         model = uv__strndup(model, strlen(model) - 1);  /* Strip newline. */
         model = uv__strndup(model, strlen(model) - 1);  /* Strip newline. */
         if (model == NULL) {
         if (model == NULL) {
           fclose(fp);
           fclose(fp);
-          return -ENOMEM;
+          return UV_ENOMEM;
         }
         }
         ci[model_idx++].model = model;
         ci[model_idx++].model = model;
         continue;
         continue;
@@ -725,7 +725,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
   while (model_idx < numcpus) {
   while (model_idx < numcpus) {
     model = uv__strndup(inferred_model, strlen(inferred_model));
     model = uv__strndup(inferred_model, strlen(inferred_model));
     if (model == NULL)
     if (model == NULL)
-      return -ENOMEM;
+      return UV_ENOMEM;
     ci[model_idx++].model = model;
     ci[model_idx++].model = model;
   }
   }
 
 
@@ -854,7 +854,7 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
 int uv_interface_addresses(uv_interface_address_t** addresses,
 int uv_interface_addresses(uv_interface_address_t** addresses,
   int* count) {
   int* count) {
 #ifndef HAVE_IFADDRS_H
 #ifndef HAVE_IFADDRS_H
-  return -ENOSYS;
+  return UV_ENOSYS;
 #else
 #else
   struct ifaddrs *addrs, *ent;
   struct ifaddrs *addrs, *ent;
   uv_interface_address_t* address;
   uv_interface_address_t* address;
@@ -862,7 +862,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
   struct sockaddr_ll *sll;
   struct sockaddr_ll *sll;
 
 
   if (getifaddrs(&addrs))
   if (getifaddrs(&addrs))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *count = 0;
   *count = 0;
   *addresses = NULL;
   *addresses = NULL;
@@ -881,7 +881,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
   *addresses = uv__malloc(*count * sizeof(**addresses));
   *addresses = uv__malloc(*count * sizeof(**addresses));
   if (!(*addresses)) {
   if (!(*addresses)) {
     freeifaddrs(addrs);
     freeifaddrs(addrs);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   address = *addresses;
   address = *addresses;

+ 5 - 5
src/unix/linux-inotify.c

@@ -73,11 +73,11 @@ static int new_inotify_fd(void) {
     return fd;
     return fd;
 
 
   if (errno != ENOSYS)
   if (errno != ENOSYS)
-    return -errno;
+    return UV__ERR(errno);
 
 
   fd = uv__inotify_init();
   fd = uv__inotify_init();
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   err = uv__cloexec(fd, 1);
   err = uv__cloexec(fd, 1);
   if (err == 0)
   if (err == 0)
@@ -283,7 +283,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   int wd;
   int wd;
 
 
   if (uv__is_active(handle))
   if (uv__is_active(handle))
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   err = init_inotify(handle->loop);
   err = init_inotify(handle->loop);
   if (err)
   if (err)
@@ -300,7 +300,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
 
 
   wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events);
   wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events);
   if (wd == -1)
   if (wd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   w = find_watcher(handle->loop, wd);
   w = find_watcher(handle->loop, wd);
   if (w)
   if (w)
@@ -308,7 +308,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
 
 
   w = uv__malloc(sizeof(*w) + strlen(path) + 1);
   w = uv__malloc(sizeof(*w) + strlen(path) + 1);
   if (w == NULL)
   if (w == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   w->wd = wd;
   w->wd = wd;
   w->path = strcpy((char*)(w + 1), path);
   w->path = strcpy((char*)(w + 1), path);

+ 1 - 1
src/unix/loop-watcher.c

@@ -31,7 +31,7 @@
                                                                               \
                                                                               \
   int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) {           \
   int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) {           \
     if (uv__is_active(handle)) return 0;                                      \
     if (uv__is_active(handle)) return 0;                                      \
-    if (cb == NULL) return -EINVAL;                                           \
+    if (cb == NULL) return UV_EINVAL;                                         \
     QUEUE_INSERT_HEAD(&handle->loop->name##_handles, &handle->queue);         \
     QUEUE_INSERT_HEAD(&handle->loop->name##_handles, &handle->queue);         \
     handle->name##_cb = cb;                                                   \
     handle->name##_cb = cb;                                                   \
     uv__handle_start(handle);                                                 \
     uv__handle_start(handle);                                                 \

+ 2 - 1
src/unix/loop.c

@@ -38,13 +38,14 @@ int uv_loop_init(uv_loop_t* loop) {
 
 
   heap_init((struct heap*) &loop->timer_heap);
   heap_init((struct heap*) &loop->timer_heap);
   QUEUE_INIT(&loop->wq);
   QUEUE_INIT(&loop->wq);
-  QUEUE_INIT(&loop->active_reqs);
   QUEUE_INIT(&loop->idle_handles);
   QUEUE_INIT(&loop->idle_handles);
   QUEUE_INIT(&loop->async_handles);
   QUEUE_INIT(&loop->async_handles);
   QUEUE_INIT(&loop->check_handles);
   QUEUE_INIT(&loop->check_handles);
   QUEUE_INIT(&loop->prepare_handles);
   QUEUE_INIT(&loop->prepare_handles);
   QUEUE_INIT(&loop->handle_queue);
   QUEUE_INIT(&loop->handle_queue);
 
 
+  loop->active_handles = 0;
+  loop->active_reqs.count = 0;
   loop->nfds = 0;
   loop->nfds = 0;
   loop->watchers = NULL;
   loop->watchers = NULL;
   loop->nwatchers = 0;
   loop->nwatchers = 0;

+ 14 - 14
src/unix/netbsd.c

@@ -82,7 +82,7 @@ int uv_exepath(char* buffer, size_t* size) {
   int mib[4];
   int mib[4];
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   mib[0] = CTL_KERN;
   mib[0] = CTL_KERN;
   mib[1] = KERN_PROC_ARGS;
   mib[1] = KERN_PROC_ARGS;
@@ -91,7 +91,7 @@ int uv_exepath(char* buffer, size_t* size) {
   int_size = ARRAY_SIZE(int_buf);
   int_size = ARRAY_SIZE(int_buf);
 
 
   if (sysctl(mib, 4, int_buf, &int_size, NULL, 0))
   if (sysctl(mib, 4, int_buf, &int_size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   /* Copy string from the intermediate buffer to outer one with appropriate
   /* Copy string from the intermediate buffer to outer one with appropriate
    * length.
    * length.
@@ -111,7 +111,7 @@ uint64_t uv_get_free_memory(void) {
   int which[] = {CTL_VM, VM_UVMEXP};
   int which[] = {CTL_VM, VM_UVMEXP};
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
 }
 }
@@ -128,7 +128,7 @@ uint64_t uv_get_total_memory(void) {
   size_t size = sizeof(info);
   size_t size = sizeof(info);
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return (uint64_t) info;
   return (uint64_t) info;
 }
 }
@@ -150,7 +150,7 @@ int uv_set_process_title(const char* title) {
 
 
   if (process_title == NULL) {
   if (process_title == NULL) {
     uv_mutex_unlock(&process_title_mutex);
     uv_mutex_unlock(&process_title_mutex);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   uv__free(process_title);
   uv__free(process_title);
@@ -167,7 +167,7 @@ int uv_get_process_title(char* buffer, size_t size) {
   size_t len;
   size_t len;
 
 
   if (buffer == NULL || size == 0)
   if (buffer == NULL || size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_mutex_lock(&process_title_mutex);
   uv_mutex_lock(&process_title_mutex);
@@ -177,7 +177,7 @@ int uv_get_process_title(char* buffer, size_t size) {
 
 
     if (size < len) {
     if (size < len) {
       uv_mutex_unlock(&process_title_mutex);
       uv_mutex_unlock(&process_title_mutex);
-      return -ENOBUFS;
+      return UV_ENOBUFS;
     }
     }
 
 
     memcpy(buffer, process_title, len);
     memcpy(buffer, process_title, len);
@@ -219,7 +219,7 @@ int uv_resident_set_memory(size_t* rss) {
 
 
 error:
 error:
   if (kd) kvm_close(kd);
   if (kd) kvm_close(kd);
-  return -EPERM;
+  return UV_EPERM;
 }
 }
 
 
 
 
@@ -230,7 +230,7 @@ int uv_uptime(double* uptime) {
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   now = time(NULL);
   now = time(NULL);
 
 
@@ -254,12 +254,12 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   size = sizeof(model);
   size = sizeof(model);
   if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) &&
   if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) &&
       sysctlbyname("hw.model", &model, &size, NULL, 0)) {
       sysctlbyname("hw.model", &model, &size, NULL, 0)) {
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   size = sizeof(numcpus);
   size = sizeof(numcpus);
   if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
   if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
   *count = numcpus;
   *count = numcpus;
 
 
   /* Only i386 and amd64 have machdep.tsc_freq */
   /* Only i386 and amd64 have machdep.tsc_freq */
@@ -270,16 +270,16 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   size = numcpus * CPUSTATES * sizeof(*cp_times);
   size = numcpus * CPUSTATES * sizeof(*cp_times);
   cp_times = uv__malloc(size);
   cp_times = uv__malloc(size);
   if (cp_times == NULL)
   if (cp_times == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0))
   if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos)) {
   if (!(*cpu_infos)) {
     uv__free(cp_times);
     uv__free(cp_times);
     uv__free(*cpu_infos);
     uv__free(*cpu_infos);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   for (i = 0; i < numcpus; i++) {
   for (i = 0; i < numcpus; i++) {

+ 3 - 3
src/unix/no-fsevents.c

@@ -25,16 +25,16 @@
 #include <errno.h>
 #include <errno.h>
 
 
 int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
 int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }
 
 
 int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
 int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
                       const char* filename, unsigned int flags) {
                       const char* filename, unsigned int flags) {
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }
 
 
 int uv_fs_event_stop(uv_fs_event_t* handle) {
 int uv_fs_event_stop(uv_fs_event_t* handle) {
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }
 
 
 void uv__fs_event_close(uv_fs_event_t* handle) {
 void uv__fs_event_close(uv_fs_event_t* handle) {

+ 1 - 1
src/unix/no-proctitle.c

@@ -35,7 +35,7 @@ int uv_set_process_title(const char* title) {
 
 
 int uv_get_process_title(char* buffer, size_t size) {
 int uv_get_process_title(char* buffer, size_t size) {
   if (buffer == NULL || size == 0)
   if (buffer == NULL || size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   buffer[0] = '\0';
   buffer[0] = '\0';
   return 0;
   return 0;

+ 16 - 16
src/unix/openbsd.c

@@ -78,11 +78,11 @@ int uv_exepath(char* buffer, size_t* size) {
   int err;
   int err;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   mypid = getpid();
   mypid = getpid();
   for (;;) {
   for (;;) {
-    err = -ENOMEM;
+    err = UV_ENOMEM;
     argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size);
     argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size);
     if (argsbuf_tmp == NULL)
     if (argsbuf_tmp == NULL)
       goto out;
       goto out;
@@ -95,14 +95,14 @@ int uv_exepath(char* buffer, size_t* size) {
       break;
       break;
     }
     }
     if (errno != ENOMEM) {
     if (errno != ENOMEM) {
-      err = -errno;
+      err = UV__ERR(errno);
       goto out;
       goto out;
     }
     }
     argsbuf_size *= 2U;
     argsbuf_size *= 2U;
   }
   }
 
 
   if (argsbuf[0] == NULL) {
   if (argsbuf[0] == NULL) {
-    err = -EINVAL;  /* FIXME(bnoordhuis) More appropriate error. */
+    err = UV_EINVAL;  /* FIXME(bnoordhuis) More appropriate error. */
     goto out;
     goto out;
   }
   }
 
 
@@ -128,7 +128,7 @@ uint64_t uv_get_free_memory(void) {
   int which[] = {CTL_VM, VM_UVMEXP};
   int which[] = {CTL_VM, VM_UVMEXP};
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
 }
 }
@@ -140,7 +140,7 @@ uint64_t uv_get_total_memory(void) {
   size_t size = sizeof(info);
   size_t size = sizeof(info);
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return (uint64_t) info;
   return (uint64_t) info;
 }
 }
@@ -162,7 +162,7 @@ int uv_set_process_title(const char* title) {
 
 
   if (process_title == NULL) {
   if (process_title == NULL) {
     uv_mutex_unlock(&process_title_mutex);
     uv_mutex_unlock(&process_title_mutex);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   uv__free(process_title);
   uv__free(process_title);
@@ -179,7 +179,7 @@ int uv_get_process_title(char* buffer, size_t size) {
   size_t len;
   size_t len;
 
 
   if (buffer == NULL || size == 0)
   if (buffer == NULL || size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_mutex_lock(&process_title_mutex);
   uv_mutex_lock(&process_title_mutex);
@@ -189,7 +189,7 @@ int uv_get_process_title(char* buffer, size_t size) {
 
 
     if (size < len) {
     if (size < len) {
       uv_mutex_unlock(&process_title_mutex);
       uv_mutex_unlock(&process_title_mutex);
-      return -ENOBUFS;
+      return UV_ENOBUFS;
     }
     }
 
 
     memcpy(buffer, process_title, len);
     memcpy(buffer, process_title, len);
@@ -219,7 +219,7 @@ int uv_resident_set_memory(size_t* rss) {
   mib[5] = 1;
   mib[5] = 1;
 
 
   if (sysctl(mib, 6, &kinfo, &size, NULL, 0) < 0)
   if (sysctl(mib, 6, &kinfo, &size, NULL, 0) < 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   *rss = kinfo.p_vm_rssize * page_size;
   *rss = kinfo.p_vm_rssize * page_size;
   return 0;
   return 0;
@@ -233,7 +233,7 @@ int uv_uptime(double* uptime) {
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
 
 
   if (sysctl(which, 2, &info, &size, NULL, 0))
   if (sysctl(which, 2, &info, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   now = time(NULL);
   now = time(NULL);
 
 
@@ -255,16 +255,16 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
 
   size = sizeof(model);
   size = sizeof(model);
   if (sysctl(which, 2, &model, &size, NULL, 0))
   if (sysctl(which, 2, &model, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   which[1] = HW_NCPU;
   which[1] = HW_NCPU;
   size = sizeof(numcpus);
   size = sizeof(numcpus);
   if (sysctl(which, 2, &numcpus, &size, NULL, 0))
   if (sysctl(which, 2, &numcpus, &size, NULL, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos))
   if (!(*cpu_infos))
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   *count = numcpus;
   *count = numcpus;
 
 
@@ -272,7 +272,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   size = sizeof(cpuspeed);
   size = sizeof(cpuspeed);
   if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) {
   if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) {
     uv__free(*cpu_infos);
     uv__free(*cpu_infos);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   size = sizeof(info);
   size = sizeof(info);
@@ -283,7 +283,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     size = sizeof(info);
     size = sizeof(info);
     if (sysctl(which, 3, &info, &size, NULL, 0)) {
     if (sysctl(which, 3, &info, &size, NULL, 0)) {
       uv__free(*cpu_infos);
       uv__free(*cpu_infos);
-      return -errno;
+      return UV__ERR(errno);
     }
     }
 
 
     cpu_info = &(*cpu_infos)[i];
     cpu_info = &(*cpu_infos)[i];

+ 2 - 0
src/unix/os390-syscalls.c

@@ -215,6 +215,7 @@ uv__os390_epoll* epoll_create1(int flags) {
     maybe_resize(lst, 1);
     maybe_resize(lst, 1);
     lst->items[lst->size - 1].fd = lst->msg_queue;
     lst->items[lst->size - 1].fd = lst->msg_queue;
     lst->items[lst->size - 1].events = POLLIN;
     lst->items[lst->size - 1].events = POLLIN;
+    lst->items[lst->size - 1].revents = 0;
     uv_once(&once, epoll_init);
     uv_once(&once, epoll_init);
     uv_mutex_lock(&global_epoll_lock);
     uv_mutex_lock(&global_epoll_lock);
     QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member);
     QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member);
@@ -252,6 +253,7 @@ int epoll_ctl(uv__os390_epoll* lst,
     }
     }
     lst->items[fd].fd = fd;
     lst->items[fd].fd = fd;
     lst->items[fd].events = event->events;
     lst->items[fd].events = event->events;
+    lst->items[fd].revents = 0;
   } else if (op == EPOLL_CTL_MOD) {
   } else if (op == EPOLL_CTL_MOD) {
     if (fd >= lst->size || lst->items[fd].fd == -1) {
     if (fd >= lst->size || lst->items[fd].fd == -1) {
       uv_mutex_unlock(&global_epoll_lock);
       uv_mutex_unlock(&global_epoll_lock);

+ 19 - 19
src/unix/os390.c

@@ -122,7 +122,7 @@ int uv__platform_loop_init(uv_loop_t* loop) {
   ep = epoll_create1(0);
   ep = epoll_create1(0);
   loop->ep = ep;
   loop->ep = ep;
   if (ep == NULL)
   if (ep == NULL)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -259,12 +259,12 @@ int uv_exepath(char* buffer, size_t* size) {
   int pid;
   int pid;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   pid = getpid();
   pid = getpid();
   res = getexe(pid, args, sizeof(args));
   res = getexe(pid, args, sizeof(args));
   if (res < 0)
   if (res < 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   /*
   /*
    * Possibilities for args:
    * Possibilities for args:
@@ -277,7 +277,7 @@ int uv_exepath(char* buffer, size_t* size) {
   /* Case i) and ii) absolute or relative paths */
   /* Case i) and ii) absolute or relative paths */
   if (strchr(args, '/') != NULL) {
   if (strchr(args, '/') != NULL) {
     if (realpath(args, abspath) != abspath)
     if (realpath(args, abspath) != abspath)
-      return -errno;
+      return UV__ERR(errno);
 
 
     abspath_size = strlen(abspath);
     abspath_size = strlen(abspath);
 
 
@@ -297,11 +297,11 @@ int uv_exepath(char* buffer, size_t* size) {
     char* path = getenv("PATH");
     char* path = getenv("PATH");
 
 
     if (path == NULL)
     if (path == NULL)
-      return -EINVAL;
+      return UV_EINVAL;
 
 
     clonedpath = uv__strdup(path);
     clonedpath = uv__strdup(path);
     if (clonedpath == NULL)
     if (clonedpath == NULL)
-      return -ENOMEM;
+      return UV_ENOMEM;
 
 
     token = strtok(clonedpath, ":");
     token = strtok(clonedpath, ":");
     while (token != NULL) {
     while (token != NULL) {
@@ -327,7 +327,7 @@ int uv_exepath(char* buffer, size_t* size) {
     uv__free(clonedpath);
     uv__free(clonedpath);
 
 
     /* Out of tokens (path entries), and no match found */
     /* Out of tokens (path entries), and no match found */
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 }
 }
 
 
@@ -407,7 +407,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
 
   *cpu_infos = uv__malloc(*count * sizeof(uv_cpu_info_t));
   *cpu_infos = uv__malloc(*count * sizeof(uv_cpu_info_t));
   if (!*cpu_infos)
   if (!*cpu_infos)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   cpu_info = *cpu_infos;
   cpu_info = *cpu_infos;
   idx = 0;
   idx = 0;
@@ -452,7 +452,7 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
   maxsize = 16384;
   maxsize = 16384;
 
 
   if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)))
   if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)))
-    return -errno;
+    return UV__ERR(errno);
 
 
   ifc.__nif6h_version = 1;
   ifc.__nif6h_version = 1;
   ifc.__nif6h_buflen = maxsize;
   ifc.__nif6h_buflen = maxsize;
@@ -460,7 +460,7 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
 
 
   if (ioctl(sockfd, SIOCGIFCONF6, &ifc) == -1) {
   if (ioctl(sockfd, SIOCGIFCONF6, &ifc) == -1) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
 
 
@@ -484,7 +484,7 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
   *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
   *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
   if (!(*addresses)) {
   if (!(*addresses)) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
   address = *addresses;
   address = *addresses;
 
 
@@ -543,13 +543,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
 
 
   sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
   sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
   if (0 > sockfd)
   if (0 > sockfd)
-    return -errno;
+    return UV__ERR(errno);
 
 
   ifc.ifc_req = uv__calloc(1, maxsize);
   ifc.ifc_req = uv__calloc(1, maxsize);
   ifc.ifc_len = maxsize;
   ifc.ifc_len = maxsize;
   if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
   if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
 #define MAX(a,b) (((a)>(b))?(a):(b))
 #define MAX(a,b) (((a)>(b))?(a):(b))
@@ -569,7 +569,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
       uv__close(sockfd);
       uv__close(sockfd);
-      return -errno;
+      return UV__ERR(errno);
     }
     }
 
 
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@@ -584,7 +584,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
 
 
   if (!(*addresses)) {
   if (!(*addresses)) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
   address = *addresses;
   address = *addresses;
 
 
@@ -607,7 +607,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
       uv__close(sockfd);
       uv__close(sockfd);
-      return -ENOSYS;
+      return UV_ENOSYS;
     }
     }
 
 
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@@ -706,7 +706,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
   int rc;
   int rc;
 
 
   if (uv__is_active(handle))
   if (uv__is_active(handle))
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   ep = handle->loop->ep;
   ep = handle->loop->ep;
   assert(ep->msg_queue != -1);
   assert(ep->msg_queue != -1);
@@ -718,11 +718,11 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
 
 
   path = uv__strdup(filename);
   path = uv__strdup(filename);
   if (path == NULL)
   if (path == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
   rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
   if (rc != 0)
   if (rc != 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   uv__handle_start(handle);
   uv__handle_start(handle);
   handle->path = path;
   handle->path = path;

+ 34 - 29
src/unix/pipe.c

@@ -50,12 +50,12 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
 
 
   /* Already bound? */
   /* Already bound? */
   if (uv__stream_fd(handle) >= 0)
   if (uv__stream_fd(handle) >= 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   /* Make a copy of the file name, it outlives this function's scope. */
   /* Make a copy of the file name, it outlives this function's scope. */
   pipe_fname = uv__strdup(name);
   pipe_fname = uv__strdup(name);
   if (pipe_fname == NULL)
   if (pipe_fname == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   /* We've got a copy, don't touch the original any more. */
   /* We've got a copy, don't touch the original any more. */
   name = NULL;
   name = NULL;
@@ -71,10 +71,10 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
   saddr.sun_family = AF_UNIX;
   saddr.sun_family = AF_UNIX;
 
 
   if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
   if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
-    err = -errno;
+    err = UV__ERR(errno);
     /* Convert ENOENT to EACCES for compatibility with Windows. */
     /* Convert ENOENT to EACCES for compatibility with Windows. */
-    if (err == -ENOENT)
-      err = -EACCES;
+    if (err == UV_ENOENT)
+      err = UV_EACCES;
 
 
     uv__close(sockfd);
     uv__close(sockfd);
     goto err_socket;
     goto err_socket;
@@ -94,7 +94,7 @@ err_socket:
 
 
 int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
 int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
   if (uv__stream_fd(handle) == -1)
   if (uv__stream_fd(handle) == -1)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
 #if defined(__MVS__)
 #if defined(__MVS__)
   /* On zOS, backlog=0 has undefined behaviour */
   /* On zOS, backlog=0 has undefined behaviour */
@@ -105,7 +105,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
 #endif
 #endif
 
 
   if (listen(uv__stream_fd(handle), backlog))
   if (listen(uv__stream_fd(handle), backlog))
-    return -errno;
+    return UV__ERR(errno);
 
 
   handle->connection_cb = cb;
   handle->connection_cb = cb;
   handle->io_watcher.cb = uv__server_io;
   handle->io_watcher.cb = uv__server_io;
@@ -180,14 +180,14 @@ void uv_pipe_connect(uv_connect_t* req,
   while (r == -1 && errno == EINTR);
   while (r == -1 && errno == EINTR);
 
 
   if (r == -1 && errno != EINPROGRESS) {
   if (r == -1 && errno != EINPROGRESS) {
-    err = -errno;
+    err = UV__ERR(errno);
 #if defined(__CYGWIN__) || defined(__MSYS__)
 #if defined(__CYGWIN__) || defined(__MSYS__)
     /* EBADF is supposed to mean that the socket fd is bad, but
     /* EBADF is supposed to mean that the socket fd is bad, but
        Cygwin reports EBADF instead of ENOTSOCK when the file is
        Cygwin reports EBADF instead of ENOTSOCK when the file is
        not a socket.  We do not expect to see a bad fd here
        not a socket.  We do not expect to see a bad fd here
        (e.g. due to new_sock), so translate the error.  */
        (e.g. due to new_sock), so translate the error.  */
-    if (err == -EBADF)
-      err = -ENOTSOCK;
+    if (err == UV_EBADF)
+      err = UV_ENOTSOCK;
 #endif
 #endif
     goto out;
     goto out;
   }
   }
@@ -234,7 +234,7 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
   err = func(uv__stream_fd(handle), (struct sockaddr*) &sa, &addrlen);
   err = func(uv__stream_fd(handle), (struct sockaddr*) &sa, &addrlen);
   if (err < 0) {
   if (err < 0) {
     *size = 0;
     *size = 0;
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
 #if defined(__linux__)
 #if defined(__linux__)
@@ -312,27 +312,12 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
   int r;
   int r;
 
 
   if (handle == NULL || uv__stream_fd(handle) == -1)
   if (handle == NULL || uv__stream_fd(handle) == -1)
-    return -EBADF;
+    return UV_EBADF;
 
 
   if (mode != UV_READABLE &&
   if (mode != UV_READABLE &&
       mode != UV_WRITABLE &&
       mode != UV_WRITABLE &&
       mode != (UV_WRITABLE | UV_READABLE))
       mode != (UV_WRITABLE | UV_READABLE))
-    return -EINVAL;
-
-  if (fstat(uv__stream_fd(handle), &pipe_stat) == -1)
-    return -errno;
-
-  desired_mode = 0;
-  if (mode & UV_READABLE)
-    desired_mode |= S_IRUSR | S_IRGRP | S_IROTH;
-  if (mode & UV_WRITABLE)
-    desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
-
-  /* Exit early if pipe already has desired mode. */
-  if ((pipe_stat.st_mode & desired_mode) == desired_mode)
-    return 0;
-
-  pipe_stat.st_mode |= desired_mode;
+    return UV_EINVAL;
 
 
   /* Unfortunately fchmod does not work on all platforms, we will use chmod. */
   /* Unfortunately fchmod does not work on all platforms, we will use chmod. */
   name_len = 0;
   name_len = 0;
@@ -350,8 +335,28 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
     return r;
     return r;
   }
   }
 
 
+  /* stat must be used as fstat has a bug on Darwin */
+  if (stat(name_buffer, &pipe_stat) == -1) {
+    uv__free(name_buffer);
+    return -errno;
+  }
+
+  desired_mode = 0;
+  if (mode & UV_READABLE)
+    desired_mode |= S_IRUSR | S_IRGRP | S_IROTH;
+  if (mode & UV_WRITABLE)
+    desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+
+  /* Exit early if pipe already has desired mode. */
+  if ((pipe_stat.st_mode & desired_mode) == desired_mode) {
+    uv__free(name_buffer);
+    return 0;
+  }
+
+  pipe_stat.st_mode |= desired_mode;
+
   r = chmod(name_buffer, pipe_stat.st_mode);
   r = chmod(name_buffer, pipe_stat.st_mode);
   uv__free(name_buffer);
   uv__free(name_buffer);
 
 
-  return r != -1 ? 0 : -errno;
+  return r != -1 ? 0 : UV__ERR(errno);
 }
 }

+ 2 - 2
src/unix/poll.c

@@ -47,7 +47,7 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
   if ((events & POLLERR) && !(events & UV__POLLPRI)) {
   if ((events & POLLERR) && !(events & UV__POLLPRI)) {
     uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
     uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
     uv__handle_stop(handle);
     uv__handle_stop(handle);
-    handle->poll_cb(handle, -EBADF, 0);
+    handle->poll_cb(handle, UV_EBADF, 0);
     return;
     return;
   }
   }
 
 
@@ -76,7 +76,7 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
    * Workaround for e.g. kqueue fds not supporting ioctls.
    * Workaround for e.g. kqueue fds not supporting ioctls.
    */
    */
   err = uv__nonblock(fd, 1);
   err = uv__nonblock(fd, 1);
-  if (err == -ENOTTY)
+  if (err == UV_ENOTTY)
     if (uv__nonblock == uv__nonblock_ioctl)
     if (uv__nonblock == uv__nonblock_ioctl)
       err = uv__nonblock_fcntl(fd, 1);
       err = uv__nonblock_fcntl(fd, 1);
 
 

+ 14 - 4
src/unix/posix-poll.c

@@ -107,7 +107,7 @@ static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) {
 static void uv__pollfds_del(uv_loop_t* loop, int fd) {
 static void uv__pollfds_del(uv_loop_t* loop, int fd) {
   size_t i;
   size_t i;
   assert(!loop->poll_fds_iterating);
   assert(!loop->poll_fds_iterating);
-  for (i = 0; i < loop->poll_fds_used; ++i) {
+  for (i = 0; i < loop->poll_fds_used;) {
     if (loop->poll_fds[i].fd == fd) {
     if (loop->poll_fds[i].fd == fd) {
       /* swap to last position and remove */
       /* swap to last position and remove */
       --loop->poll_fds_used;
       --loop->poll_fds_used;
@@ -115,7 +115,17 @@ static void uv__pollfds_del(uv_loop_t* loop, int fd) {
       loop->poll_fds[loop->poll_fds_used].fd = -1;
       loop->poll_fds[loop->poll_fds_used].fd = -1;
       loop->poll_fds[loop->poll_fds_used].events = 0;
       loop->poll_fds[loop->poll_fds_used].events = 0;
       loop->poll_fds[loop->poll_fds_used].revents = 0;
       loop->poll_fds[loop->poll_fds_used].revents = 0;
-      return;
+      /* This method is called with an fd of -1 to purge the invalidated fds,
+       * so we may possibly have multiples to remove.
+       */
+      if (-1 != fd)
+        return;
+    } else {
+      /* We must only increment the loop counter when the fds do not match.
+       * Otherwise, when we are purging an invalidated fd, the value just
+       * swapped here from the previous end of the array will be skipped.
+       */
+       ++i;
     }
     }
   }
   }
 }
 }
@@ -315,10 +325,10 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
   while (rv == -1 && (errno == EINTR || errno == EAGAIN));
   while (rv == -1 && (errno == EINTR || errno == EAGAIN));
 
 
   if (rv == -1)
   if (rv == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   if (p[0].revents & POLLNVAL)
   if (p[0].revents & POLLNVAL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   return 0;
   return 0;
 }
 }

+ 27 - 30
src/unix/process.c

@@ -126,7 +126,7 @@ int uv__make_socketpair(int fds[2], int flags) {
    * Anything else is a genuine error.
    * Anything else is a genuine error.
    */
    */
   if (errno != EINVAL)
   if (errno != EINVAL)
-    return -errno;
+    return UV__ERR(errno);
 
 
   no_cloexec = 1;
   no_cloexec = 1;
 
 
@@ -134,7 +134,7 @@ skip:
 #endif
 #endif
 
 
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
-    return -errno;
+    return UV__ERR(errno);
 
 
   uv__cloexec(fds[0], 1);
   uv__cloexec(fds[0], 1);
   uv__cloexec(fds[1], 1);
   uv__cloexec(fds[1], 1);
@@ -159,7 +159,7 @@ int uv__make_pipe(int fds[2], int flags) {
     return 0;
     return 0;
 
 
   if (errno != ENOSYS)
   if (errno != ENOSYS)
-    return -errno;
+    return UV__ERR(errno);
 
 
   no_pipe2 = 1;
   no_pipe2 = 1;
 
 
@@ -167,7 +167,7 @@ skip:
 #endif
 #endif
 
 
   if (pipe(fds))
   if (pipe(fds))
-    return -errno;
+    return UV__ERR(errno);
 
 
   uv__cloexec(fds[0], 1);
   uv__cloexec(fds[0], 1);
   uv__cloexec(fds[1], 1);
   uv__cloexec(fds[1], 1);
@@ -198,7 +198,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
   case UV_CREATE_PIPE:
   case UV_CREATE_PIPE:
     assert(container->data.stream != NULL);
     assert(container->data.stream != NULL);
     if (container->data.stream->type != UV_NAMED_PIPE)
     if (container->data.stream->type != UV_NAMED_PIPE)
-      return -EINVAL;
+      return UV_EINVAL;
     else
     else
       return uv__make_socketpair(fds, 0);
       return uv__make_socketpair(fds, 0);
 
 
@@ -210,21 +210,20 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
       fd = uv__stream_fd(container->data.stream);
       fd = uv__stream_fd(container->data.stream);
 
 
     if (fd == -1)
     if (fd == -1)
-      return -EINVAL;
+      return UV_EINVAL;
 
 
     fds[1] = fd;
     fds[1] = fd;
     return 0;
     return 0;
 
 
   default:
   default:
     assert(0 && "Unexpected flags");
     assert(0 && "Unexpected flags");
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 }
 }
 
 
 
 
 static int uv__process_open_stream(uv_stdio_container_t* container,
 static int uv__process_open_stream(uv_stdio_container_t* container,
-                                   int pipefds[2],
-                                   int writable) {
+                                   int pipefds[2]) {
   int flags;
   int flags;
   int err;
   int err;
 
 
@@ -238,13 +237,11 @@ static int uv__process_open_stream(uv_stdio_container_t* container,
   pipefds[1] = -1;
   pipefds[1] = -1;
   uv__nonblock(pipefds[0], 1);
   uv__nonblock(pipefds[0], 1);
 
 
-  if (container->data.stream->type == UV_NAMED_PIPE &&
-      ((uv_pipe_t*)container->data.stream)->ipc)
-    flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
-  else if (writable)
-    flags = UV_STREAM_WRITABLE;
-  else
-    flags = UV_STREAM_READABLE;
+  flags = 0;
+  if (container->flags & UV_WRITABLE_PIPE)
+    flags |= UV_STREAM_READABLE;
+  if (container->flags & UV_READABLE_PIPE)
+    flags |= UV_STREAM_WRITABLE;
 
 
   return uv__stream_open(container->data.stream, pipefds[0], flags);
   return uv__stream_open(container->data.stream, pipefds[0], flags);
 }
 }
@@ -299,7 +296,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
       continue;
       continue;
     pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
     pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
     if (pipes[fd][1] == -1) {
     if (pipes[fd][1] == -1) {
-      uv__write_int(error_fd, -errno);
+      uv__write_int(error_fd, UV__ERR(errno));
       _exit(127);
       _exit(127);
     }
     }
   }
   }
@@ -319,7 +316,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
         close_fd = use_fd;
         close_fd = use_fd;
 
 
         if (use_fd == -1) {
         if (use_fd == -1) {
-          uv__write_int(error_fd, -errno);
+          uv__write_int(error_fd, UV__ERR(errno));
           _exit(127);
           _exit(127);
         }
         }
       }
       }
@@ -331,7 +328,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
       fd = dup2(use_fd, fd);
       fd = dup2(use_fd, fd);
 
 
     if (fd == -1) {
     if (fd == -1) {
-      uv__write_int(error_fd, -errno);
+      uv__write_int(error_fd, UV__ERR(errno));
       _exit(127);
       _exit(127);
     }
     }
 
 
@@ -350,7 +347,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
   }
   }
 
 
   if (options->cwd != NULL && chdir(options->cwd)) {
   if (options->cwd != NULL && chdir(options->cwd)) {
-    uv__write_int(error_fd, -errno);
+    uv__write_int(error_fd, UV__ERR(errno));
     _exit(127);
     _exit(127);
   }
   }
 
 
@@ -366,12 +363,12 @@ static void uv__process_child_init(const uv_process_options_t* options,
   }
   }
 
 
   if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
   if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
-    uv__write_int(error_fd, -errno);
+    uv__write_int(error_fd, UV__ERR(errno));
     _exit(127);
     _exit(127);
   }
   }
 
 
   if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) {
   if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) {
-    uv__write_int(error_fd, -errno);
+    uv__write_int(error_fd, UV__ERR(errno));
     _exit(127);
     _exit(127);
   }
   }
 
 
@@ -391,7 +388,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
     if (SIG_ERR != signal(n, SIG_DFL))
     if (SIG_ERR != signal(n, SIG_DFL))
       continue;
       continue;
 
 
-    uv__write_int(error_fd, -errno);
+    uv__write_int(error_fd, UV__ERR(errno));
     _exit(127);
     _exit(127);
   }
   }
 
 
@@ -400,12 +397,12 @@ static void uv__process_child_init(const uv_process_options_t* options,
   err = pthread_sigmask(SIG_SETMASK, &set, NULL);
   err = pthread_sigmask(SIG_SETMASK, &set, NULL);
 
 
   if (err != 0) {
   if (err != 0) {
-    uv__write_int(error_fd, -err);
+    uv__write_int(error_fd, UV__ERR(err));
     _exit(127);
     _exit(127);
   }
   }
 
 
   execvp(options->file, options->args);
   execvp(options->file, options->args);
-  uv__write_int(error_fd, -errno);
+  uv__write_int(error_fd, UV__ERR(errno));
   _exit(127);
   _exit(127);
 }
 }
 #endif
 #endif
@@ -416,7 +413,7 @@ int uv_spawn(uv_loop_t* loop,
              const uv_process_options_t* options) {
              const uv_process_options_t* options) {
 #if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)
 #if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)
   /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */
   /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */
-  return -ENOSYS;
+  return UV_ENOSYS;
 #else
 #else
   int signal_pipe[2] = { -1, -1 };
   int signal_pipe[2] = { -1, -1 };
   int pipes_storage[8][2];
   int pipes_storage[8][2];
@@ -443,7 +440,7 @@ int uv_spawn(uv_loop_t* loop,
   if (stdio_count < 3)
   if (stdio_count < 3)
     stdio_count = 3;
     stdio_count = 3;
 
 
-  err = -ENOMEM;
+  err = UV_ENOMEM;
   pipes = pipes_storage;
   pipes = pipes_storage;
   if (stdio_count > (int) ARRAY_SIZE(pipes_storage))
   if (stdio_count > (int) ARRAY_SIZE(pipes_storage))
     pipes = uv__malloc(stdio_count * sizeof(*pipes));
     pipes = uv__malloc(stdio_count * sizeof(*pipes));
@@ -493,7 +490,7 @@ int uv_spawn(uv_loop_t* loop,
   pid = fork();
   pid = fork();
 
 
   if (pid == -1) {
   if (pid == -1) {
-    err = -errno;
+    err = UV__ERR(errno);
     uv_rwlock_wrunlock(&loop->cloexec_lock);
     uv_rwlock_wrunlock(&loop->cloexec_lock);
     uv__close(signal_pipe[0]);
     uv__close(signal_pipe[0]);
     uv__close(signal_pipe[1]);
     uv__close(signal_pipe[1]);
@@ -533,7 +530,7 @@ int uv_spawn(uv_loop_t* loop,
   uv__close_nocheckstdio(signal_pipe[0]);
   uv__close_nocheckstdio(signal_pipe[0]);
 
 
   for (i = 0; i < options->stdio_count; i++) {
   for (i = 0; i < options->stdio_count; i++) {
-    err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0);
+    err = uv__process_open_stream(options->stdio + i, pipes[i]);
     if (err == 0)
     if (err == 0)
       continue;
       continue;
 
 
@@ -585,7 +582,7 @@ int uv_process_kill(uv_process_t* process, int signum) {
 
 
 int uv_kill(int pid, int signum) {
 int uv_kill(int pid, int signum) {
   if (kill(pid, signum))
   if (kill(pid, signum))
-    return -errno;
+    return UV__ERR(errno);
   else
   else
     return 0;
     return 0;
 }
 }

+ 2 - 2
src/unix/procfs-exepath.c

@@ -29,14 +29,14 @@ int uv_exepath(char* buffer, size_t* size) {
   ssize_t n;
   ssize_t n;
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   n = *size - 1;
   n = *size - 1;
   if (n > 0)
   if (n > 0)
     n = readlink("/proc/self/exe", buffer, n);
     n = readlink("/proc/self/exe", buffer, n);
 
 
   if (n == -1)
   if (n == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   buffer[n] = '\0';
   buffer[n] = '\0';
   *size = n;
   *size = n;

+ 2 - 2
src/unix/proctitle.c

@@ -105,14 +105,14 @@ int uv_set_process_title(const char* title) {
 
 
 int uv_get_process_title(char* buffer, size_t size) {
 int uv_get_process_title(char* buffer, size_t size) {
   if (buffer == NULL || size == 0)
   if (buffer == NULL || size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_mutex_lock(&process_title_mutex);
   uv_mutex_lock(&process_title_mutex);
 
 
   if (size <= process_title.len) {
   if (size <= process_title.len) {
     uv_mutex_unlock(&process_title_mutex);
     uv_mutex_unlock(&process_title_mutex);
-    return -ENOBUFS;
+    return UV_ENOBUFS;
   }
   }
 
 
   if (process_title.len != 0)
   if (process_title.len != 0)

+ 2 - 2
src/unix/signal.c

@@ -225,7 +225,7 @@ static int uv__signal_register_handler(int signum, int oneshot) {
 
 
   /* XXX save old action so we can restore it later on? */
   /* XXX save old action so we can restore it later on? */
   if (sigaction(signum, &sa, NULL))
   if (sigaction(signum, &sa, NULL))
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -362,7 +362,7 @@ static int uv__signal_start(uv_signal_t* handle,
    * eventually.
    * eventually.
    */
    */
   if (signum == 0)
   if (signum == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   /* Short circuit: if the signal watcher is already watching {signum} don't
   /* Short circuit: if the signal watcher is already watching {signum} don't
    * go through the process of deregistering and registering the handler.
    * go through the process of deregistering and registering the handler.

+ 51 - 39
src/unix/stream.c

@@ -58,6 +58,12 @@ struct uv__stream_select_s {
   fd_set* swrite;
   fd_set* swrite;
   size_t swrite_sz;
   size_t swrite_sz;
 };
 };
+# define WRITE_RETRY_ON_ERROR(send_handle) \
+    (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \
+     (errno == EMSGSIZE && send_handle))
+#else
+# define WRITE_RETRY_ON_ERROR(send_handle) \
+    (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
 #endif /* defined(__APPLE__) */
 #endif /* defined(__APPLE__) */
 
 
 static void uv__stream_connect(uv_stream_t*);
 static void uv__stream_connect(uv_stream_t*);
@@ -282,7 +288,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
   kq = kqueue();
   kq = kqueue();
   if (kq == -1) {
   if (kq == -1) {
     perror("(libuv) kqueue()");
     perror("(libuv) kqueue()");
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   EV_SET(&filter[0], *fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
   EV_SET(&filter[0], *fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
@@ -298,7 +304,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
   uv__close(kq);
   uv__close(kq);
 
 
   if (ret == -1)
   if (ret == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   if (ret == 0 || (events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL)
   if (ret == 0 || (events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL)
     return 0;
     return 0;
@@ -310,7 +316,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
    * NOTE: do it ahead of malloc below to allocate enough space for fd_sets
    * NOTE: do it ahead of malloc below to allocate enough space for fd_sets
    */
    */
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
-    return -errno;
+    return UV__ERR(errno);
 
 
   max_fd = *fd;
   max_fd = *fd;
   if (fds[1] > max_fd)
   if (fds[1] > max_fd)
@@ -321,7 +327,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
 
 
   s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz);
   s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz);
   if (s == NULL) {
   if (s == NULL) {
-    err = -ENOMEM;
+    err = UV_ENOMEM;
     goto failed_malloc;
     goto failed_malloc;
   }
   }
 
 
@@ -395,18 +401,18 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
 #endif
 #endif
 
 
   if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd))
   if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd))
-    return -EBUSY;
+    return UV_EBUSY;
 
 
   assert(fd >= 0);
   assert(fd >= 0);
   stream->flags |= flags;
   stream->flags |= flags;
 
 
   if (stream->type == UV_TCP) {
   if (stream->type == UV_TCP) {
     if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
     if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
-      return -errno;
+      return UV__ERR(errno);
 
 
     /* TODO Use delay the user passed in. */
     /* TODO Use delay the user passed in. */
     if ((stream->flags & UV_TCP_KEEPALIVE) && uv__tcp_keepalive(fd, 1, 60))
     if ((stream->flags & UV_TCP_KEEPALIVE) && uv__tcp_keepalive(fd, 1, 60))
-      return -errno;
+      return UV__ERR(errno);
   }
   }
 
 
 #if defined(__APPLE__)
 #if defined(__APPLE__)
@@ -414,7 +420,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
   if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
   if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
       errno != ENOTSOCK &&
       errno != ENOTSOCK &&
       errno != EINVAL) {
       errno != EINVAL) {
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 #endif
 #endif
 
 
@@ -445,11 +451,11 @@ void uv__stream_destroy(uv_stream_t* stream) {
 
 
   if (stream->connect_req) {
   if (stream->connect_req) {
     uv__req_unregister(stream->loop, stream->connect_req);
     uv__req_unregister(stream->loop, stream->connect_req);
-    stream->connect_req->cb(stream->connect_req, -ECANCELED);
+    stream->connect_req->cb(stream->connect_req, UV_ECANCELED);
     stream->connect_req = NULL;
     stream->connect_req = NULL;
   }
   }
 
 
-  uv__stream_flush_write_queue(stream, -ECANCELED);
+  uv__stream_flush_write_queue(stream, UV_ECANCELED);
   uv__write_callbacks(stream);
   uv__write_callbacks(stream);
 
 
   if (stream->shutdown_req) {
   if (stream->shutdown_req) {
@@ -459,7 +465,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
      * callee that the handle has been destroyed.
      * callee that the handle has been destroyed.
      */
      */
     uv__req_unregister(stream->loop, stream->shutdown_req);
     uv__req_unregister(stream->loop, stream->shutdown_req);
-    stream->shutdown_req->cb(stream->shutdown_req, -ECANCELED);
+    stream->shutdown_req->cb(stream->shutdown_req, UV_ECANCELED);
     stream->shutdown_req = NULL;
     stream->shutdown_req = NULL;
   }
   }
 
 
@@ -483,7 +489,7 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
   int emfile_fd;
   int emfile_fd;
 
 
   if (loop->emfile_fd == -1)
   if (loop->emfile_fd == -1)
-    return -EMFILE;
+    return UV_EMFILE;
 
 
   uv__close(loop->emfile_fd);
   uv__close(loop->emfile_fd);
   loop->emfile_fd = -1;
   loop->emfile_fd = -1;
@@ -492,7 +498,7 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
     err = uv__accept(accept_fd);
     err = uv__accept(accept_fd);
     if (err >= 0)
     if (err >= 0)
       uv__close(err);
       uv__close(err);
-  } while (err >= 0 || err == -EINTR);
+  } while (err >= 0 || err == UV_EINTR);
 
 
   emfile_fd = uv__open_cloexec("/", O_RDONLY);
   emfile_fd = uv__open_cloexec("/", O_RDONLY);
   if (emfile_fd >= 0)
   if (emfile_fd >= 0)
@@ -533,15 +539,15 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
 
 
     err = uv__accept(uv__stream_fd(stream));
     err = uv__accept(uv__stream_fd(stream));
     if (err < 0) {
     if (err < 0) {
-      if (err == -EAGAIN || err == -EWOULDBLOCK)
+      if (err == UV_EAGAIN || err == UV__ERR(EWOULDBLOCK))
         return;  /* Not an error. */
         return;  /* Not an error. */
 
 
-      if (err == -ECONNABORTED)
+      if (err == UV_ECONNABORTED)
         continue;  /* Ignore. Nothing we can do about that. */
         continue;  /* Ignore. Nothing we can do about that. */
 
 
-      if (err == -EMFILE || err == -ENFILE) {
+      if (err == UV_EMFILE || err == UV_ENFILE) {
         err = uv__emfile_trick(loop, uv__stream_fd(stream));
         err = uv__emfile_trick(loop, uv__stream_fd(stream));
-        if (err == -EAGAIN || err == -EWOULDBLOCK)
+        if (err == UV_EAGAIN || err == UV__ERR(EWOULDBLOCK))
           break;
           break;
       }
       }
 
 
@@ -577,7 +583,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
   assert(server->loop == client->loop);
   assert(server->loop == client->loop);
 
 
   if (server->accepted_fd == -1)
   if (server->accepted_fd == -1)
-    return -EAGAIN;
+    return UV_EAGAIN;
 
 
   switch (client->type) {
   switch (client->type) {
     case UV_NAMED_PIPE:
     case UV_NAMED_PIPE:
@@ -601,7 +607,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
       break;
       break;
 
 
     default:
     default:
-      return -EINVAL;
+      return UV_EINVAL;
   }
   }
 
 
   client->flags |= UV_HANDLE_BOUND;
   client->flags |= UV_HANDLE_BOUND;
@@ -649,7 +655,7 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
     break;
     break;
 
 
   default:
   default:
-    err = -EINVAL;
+    err = UV_EINVAL;
   }
   }
 
 
   if (err == 0)
   if (err == 0)
@@ -680,7 +686,7 @@ static void uv__drain(uv_stream_t* stream) {
 
 
     err = 0;
     err = 0;
     if (shutdown(uv__stream_fd(stream), SHUT_WR))
     if (shutdown(uv__stream_fd(stream), SHUT_WR))
-      err = -errno;
+      err = UV__ERR(errno);
 
 
     if (err == 0)
     if (err == 0)
       stream->flags |= UV_STREAM_SHUT;
       stream->flags |= UV_STREAM_SHUT;
@@ -792,7 +798,7 @@ start:
     } scratch;
     } scratch;
 
 
     if (uv__is_closing(req->send_handle)) {
     if (uv__is_closing(req->send_handle)) {
-      err = -EBADF;
+      err = UV_EBADF;
       goto error;
       goto error;
     }
     }
 
 
@@ -859,8 +865,8 @@ start:
   }
   }
 
 
   if (n < 0) {
   if (n < 0) {
-    if (errno != EAGAIN && errno != EWOULDBLOCK && errno != ENOBUFS) {
-      err = -errno;
+    if (!WRITE_RETRY_ON_ERROR(req->send_handle)) {
+      err = UV__ERR(errno);
       goto error;
       goto error;
     } else if (stream->flags & UV_STREAM_BLOCKING) {
     } else if (stream->flags & UV_STREAM_BLOCKING) {
       /* If this is a blocking stream, try again. */
       /* If this is a blocking stream, try again. */
@@ -1029,7 +1035,7 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
     queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) +
     queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) +
                             sizeof(*queued_fds));
                             sizeof(*queued_fds));
     if (queued_fds == NULL)
     if (queued_fds == NULL)
-      return -ENOMEM;
+      return UV_ENOMEM;
     queued_fds->size = queue_size;
     queued_fds->size = queue_size;
     queued_fds->offset = 0;
     queued_fds->offset = 0;
     stream->queued_fds = queued_fds;
     stream->queued_fds = queued_fds;
@@ -1046,7 +1052,7 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
      * NOTE: if it is fatal - sockets will be closed in uv__stream_close
      * NOTE: if it is fatal - sockets will be closed in uv__stream_close
      */
      */
     if (queued_fds == NULL)
     if (queued_fds == NULL)
-      return -ENOMEM;
+      return UV_ENOMEM;
     queued_fds->size = queue_size;
     queued_fds->size = queue_size;
     stream->queued_fds = queued_fds;
     stream->queued_fds = queued_fds;
   }
   }
@@ -1192,7 +1198,7 @@ static void uv__read(uv_stream_t* stream) {
 #endif
 #endif
       } else {
       } else {
         /* Error. User should call uv_close(). */
         /* Error. User should call uv_close(). */
-        stream->read_cb(stream, -errno, &buf);
+        stream->read_cb(stream, UV__ERR(errno), &buf);
         if (stream->flags & UV_STREAM_READING) {
         if (stream->flags & UV_STREAM_READING) {
           stream->flags &= ~UV_STREAM_READING;
           stream->flags &= ~UV_STREAM_READING;
           uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
           uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
@@ -1269,7 +1275,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
       stream->flags & UV_STREAM_SHUT ||
       stream->flags & UV_STREAM_SHUT ||
       stream->flags & UV_STREAM_SHUTTING ||
       stream->flags & UV_STREAM_SHUTTING ||
       uv__is_closing(stream)) {
       uv__is_closing(stream)) {
-    return -ENOTCONN;
+    return UV_ENOTCONN;
   }
   }
 
 
   assert(uv__stream_fd(stream) >= 0);
   assert(uv__stream_fd(stream) >= 0);
@@ -1368,10 +1374,10 @@ static void uv__stream_connect(uv_stream_t* stream) {
                SO_ERROR,
                SO_ERROR,
                &error,
                &error,
                &errorsize);
                &errorsize);
-    error = -error;
+    error = UV__ERR(error);
   }
   }
 
 
-  if (error == -EINPROGRESS)
+  if (error == UV__ERR(EINPROGRESS))
     return;
     return;
 
 
   stream->connect_req = NULL;
   stream->connect_req = NULL;
@@ -1388,7 +1394,7 @@ static void uv__stream_connect(uv_stream_t* stream) {
     return;
     return;
 
 
   if (error < 0) {
   if (error < 0) {
-    uv__stream_flush_write_queue(stream, -ECANCELED);
+    uv__stream_flush_write_queue(stream, UV_ECANCELED);
     uv__write_callbacks(stream);
     uv__write_callbacks(stream);
   }
   }
 }
 }
@@ -1409,11 +1415,14 @@ int uv_write2(uv_write_t* req,
          "uv_write (unix) does not yet support other types of streams");
          "uv_write (unix) does not yet support other types of streams");
 
 
   if (uv__stream_fd(stream) < 0)
   if (uv__stream_fd(stream) < 0)
-    return -EBADF;
+    return UV_EBADF;
+
+  if (!(stream->flags & UV_STREAM_WRITABLE))
+    return -EPIPE;
 
 
   if (send_handle) {
   if (send_handle) {
     if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
     if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
-      return -EINVAL;
+      return UV_EINVAL;
 
 
     /* XXX We abuse uv_write2() to send over UDP handles to child processes.
     /* XXX We abuse uv_write2() to send over UDP handles to child processes.
      * Don't call uv__stream_fd() on those handles, it's a macro that on OS X
      * Don't call uv__stream_fd() on those handles, it's a macro that on OS X
@@ -1422,12 +1431,12 @@ int uv_write2(uv_write_t* req,
      * which works but only by accident.
      * which works but only by accident.
      */
      */
     if (uv__handle_fd((uv_handle_t*) send_handle) < 0)
     if (uv__handle_fd((uv_handle_t*) send_handle) < 0)
-      return -EBADF;
+      return UV_EBADF;
 
 
 #if defined(__CYGWIN__) || defined(__MSYS__)
 #if defined(__CYGWIN__) || defined(__MSYS__)
     /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it.
     /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it.
        See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */
        See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */
-    return -ENOSYS;
+    return UV_ENOSYS;
 #endif
 #endif
   }
   }
 
 
@@ -1452,7 +1461,7 @@ int uv_write2(uv_write_t* req,
     req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
     req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
 
 
   if (req->bufs == NULL)
   if (req->bufs == NULL)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
   memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
   req->nbufs = nbufs;
   req->nbufs = nbufs;
@@ -1516,7 +1525,7 @@ int uv_try_write(uv_stream_t* stream,
 
 
   /* Connecting or already writing some data */
   /* Connecting or already writing some data */
   if (stream->connect_req != NULL || stream->write_queue_size != 0)
   if (stream->connect_req != NULL || stream->write_queue_size != 0)
-    return -EAGAIN;
+    return UV_EAGAIN;
 
 
   has_pollout = uv__io_active(&stream->io_watcher, POLLOUT);
   has_pollout = uv__io_active(&stream->io_watcher, POLLOUT);
 
 
@@ -1547,7 +1556,7 @@ int uv_try_write(uv_stream_t* stream,
   }
   }
 
 
   if (written == 0 && req_size != 0)
   if (written == 0 && req_size != 0)
-    return -EAGAIN;
+    return UV_EAGAIN;
   else
   else
     return written;
     return written;
 }
 }
@@ -1560,7 +1569,10 @@ int uv_read_start(uv_stream_t* stream,
       stream->type == UV_TTY);
       stream->type == UV_TTY);
 
 
   if (stream->flags & UV_CLOSING)
   if (stream->flags & UV_CLOSING)
-    return -EINVAL;
+    return UV_EINVAL;
+
+  if (!(stream->flags & UV_STREAM_READABLE))
+    return -ENOTCONN;
 
 
   /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
   /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
    * expresses the desired state of the user.
    * expresses the desired state of the user.

+ 21 - 21
src/unix/sunos.c

@@ -73,7 +73,7 @@ int uv__platform_loop_init(uv_loop_t* loop) {
 
 
   fd = port_create();
   fd = port_create();
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   err = uv__cloexec(fd, 1);
   err = uv__cloexec(fd, 1);
   if (err) {
   if (err) {
@@ -132,7 +132,7 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
 
 
 int uv__io_check_fd(uv_loop_t* loop, int fd) {
 int uv__io_check_fd(uv_loop_t* loop, int fd) {
   if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0))
   if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0))
-    return -errno;
+    return UV__ERR(errno);
 
 
   if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd))
   if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd))
     abort();
     abort();
@@ -342,7 +342,7 @@ int uv_exepath(char* buffer, size_t* size) {
   char buf[128];
   char buf[128];
 
 
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid());
   snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid());
 
 
@@ -351,7 +351,7 @@ int uv_exepath(char* buffer, size_t* size) {
     res = readlink(buf, buffer, res);
     res = readlink(buf, buffer, res);
 
 
   if (res == -1)
   if (res == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   buffer[res] = '\0';
   buffer[res] = '\0';
   *size = res;
   *size = res;
@@ -378,14 +378,14 @@ void uv_loadavg(double avg[3]) {
 
 
 static int uv__fs_event_rearm(uv_fs_event_t *handle) {
 static int uv__fs_event_rearm(uv_fs_event_t *handle) {
   if (handle->fd == -1)
   if (handle->fd == -1)
-    return -EBADF;
+    return UV_EBADF;
 
 
   if (port_associate(handle->loop->fs_fd,
   if (port_associate(handle->loop->fs_fd,
                      PORT_SOURCE_FILE,
                      PORT_SOURCE_FILE,
                      (uintptr_t) &handle->fo,
                      (uintptr_t) &handle->fo,
                      FILE_ATTRIB | FILE_MODIFIED,
                      FILE_ATTRIB | FILE_MODIFIED,
                      handle) == -1) {
                      handle) == -1) {
-    return -errno;
+    return UV__ERR(errno);
   }
   }
   handle->fd = PORT_LOADED;
   handle->fd = PORT_LOADED;
 
 
@@ -462,13 +462,13 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   int err;
   int err;
 
 
   if (uv__is_active(handle))
   if (uv__is_active(handle))
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   first_run = 0;
   first_run = 0;
   if (handle->loop->fs_fd == -1) {
   if (handle->loop->fs_fd == -1) {
     portfd = port_create();
     portfd = port_create();
     if (portfd == -1)
     if (portfd == -1)
-      return -errno;
+      return UV__ERR(errno);
     handle->loop->fs_fd = portfd;
     handle->loop->fs_fd = portfd;
     first_run = 1;
     first_run = 1;
   }
   }
@@ -521,7 +521,7 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
 #else /* !defined(PORT_SOURCE_FILE) */
 #else /* !defined(PORT_SOURCE_FILE) */
 
 
 int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
 int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }
 
 
 
 
@@ -529,12 +529,12 @@ int uv_fs_event_start(uv_fs_event_t* handle,
                       uv_fs_event_cb cb,
                       uv_fs_event_cb cb,
                       const char* filename,
                       const char* filename,
                       unsigned int flags) {
                       unsigned int flags) {
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }
 
 
 
 
 int uv_fs_event_stop(uv_fs_event_t* handle) {
 int uv_fs_event_stop(uv_fs_event_t* handle) {
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }
 
 
 
 
@@ -552,10 +552,10 @@ int uv_resident_set_memory(size_t* rss) {
 
 
   fd = open("/proc/self/psinfo", O_RDONLY);
   fd = open("/proc/self/psinfo", O_RDONLY);
   if (fd == -1)
   if (fd == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   /* FIXME(bnoordhuis) Handle EINTR. */
   /* FIXME(bnoordhuis) Handle EINTR. */
-  err = -EINVAL;
+  err = UV_EINVAL;
   if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
   if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
     *rss = (size_t)psinfo.pr_rssize * 1024;
     *rss = (size_t)psinfo.pr_rssize * 1024;
     err = 0;
     err = 0;
@@ -575,7 +575,7 @@ int uv_uptime(double* uptime) {
 
 
   kc = kstat_open();
   kc = kstat_open();
   if (kc == NULL)
   if (kc == NULL)
-    return -EPERM;
+    return UV_EPERM;
 
 
   ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc");
   ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc");
   if (kstat_read(kc, ksp, NULL) == -1) {
   if (kstat_read(kc, ksp, NULL) == -1) {
@@ -599,7 +599,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
 
   kc = kstat_open();
   kc = kstat_open();
   if (kc == NULL)
   if (kc == NULL)
-    return -EPERM;
+    return UV_EPERM;
 
 
   /* Get count of cpus */
   /* Get count of cpus */
   lookup_instance = 0;
   lookup_instance = 0;
@@ -610,7 +610,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos));
   *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos));
   if (!(*cpu_infos)) {
   if (!(*cpu_infos)) {
     kstat_close(kc);
     kstat_close(kc);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   *count = lookup_instance;
   *count = lookup_instance;
@@ -692,7 +692,7 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
 
 
 #ifdef SUNOS_NO_IFADDRS
 #ifdef SUNOS_NO_IFADDRS
 int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
 int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
-  return -ENOSYS;
+  return UV_ENOSYS;
 }
 }
 #else  /* SUNOS_NO_IFADDRS */
 #else  /* SUNOS_NO_IFADDRS */
 /*
 /*
@@ -730,11 +730,11 @@ static int uv__set_phys_addr(uv_interface_address_t* address,
 
 
   sockfd = socket(AF_INET, SOCK_DGRAM, 0);
   sockfd = socket(AF_INET, SOCK_DGRAM, 0);
   if (sockfd < 0)
   if (sockfd < 0)
-    return -errno;
+    return UV__ERR(errno);
 
 
   if (ioctl(sockfd, SIOCGARP, (char*)&arpreq) == -1) {
   if (ioctl(sockfd, SIOCGARP, (char*)&arpreq) == -1) {
     uv__close(sockfd);
     uv__close(sockfd);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
   memcpy(address->phys_addr, arpreq.arp_ha.sa_data, sizeof(address->phys_addr));
   memcpy(address->phys_addr, arpreq.arp_ha.sa_data, sizeof(address->phys_addr));
   uv__close(sockfd);
   uv__close(sockfd);
@@ -759,7 +759,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
   struct ifaddrs* ent;
   struct ifaddrs* ent;
 
 
   if (getifaddrs(&addrs))
   if (getifaddrs(&addrs))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *count = 0;
   *count = 0;
 
 
@@ -773,7 +773,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
   *addresses = uv__malloc(*count * sizeof(**addresses));
   *addresses = uv__malloc(*count * sizeof(**addresses));
   if (!(*addresses)) {
   if (!(*addresses)) {
     freeifaddrs(addrs);
     freeifaddrs(addrs);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   address = *addresses;
   address = *addresses;

+ 32 - 34
src/unix/tcp.c

@@ -49,16 +49,14 @@ static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
     /* Bind this new socket to an arbitrary port */
     /* Bind this new socket to an arbitrary port */
     slen = sizeof(saddr);
     slen = sizeof(saddr);
     memset(&saddr, 0, sizeof(saddr));
     memset(&saddr, 0, sizeof(saddr));
-    err = getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen);
-    if (err) {
+    if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) {
       uv__close(sockfd);
       uv__close(sockfd);
-      return err;
+      return UV__ERR(errno);
     }
     }
 
 
-    err = bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen);
-    if (err) {
+    if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) {
       uv__close(sockfd);
       uv__close(sockfd);
-      return err;
+      return UV__ERR(errno);
     }
     }
   }
   }
 
 
@@ -89,7 +87,7 @@ static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
       slen = sizeof(saddr);
       slen = sizeof(saddr);
       memset(&saddr, 0, sizeof(saddr));
       memset(&saddr, 0, sizeof(saddr));
       if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen))
       if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen))
-        return -errno;
+        return UV__ERR(errno);
 
 
       if ((saddr.ss_family == AF_INET6 &&
       if ((saddr.ss_family == AF_INET6 &&
           ((struct sockaddr_in6*) &saddr)->sin6_port != 0) ||
           ((struct sockaddr_in6*) &saddr)->sin6_port != 0) ||
@@ -102,7 +100,7 @@ static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
 
 
       /* Bind to arbitrary port */
       /* Bind to arbitrary port */
       if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen))
       if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen))
-        return -errno;
+        return UV__ERR(errno);
     }
     }
 
 
     handle->flags |= flags;
     handle->flags |= flags;
@@ -119,10 +117,10 @@ int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* tcp, unsigned int flags) {
   /* Use the lower 8 bits for the domain */
   /* Use the lower 8 bits for the domain */
   domain = flags & 0xFF;
   domain = flags & 0xFF;
   if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
   if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (flags & ~0xFF)
   if (flags & ~0xFF)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
   uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
 
 
@@ -156,18 +154,17 @@ int uv__tcp_bind(uv_tcp_t* tcp,
 
 
   /* Cannot set IPv6-only mode on non-IPv6 socket. */
   /* Cannot set IPv6-only mode on non-IPv6 socket. */
   if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
   if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
-  err = maybe_new_socket(tcp,
-                         addr->sa_family,
-                         UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+  err = maybe_new_socket(tcp, addr->sa_family, 0);
   if (err)
   if (err)
     return err;
     return err;
 
 
   on = 1;
   on = 1;
   if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
   if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
-    return -errno;
+    return UV__ERR(errno);
 
 
+#ifndef __OpenBSD__
 #ifdef IPV6_V6ONLY
 #ifdef IPV6_V6ONLY
   if (addr->sa_family == AF_INET6) {
   if (addr->sa_family == AF_INET6) {
     on = (flags & UV_TCP_IPV6ONLY) != 0;
     on = (flags & UV_TCP_IPV6ONLY) != 0;
@@ -178,11 +175,12 @@ int uv__tcp_bind(uv_tcp_t* tcp,
                    sizeof on) == -1) {
                    sizeof on) == -1) {
 #if defined(__MVS__)
 #if defined(__MVS__)
       if (errno == EOPNOTSUPP)
       if (errno == EOPNOTSUPP)
-        return -EINVAL;
+        return UV_EINVAL;
 #endif
 #endif
-      return -errno;
+      return UV__ERR(errno);
     }
     }
   }
   }
+#endif
 #endif
 #endif
 
 
   errno = 0;
   errno = 0;
@@ -190,10 +188,10 @@ int uv__tcp_bind(uv_tcp_t* tcp,
     if (errno == EAFNOSUPPORT)
     if (errno == EAFNOSUPPORT)
       /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
       /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
        * socket created with AF_INET to an AF_INET6 address or vice versa. */
        * socket created with AF_INET to an AF_INET6 address or vice versa. */
-      return -EINVAL;
-    return -errno;
+      return UV_EINVAL;
+    return UV__ERR(errno);
   }
   }
-  tcp->delayed_error = -errno;
+  tcp->delayed_error = UV__ERR(errno);
 
 
   tcp->flags |= UV_HANDLE_BOUND;
   tcp->flags |= UV_HANDLE_BOUND;
   if (addr->sa_family == AF_INET6)
   if (addr->sa_family == AF_INET6)
@@ -214,7 +212,7 @@ int uv__tcp_connect(uv_connect_t* req,
   assert(handle->type == UV_TCP);
   assert(handle->type == UV_TCP);
 
 
   if (handle->connect_req != NULL)
   if (handle->connect_req != NULL)
-    return -EALREADY;  /* FIXME(bnoordhuis) -EINVAL or maybe -EBUSY. */
+    return UV_EALREADY;  /* FIXME(bnoordhuis) UV_EINVAL or maybe UV_EBUSY. */
 
 
   err = maybe_new_socket(handle,
   err = maybe_new_socket(handle,
                          addr->sa_family,
                          addr->sa_family,
@@ -242,9 +240,9 @@ int uv__tcp_connect(uv_connect_t* req,
      * error. Solaris wants to report immediately--other unixes want to
      * error. Solaris wants to report immediately--other unixes want to
      * wait.
      * wait.
      */
      */
-      handle->delayed_error = -errno;
+      handle->delayed_error = UV__ERR(errno);
     else
     else
-      return -errno;
+      return UV__ERR(errno);
   }
   }
 
 
   uv__req_init(handle->loop, req, UV_CONNECT);
   uv__req_init(handle->loop, req, UV_CONNECT);
@@ -284,13 +282,13 @@ int uv_tcp_getsockname(const uv_tcp_t* handle,
     return handle->delayed_error;
     return handle->delayed_error;
 
 
   if (uv__stream_fd(handle) < 0)
   if (uv__stream_fd(handle) < 0)
-    return -EINVAL;  /* FIXME(bnoordhuis) -EBADF */
+    return UV_EINVAL;  /* FIXME(bnoordhuis) UV_EBADF */
 
 
   /* sizeof(socklen_t) != sizeof(int) on some systems. */
   /* sizeof(socklen_t) != sizeof(int) on some systems. */
   socklen = (socklen_t) *namelen;
   socklen = (socklen_t) *namelen;
 
 
   if (getsockname(uv__stream_fd(handle), name, &socklen))
   if (getsockname(uv__stream_fd(handle), name, &socklen))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *namelen = (int) socklen;
   *namelen = (int) socklen;
   return 0;
   return 0;
@@ -306,13 +304,13 @@ int uv_tcp_getpeername(const uv_tcp_t* handle,
     return handle->delayed_error;
     return handle->delayed_error;
 
 
   if (uv__stream_fd(handle) < 0)
   if (uv__stream_fd(handle) < 0)
-    return -EINVAL;  /* FIXME(bnoordhuis) -EBADF */
+    return UV_EINVAL;  /* FIXME(bnoordhuis) UV_EBADF */
 
 
   /* sizeof(socklen_t) != sizeof(int) on some systems. */
   /* sizeof(socklen_t) != sizeof(int) on some systems. */
   socklen = (socklen_t) *namelen;
   socklen = (socklen_t) *namelen;
 
 
   if (getpeername(uv__stream_fd(handle), name, &socklen))
   if (getpeername(uv__stream_fd(handle), name, &socklen))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *namelen = (int) socklen;
   *namelen = (int) socklen;
   return 0;
   return 0;
@@ -335,20 +333,20 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
   if (single_accept)
   if (single_accept)
     tcp->flags |= UV_TCP_SINGLE_ACCEPT;
     tcp->flags |= UV_TCP_SINGLE_ACCEPT;
 
 
-  flags = UV_STREAM_READABLE;
+  flags = 0;
 #if defined(__MVS__)
 #if defined(__MVS__)
   /* on zOS the listen call does not bind automatically
   /* on zOS the listen call does not bind automatically
      if the socket is unbound. Hence the manual binding to
      if the socket is unbound. Hence the manual binding to
      an arbitrary port is required to be done manually
      an arbitrary port is required to be done manually
   */
   */
   flags |= UV_HANDLE_BOUND;
   flags |= UV_HANDLE_BOUND;
-#endif  
+#endif
   err = maybe_new_socket(tcp, AF_INET, flags);
   err = maybe_new_socket(tcp, AF_INET, flags);
   if (err)
   if (err)
     return err;
     return err;
 
 
   if (listen(tcp->io_watcher.fd, backlog))
   if (listen(tcp->io_watcher.fd, backlog))
-    return -errno;
+    return UV__ERR(errno);
 
 
   tcp->connection_cb = cb;
   tcp->connection_cb = cb;
   tcp->flags |= UV_HANDLE_BOUND;
   tcp->flags |= UV_HANDLE_BOUND;
@@ -363,18 +361,18 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
 
 
 int uv__tcp_nodelay(int fd, int on) {
 int uv__tcp_nodelay(int fd, int on) {
   if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))
   if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))
-    return -errno;
+    return UV__ERR(errno);
   return 0;
   return 0;
 }
 }
 
 
 
 
 int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
 int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
   if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
   if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
-    return -errno;
+    return UV__ERR(errno);
 
 
 #ifdef TCP_KEEPIDLE
 #ifdef TCP_KEEPIDLE
   if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
   if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
-    return -errno;
+    return UV__ERR(errno);
 #endif
 #endif
 
 
   /* Solaris/SmartOS, if you don't support keep-alive,
   /* Solaris/SmartOS, if you don't support keep-alive,
@@ -383,7 +381,7 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
   /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
   /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
 #if defined(TCP_KEEPALIVE) && !defined(__sun)
 #if defined(TCP_KEEPALIVE) && !defined(__sun)
   if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
   if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
-    return -errno;
+    return UV__ERR(errno);
 #endif
 #endif
 
 
   return 0;
   return 0;

+ 174 - 82
src/unix/thread.c

@@ -37,6 +37,10 @@
 #include <sys/sem.h>
 #include <sys/sem.h>
 #endif
 #endif
 
 
+#ifdef __GLIBC__
+#include <gnu/libc-version.h>  /* gnu_get_libc_version() */
+#endif
+
 #undef NANOSEC
 #undef NANOSEC
 #define NANOSEC ((uint64_t) 1e9)
 #define NANOSEC ((uint64_t) 1e9)
 
 
@@ -200,7 +204,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
   if (attr != NULL)
   if (attr != NULL)
     pthread_attr_destroy(attr);
     pthread_attr_destroy(attr);
 
 
-  return -err;
+  return UV__ERR(err);
 }
 }
 
 
 
 
@@ -209,7 +213,7 @@ uv_thread_t uv_thread_self(void) {
 }
 }
 
 
 int uv_thread_join(uv_thread_t *tid) {
 int uv_thread_join(uv_thread_t *tid) {
-  return -pthread_join(*tid, NULL);
+  return UV__ERR(pthread_join(*tid, NULL));
 }
 }
 
 
 
 
@@ -220,7 +224,7 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
 
 
 int uv_mutex_init(uv_mutex_t* mutex) {
 int uv_mutex_init(uv_mutex_t* mutex) {
 #if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
 #if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
-  return -pthread_mutex_init(mutex, NULL);
+  return UV__ERR(pthread_mutex_init(mutex, NULL));
 #else
 #else
   pthread_mutexattr_t attr;
   pthread_mutexattr_t attr;
   int err;
   int err;
@@ -236,7 +240,7 @@ int uv_mutex_init(uv_mutex_t* mutex) {
   if (pthread_mutexattr_destroy(&attr))
   if (pthread_mutexattr_destroy(&attr))
     abort();
     abort();
 
 
-  return -err;
+  return UV__ERR(err);
 #endif
 #endif
 }
 }
 
 
@@ -256,7 +260,7 @@ int uv_mutex_init_recursive(uv_mutex_t* mutex) {
   if (pthread_mutexattr_destroy(&attr))
   if (pthread_mutexattr_destroy(&attr))
     abort();
     abort();
 
 
-  return -err;
+  return UV__ERR(err);
 }
 }
 
 
 
 
@@ -279,7 +283,7 @@ int uv_mutex_trylock(uv_mutex_t* mutex) {
   if (err) {
   if (err) {
     if (err != EBUSY && err != EAGAIN)
     if (err != EBUSY && err != EAGAIN)
       abort();
       abort();
-    return -EBUSY;
+    return UV_EBUSY;
   }
   }
 
 
   return 0;
   return 0;
@@ -293,7 +297,7 @@ void uv_mutex_unlock(uv_mutex_t* mutex) {
 
 
 
 
 int uv_rwlock_init(uv_rwlock_t* rwlock) {
 int uv_rwlock_init(uv_rwlock_t* rwlock) {
-  return -pthread_rwlock_init(rwlock, NULL);
+  return UV__ERR(pthread_rwlock_init(rwlock, NULL));
 }
 }
 
 
 
 
@@ -316,7 +320,7 @@ int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
   if (err) {
   if (err) {
     if (err != EBUSY && err != EAGAIN)
     if (err != EBUSY && err != EAGAIN)
       abort();
       abort();
-    return -EBUSY;
+    return UV_EBUSY;
   }
   }
 
 
   return 0;
   return 0;
@@ -342,7 +346,7 @@ int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
   if (err) {
   if (err) {
     if (err != EBUSY && err != EAGAIN)
     if (err != EBUSY && err != EAGAIN)
       abort();
       abort();
-    return -EBUSY;
+    return UV_EBUSY;
   }
   }
 
 
   return 0;
   return 0;
@@ -369,12 +373,12 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) {
   if (err == KERN_SUCCESS)
   if (err == KERN_SUCCESS)
     return 0;
     return 0;
   if (err == KERN_INVALID_ARGUMENT)
   if (err == KERN_INVALID_ARGUMENT)
-    return -EINVAL;
+    return UV_EINVAL;
   if (err == KERN_RESOURCE_SHORTAGE)
   if (err == KERN_RESOURCE_SHORTAGE)
-    return -ENOMEM;
+    return UV_ENOMEM;
 
 
   abort();
   abort();
-  return -EINVAL;  /* Satisfy the compiler. */
+  return UV_EINVAL;  /* Satisfy the compiler. */
 }
 }
 
 
 
 
@@ -413,115 +417,151 @@ int uv_sem_trywait(uv_sem_t* sem) {
   if (err == KERN_SUCCESS)
   if (err == KERN_SUCCESS)
     return 0;
     return 0;
   if (err == KERN_OPERATION_TIMED_OUT)
   if (err == KERN_OPERATION_TIMED_OUT)
-    return -EAGAIN;
+    return UV_EAGAIN;
 
 
   abort();
   abort();
-  return -EINVAL;  /* Satisfy the compiler. */
+  return UV_EINVAL;  /* Satisfy the compiler. */
+}
+
+#else /* !(defined(__APPLE__) && defined(__MACH__)) */
+
+#ifdef __GLIBC__
+
+/* Hack around https://sourceware.org/bugzilla/show_bug.cgi?id=12674
+ * by providing a custom implementation for glibc < 2.21 in terms of other
+ * concurrency primitives.
+ * Refs: https://github.com/nodejs/node/issues/19903 */
+
+/* To preserve ABI compatibility, we treat the uv_sem_t as storage for
+ * a pointer to the actual struct we're using underneath. */
+
+static uv_once_t glibc_version_check_once = UV_ONCE_INIT;
+static int platform_needs_custom_semaphore = 0;
+
+static void glibc_version_check(void) {
+  const char* version = gnu_get_libc_version();
+  platform_needs_custom_semaphore =
+      version[0] == '2' && version[1] == '.' &&
+      atoi(version + 2) < 21;
 }
 }
 
 
 #elif defined(__MVS__)
 #elif defined(__MVS__)
 
 
-int uv_sem_init(uv_sem_t* sem, unsigned int value) {
-  uv_sem_t semid;
+#define platform_needs_custom_semaphore 1
+
+#else /* !defined(__GLIBC__) && !defined(__MVS__) */
+
+#define platform_needs_custom_semaphore 0
+
+#endif
+
+typedef struct uv_semaphore_s {
+  uv_mutex_t mutex;
+  uv_cond_t cond;
+  unsigned int value;
+} uv_semaphore_t;
+
+#if defined(__GLIBC__) || platform_needs_custom_semaphore
+STATIC_ASSERT(sizeof(uv_sem_t) >= sizeof(uv_semaphore_t*));
+#endif
+
+static int uv__custom_sem_init(uv_sem_t* sem_, unsigned int value) {
   int err;
   int err;
-  union {
-    int val;
-    struct semid_ds* buf;
-    unsigned short* array;
-  } arg;
+  uv_semaphore_t* sem;
 
 
+  sem = uv__malloc(sizeof(*sem));
+  if (sem == NULL)
+    return UV_ENOMEM;
 
 
-  semid = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR);
-  if (semid == -1)
-    return -errno;
+  if ((err = uv_mutex_init(&sem->mutex)) != 0) {
+    uv__free(sem);
+    return err;
+  }
 
 
-  arg.val = value;
-  if (-1 == semctl(semid, 0, SETVAL, arg)) {
-    err = errno;
-    if (-1 == semctl(*sem, 0, IPC_RMID))
-      abort();
-    return -err;
+  if ((err = uv_cond_init(&sem->cond)) != 0) {
+    uv_mutex_destroy(&sem->mutex);
+    uv__free(sem);
+    return err;
   }
   }
 
 
-  *sem = semid;
+  sem->value = value;
+  *(uv_semaphore_t**)sem_ = sem;
   return 0;
   return 0;
 }
 }
 
 
-void uv_sem_destroy(uv_sem_t* sem) {
-  if (-1 == semctl(*sem, 0, IPC_RMID))
-    abort();
+
+static void uv__custom_sem_destroy(uv_sem_t* sem_) {
+  uv_semaphore_t* sem;
+
+  sem = *(uv_semaphore_t**)sem_;
+  uv_cond_destroy(&sem->cond);
+  uv_mutex_destroy(&sem->mutex);
+  uv__free(sem);
 }
 }
 
 
-void uv_sem_post(uv_sem_t* sem) {
-  struct sembuf buf;
 
 
-  buf.sem_num = 0;
-  buf.sem_op = 1;
-  buf.sem_flg = 0;
+static void uv__custom_sem_post(uv_sem_t* sem_) {
+  uv_semaphore_t* sem;
 
 
-  if (-1 == semop(*sem, &buf, 1))
-    abort();
+  sem = *(uv_semaphore_t**)sem_;
+  uv_mutex_lock(&sem->mutex);
+  sem->value++;
+  if (sem->value == 1)
+    uv_cond_signal(&sem->cond);
+  uv_mutex_unlock(&sem->mutex);
 }
 }
 
 
-void uv_sem_wait(uv_sem_t* sem) {
-  struct sembuf buf;
-  int op_status;
-
-  buf.sem_num = 0;
-  buf.sem_op = -1;
-  buf.sem_flg = 0;
 
 
-  do
-    op_status = semop(*sem, &buf, 1);
-  while (op_status == -1 && errno == EINTR);
+static void uv__custom_sem_wait(uv_sem_t* sem_) {
+  uv_semaphore_t* sem;
 
 
-  if (op_status)
-    abort();
+  sem = *(uv_semaphore_t**)sem_;
+  uv_mutex_lock(&sem->mutex);
+  while (sem->value == 0)
+    uv_cond_wait(&sem->cond, &sem->mutex);
+  sem->value--;
+  uv_mutex_unlock(&sem->mutex);
 }
 }
 
 
-int uv_sem_trywait(uv_sem_t* sem) {
-  struct sembuf buf;
-  int op_status;
 
 
-  buf.sem_num = 0;
-  buf.sem_op = -1;
-  buf.sem_flg = IPC_NOWAIT;
+static int uv__custom_sem_trywait(uv_sem_t* sem_) {
+  uv_semaphore_t* sem;
 
 
-  do
-    op_status = semop(*sem, &buf, 1);
-  while (op_status == -1 && errno == EINTR);
+  sem = *(uv_semaphore_t**)sem_;
+  if (uv_mutex_trylock(&sem->mutex) != 0)
+    return UV_EAGAIN;
 
 
-  if (op_status) {
-    if (errno == EAGAIN)
-      return -EAGAIN;
-    abort();
+  if (sem->value == 0) {
+    uv_mutex_unlock(&sem->mutex);
+    return UV_EAGAIN;
   }
   }
 
 
+  sem->value--;
+  uv_mutex_unlock(&sem->mutex);
+
   return 0;
   return 0;
 }
 }
 
 
-#else /* !(defined(__APPLE__) && defined(__MACH__)) */
-
-int uv_sem_init(uv_sem_t* sem, unsigned int value) {
+static int uv__sem_init(uv_sem_t* sem, unsigned int value) {
   if (sem_init(sem, 0, value))
   if (sem_init(sem, 0, value))
-    return -errno;
+    return UV__ERR(errno);
   return 0;
   return 0;
 }
 }
 
 
 
 
-void uv_sem_destroy(uv_sem_t* sem) {
+static void uv__sem_destroy(uv_sem_t* sem) {
   if (sem_destroy(sem))
   if (sem_destroy(sem))
     abort();
     abort();
 }
 }
 
 
 
 
-void uv_sem_post(uv_sem_t* sem) {
+static void uv__sem_post(uv_sem_t* sem) {
   if (sem_post(sem))
   if (sem_post(sem))
     abort();
     abort();
 }
 }
 
 
 
 
-void uv_sem_wait(uv_sem_t* sem) {
+static void uv__sem_wait(uv_sem_t* sem) {
   int r;
   int r;
 
 
   do
   do
@@ -533,7 +573,7 @@ void uv_sem_wait(uv_sem_t* sem) {
 }
 }
 
 
 
 
-int uv_sem_trywait(uv_sem_t* sem) {
+static int uv__sem_trywait(uv_sem_t* sem) {
   int r;
   int r;
 
 
   do
   do
@@ -542,20 +582,63 @@ int uv_sem_trywait(uv_sem_t* sem) {
 
 
   if (r) {
   if (r) {
     if (errno == EAGAIN)
     if (errno == EAGAIN)
-      return -EAGAIN;
+      return UV_EAGAIN;
     abort();
     abort();
   }
   }
 
 
   return 0;
   return 0;
 }
 }
 
 
+int uv_sem_init(uv_sem_t* sem, unsigned int value) {
+#ifdef __GLIBC__
+  uv_once(&glibc_version_check_once, glibc_version_check);
+#endif
+
+  if (platform_needs_custom_semaphore)
+    return uv__custom_sem_init(sem, value);
+  else
+    return uv__sem_init(sem, value);
+}
+
+
+void uv_sem_destroy(uv_sem_t* sem) {
+  if (platform_needs_custom_semaphore)
+    uv__custom_sem_destroy(sem);
+  else
+    uv__sem_destroy(sem);
+}
+
+
+void uv_sem_post(uv_sem_t* sem) {
+  if (platform_needs_custom_semaphore)
+    uv__custom_sem_post(sem);
+  else
+    uv__sem_post(sem);
+}
+
+
+void uv_sem_wait(uv_sem_t* sem) {
+  if (platform_needs_custom_semaphore)
+    uv__custom_sem_wait(sem);
+  else
+    uv__sem_wait(sem);
+}
+
+
+int uv_sem_trywait(uv_sem_t* sem) {
+  if (platform_needs_custom_semaphore)
+    return uv__custom_sem_trywait(sem);
+  else
+    return uv__sem_trywait(sem);
+}
+
 #endif /* defined(__APPLE__) && defined(__MACH__) */
 #endif /* defined(__APPLE__) && defined(__MACH__) */
 
 
 
 
 #if defined(__APPLE__) && defined(__MACH__) || defined(__MVS__)
 #if defined(__APPLE__) && defined(__MACH__) || defined(__MVS__)
 
 
 int uv_cond_init(uv_cond_t* cond) {
 int uv_cond_init(uv_cond_t* cond) {
-  return -pthread_cond_init(cond, NULL);
+  return UV__ERR(pthread_cond_init(cond, NULL));
 }
 }
 
 
 #else /* !(defined(__APPLE__) && defined(__MACH__)) */
 #else /* !(defined(__APPLE__) && defined(__MACH__)) */
@@ -566,7 +649,7 @@ int uv_cond_init(uv_cond_t* cond) {
 
 
   err = pthread_condattr_init(&attr);
   err = pthread_condattr_init(&attr);
   if (err)
   if (err)
-    return -err;
+    return UV__ERR(err);
 
 
 #if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21)
 #if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21)
   err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
   err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
@@ -588,7 +671,7 @@ error:
   pthread_cond_destroy(cond);
   pthread_cond_destroy(cond);
 error2:
 error2:
   pthread_condattr_destroy(&attr);
   pthread_condattr_destroy(&attr);
-  return -err;
+  return UV__ERR(err);
 }
 }
 
 
 #endif /* defined(__APPLE__) && defined(__MACH__) */
 #endif /* defined(__APPLE__) && defined(__MACH__) */
@@ -646,13 +729,22 @@ void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
 int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
 int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
   int r;
   int r;
   struct timespec ts;
   struct timespec ts;
+#if defined(__MVS__)
+  struct timeval tv;
+#endif
 
 
 #if defined(__APPLE__) && defined(__MACH__)
 #if defined(__APPLE__) && defined(__MACH__)
   ts.tv_sec = timeout / NANOSEC;
   ts.tv_sec = timeout / NANOSEC;
   ts.tv_nsec = timeout % NANOSEC;
   ts.tv_nsec = timeout % NANOSEC;
   r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
   r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
+#else
+#if defined(__MVS__)
+  if (gettimeofday(&tv, NULL))
+    abort();
+  timeout += tv.tv_sec * NANOSEC + tv.tv_usec * 1e3;
 #else
 #else
   timeout += uv__hrtime(UV_CLOCK_PRECISE);
   timeout += uv__hrtime(UV_CLOCK_PRECISE);
+#endif
   ts.tv_sec = timeout / NANOSEC;
   ts.tv_sec = timeout / NANOSEC;
   ts.tv_nsec = timeout % NANOSEC;
   ts.tv_nsec = timeout % NANOSEC;
 #if defined(__ANDROID_API__) && __ANDROID_API__ < 21
 #if defined(__ANDROID_API__) && __ANDROID_API__ < 21
@@ -672,15 +764,15 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
     return 0;
     return 0;
 
 
   if (r == ETIMEDOUT)
   if (r == ETIMEDOUT)
-    return -ETIMEDOUT;
+    return UV_ETIMEDOUT;
 
 
   abort();
   abort();
-  return -EINVAL;  /* Satisfy the compiler. */
+  return UV_EINVAL;  /* Satisfy the compiler. */
 }
 }
 
 
 
 
 int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
 int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
-  return -pthread_barrier_init(barrier, NULL, count);
+  return UV__ERR(pthread_barrier_init(barrier, NULL, count));
 }
 }
 
 
 
 
@@ -699,7 +791,7 @@ int uv_barrier_wait(uv_barrier_t* barrier) {
 
 
 
 
 int uv_key_create(uv_key_t* key) {
 int uv_key_create(uv_key_t* key) {
-  return -pthread_key_create(key, NULL);
+  return UV__ERR(pthread_key_create(key, NULL));
 }
 }
 
 
 
 

+ 2 - 2
src/unix/timer.c

@@ -66,7 +66,7 @@ int uv_timer_start(uv_timer_t* handle,
   uint64_t clamped_timeout;
   uint64_t clamped_timeout;
 
 
   if (cb == NULL)
   if (cb == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (uv__is_active(handle))
   if (uv__is_active(handle))
     uv_timer_stop(handle);
     uv_timer_stop(handle);
@@ -105,7 +105,7 @@ int uv_timer_stop(uv_timer_t* handle) {
 
 
 int uv_timer_again(uv_timer_t* handle) {
 int uv_timer_again(uv_timer_t* handle) {
   if (handle->timer_cb == NULL)
   if (handle->timer_cb == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (handle->repeat) {
   if (handle->repeat) {
     uv_timer_stop(handle);
     uv_timer_stop(handle);

+ 8 - 8
src/unix/tty.c

@@ -106,7 +106,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
    */
    */
   type = uv_guess_handle(fd);
   type = uv_guess_handle(fd);
   if (type == UV_FILE || type == UV_UNKNOWN_HANDLE)
   if (type == UV_FILE || type == UV_UNKNOWN_HANDLE)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   flags = 0;
   flags = 0;
   newfd = -1;
   newfd = -1;
@@ -142,7 +142,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
     newfd = r;
     newfd = r;
 
 
     r = uv__dup2_cloexec(newfd, fd);
     r = uv__dup2_cloexec(newfd, fd);
-    if (r < 0 && r != -EINVAL) {
+    if (r < 0 && r != UV_EINVAL) {
       /* EINVAL means newfd == fd which could conceivably happen if another
       /* EINVAL means newfd == fd which could conceivably happen if another
        * thread called close(fd) between our calls to isatty() and open().
        * thread called close(fd) between our calls to isatty() and open().
        * That's a rather unlikely event but let's handle it anyway.
        * That's a rather unlikely event but let's handle it anyway.
@@ -163,7 +163,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
   if (saved_flags == -1) {
   if (saved_flags == -1) {
     if (newfd != -1)
     if (newfd != -1)
       uv__close(newfd);
       uv__close(newfd);
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 #endif
 #endif
 
 
@@ -234,7 +234,7 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
   fd = uv__stream_fd(tty);
   fd = uv__stream_fd(tty);
   if (tty->mode == UV_TTY_MODE_NORMAL && mode != UV_TTY_MODE_NORMAL) {
   if (tty->mode == UV_TTY_MODE_NORMAL && mode != UV_TTY_MODE_NORMAL) {
     if (tcgetattr(fd, &tty->orig_termios))
     if (tcgetattr(fd, &tty->orig_termios))
-      return -errno;
+      return UV__ERR(errno);
 
 
     /* This is used for uv_tty_reset_mode() */
     /* This is used for uv_tty_reset_mode() */
     uv_spinlock_lock(&termios_spinlock);
     uv_spinlock_lock(&termios_spinlock);
@@ -264,7 +264,7 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
 
 
   /* Apply changes after draining */
   /* Apply changes after draining */
   if (tcsetattr(fd, TCSADRAIN, &tmp))
   if (tcsetattr(fd, TCSADRAIN, &tmp))
-    return -errno;
+    return UV__ERR(errno);
 
 
   tty->mode = mode;
   tty->mode = mode;
   return 0;
   return 0;
@@ -280,7 +280,7 @@ int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
   while (err == -1 && errno == EINTR);
   while (err == -1 && errno == EINTR);
 
 
   if (err == -1)
   if (err == -1)
-    return -errno;
+    return UV__ERR(errno);
 
 
   *width = ws.ws_col;
   *width = ws.ws_col;
   *height = ws.ws_row;
   *height = ws.ws_row;
@@ -358,12 +358,12 @@ int uv_tty_reset_mode(void) {
 
 
   saved_errno = errno;
   saved_errno = errno;
   if (!uv_spinlock_trylock(&termios_spinlock))
   if (!uv_spinlock_trylock(&termios_spinlock))
-    return -EBUSY;  /* In uv_tty_set_mode(). */
+    return UV_EBUSY;  /* In uv_tty_set_mode(). */
 
 
   err = 0;
   err = 0;
   if (orig_termios_fd != -1)
   if (orig_termios_fd != -1)
     if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios))
     if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios))
-      err = -errno;
+      err = UV__ERR(errno);
 
 
   uv_spinlock_unlock(&termios_spinlock);
   uv_spinlock_unlock(&termios_spinlock);
   errno = saved_errno;
   errno = saved_errno;

+ 38 - 38
src/unix/udp.c

@@ -72,7 +72,7 @@ void uv__udp_finish_close(uv_udp_t* handle) {
     QUEUE_REMOVE(q);
     QUEUE_REMOVE(q);
 
 
     req = QUEUE_DATA(q, uv_udp_send_t, queue);
     req = QUEUE_DATA(q, uv_udp_send_t, queue);
-    req->status = -ECANCELED;
+    req->status = UV_ECANCELED;
     QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
     QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
   }
   }
 
 
@@ -189,7 +189,7 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
       if (errno == EAGAIN || errno == EWOULDBLOCK)
       if (errno == EAGAIN || errno == EWOULDBLOCK)
         handle->recv_cb(handle, 0, &buf, NULL, 0);
         handle->recv_cb(handle, 0, &buf, NULL, 0);
       else
       else
-        handle->recv_cb(handle, -errno, &buf, NULL, 0);
+        handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
     }
     }
     else {
     else {
       const struct sockaddr *addr;
       const struct sockaddr *addr;
@@ -242,7 +242,7 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
         break;
         break;
     }
     }
 
 
-    req->status = (size == -1 ? -errno : size);
+    req->status = (size == -1 ? UV__ERR(errno) : size);
 
 
     /* Sending a datagram is an atomic operation: either all data
     /* Sending a datagram is an atomic operation: either all data
      * is written or nothing is (and EMSGSIZE is raised). That is
      * is written or nothing is (and EMSGSIZE is raised). That is
@@ -270,11 +270,11 @@ static int uv__set_reuse(int fd) {
 #if defined(SO_REUSEPORT) && !defined(__linux__)
 #if defined(SO_REUSEPORT) && !defined(__linux__)
   yes = 1;
   yes = 1;
   if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
   if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
-    return -errno;
+    return UV__ERR(errno);
 #else
 #else
   yes = 1;
   yes = 1;
   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
-    return -errno;
+    return UV__ERR(errno);
 #endif
 #endif
 
 
   return 0;
   return 0;
@@ -291,11 +291,11 @@ int uv__udp_bind(uv_udp_t* handle,
 
 
   /* Check for bad flags. */
   /* Check for bad flags. */
   if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR))
   if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR))
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   /* Cannot set IPv6-only mode on non-IPv6 socket. */
   /* Cannot set IPv6-only mode on non-IPv6 socket. */
   if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6)
   if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   fd = handle->io_watcher.fd;
   fd = handle->io_watcher.fd;
   if (fd == -1) {
   if (fd == -1) {
@@ -316,21 +316,21 @@ int uv__udp_bind(uv_udp_t* handle,
 #ifdef IPV6_V6ONLY
 #ifdef IPV6_V6ONLY
     yes = 1;
     yes = 1;
     if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
     if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
-      err = -errno;
+      err = UV__ERR(errno);
       return err;
       return err;
     }
     }
 #else
 #else
-    err = -ENOTSUP;
+    err = UV_ENOTSUP;
     return err;
     return err;
 #endif
 #endif
   }
   }
 
 
   if (bind(fd, addr, addrlen)) {
   if (bind(fd, addr, addrlen)) {
-    err = -errno;
+    err = UV__ERR(errno);
     if (errno == EAFNOSUPPORT)
     if (errno == EAFNOSUPPORT)
       /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
       /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
        * socket created with AF_INET to an AF_INET6 address or vice versa. */
        * socket created with AF_INET to an AF_INET6 address or vice versa. */
-      err = -EINVAL;
+      err = UV_EINVAL;
     return err;
     return err;
   }
   }
 
 
@@ -418,7 +418,7 @@ int uv__udp_send(uv_udp_send_t* req,
 
 
   if (req->bufs == NULL) {
   if (req->bufs == NULL) {
     uv__req_unregister(handle->loop, req);
     uv__req_unregister(handle->loop, req);
-    return -ENOMEM;
+    return UV_ENOMEM;
   }
   }
 
 
   memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
   memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
@@ -457,7 +457,7 @@ int uv__udp_try_send(uv_udp_t* handle,
 
 
   /* already sending a message */
   /* already sending a message */
   if (handle->send_queue_count != 0)
   if (handle->send_queue_count != 0)
-    return -EAGAIN;
+    return UV_EAGAIN;
 
 
   err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
   err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
   if (err)
   if (err)
@@ -475,9 +475,9 @@ int uv__udp_try_send(uv_udp_t* handle,
 
 
   if (size == -1) {
   if (size == -1) {
     if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
     if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
-      return -EAGAIN;
+      return UV_EAGAIN;
     else
     else
-      return -errno;
+      return UV__ERR(errno);
   }
   }
 
 
   return size;
   return size;
@@ -512,7 +512,7 @@ static int uv__udp_set_membership4(uv_udp_t* handle,
     optname = IP_DROP_MEMBERSHIP;
     optname = IP_DROP_MEMBERSHIP;
     break;
     break;
   default:
   default:
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 
 
   if (setsockopt(handle->io_watcher.fd,
   if (setsockopt(handle->io_watcher.fd,
@@ -522,9 +522,9 @@ static int uv__udp_set_membership4(uv_udp_t* handle,
                  sizeof(mreq))) {
                  sizeof(mreq))) {
 #if defined(__MVS__)
 #if defined(__MVS__)
   if (errno == ENXIO)
   if (errno == ENXIO)
-    return -ENODEV;
+    return UV_ENODEV;
 #endif
 #endif
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   return 0;
   return 0;
@@ -543,7 +543,7 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
 
 
   if (interface_addr) {
   if (interface_addr) {
     if (uv_ip6_addr(interface_addr, 0, &addr6))
     if (uv_ip6_addr(interface_addr, 0, &addr6))
-      return -EINVAL;
+      return UV_EINVAL;
     mreq.ipv6mr_interface = addr6.sin6_scope_id;
     mreq.ipv6mr_interface = addr6.sin6_scope_id;
   } else {
   } else {
     mreq.ipv6mr_interface = 0;
     mreq.ipv6mr_interface = 0;
@@ -559,7 +559,7 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
     optname = IPV6_DROP_MEMBERSHIP;
     optname = IPV6_DROP_MEMBERSHIP;
     break;
     break;
   default:
   default:
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 
 
   if (setsockopt(handle->io_watcher.fd,
   if (setsockopt(handle->io_watcher.fd,
@@ -569,9 +569,9 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
                  sizeof(mreq))) {
                  sizeof(mreq))) {
 #if defined(__MVS__)
 #if defined(__MVS__)
   if (errno == ENXIO)
   if (errno == ENXIO)
-    return -ENODEV;
+    return UV_ENODEV;
 #endif
 #endif
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   return 0;
   return 0;
@@ -586,10 +586,10 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
   /* Use the lower 8 bits for the domain */
   /* Use the lower 8 bits for the domain */
   domain = flags & 0xFF;
   domain = flags & 0xFF;
   if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
   if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (flags & ~0xFF)
   if (flags & ~0xFF)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (domain != AF_UNSPEC) {
   if (domain != AF_UNSPEC) {
     err = uv__socket(domain, SOCK_DGRAM, 0);
     err = uv__socket(domain, SOCK_DGRAM, 0);
@@ -622,7 +622,7 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
 
 
   /* Check for already active socket. */
   /* Check for already active socket. */
   if (handle->io_watcher.fd != -1)
   if (handle->io_watcher.fd != -1)
-    return -EBUSY;
+    return UV_EBUSY;
 
 
   err = uv__nonblock(sock, 1);
   err = uv__nonblock(sock, 1);
   if (err)
   if (err)
@@ -656,7 +656,7 @@ int uv_udp_set_membership(uv_udp_t* handle,
       return err;
       return err;
     return uv__udp_set_membership6(handle, &addr6, interface_addr, membership);
     return uv__udp_set_membership6(handle, &addr6, interface_addr, membership);
   } else {
   } else {
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 }
 }
 
 
@@ -680,7 +680,7 @@ static int uv__setsockopt(uv_udp_t* handle,
                    val,
                    val,
                    size);
                    size);
   if (r)
   if (r)
-    return -errno;
+    return UV__ERR(errno);
 
 
   return 0;
   return 0;
 }
 }
@@ -698,7 +698,7 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle,
 #endif
 #endif
 
 
   if (val < 0 || val > 255)
   if (val < 0 || val > 255)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
   return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
 }
 }
@@ -710,7 +710,7 @@ int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
                  SO_BROADCAST,
                  SO_BROADCAST,
                  &on,
                  &on,
                  sizeof(on))) {
                  sizeof(on))) {
-    return -errno;
+    return UV__ERR(errno);
   }
   }
 
 
   return 0;
   return 0;
@@ -719,11 +719,11 @@ int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
 
 
 int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
 int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
   if (ttl < 1 || ttl > 255)
   if (ttl < 1 || ttl > 255)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
 #if defined(__MVS__)
 #if defined(__MVS__)
   if (!(handle->flags & UV_HANDLE_IPV6))
   if (!(handle->flags & UV_HANDLE_IPV6))
-    return -ENOTSUP;  /* zOS does not support setting ttl for IPv4 */
+    return UV_ENOTSUP;  /* zOS does not support setting ttl for IPv4 */
 #endif
 #endif
 
 
 /*
 /*
@@ -817,7 +817,7 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
   } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) {
   } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) {
     /* nothing, address was parsed */
     /* nothing, address was parsed */
   } else {
   } else {
-    return -EINVAL;
+    return UV_EINVAL;
   }
   }
 
 
   if (addr_st.ss_family == AF_INET) {
   if (addr_st.ss_family == AF_INET) {
@@ -826,7 +826,7 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
                    IP_MULTICAST_IF,
                    IP_MULTICAST_IF,
                    (void*) &addr4->sin_addr,
                    (void*) &addr4->sin_addr,
                    sizeof(addr4->sin_addr)) == -1) {
                    sizeof(addr4->sin_addr)) == -1) {
-      return -errno;
+      return UV__ERR(errno);
     }
     }
   } else if (addr_st.ss_family == AF_INET6) {
   } else if (addr_st.ss_family == AF_INET6) {
     if (setsockopt(handle->io_watcher.fd,
     if (setsockopt(handle->io_watcher.fd,
@@ -834,7 +834,7 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
                    IPV6_MULTICAST_IF,
                    IPV6_MULTICAST_IF,
                    &addr6->sin6_scope_id,
                    &addr6->sin6_scope_id,
                    sizeof(addr6->sin6_scope_id)) == -1) {
                    sizeof(addr6->sin6_scope_id)) == -1) {
-      return -errno;
+      return UV__ERR(errno);
     }
     }
   } else {
   } else {
     assert(0 && "unexpected address family");
     assert(0 && "unexpected address family");
@@ -851,13 +851,13 @@ int uv_udp_getsockname(const uv_udp_t* handle,
   socklen_t socklen;
   socklen_t socklen;
 
 
   if (handle->io_watcher.fd == -1)
   if (handle->io_watcher.fd == -1)
-    return -EINVAL;  /* FIXME(bnoordhuis) -EBADF */
+    return UV_EINVAL;  /* FIXME(bnoordhuis) UV_EBADF */
 
 
   /* sizeof(socklen_t) != sizeof(int) on some systems. */
   /* sizeof(socklen_t) != sizeof(int) on some systems. */
   socklen = (socklen_t) *namelen;
   socklen = (socklen_t) *namelen;
 
 
   if (getsockname(handle->io_watcher.fd, name, &socklen))
   if (getsockname(handle->io_watcher.fd, name, &socklen))
-    return -errno;
+    return UV__ERR(errno);
 
 
   *namelen = (int) socklen;
   *namelen = (int) socklen;
   return 0;
   return 0;
@@ -870,10 +870,10 @@ int uv__udp_recv_start(uv_udp_t* handle,
   int err;
   int err;
 
 
   if (alloc_cb == NULL || recv_cb == NULL)
   if (alloc_cb == NULL || recv_cb == NULL)
-    return -EINVAL;
+    return UV_EINVAL;
 
 
   if (uv__io_active(&handle->io_watcher, POLLIN))
   if (uv__io_active(&handle->io_watcher, POLLIN))
-    return -EALREADY;  /* FIXME(bnoordhuis) Should be -EBUSY. */
+    return UV_EALREADY;  /* FIXME(bnoordhuis) Should be UV_EBUSY. */
 
 
   err = uv__udp_maybe_deferred_bind(handle, AF_INET, 0);
   err = uv__udp_maybe_deferred_bind(handle, AF_INET, 0);
   if (err)
   if (err)

+ 1 - 1
src/uv-common.c

@@ -627,7 +627,7 @@ int uv_loop_close(uv_loop_t* loop) {
   void* saved_data;
   void* saved_data;
 #endif
 #endif
 
 
-  if (!QUEUE_EMPTY(&(loop)->active_reqs))
+  if (uv__has_active_reqs(loop))
     return UV_EBUSY;
     return UV_EBUSY;
 
 
   QUEUE_FOREACH(q, &loop->handle_queue) {
   QUEUE_FOREACH(q, &loop->handle_queue) {

+ 9 - 3
src/uv-common.h

@@ -41,6 +41,12 @@
 #include "tree.h"
 #include "tree.h"
 #include "queue.h"
 #include "queue.h"
 
 
+#if EDOM > 0
+# define UV__ERR(x) (-(x))
+#else
+# define UV__ERR(x) (x)
+#endif
+
 #if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900
 #if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900
 extern int snprintf(char*, size_t, const char*, ...);
 extern int snprintf(char*, size_t, const char*, ...);
 #endif
 #endif
@@ -127,18 +133,18 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
 void uv__fs_scandir_cleanup(uv_fs_t* req);
 void uv__fs_scandir_cleanup(uv_fs_t* req);
 
 
 #define uv__has_active_reqs(loop)                                             \
 #define uv__has_active_reqs(loop)                                             \
-  (QUEUE_EMPTY(&(loop)->active_reqs) == 0)
+  ((loop)->active_reqs.count > 0)
 
 
 #define uv__req_register(loop, req)                                           \
 #define uv__req_register(loop, req)                                           \
   do {                                                                        \
   do {                                                                        \
-    QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue);            \
+    (loop)->active_reqs.count++;                                              \
   }                                                                           \
   }                                                                           \
   while (0)
   while (0)
 
 
 #define uv__req_unregister(loop, req)                                         \
 #define uv__req_unregister(loop, req)                                         \
   do {                                                                        \
   do {                                                                        \
     assert(uv__has_active_reqs(loop));                                        \
     assert(uv__has_active_reqs(loop));                                        \
-    QUEUE_REMOVE(&(req)->active_queue);                                       \
+    (loop)->active_reqs.count--;                                              \
   }                                                                           \
   }                                                                           \
   while (0)
   while (0)
 
 

+ 3 - 3
src/win/core.c

@@ -239,7 +239,7 @@ int uv_loop_init(uv_loop_t* loop) {
 
 
   QUEUE_INIT(&loop->wq);
   QUEUE_INIT(&loop->wq);
   QUEUE_INIT(&loop->handle_queue);
   QUEUE_INIT(&loop->handle_queue);
-  QUEUE_INIT(&loop->active_reqs);
+  loop->active_reqs.count = 0;
   loop->active_handles = 0;
   loop->active_handles = 0;
 
 
   loop->pending_reqs_tail = NULL;
   loop->pending_reqs_tail = NULL;
@@ -470,8 +470,8 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
 
 
 
 
 static int uv__loop_alive(const uv_loop_t* loop) {
 static int uv__loop_alive(const uv_loop_t* loop) {
-  return loop->active_handles > 0 ||
-         !QUEUE_EMPTY(&loop->active_reqs) ||
+  return uv__has_active_handles(loop) ||
+         uv__has_active_reqs(loop) ||
          loop->endgame_handles != NULL;
          loop->endgame_handles != NULL;
 }
 }
 
 

+ 27 - 2
src/win/fs-event.c

@@ -69,6 +69,7 @@ static void uv_relative_path(const WCHAR* filename,
   size_t relpathlen;
   size_t relpathlen;
   size_t filenamelen = wcslen(filename);
   size_t filenamelen = wcslen(filename);
   size_t dirlen = wcslen(dir);
   size_t dirlen = wcslen(dir);
+  assert(!_wcsnicmp(filename, dir, dirlen));
   if (dirlen > 0 && dir[dirlen - 1] == '\\')
   if (dirlen > 0 && dir[dirlen - 1] == '\\')
     dirlen--;
     dirlen--;
   relpathlen = filenamelen - dirlen - 1;
   relpathlen = filenamelen - dirlen - 1;
@@ -151,11 +152,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
                       uv_fs_event_cb cb,
                       uv_fs_event_cb cb,
                       const char* path,
                       const char* path,
                       unsigned int flags) {
                       unsigned int flags) {
-  int name_size, is_path_dir;
+  int name_size, is_path_dir, size;
   DWORD attr, last_error;
   DWORD attr, last_error;
   WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
   WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
   WCHAR short_path_buffer[MAX_PATH];
   WCHAR short_path_buffer[MAX_PATH];
-  WCHAR* short_path;
+  WCHAR* short_path, *long_path;
 
 
   if (uv__is_active(handle))
   if (uv__is_active(handle))
     return UV_EINVAL;
     return UV_EINVAL;
@@ -197,6 +198,30 @@ int uv_fs_event_start(uv_fs_event_t* handle,
 
 
   if (is_path_dir) {
   if (is_path_dir) {
      /* path is a directory, so that's the directory that we will watch. */
      /* path is a directory, so that's the directory that we will watch. */
+
+    /* Convert to long path. */
+    size = GetLongPathNameW(pathw, NULL, 0);
+
+    if (size) {
+      long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
+      if (!long_path) {
+        uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+      }
+
+      size = GetLongPathNameW(pathw, long_path, size);
+      if (size) {
+        long_path[size] = '\0';
+      } else {
+        uv__free(long_path);
+        long_path = NULL;
+      }
+    }
+
+    if (long_path) {
+      uv__free(pathw);
+      pathw = long_path;
+    }
+
     dir_to_watch = pathw;
     dir_to_watch = pathw;
   } else {
   } else {
     /*
     /*

+ 13 - 2
src/win/fs.c

@@ -783,7 +783,9 @@ void fs__unlink(uv_fs_t* req) {
     /* Remove read-only attribute */
     /* Remove read-only attribute */
     FILE_BASIC_INFORMATION basic = { 0 };
     FILE_BASIC_INFORMATION basic = { 0 };
 
 
-    basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY);
+    basic.FileAttributes = info.dwFileAttributes
+                           & ~(FILE_ATTRIBUTE_READONLY)
+                           | FILE_ATTRIBUTE_ARCHIVE;
 
 
     status = pNtSetInformationFile(handle,
     status = pNtSetInformationFile(handle,
                                    &iosb,
                                    &iosb,
@@ -1390,6 +1392,12 @@ static void fs__copyfile(uv_fs_t* req) {
   int overwrite;
   int overwrite;
 
 
   flags = req->fs.info.file_flags;
   flags = req->fs.info.file_flags;
+
+  if (flags & UV_FS_COPYFILE_FICLONE_FORCE) {
+    SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
+    return;
+  }
+
   overwrite = flags & UV_FS_COPYFILE_EXCL;
   overwrite = flags & UV_FS_COPYFILE_EXCL;
 
 
   if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) {
   if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) {
@@ -2334,8 +2342,11 @@ int uv_fs_copyfile(uv_loop_t* loop,
 
 
   INIT(UV_FS_COPYFILE);
   INIT(UV_FS_COPYFILE);
 
 
-  if (flags & ~UV_FS_COPYFILE_EXCL)
+  if (flags & ~(UV_FS_COPYFILE_EXCL |
+                UV_FS_COPYFILE_FICLONE |
+                UV_FS_COPYFILE_FICLONE_FORCE)) {
     return UV_EINVAL;
     return UV_EINVAL;
+  }
 
 
   err = fs__capture_path(req, path, new_path, cb != NULL);
   err = fs__capture_path(req, path, new_path, cb != NULL);
 
 

+ 8 - 2
src/win/getaddrinfo.c

@@ -392,15 +392,21 @@ int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) {
   DWORD bufsize;
   DWORD bufsize;
   int r;
   int r;
 
 
+  uv__once_init();
+
   if (buffer == NULL || size == NULL || *size == 0)
   if (buffer == NULL || size == NULL || *size == 0)
     return UV_EINVAL;
     return UV_EINVAL;
 
 
-  r = ConvertInterfaceIndexToLuid(ifindex, &luid);
+  if (pConvertInterfaceIndexToLuid == NULL)
+    return UV_ENOSYS;
+  r = pConvertInterfaceIndexToLuid(ifindex, &luid);
 
 
   if (r != 0)
   if (r != 0)
     return uv_translate_sys_error(r);
     return uv_translate_sys_error(r);
 
 
-  r = ConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname));
+  if (pConvertInterfaceLuidToNameW == NULL)
+    return UV_ENOSYS;
+  r = pConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname));
 
 
   if (r != 0)
   if (r != 0)
     return uv_translate_sys_error(r);
     return uv_translate_sys_error(r);

+ 8 - 2
src/win/internal.h

@@ -221,10 +221,16 @@ void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
     uv_req_t* req);
     uv_req_t* req);
 void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
 void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
     uv_write_t* req);
     uv_write_t* req);
-/* TODO: remove me */
+/*
+ * uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working
+ * TODO: find a way to remove it
+ */
 void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
 void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
     uv_req_t* raw_req);
     uv_req_t* raw_req);
-/* TODO: remove me */
+/*
+ * uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working
+ * TODO: find a way to remove it
+ */
 void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
 void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
     uv_connect_t* req);
     uv_connect_t* req);
 
 

+ 8 - 0
src/win/pipe.c

@@ -735,6 +735,13 @@ void uv__pipe_unpause_read(uv_pipe_t* handle) {
 
 
 
 
 void uv__pipe_stop_read(uv_pipe_t* handle) {
 void uv__pipe_stop_read(uv_pipe_t* handle) {
+  if (pCancelIoEx &&
+      !(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) &&
+      !(handle->flags & UV_HANDLE_EMULATE_IOCP) &&
+      handle->flags & UV_HANDLE_READING &&
+      handle->read_req.type == UV_READ) {
+    pCancelIoEx(handle->handle, &handle->read_req.u.io.overlapped);
+  }
   handle->flags &= ~UV_HANDLE_READING;
   handle->flags &= ~UV_HANDLE_READING;
   uv__pipe_pause_read((uv_pipe_t*)handle);
   uv__pipe_pause_read((uv_pipe_t*)handle);
   uv__pipe_unpause_read((uv_pipe_t*)handle);
   uv__pipe_unpause_read((uv_pipe_t*)handle);
@@ -847,6 +854,7 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
     return;
     return;
   }
   }
 
 
+  /* Wait for completion via IOCP */
   handle->reqs_pending++;
   handle->reqs_pending++;
 }
 }
 
 

+ 8 - 3
src/win/process.c

@@ -1061,11 +1061,16 @@ int uv_spawn(uv_loop_t* loop,
   process_flags = CREATE_UNICODE_ENVIRONMENT;
   process_flags = CREATE_UNICODE_ENVIRONMENT;
 
 
   if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
   if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
+    /* Avoid creating console window if stdio is not inherited. */
+    for (i = 0; i < options->stdio_count; i++) {
+      if (options->stdio[i].flags & UV_INHERIT_FD)
+        break;
+      if (i == options->stdio_count - 1)
+        process_flags |= CREATE_NO_WINDOW;
+    }
+
     /* Use SW_HIDE to avoid any potential process window. */
     /* Use SW_HIDE to avoid any potential process window. */
     startup.wShowWindow = SW_HIDE;
     startup.wShowWindow = SW_HIDE;
-
-    /* Hide console windows. */
-    process_flags |= CREATE_NO_WINDOW;
   } else {
   } else {
     startup.wShowWindow = SW_SHOWDEFAULT;
     startup.wShowWindow = SW_SHOWDEFAULT;
   }
   }

+ 5 - 5
src/win/stream-inl.h

@@ -37,11 +37,6 @@ INLINE static void uv_stream_init(uv_loop_t* loop,
   handle->write_queue_size = 0;
   handle->write_queue_size = 0;
   handle->activecnt = 0;
   handle->activecnt = 0;
   handle->stream.conn.shutdown_req = NULL;
   handle->stream.conn.shutdown_req = NULL;
-}
-
-
-INLINE static void uv_connection_init(uv_stream_t* handle) {
-  handle->flags |= UV_HANDLE_CONNECTION;
   handle->stream.conn.write_reqs_pending = 0;
   handle->stream.conn.write_reqs_pending = 0;
 
 
   UV_REQ_INIT(&handle->read_req, UV_READ);
   UV_REQ_INIT(&handle->read_req, UV_READ);
@@ -51,4 +46,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) {
 }
 }
 
 
 
 
+INLINE static void uv_connection_init(uv_stream_t* handle) {
+  handle->flags |= UV_HANDLE_CONNECTION;
+}
+
+
 #endif /* UV_WIN_STREAM_INL_H_ */
 #endif /* UV_WIN_STREAM_INL_H_ */

+ 8 - 7
src/win/tcp.c

@@ -459,8 +459,6 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
           INFINITE, WT_EXECUTEINWAITTHREAD)) {
           INFINITE, WT_EXECUTEINWAITTHREAD)) {
       SET_REQ_ERROR(req, GetLastError());
       SET_REQ_ERROR(req, GetLastError());
       uv_insert_pending_req(loop, (uv_req_t*)req);
       uv_insert_pending_req(loop, (uv_req_t*)req);
-      handle->reqs_pending++;
-      return;
     }
     }
   } else {
   } else {
     /* Make this req pending reporting an error. */
     /* Make this req pending reporting an error. */
@@ -1173,11 +1171,14 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
 
 
   err = 0;
   err = 0;
   if (REQ_SUCCESS(req)) {
   if (REQ_SUCCESS(req)) {
-    if (setsockopt(handle->socket,
-                    SOL_SOCKET,
-                    SO_UPDATE_CONNECT_CONTEXT,
-                    NULL,
-                    0) == 0) {
+    if (handle->flags & UV__HANDLE_CLOSING) {
+      /* use UV_ECANCELED for consistency with Unix */
+      err = ERROR_OPERATION_ABORTED;
+    } else if (setsockopt(handle->socket,
+                          SOL_SOCKET,
+                          SO_UPDATE_CONNECT_CONTEXT,
+                          NULL,
+                          0) == 0) {
       uv_connection_init((uv_stream_t*)handle);
       uv_connection_init((uv_stream_t*)handle);
       handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
       handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
       loop->active_tcp_streams++;
       loop->active_tcp_streams++;

+ 8 - 2
src/win/tty.c

@@ -2235,14 +2235,20 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
 }
 }
 
 
 
 
-/* TODO: remove me */
+/*
+ * uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working
+ * TODO: find a way to remove it
+ */
 void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
 void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
     uv_req_t* raw_req) {
     uv_req_t* raw_req) {
   abort();
   abort();
 }
 }
 
 
 
 
-/* TODO: remove me */
+/*
+ * uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working
+ * TODO: find a way to remove it
+ */
 void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
 void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
     uv_connect_t* req) {
     uv_connect_t* req) {
   abort();
   abort();

+ 31 - 68
src/win/util.c

@@ -37,7 +37,7 @@
 #include <tlhelp32.h>
 #include <tlhelp32.h>
 #include <windows.h>
 #include <windows.h>
 #include <userenv.h>
 #include <userenv.h>
-
+#include <math.h>
 
 
 /*
 /*
  * Max title length; the only thing MSDN tells us about the maximum length
  * Max title length; the only thing MSDN tells us about the maximum length
@@ -587,8 +587,8 @@ int uv_uptime(double* uptime) {
         BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
         BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
                         counter_definition->CounterOffset;
                         counter_definition->CounterOffset;
         uint64_t value = *((uint64_t*) address);
         uint64_t value = *((uint64_t*) address);
-        *uptime = (double) (object_type->PerfTime.QuadPart - value) /
-                  (double) object_type->PerfFreq.QuadPart;
+        *uptime = floor((double) (object_type->PerfTime.QuadPart - value) /
+                        (double) object_type->PerfFreq.QuadPart);
         uv__free(malloced_buffer);
         uv__free(malloced_buffer);
         return 0;
         return 0;
       }
       }
@@ -615,7 +615,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
   SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
   SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
   DWORD sppi_size;
   DWORD sppi_size;
   SYSTEM_INFO system_info;
   SYSTEM_INFO system_info;
-  DWORD cpu_count, r, i;
+  DWORD cpu_count, i;
   NTSTATUS status;
   NTSTATUS status;
   ULONG result_size;
   ULONG result_size;
   int err;
   int err;
@@ -670,34 +670,33 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
 
 
     assert(len > 0 && len < ARRAY_SIZE(key_name));
     assert(len > 0 && len < ARRAY_SIZE(key_name));
 
 
-    r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                      key_name,
-                      0,
-                      KEY_QUERY_VALUE,
-                      &processor_key);
-    if (r != ERROR_SUCCESS) {
-      err = GetLastError();
+    err = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                        key_name,
+                        0,
+                        KEY_QUERY_VALUE,
+                        &processor_key);
+    if (err != ERROR_SUCCESS) {
       goto error;
       goto error;
     }
     }
 
 
-    if (RegQueryValueExW(processor_key,
-                         L"~MHz",
-                         NULL,
-                         NULL,
-                         (BYTE*) &cpu_speed,
-                         &cpu_speed_size) != ERROR_SUCCESS) {
-      err = GetLastError();
+    err = RegQueryValueExW(processor_key,
+                           L"~MHz",
+                           NULL,
+                           NULL,
+                           (BYTE*)&cpu_speed,
+                           &cpu_speed_size);
+    if (err != ERROR_SUCCESS) {
       RegCloseKey(processor_key);
       RegCloseKey(processor_key);
       goto error;
       goto error;
     }
     }
 
 
-    if (RegQueryValueExW(processor_key,
-                         L"ProcessorNameString",
-                         NULL,
-                         NULL,
-                         (BYTE*) &cpu_brand,
-                         &cpu_brand_size) != ERROR_SUCCESS) {
-      err = GetLastError();
+    err = RegQueryValueExW(processor_key,
+                           L"ProcessorNameString",
+                           NULL,
+                           NULL,
+                           (BYTE*)&cpu_brand,
+                           &cpu_brand_size);
+    if (err != ERROR_SUCCESS) {
       RegCloseKey(processor_key);
       RegCloseKey(processor_key);
       goto error;
       goto error;
     }
     }
@@ -1148,53 +1147,17 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
 
 
 int uv_os_homedir(char* buffer, size_t* size) {
 int uv_os_homedir(char* buffer, size_t* size) {
   uv_passwd_t pwd;
   uv_passwd_t pwd;
-  wchar_t path[MAX_PATH];
-  DWORD bufsize;
   size_t len;
   size_t len;
   int r;
   int r;
 
 
-  if (buffer == NULL || size == NULL || *size == 0)
-    return UV_EINVAL;
-
-  /* Check if the USERPROFILE environment variable is set first */
-  len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH);
+  /* Check if the USERPROFILE environment variable is set first. The task of
+     performing input validation on buffer and size is taken care of by
+     uv_os_getenv(). */
+  r = uv_os_getenv("USERPROFILE", buffer, size);
 
 
-  if (len == 0) {
-    r = GetLastError();
-
-    /* Don't return an error if USERPROFILE was not found */
-    if (r != ERROR_ENVVAR_NOT_FOUND)
-      return uv_translate_sys_error(r);
-  } else if (len > MAX_PATH) {
-    /* This should not be possible */
-    return UV_EIO;
-  } else {
-    /* Check how much space we need */
-    bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
-
-    if (bufsize == 0) {
-      return uv_translate_sys_error(GetLastError());
-    } else if (bufsize > *size) {
-      *size = bufsize;
-      return UV_ENOBUFS;
-    }
-
-    /* Convert to UTF-8 */
-    bufsize = WideCharToMultiByte(CP_UTF8,
-                                  0,
-                                  path,
-                                  -1,
-                                  buffer,
-                                  *size,
-                                  NULL,
-                                  NULL);
-
-    if (bufsize == 0)
-      return uv_translate_sys_error(GetLastError());
-
-    *size = bufsize - 1;
-    return 0;
-  }
+  /* Don't return an error if USERPROFILE was not found. */
+  if (r != UV_ENOENT)
+    return r;
 
 
   /* USERPROFILE is not set, so call uv__getpwuid_r() */
   /* USERPROFILE is not set, so call uv__getpwuid_r() */
   r = uv__getpwuid_r(&pwd);
   r = uv__getpwuid_r(&pwd);

+ 11 - 0
src/win/winapi.c

@@ -55,12 +55,16 @@ sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
 /* User32.dll function pointer */
 /* User32.dll function pointer */
 sSetWinEventHook pSetWinEventHook;
 sSetWinEventHook pSetWinEventHook;
 
 
+/* iphlpapi.dll function pointer */
+sConvertInterfaceIndexToLuid pConvertInterfaceIndexToLuid = NULL;
+sConvertInterfaceLuidToNameW pConvertInterfaceLuidToNameW = NULL;
 
 
 void uv_winapi_init(void) {
 void uv_winapi_init(void) {
   HMODULE ntdll_module;
   HMODULE ntdll_module;
   HMODULE kernel32_module;
   HMODULE kernel32_module;
   HMODULE powrprof_module;
   HMODULE powrprof_module;
   HMODULE user32_module;
   HMODULE user32_module;
+  HMODULE iphlpapi_module;
 
 
   ntdll_module = GetModuleHandleA("ntdll.dll");
   ntdll_module = GetModuleHandleA("ntdll.dll");
   if (ntdll_module == NULL) {
   if (ntdll_module == NULL) {
@@ -166,4 +170,11 @@ void uv_winapi_init(void) {
       GetProcAddress(user32_module, "SetWinEventHook");
       GetProcAddress(user32_module, "SetWinEventHook");
   }
   }
 
 
+  iphlpapi_module = LoadLibraryA("iphlpapi.dll");
+  if (iphlpapi_module != NULL) {
+    pConvertInterfaceIndexToLuid = (sConvertInterfaceIndexToLuid)
+      GetProcAddress(iphlpapi_module, "ConvertInterfaceIndexToLuid");
+    pConvertInterfaceLuidToNameW = (sConvertInterfaceLuidToNameW)
+      GetProcAddress(iphlpapi_module, "ConvertInterfaceLuidToNameW");
+  }
 }
 }

+ 15 - 0
src/win/winapi.h

@@ -4775,4 +4775,19 @@ extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotifi
 /* User32.dll function pointer */
 /* User32.dll function pointer */
 extern sSetWinEventHook pSetWinEventHook;
 extern sSetWinEventHook pSetWinEventHook;
 
 
+/* iphlpapi.dll function pointer */
+union _NET_LUID_LH;
+typedef DWORD (WINAPI *sConvertInterfaceIndexToLuid)(
+    ULONG InterfaceIndex,
+    union _NET_LUID_LH *InterfaceLuid);
+
+typedef DWORD (WINAPI *sConvertInterfaceLuidToNameW)(
+    const union _NET_LUID_LH *InterfaceLuid,
+    PWSTR InterfaceName,
+    size_t Length);
+
+extern sConvertInterfaceIndexToLuid pConvertInterfaceIndexToLuid;
+extern sConvertInterfaceLuidToNameW pConvertInterfaceLuidToNameW;
+
+
 #endif /* UV_WIN_WINAPI_H_ */
 #endif /* UV_WIN_WINAPI_H_ */

+ 4 - 2
src/win/winsock.c

@@ -580,8 +580,10 @@ int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr,
     memcpy(dest6, addr, sizeof(*dest6));
     memcpy(dest6, addr, sizeof(*dest6));
     if (memcmp(&dest6->sin6_addr,
     if (memcmp(&dest6->sin6_addr,
                &uv_addr_ip6_any_.sin6_addr,
                &uv_addr_ip6_any_.sin6_addr,
-               sizeof(uv_addr_ip6_any_.sin6_addr)) == 0)
-      dest6->sin6_addr = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
+               sizeof(uv_addr_ip6_any_.sin6_addr)) == 0) {
+      struct in6_addr init_sin6_addr = IN6ADDR_LOOPBACK_INIT;
+      dest6->sin6_addr = init_sin6_addr;
+    }
     return 0;
     return 0;
   default:
   default:
     return UV_EINVAL;
     return UV_EINVAL;