Skip to content

Commit aec2ce4

Browse files
committedApr 22, 2019
deps: upgrade to libuv 1.28.0
Notable changes: - uv_gettimeofday() has been added. - Streaming readdir() via the uv_fs_{open,read,close}dir() methods. - A macOS copyfile() permissions bug has been fixed. - A bug in uv_interface_addresses() on machines with multiple interfaces has been fixed. Fixes: #27273 PR-URL: #27241 Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent 2161690 commit aec2ce4

28 files changed

+1192
-133
lines changed
 

‎deps/uv/AUTHORS

+5
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,8 @@ yeyuanfeng <yeyuanfeng@bytedance.com>
371371
erw7 <erw7.github@gmail.com>
372372
Thomas Karl Pietrowski <thopiekar@gmail.com>
373373
evgley <evgley@gmail.com>
374+
Andreas Rohner <andreas.rohner@gmx.net>
375+
Rich Trott <rtrott@gmail.com>
376+
Milad Farazmand <miladfar@ca.ibm.com>
377+
zlargon <zlargon1988@gmail.com>
378+
Yury Selivanov <yury@magic.io>

‎deps/uv/CMakeLists.txt

+6-4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ set(uv_test_sources
5353
test/test-fs-event.c
5454
test/test-fs-poll.c
5555
test/test-fs.c
56+
test/test-fs-readdir.c
5657
test/test-get-currentexe.c
5758
test/test-get-loadavg.c
5859
test/test-get-memory.c
@@ -62,6 +63,7 @@ set(uv_test_sources
6263
test/test-getnameinfo.c
6364
test/test-getsockname.c
6465
test/test-getters-setters.c
66+
test/test-gettimeofday.c
6567
test/test-handle-fileno.c
6668
test/test-homedir.c
6769
test/test-hrtime.c
@@ -262,7 +264,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
262264
src/unix/sysinfo-memory.c)
263265
endif()
264266

265-
if(CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|Linux|OS/390")
267+
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS/390")
266268
list(APPEND uv_sources src/unix/proctitle.c)
267269
endif()
268270

@@ -275,11 +277,11 @@ if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD")
275277
list(APPEND uv_libraries kvm)
276278
endif()
277279

278-
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|DragonFly|FreeBSD|NetBSD|OpenBSD")
280+
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD")
279281
list(APPEND uv_sources src/unix/bsd-ifaddrs.c src/unix/kqueue.c)
280282
endif()
281283

282-
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
284+
if(APPLE)
283285
list(APPEND uv_defines _DARWIN_UNLIMITED_SELECT=1 _DARWIN_USE_64_BIT_INODE=1)
284286
list(APPEND uv_sources
285287
src/unix/darwin-proctitle.c
@@ -333,7 +335,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
333335
list(APPEND uv_sources src/unix/no-proctitle.c src/unix/sunos.c)
334336
endif()
335337

336-
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|DragonFly|FreeBSD|Linux|NetBSD|OpenBSD")
338+
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|Linux|NetBSD|OpenBSD")
337339
list(APPEND uv_test_libraries util)
338340
endif()
339341

‎deps/uv/ChangeLog

+35
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
1+
2019.04.16, Version 1.28.0 (Stable), 7bf8fabfa934660ee0fe889f78e151198a1165fc
2+
3+
Changes since version 1.27.0:
4+
5+
* unix,win: add uv_gettimeofday() (cjihrig)
6+
7+
* unix,win: add uv_fs_{open,read,close}dir() (cjihrig)
8+
9+
* unix: fix uv_interface_addresses() (Andreas Rohner)
10+
11+
* fs: remove macOS-specific copyfile(3) (Rich Trott)
12+
13+
* fs: add test for copyfile() respecting permissions (Rich Trott)
14+
15+
* build: partially revert 5234b1c43a (Ben Noordhuis)
16+
17+
* zos: fix setsockopt error when using AF_UNIX (Milad Farazmand)
18+
19+
* unix: suppress EINTR/EINPROGRESS in uv_fs_close() (Ben Noordhuis)
20+
21+
* build: use cmake APPLE variable to detect platform (zlargon)
22+
23+
* distcheck: remove duplicate test/ entry (Jameson Nash)
24+
25+
* unix: remove unused cmpxchgl() function (Ben Noordhuis)
26+
27+
* unix: support sockaddr_un in uv_udp_send() (Yury Selivanov)
28+
29+
* unix: guard use of PTHREAD_STACK_MIN (Kamil Rytarowski)
30+
31+
* unix,win: introduce uv_timeval64_t (cjihrig)
32+
33+
* doc: document uv_timeval_t and uv_timeval64_t (cjihrig)
34+
35+
136
2019.03.17, Version 1.27.0 (Stable), a4fc9a66cc35256dbc4dcd67c910174f05b6daa6
237

338
Changes since version 1.26.0:

‎deps/uv/Makefile.am

+2-9
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,10 @@ libuv_la_SOURCES = src/fs-poll.c \
4545
src/version.c
4646

4747
if SUNOS
48-
if GCC
4948
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
5049
# on other platforms complain that the argument is unused during compilation.
5150
libuv_la_CFLAGS += -pthreads
5251
endif
53-
endif
5452

5553
if WINNT
5654

@@ -120,7 +118,6 @@ endif # WINNT
120118
EXTRA_DIST = test/fixtures/empty_file \
121119
test/fixtures/load_error.node \
122120
include \
123-
test \
124121
docs \
125122
img \
126123
samples \
@@ -143,20 +140,14 @@ check_PROGRAMS = test/run-tests
143140
if OS390
144141
test_run_tests_CFLAGS =
145142
else
146-
if GCC
147143
test_run_tests_CFLAGS = -Wno-long-long
148-
else
149-
test_run_tests_CFLAGS =
150-
endif
151144
endif
152145

153146
if SUNOS
154-
if GCC
155147
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
156148
# on other platforms complain that the argument is unused during compilation.
157149
test_run_tests_CFLAGS += -pthreads
158150
endif
159-
endif
160151

161152
test_run_tests_LDFLAGS =
162153
test_run_tests_SOURCES = test/blackhole-server.c \
@@ -191,6 +182,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
191182
test/test-fs-event.c \
192183
test/test-fs-poll.c \
193184
test/test-fs.c \
185+
test/test-fs-readdir.c \
194186
test/test-fork.c \
195187
test/test-getters-setters.c \
196188
test/test-get-currentexe.c \
@@ -201,6 +193,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
201193
test/test-gethostname.c \
202194
test/test-getnameinfo.c \
203195
test/test-getsockname.c \
196+
test/test-gettimeofday.c \
204197
test/test-handle-fileno.c \
205198
test/test-homedir.c \
206199
test/test-hrtime.c \

‎deps/uv/configure.ac

+9-12
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

1515
AC_PREREQ(2.57)
16-
AC_INIT([libuv], [1.27.0], [https://github.com/libuv/libuv/issues])
16+
AC_INIT([libuv], [1.28.0], [https://github.com/libuv/libuv/issues])
1717
AC_CONFIG_MACRO_DIR([m4])
1818
m4_include([m4/libuv-extra-automake-flags.m4])
1919
m4_include([m4/as_case.m4])
@@ -24,18 +24,16 @@ AC_ENABLE_SHARED
2424
AC_ENABLE_STATIC
2525
AC_PROG_CC
2626
AM_PROG_CC_C_O
27+
AS_IF([AS_CASE([$host_os],[openedition*], [false], [true])], [
28+
CC_CHECK_CFLAGS_APPEND([-pedantic])
29+
])
2730
CC_FLAG_VISIBILITY #[-fvisibility=hidden]
2831
CC_CHECK_CFLAGS_APPEND([-g])
29-
AS_IF([test "x$GCC" = xyes], [
30-
AS_IF([AS_CASE([$host_os], [openedition*], [false], [true])], [
31-
CC_CHECK_CFLAGS_APPEND([-pedantic])
32-
])
33-
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
34-
CC_CHECK_CFLAGS_APPEND([-Wall])
35-
CC_CHECK_CFLAGS_APPEND([-Wextra])
36-
CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter])
37-
CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes])
38-
])
32+
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
33+
CC_CHECK_CFLAGS_APPEND([-Wall])
34+
CC_CHECK_CFLAGS_APPEND([-Wextra])
35+
CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter])
36+
CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes])
3937
# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12.
4038
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
4139
# autoconf complains if AC_PROG_LIBTOOL precedes AM_PROG_AR.
@@ -52,7 +50,6 @@ AC_CHECK_LIB([rt], [clock_gettime])
5250
AC_CHECK_LIB([sendfile], [sendfile])
5351
AC_CHECK_LIB([socket], [socket])
5452
AC_SYS_LARGEFILE
55-
AM_CONDITIONAL([GCC], [AS_IF([test "x$GCC" = xyes], [true], [false])])
5653
AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])])
5754
AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])])
5855
AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])])

‎deps/uv/docs/src/fs.rst

+58
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,21 @@ Data types
122122
uv_dirent_type_t type;
123123
} uv_dirent_t;
124124

125+
.. c:type:: uv_dir_t
126+
127+
Data type used for streaming directory iteration.
128+
Used by :c:func:`uv_fs_opendir()`, :c:func:`uv_fs_readdir()`, and
129+
:c:func:`uv_fs_closedir()`. `dirents` represents a user provided array of
130+
`uv_dirent_t`s used to hold results. `nentries` is the user provided maximum
131+
array size of `dirents`.
132+
133+
::
134+
135+
typedef struct uv_dir_s {
136+
uv_dirent_t* dirents;
137+
size_t nentries;
138+
} uv_dir_t;
139+
125140

126141
Public members
127142
^^^^^^^^^^^^^^
@@ -208,6 +223,49 @@ API
208223
209224
Equivalent to :man:`rmdir(2)`.
210225
226+
.. c:function:: int uv_fs_opendir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
227+
228+
Opens `path` as a directory stream. On success, a `uv_dir_t` is allocated
229+
and returned via `req->ptr`. This memory is not freed by
230+
`uv_fs_req_cleanup()`, although `req->ptr` is set to `NULL`. The allocated
231+
memory must be freed by calling `uv_fs_closedir()`. On failure, no memory
232+
is allocated.
233+
234+
The contents of the directory can be iterated over by passing the resulting
235+
`uv_dir_t` to `uv_fs_readdir()`.
236+
237+
.. versionadded:: 1.28.0
238+
239+
.. c:function:: int uv_fs_closedir(uv_loop_t* loop, uv_fs_t* req, uv_dir_t* dir, uv_fs_cb cb)
240+
241+
Closes the directory stream represented by `dir` and frees the memory
242+
allocated by `uv_fs_opendir()`.
243+
244+
.. versionadded:: 1.28.0
245+
246+
.. c:function:: int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, uv_dir_t* dir, uv_fs_cb cb)
247+
248+
Iterates over the directory stream, `dir`, returned by a successful
249+
`uv_fs_opendir()` call. Prior to invoking `uv_fs_readdir()`, the caller
250+
must set `dir->dirents` and `dir->nentries`, representing the array of
251+
:c:type:`uv_dirent_t` elements used to hold the read directory entries and
252+
its size.
253+
254+
On success, the result is an integer >= 0 representing the number of entries
255+
read from the stream.
256+
257+
.. versionadded:: 1.28.0
258+
259+
.. warning::
260+
`uv_fs_readdir()` is not thread safe.
261+
262+
.. note::
263+
This function does not return the "." and ".." entries.
264+
265+
.. note::
266+
On success this function allocates memory that must be freed using
267+
`uv_fs_req_cleanup()`.
268+
211269
.. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
212270
.. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent)
213271

‎deps/uv/docs/src/misc.rst

+29
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,28 @@ Data types
6565

6666
.. versionadded:: 1.16.0
6767

68+
.. c:type:: uv_timeval_t
69+
70+
Data type for storing times.
71+
72+
::
73+
74+
typedef struct {
75+
long tv_sec;
76+
long tv_usec;
77+
} uv_timeval_t;
78+
79+
.. c:type:: uv_timeval64_t
80+
81+
Alternative data type for storing times.
82+
83+
::
84+
85+
typedef struct {
86+
int64_t tv_sec;
87+
int32_t tv_usec;
88+
} uv_timeval64_t;
89+
6890
.. c:type:: uv_rusage_t
6991
7092
Data type for resource usage results.
@@ -578,3 +600,10 @@ API
578600
zero on success, and a non-zero error value otherwise.
579601
580602
.. versionadded:: 1.25.0
603+
604+
.. c:function:: int uv_gettimeofday(uv_timeval64_t* tv)
605+
606+
Cross-platform implementation of :man:`gettimeofday(2)`. The timezone
607+
argument to `gettimeofday()` is not supported, as it is considered obsolete.
608+
609+
.. versionadded:: 1.28.0

‎deps/uv/include/uv.h

+31-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ typedef enum {
202202
/* Handle types. */
203203
typedef struct uv_loop_s uv_loop_t;
204204
typedef struct uv_handle_s uv_handle_t;
205+
typedef struct uv_dir_s uv_dir_t;
205206
typedef struct uv_stream_s uv_stream_t;
206207
typedef struct uv_tcp_s uv_tcp_t;
207208
typedef struct uv_udp_s uv_udp_t;
@@ -1098,6 +1099,11 @@ typedef struct {
10981099
long tv_usec;
10991100
} uv_timeval_t;
11001101

1102+
typedef struct {
1103+
int64_t tv_sec;
1104+
int32_t tv_usec;
1105+
} uv_timeval64_t;
1106+
11011107
typedef struct {
11021108
uv_timeval_t ru_utime; /* user CPU time used */
11031109
uv_timeval_t ru_stime; /* system CPU time used */
@@ -1196,9 +1202,19 @@ typedef enum {
11961202
UV_FS_FCHOWN,
11971203
UV_FS_REALPATH,
11981204
UV_FS_COPYFILE,
1199-
UV_FS_LCHOWN
1205+
UV_FS_LCHOWN,
1206+
UV_FS_OPENDIR,
1207+
UV_FS_READDIR,
1208+
UV_FS_CLOSEDIR
12001209
} uv_fs_type;
12011210

1211+
struct uv_dir_s {
1212+
uv_dirent_t* dirents;
1213+
size_t nentries;
1214+
void* reserved[4];
1215+
UV_DIR_PRIVATE_FIELDS
1216+
};
1217+
12021218
/* uv_fs_t is a subclass of uv_req_t. */
12031219
struct uv_fs_s {
12041220
UV_REQ_FIELDS
@@ -1291,6 +1307,18 @@ UV_EXTERN int uv_fs_scandir(uv_loop_t* loop,
12911307
uv_fs_cb cb);
12921308
UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req,
12931309
uv_dirent_t* ent);
1310+
UV_EXTERN int uv_fs_opendir(uv_loop_t* loop,
1311+
uv_fs_t* req,
1312+
const char* path,
1313+
uv_fs_cb cb);
1314+
UV_EXTERN int uv_fs_readdir(uv_loop_t* loop,
1315+
uv_fs_t* req,
1316+
uv_dir_t* dir,
1317+
uv_fs_cb cb);
1318+
UV_EXTERN int uv_fs_closedir(uv_loop_t* loop,
1319+
uv_fs_t* req,
1320+
uv_dir_t* dir,
1321+
uv_fs_cb cb);
12941322
UV_EXTERN int uv_fs_stat(uv_loop_t* loop,
12951323
uv_fs_t* req,
12961324
const char* path,
@@ -1586,6 +1614,8 @@ UV_EXTERN void uv_key_delete(uv_key_t* key);
15861614
UV_EXTERN void* uv_key_get(uv_key_t* key);
15871615
UV_EXTERN void uv_key_set(uv_key_t* key, void* value);
15881616

1617+
UV_EXTERN int uv_gettimeofday(uv_timeval64_t* tv);
1618+
15891619
typedef void (*uv_thread_cb)(void* arg);
15901620

15911621
UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);

‎deps/uv/include/uv/unix.h

+3
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ typedef uid_t uv_uid_t;
166166

167167
typedef struct dirent uv__dirent_t;
168168

169+
#define UV_DIR_PRIVATE_FIELDS \
170+
DIR* dir;
171+
169172
#if defined(DT_UNKNOWN)
170173
# define HAVE_DIRENT_TYPES
171174
# if defined(DT_REG)

‎deps/uv/include/uv/version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
*/
3232

3333
#define UV_VERSION_MAJOR 1
34-
#define UV_VERSION_MINOR 27
34+
#define UV_VERSION_MINOR 28
3535
#define UV_VERSION_PATCH 0
3636
#define UV_VERSION_IS_RELEASE 1
3737
#define UV_VERSION_SUFFIX ""

‎deps/uv/include/uv/win.h

+5
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ typedef struct uv__dirent_s {
301301
char d_name[1];
302302
} uv__dirent_t;
303303

304+
#define UV_DIR_PRIVATE_FIELDS \
305+
HANDLE dir_handle; \
306+
WIN32_FIND_DATAW find_data; \
307+
BOOL need_find_call;
308+
304309
#define HAVE_DIRENT_TYPES
305310
#define UV__DT_DIR UV_DIRENT_DIR
306311
#define UV__DT_FILE UV_DIRENT_FILE

‎deps/uv/src/unix/atomic-ops.h

-37
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#endif
2424

2525
UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval));
26-
UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval));
2726
UV_UNUSED(static void cpu_relax(void));
2827

2928
/* Prefer hand-rolled assembly over the gcc builtins because the latter also
@@ -55,42 +54,6 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
5554
#endif
5655
}
5756

58-
UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
59-
#if defined(__i386__) || defined(__x86_64__)
60-
long out;
61-
__asm__ __volatile__ ("lock; cmpxchg %2, %1;"
62-
: "=a" (out), "+m" (*(volatile long*) ptr)
63-
: "r" (newval), "0" (oldval)
64-
: "memory");
65-
return out;
66-
#elif defined(_AIX) && defined(__xlC__)
67-
const long out = (*(volatile int*) ptr);
68-
# if defined(__64BIT__)
69-
__compare_and_swaplp(ptr, &oldval, newval);
70-
# else
71-
__compare_and_swap(ptr, &oldval, newval);
72-
# endif /* if defined(__64BIT__) */
73-
return out;
74-
#elif defined (__MVS__)
75-
#ifdef _LP64
76-
unsigned long long op4;
77-
if (__plo_CSSTGR(ptr, (unsigned long long*) &oldval, newval,
78-
(unsigned long long*) ptr, *ptr, &op4))
79-
#else
80-
unsigned long op4;
81-
if (__plo_CSST(ptr, (unsigned int*) &oldval, newval,
82-
(unsigned int*) ptr, *ptr, &op4))
83-
#endif
84-
return oldval;
85-
else
86-
return op4;
87-
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
88-
return atomic_cas_ulong((ulong_t *)ptr, (ulong_t)oldval, (ulong_t)newval);
89-
#else
90-
return __sync_val_compare_and_swap(ptr, oldval, newval);
91-
#endif
92-
}
93-
9457
UV_UNUSED(static void cpu_relax(void)) {
9558
#if defined(__i386__) || defined(__x86_64__)
9659
__asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */

‎deps/uv/src/unix/bsd-ifaddrs.c

+4-7
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
8484
return 0;
8585
}
8686

87-
*addresses = uv__malloc(*count * sizeof(**addresses));
87+
/* Make sure the memory is initiallized to zero using calloc() */
88+
*addresses = uv__calloc(*count, sizeof(**addresses));
8889

8990
if (*addresses == NULL) {
9091
freeifaddrs(addrs);
@@ -116,6 +117,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
116117
address++;
117118
}
118119

120+
#if !(defined(__CYGWIN__) || defined(__MSYS__))
119121
/* Fill in physical addresses for each interface */
120122
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
121123
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
@@ -124,20 +126,15 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
124126
address = *addresses;
125127

126128
for (i = 0; i < *count; i++) {
127-
#if defined(__CYGWIN__) || defined(__MSYS__)
128-
memset(address->phys_addr, 0, sizeof(address->phys_addr));
129-
#else
130129
if (strcmp(address->name, ent->ifa_name) == 0) {
131130
struct sockaddr_dl* sa_addr;
132131
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
133132
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
134-
} else {
135-
memset(address->phys_addr, 0, sizeof(address->phys_addr));
136133
}
137-
#endif
138134
address++;
139135
}
140136
}
137+
#endif
141138

142139
freeifaddrs(addrs);
143140

‎deps/uv/src/unix/core.c

+15
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <sys/resource.h> /* getrusage */
4242
#include <pwd.h>
4343
#include <sys/utsname.h>
44+
#include <sys/time.h>
4445

4546
#ifdef __sun
4647
# include <sys/filio.h>
@@ -1429,3 +1430,17 @@ int uv__getsockpeername(const uv_handle_t* handle,
14291430
*namelen = (int) socklen;
14301431
return 0;
14311432
}
1433+
1434+
int uv_gettimeofday(uv_timeval64_t* tv) {
1435+
struct timeval time;
1436+
1437+
if (tv == NULL)
1438+
return UV_EINVAL;
1439+
1440+
if (gettimeofday(&time, NULL) != 0)
1441+
return UV__ERR(errno);
1442+
1443+
tv->tv_sec = (int64_t) time.tv_sec;
1444+
tv->tv_usec = (int32_t) time.tv_usec;
1445+
return 0;
1446+
}

‎deps/uv/src/unix/fs.c

+136-44
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
#endif
6161

6262
#if defined(__APPLE__)
63-
# include <copyfile.h>
6463
# include <sys/sysctl.h>
6564
#elif defined(__linux__) && !defined(FICLONE)
6665
# include <sys/ioctl.h>
@@ -143,6 +142,18 @@ extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
143142
while (0)
144143

145144

145+
static int uv__fs_close(int fd) {
146+
int rc;
147+
148+
rc = close(fd);
149+
if (rc == -1)
150+
if (errno == EINTR || errno == EINPROGRESS)
151+
rc = 0; /* The close is in progress, not an error. */
152+
153+
return rc;
154+
}
155+
156+
146157
static ssize_t uv__fs_fsync(uv_fs_t* req) {
147158
#if defined(__APPLE__)
148159
/* Apple's fdatasync and fsync explicitly do NOT flush the drive write cache
@@ -351,7 +362,7 @@ static int uv__fs_scandir_sort(UV_CONST_DIRENT** a, UV_CONST_DIRENT** b) {
351362

352363

353364
static ssize_t uv__fs_scandir(uv_fs_t* req) {
354-
uv__dirent_t **dents;
365+
uv__dirent_t** dents;
355366
int n;
356367

357368
dents = NULL;
@@ -375,6 +386,87 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) {
375386
return n;
376387
}
377388

389+
static int uv__fs_opendir(uv_fs_t* req) {
390+
uv_dir_t* dir;
391+
392+
dir = uv__malloc(sizeof(*dir));
393+
if (dir == NULL)
394+
goto error;
395+
396+
dir->dir = opendir(req->path);
397+
if (dir->dir == NULL)
398+
goto error;
399+
400+
req->ptr = dir;
401+
return 0;
402+
403+
error:
404+
uv__free(dir);
405+
req->ptr = NULL;
406+
return -1;
407+
}
408+
409+
static int uv__fs_readdir(uv_fs_t* req) {
410+
uv_dir_t* dir;
411+
uv_dirent_t* dirent;
412+
struct dirent* res;
413+
unsigned int dirent_idx;
414+
unsigned int i;
415+
416+
dir = req->ptr;
417+
dirent_idx = 0;
418+
419+
while (dirent_idx < dir->nentries) {
420+
/* readdir() returns NULL on end of directory, as well as on error. errno
421+
is used to differentiate between the two conditions. */
422+
errno = 0;
423+
res = readdir(dir->dir);
424+
425+
if (res == NULL) {
426+
if (errno != 0)
427+
goto error;
428+
break;
429+
}
430+
431+
if (strcmp(res->d_name, ".") == 0 || strcmp(res->d_name, "..") == 0)
432+
continue;
433+
434+
dirent = &dir->dirents[dirent_idx];
435+
dirent->name = uv__strdup(res->d_name);
436+
437+
if (dirent->name == NULL)
438+
goto error;
439+
440+
dirent->type = uv__fs_get_dirent_type(res);
441+
++dirent_idx;
442+
}
443+
444+
return dirent_idx;
445+
446+
error:
447+
for (i = 0; i < dirent_idx; ++i) {
448+
uv__free((char*) dir->dirents[i].name);
449+
dir->dirents[i].name = NULL;
450+
}
451+
452+
return -1;
453+
}
454+
455+
static int uv__fs_closedir(uv_fs_t* req) {
456+
uv_dir_t* dir;
457+
458+
dir = req->ptr;
459+
460+
if (dir->dir != NULL) {
461+
closedir(dir->dir);
462+
dir->dir = NULL;
463+
}
464+
465+
uv__free(req->ptr);
466+
req->ptr = NULL;
467+
return 0;
468+
}
469+
378470
#if defined(_POSIX_PATH_MAX)
379471
# define UV__FS_PATH_MAX _POSIX_PATH_MAX
380472
#elif defined(PATH_MAX)
@@ -808,45 +900,6 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
808900
}
809901

810902
static ssize_t uv__fs_copyfile(uv_fs_t* req) {
811-
#if defined(__APPLE__) && !TARGET_OS_IPHONE
812-
/* On macOS, use the native copyfile(3). */
813-
static int can_clone;
814-
copyfile_flags_t flags;
815-
char buf[64];
816-
size_t len;
817-
int major;
818-
819-
flags = COPYFILE_ALL;
820-
821-
if (req->flags & UV_FS_COPYFILE_EXCL)
822-
flags |= COPYFILE_EXCL;
823-
824-
/* Check OS version. Cloning is only supported on macOS >= 10.12. */
825-
if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
826-
if (can_clone == 0) {
827-
len = sizeof(buf);
828-
if (sysctlbyname("kern.osrelease", buf, &len, NULL, 0))
829-
return UV__ERR(errno);
830-
831-
if (1 != sscanf(buf, "%d", &major))
832-
abort();
833-
834-
can_clone = -1 + 2 * (major >= 16); /* macOS >= 10.12 */
835-
}
836-
837-
if (can_clone < 0)
838-
return UV_ENOSYS;
839-
}
840-
841-
/* copyfile() simply ignores COPYFILE_CLONE if it's not supported. */
842-
if (req->flags & UV_FS_COPYFILE_FICLONE)
843-
flags |= 1 << 24; /* COPYFILE_CLONE */
844-
845-
if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE)
846-
flags |= 1 << 25; /* COPYFILE_CLONE_FORCE */
847-
848-
return copyfile(req->path, req->new_path, NULL, flags);
849-
#else
850903
uv_fs_t fs_req;
851904
uv_file srcfd;
852905
uv_file dstfd;
@@ -973,7 +1026,6 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
9731026

9741027
errno = UV__ERR(result);
9751028
return -1;
976-
#endif
9771029
}
9781030

9791031
static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
@@ -1249,7 +1301,7 @@ static void uv__fs_work(struct uv__work* w) {
12491301
X(ACCESS, access(req->path, req->flags));
12501302
X(CHMOD, chmod(req->path, req->mode));
12511303
X(CHOWN, chown(req->path, req->uid, req->gid));
1252-
X(CLOSE, close(req->file));
1304+
X(CLOSE, uv__fs_close(req->file));
12531305
X(COPYFILE, uv__fs_copyfile(req));
12541306
X(FCHMOD, fchmod(req->file, req->mode));
12551307
X(FCHOWN, fchown(req->file, req->uid, req->gid));
@@ -1266,6 +1318,9 @@ static void uv__fs_work(struct uv__work* w) {
12661318
X(OPEN, uv__fs_open(req));
12671319
X(READ, uv__fs_read(req));
12681320
X(SCANDIR, uv__fs_scandir(req));
1321+
X(OPENDIR, uv__fs_opendir(req));
1322+
X(READDIR, uv__fs_readdir(req));
1323+
X(CLOSEDIR, uv__fs_closedir(req));
12691324
X(READLINK, uv__fs_readlink(req));
12701325
X(REALPATH, uv__fs_realpath(req));
12711326
X(RENAME, rename(req->path, req->new_path));
@@ -1536,6 +1591,40 @@ int uv_fs_scandir(uv_loop_t* loop,
15361591
POST;
15371592
}
15381593

1594+
int uv_fs_opendir(uv_loop_t* loop,
1595+
uv_fs_t* req,
1596+
const char* path,
1597+
uv_fs_cb cb) {
1598+
INIT(OPENDIR);
1599+
PATH;
1600+
POST;
1601+
}
1602+
1603+
int uv_fs_readdir(uv_loop_t* loop,
1604+
uv_fs_t* req,
1605+
uv_dir_t* dir,
1606+
uv_fs_cb cb) {
1607+
INIT(READDIR);
1608+
1609+
if (dir == NULL || dir->dir == NULL || dir->dirents == NULL)
1610+
return UV_EINVAL;
1611+
1612+
req->ptr = dir;
1613+
POST;
1614+
}
1615+
1616+
int uv_fs_closedir(uv_loop_t* loop,
1617+
uv_fs_t* req,
1618+
uv_dir_t* dir,
1619+
uv_fs_cb cb) {
1620+
INIT(CLOSEDIR);
1621+
1622+
if (dir == NULL)
1623+
return UV_EINVAL;
1624+
1625+
req->ptr = dir;
1626+
POST;
1627+
}
15391628

15401629
int uv_fs_readlink(uv_loop_t* loop,
15411630
uv_fs_t* req,
@@ -1676,14 +1765,17 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
16761765
req->path = NULL;
16771766
req->new_path = NULL;
16781767

1768+
if (req->fs_type == UV_FS_READDIR && req->ptr != NULL)
1769+
uv__fs_readdir_cleanup(req);
1770+
16791771
if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
16801772
uv__fs_scandir_cleanup(req);
16811773

16821774
if (req->bufs != req->bufsml)
16831775
uv__free(req->bufs);
16841776
req->bufs = NULL;
16851777

1686-
if (req->ptr != &req->statbuf)
1778+
if (req->fs_type != UV_FS_OPENDIR && req->ptr != &req->statbuf)
16871779
uv__free(req->ptr);
16881780
req->ptr = NULL;
16891781
}

‎deps/uv/src/unix/linux-core.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
860860
return 0;
861861
}
862862

863-
*addresses = uv__malloc(*count * sizeof(**addresses));
863+
/* Make sure the memory is initiallized to zero using calloc() */
864+
*addresses = uv__calloc(*count, sizeof(**addresses));
864865
if (!(*addresses)) {
865866
freeifaddrs(addrs);
866867
return UV_ENOMEM;
@@ -902,8 +903,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
902903
if (strcmp(address->name, ent->ifa_name) == 0) {
903904
sll = (struct sockaddr_ll*)ent->ifa_addr;
904905
memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
905-
} else {
906-
memset(address->phys_addr, 0, sizeof(address->phys_addr));
907906
}
908907
address++;
909908
}

‎deps/uv/src/unix/thread.c

+2
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,10 @@ int uv_thread_create_ex(uv_thread_t* tid,
219219
pagesize = (size_t)getpagesize();
220220
/* Round up to the nearest page boundary. */
221221
stack_size = (stack_size + pagesize - 1) &~ (pagesize - 1);
222+
#ifdef PTHREAD_STACK_MIN
222223
if (stack_size < PTHREAD_STACK_MIN)
223224
stack_size = PTHREAD_STACK_MIN;
225+
#endif
224226
}
225227

226228
if (stack_size > 0) {

‎deps/uv/src/unix/udp.c

+28-5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#if defined(__MVS__)
3131
#include <xti.h>
3232
#endif
33+
#include <sys/un.h>
3334

3435
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
3536
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
@@ -232,8 +233,16 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
232233
h.msg_namelen = 0;
233234
} else {
234235
h.msg_name = &req->addr;
235-
h.msg_namelen = req->addr.ss_family == AF_INET6 ?
236-
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
236+
if (req->addr.ss_family == AF_INET6)
237+
h.msg_namelen = sizeof(struct sockaddr_in6);
238+
else if (req->addr.ss_family == AF_INET)
239+
h.msg_namelen = sizeof(struct sockaddr_in);
240+
else if (req->addr.ss_family == AF_UNIX)
241+
h.msg_namelen = sizeof(struct sockaddr_un);
242+
else {
243+
assert(0 && "unsupported address family");
244+
abort();
245+
}
237246
}
238247
h.msg_iov = (struct iovec*) req->bufs;
239248
h.msg_iovlen = req->nbufs;
@@ -268,16 +277,30 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
268277
* are different from the BSDs: it _shares_ the port rather than steal it
269278
* from the current listener. While useful, it's not something we can emulate
270279
* on other platforms so we don't enable it.
280+
*
281+
* zOS does not support getsockname with SO_REUSEPORT option when using
282+
* AF_UNIX.
271283
*/
272284
static int uv__set_reuse(int fd) {
273285
int yes;
274-
275-
#if defined(SO_REUSEPORT) && !defined(__linux__)
276286
yes = 1;
287+
288+
#if defined(SO_REUSEPORT) && defined(__MVS__)
289+
struct sockaddr_in sockfd;
290+
unsigned int sockfd_len = sizeof(sockfd);
291+
if (getsockname(fd, (struct sockaddr*) &sockfd, &sockfd_len) == -1)
292+
return UV__ERR(errno);
293+
if (sockfd.sin_family == AF_UNIX) {
294+
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
295+
return UV__ERR(errno);
296+
} else {
297+
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
298+
return UV__ERR(errno);
299+
}
300+
#elif defined(SO_REUSEPORT) && !defined(__linux__)
277301
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
278302
return UV__ERR(errno);
279303
#else
280-
yes = 1;
281304
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
282305
return UV__ERR(errno);
283306
#endif

‎deps/uv/src/uv-common.c

+44-10
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
# include <malloc.h> /* malloc */
3535
#else
3636
# include <net/if.h> /* if_nametoindex */
37+
# include <sys/un.h> /* AF_UNIX, sockaddr_un */
3738
#endif
3839

3940

@@ -376,6 +377,10 @@ int uv__udp_check_before_send(uv_udp_t* handle, const struct sockaddr* addr) {
376377
addrlen = sizeof(struct sockaddr_in);
377378
else if (addr->sa_family == AF_INET6)
378379
addrlen = sizeof(struct sockaddr_in6);
380+
#if defined(AF_UNIX) && !defined(_WIN32)
381+
else if (addr->sa_family == AF_UNIX)
382+
addrlen = sizeof(struct sockaddr_un);
383+
#endif
379384
else
380385
return UV_EINVAL;
381386
} else {
@@ -631,37 +636,66 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
631636
dent = dents[(*nbufs)++];
632637

633638
ent->name = dent->d_name;
639+
ent->type = uv__fs_get_dirent_type(dent);
640+
641+
return 0;
642+
}
643+
644+
uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent) {
645+
uv_dirent_type_t type;
646+
634647
#ifdef HAVE_DIRENT_TYPES
635648
switch (dent->d_type) {
636649
case UV__DT_DIR:
637-
ent->type = UV_DIRENT_DIR;
650+
type = UV_DIRENT_DIR;
638651
break;
639652
case UV__DT_FILE:
640-
ent->type = UV_DIRENT_FILE;
653+
type = UV_DIRENT_FILE;
641654
break;
642655
case UV__DT_LINK:
643-
ent->type = UV_DIRENT_LINK;
656+
type = UV_DIRENT_LINK;
644657
break;
645658
case UV__DT_FIFO:
646-
ent->type = UV_DIRENT_FIFO;
659+
type = UV_DIRENT_FIFO;
647660
break;
648661
case UV__DT_SOCKET:
649-
ent->type = UV_DIRENT_SOCKET;
662+
type = UV_DIRENT_SOCKET;
650663
break;
651664
case UV__DT_CHAR:
652-
ent->type = UV_DIRENT_CHAR;
665+
type = UV_DIRENT_CHAR;
653666
break;
654667
case UV__DT_BLOCK:
655-
ent->type = UV_DIRENT_BLOCK;
668+
type = UV_DIRENT_BLOCK;
656669
break;
657670
default:
658-
ent->type = UV_DIRENT_UNKNOWN;
671+
type = UV_DIRENT_UNKNOWN;
659672
}
660673
#else
661-
ent->type = UV_DIRENT_UNKNOWN;
674+
type = UV_DIRENT_UNKNOWN;
662675
#endif
663676

664-
return 0;
677+
return type;
678+
}
679+
680+
void uv__fs_readdir_cleanup(uv_fs_t* req) {
681+
uv_dir_t* dir;
682+
uv_dirent_t* dirents;
683+
int i;
684+
685+
if (req->ptr == NULL)
686+
return;
687+
688+
dir = req->ptr;
689+
dirents = dir->dirents;
690+
req->ptr = NULL;
691+
692+
if (dirents == NULL)
693+
return;
694+
695+
for (i = 0; i < req->result; ++i) {
696+
uv__free((char*) dirents[i].name);
697+
dirents[i].name = NULL;
698+
}
665699
}
666700

667701

‎deps/uv/src/uv-common.h

+2
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);
193193
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
194194

195195
void uv__fs_scandir_cleanup(uv_fs_t* req);
196+
void uv__fs_readdir_cleanup(uv_fs_t* req);
197+
uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent);
196198

197199
int uv__next_timeout(const uv_loop_t* loop);
198200
void uv__run_timers(uv_loop_t* loop);

‎deps/uv/src/win/fs.c

+175
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,137 @@ void fs__scandir(uv_fs_t* req) {
11251125
uv__free(dirents);
11261126
}
11271127

1128+
void fs__opendir(uv_fs_t* req) {
1129+
WCHAR* pathw;
1130+
size_t len;
1131+
const WCHAR* fmt;
1132+
WCHAR* find_path;
1133+
uv_dir_t* dir;
1134+
1135+
pathw = req->file.pathw;
1136+
dir = NULL;
1137+
find_path = NULL;
1138+
1139+
/* Figure out whether path is a file or a directory. */
1140+
if (!(GetFileAttributesW(pathw) & FILE_ATTRIBUTE_DIRECTORY)) {
1141+
SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY);
1142+
goto error;
1143+
}
1144+
1145+
dir = uv__malloc(sizeof(*dir));
1146+
if (dir == NULL) {
1147+
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
1148+
goto error;
1149+
}
1150+
1151+
len = wcslen(pathw);
1152+
1153+
if (len == 0)
1154+
fmt = L"./*";
1155+
else if (IS_SLASH(pathw[len - 1]))
1156+
fmt = L"%s*";
1157+
else
1158+
fmt = L"%s\\*";
1159+
1160+
find_path = uv__malloc(sizeof(WCHAR) * (len + 4));
1161+
if (find_path == NULL) {
1162+
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
1163+
goto error;
1164+
}
1165+
1166+
_snwprintf(find_path, len + 3, fmt, pathw);
1167+
dir->dir_handle = FindFirstFileW(find_path, &dir->find_data);
1168+
uv__free(find_path);
1169+
find_path = NULL;
1170+
if (dir->dir_handle == INVALID_HANDLE_VALUE &&
1171+
GetLastError() != ERROR_FILE_NOT_FOUND) {
1172+
SET_REQ_WIN32_ERROR(req, GetLastError());
1173+
goto error;
1174+
}
1175+
1176+
dir->need_find_call = FALSE;
1177+
req->ptr = dir;
1178+
SET_REQ_RESULT(req, 0);
1179+
return;
1180+
1181+
error:
1182+
uv__free(dir);
1183+
uv__free(find_path);
1184+
req->ptr = NULL;
1185+
}
1186+
1187+
void fs__readdir(uv_fs_t* req) {
1188+
uv_dir_t* dir;
1189+
uv_dirent_t* dirents;
1190+
uv__dirent_t dent;
1191+
unsigned int dirent_idx;
1192+
PWIN32_FIND_DATAW find_data;
1193+
unsigned int i;
1194+
int r;
1195+
1196+
req->flags |= UV_FS_FREE_PTR;
1197+
dir = req->ptr;
1198+
dirents = dir->dirents;
1199+
memset(dirents, 0, dir->nentries * sizeof(*dir->dirents));
1200+
find_data = &dir->find_data;
1201+
dirent_idx = 0;
1202+
1203+
while (dirent_idx < dir->nentries) {
1204+
if (dir->need_find_call && FindNextFileW(dir->dir_handle, find_data) == 0) {
1205+
if (GetLastError() == ERROR_NO_MORE_FILES)
1206+
break;
1207+
goto error;
1208+
}
1209+
1210+
/* Skip "." and ".." entries. */
1211+
if (find_data->cFileName[0] == L'.' &&
1212+
(find_data->cFileName[1] == L'\0' ||
1213+
(find_data->cFileName[1] == L'.' &&
1214+
find_data->cFileName[2] == L'\0'))) {
1215+
dir->need_find_call = TRUE;
1216+
continue;
1217+
}
1218+
1219+
r = uv__convert_utf16_to_utf8((const WCHAR*) &find_data->cFileName,
1220+
-1,
1221+
(char**) &dirents[dirent_idx].name);
1222+
if (r != 0)
1223+
goto error;
1224+
1225+
/* Copy file type. */
1226+
if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
1227+
dent.d_type = UV__DT_DIR;
1228+
else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
1229+
dent.d_type = UV__DT_LINK;
1230+
else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) != 0)
1231+
dent.d_type = UV__DT_CHAR;
1232+
else
1233+
dent.d_type = UV__DT_FILE;
1234+
1235+
dirents[dirent_idx].type = uv__fs_get_dirent_type(&dent);
1236+
dir->need_find_call = TRUE;
1237+
++dirent_idx;
1238+
}
1239+
1240+
SET_REQ_RESULT(req, dirent_idx);
1241+
return;
1242+
1243+
error:
1244+
SET_REQ_WIN32_ERROR(req, GetLastError());
1245+
for (i = 0; i < dirent_idx; ++i) {
1246+
uv__free((char*) dirents[i].name);
1247+
dirents[i].name = NULL;
1248+
}
1249+
}
1250+
1251+
void fs__closedir(uv_fs_t* req) {
1252+
uv_dir_t* dir;
1253+
1254+
dir = req->ptr;
1255+
FindClose(dir->dir_handle);
1256+
uv__free(req->ptr);
1257+
SET_REQ_RESULT(req, 0);
1258+
}
11281259

11291260
INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
11301261
int do_lstat) {
@@ -2039,6 +2170,9 @@ static void uv__fs_work(struct uv__work* w) {
20392170
XX(MKDTEMP, mkdtemp)
20402171
XX(RENAME, rename)
20412172
XX(SCANDIR, scandir)
2173+
XX(READDIR, readdir)
2174+
XX(OPENDIR, opendir)
2175+
XX(CLOSEDIR, closedir)
20422176
XX(LINK, link)
20432177
XX(SYMLINK, symlink)
20442178
XX(READLINK, readlink)
@@ -2080,6 +2214,8 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
20802214
if (req->flags & UV_FS_FREE_PTR) {
20812215
if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
20822216
uv__fs_scandir_cleanup(req);
2217+
else if (req->fs_type == UV_FS_READDIR)
2218+
uv__fs_readdir_cleanup(req);
20832219
else
20842220
uv__free(req->ptr);
20852221
}
@@ -2247,6 +2383,45 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
22472383
POST;
22482384
}
22492385

2386+
int uv_fs_opendir(uv_loop_t* loop,
2387+
uv_fs_t* req,
2388+
const char* path,
2389+
uv_fs_cb cb) {
2390+
int err;
2391+
2392+
INIT(UV_FS_OPENDIR);
2393+
err = fs__capture_path(req, path, NULL, cb != NULL);
2394+
if (err)
2395+
return uv_translate_sys_error(err);
2396+
POST;
2397+
}
2398+
2399+
int uv_fs_readdir(uv_loop_t* loop,
2400+
uv_fs_t* req,
2401+
uv_dir_t* dir,
2402+
uv_fs_cb cb) {
2403+
INIT(UV_FS_READDIR);
2404+
2405+
if (dir == NULL ||
2406+
dir->dirents == NULL ||
2407+
dir->dir_handle == INVALID_HANDLE_VALUE) {
2408+
return UV_EINVAL;
2409+
}
2410+
2411+
req->ptr = dir;
2412+
POST;
2413+
}
2414+
2415+
int uv_fs_closedir(uv_loop_t* loop,
2416+
uv_fs_t* req,
2417+
uv_dir_t* dir,
2418+
uv_fs_cb cb) {
2419+
INIT(UV_FS_CLOSEDIR);
2420+
if (dir == NULL)
2421+
return UV_EINVAL;
2422+
req->ptr = dir;
2423+
POST;
2424+
}
22502425

22512426
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
22522427
const char* new_path, uv_fs_cb cb) {

‎deps/uv/src/win/util.c

+17
Original file line numberDiff line numberDiff line change
@@ -1778,3 +1778,20 @@ int uv_os_uname(uv_utsname_t* buffer) {
17781778
buffer->machine[0] = '\0';
17791779
return r;
17801780
}
1781+
1782+
int uv_gettimeofday(uv_timeval64_t* tv) {
1783+
/* Based on https://doxygen.postgresql.org/gettimeofday_8c_source.html */
1784+
const uint64_t epoch = (uint64_t) 116444736000000000ULL;
1785+
FILETIME file_time;
1786+
ULARGE_INTEGER ularge;
1787+
1788+
if (tv == NULL)
1789+
return UV_EINVAL;
1790+
1791+
GetSystemTimeAsFileTime(&file_time);
1792+
ularge.LowPart = file_time.dwLowDateTime;
1793+
ularge.HighPart = file_time.dwHighDateTime;
1794+
tv->tv_sec = (int64_t) ((ularge.QuadPart - epoch) / 10000000L);
1795+
tv->tv_usec = (int32_t) (((ularge.QuadPart - epoch) % 10000000L) / 10);
1796+
return 0;
1797+
}

‎deps/uv/test/test-fs-copyfile.c

+11
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ TEST_IMPL(fs_copyfile) {
185185
if (r == 0)
186186
handle_result(&req);
187187

188+
#ifndef _WIN32
189+
/* Copying respects permissions/mode. */
190+
unlink(dst);
191+
touch_file(dst, 0);
192+
chmod(dst, S_IRUSR|S_IRGRP|S_IROTH); /* Sets file mode to 444 (read-only). */
193+
r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
194+
ASSERT(req.result == UV_EACCES);
195+
ASSERT(r == UV_EACCES);
196+
uv_fs_req_cleanup(&req);
197+
#endif
198+
188199
unlink(dst); /* Cleanup */
189200
return 0;
190201
}

‎deps/uv/test/test-fs-readdir.c

+462
Large diffs are not rendered by default.

‎deps/uv/test/test-gettimeofday.c

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* Copyright libuv project contributors. All rights reserved.
2+
*
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to
5+
* deal in the Software without restriction, including without limitation the
6+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7+
* sell copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19+
* IN THE SOFTWARE.
20+
*/
21+
22+
#include "uv.h"
23+
#include "task.h"
24+
25+
TEST_IMPL(gettimeofday) {
26+
uv_timeval64_t tv;
27+
int r;
28+
29+
tv.tv_sec = 0;
30+
r = uv_gettimeofday(&tv);
31+
ASSERT(r == 0);
32+
ASSERT(tv.tv_sec != 0);
33+
34+
/* Test invalid input. */
35+
r = uv_gettimeofday(NULL);
36+
ASSERT(r == UV_EINVAL);
37+
38+
return 0;
39+
}

‎deps/uv/test/test-list.h

+17
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ TEST_DECLARE (udp_open)
155155
TEST_DECLARE (udp_open_twice)
156156
TEST_DECLARE (udp_open_bound)
157157
TEST_DECLARE (udp_open_connect)
158+
#ifndef _WIN32
159+
TEST_DECLARE (udp_send_unix)
160+
#endif
158161
TEST_DECLARE (udp_try_send)
159162
TEST_DECLARE (pipe_bind_error_addrinuse)
160163
TEST_DECLARE (pipe_bind_error_addrnotavail)
@@ -252,6 +255,7 @@ TEST_DECLARE (getnameinfo_basic_ip4_sync)
252255
TEST_DECLARE (getnameinfo_basic_ip6)
253256
TEST_DECLARE (getsockname_tcp)
254257
TEST_DECLARE (getsockname_udp)
258+
TEST_DECLARE (gettimeofday)
255259
TEST_DECLARE (fail_always)
256260
TEST_DECLARE (pass_always)
257261
TEST_DECLARE (socket_buffer_size)
@@ -345,6 +349,10 @@ TEST_DECLARE (fs_scandir_empty_dir)
345349
TEST_DECLARE (fs_scandir_non_existent_dir)
346350
TEST_DECLARE (fs_scandir_file)
347351
TEST_DECLARE (fs_open_dir)
352+
TEST_DECLARE (fs_readdir_empty_dir)
353+
TEST_DECLARE (fs_readdir_file)
354+
TEST_DECLARE (fs_readdir_non_empty_dir)
355+
TEST_DECLARE (fs_readdir_non_existing_dir)
348356
TEST_DECLARE (fs_rename_to_existing_file)
349357
TEST_DECLARE (fs_write_multiple_bufs)
350358
TEST_DECLARE (fs_read_write_null_arguments)
@@ -652,6 +660,9 @@ TASK_LIST_START
652660
TEST_ENTRY (udp_open_bound)
653661
TEST_ENTRY (udp_open_connect)
654662
TEST_HELPER (udp_open_connect, udp4_echo_server)
663+
#ifndef _WIN32
664+
TEST_ENTRY (udp_send_unix)
665+
#endif
655666

656667
TEST_ENTRY (pipe_bind_error_addrinuse)
657668
TEST_ENTRY (pipe_bind_error_addrnotavail)
@@ -781,6 +792,8 @@ TASK_LIST_START
781792
TEST_ENTRY (getsockname_tcp)
782793
TEST_ENTRY (getsockname_udp)
783794

795+
TEST_ENTRY (gettimeofday)
796+
784797
TEST_ENTRY (poll_duplex)
785798
TEST_ENTRY (poll_unidirectional)
786799
TEST_ENTRY (poll_close)
@@ -921,6 +934,10 @@ TASK_LIST_START
921934
TEST_ENTRY (fs_scandir_non_existent_dir)
922935
TEST_ENTRY (fs_scandir_file)
923936
TEST_ENTRY (fs_open_dir)
937+
TEST_ENTRY (fs_readdir_empty_dir)
938+
TEST_ENTRY (fs_readdir_file)
939+
TEST_ENTRY (fs_readdir_non_empty_dir)
940+
TEST_ENTRY (fs_readdir_non_existing_dir)
924941
TEST_ENTRY (fs_rename_to_existing_file)
925942
TEST_ENTRY (fs_write_multiple_bufs)
926943
TEST_ENTRY (fs_write_alotof_bufs)

‎deps/uv/test/test-udp-open.c

+52
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#ifndef _WIN32
2929
# include <unistd.h>
30+
# include <sys/socket.h>
31+
# include <sys/un.h>
3032
#endif
3133

3234
static int send_cb_called = 0;
@@ -296,3 +298,53 @@ TEST_IMPL(udp_open_connect) {
296298
MAKE_VALGRIND_HAPPY();
297299
return 0;
298300
}
301+
302+
#ifndef _WIN32
303+
TEST_IMPL(udp_send_unix) {
304+
/* Test that "uv_udp_send()" supports sending over
305+
a "sockaddr_un" address. */
306+
struct sockaddr_un addr;
307+
uv_udp_t handle;
308+
uv_udp_send_t req;
309+
uv_loop_t* loop;
310+
uv_buf_t buf = uv_buf_init("PING", 4);
311+
int fd;
312+
int r;
313+
314+
loop = uv_default_loop();
315+
316+
memset(&addr, 0, sizeof addr);
317+
addr.sun_family = AF_UNIX;
318+
ASSERT(strlen(TEST_PIPENAME) < sizeof(addr.sun_path));
319+
memcpy(addr.sun_path, TEST_PIPENAME, strlen(TEST_PIPENAME));
320+
321+
fd = socket(AF_UNIX, SOCK_STREAM, 0);
322+
ASSERT(fd >= 0);
323+
324+
unlink(TEST_PIPENAME);
325+
ASSERT(0 == bind(fd, (const struct sockaddr*)&addr, sizeof addr));
326+
ASSERT(0 == listen(fd, 1));
327+
328+
r = uv_udp_init(loop, &handle);
329+
ASSERT(r == 0);
330+
r = uv_udp_open(&handle, fd);
331+
ASSERT(r == 0);
332+
uv_run(loop, UV_RUN_DEFAULT);
333+
334+
r = uv_udp_send(&req,
335+
&handle,
336+
&buf,
337+
1,
338+
(const struct sockaddr*) &addr,
339+
NULL);
340+
ASSERT(r == 0);
341+
342+
uv_close((uv_handle_t*)&handle, NULL);
343+
uv_run(loop, UV_RUN_DEFAULT);
344+
close(fd);
345+
unlink(TEST_PIPENAME);
346+
347+
MAKE_VALGRIND_HAPPY();
348+
return 0;
349+
}
350+
#endif

‎deps/uv/test/test.gyp

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
'test-fail-always.c',
3333
'test-fork.c',
3434
'test-fs.c',
35+
'test-fs-readdir.c',
3536
'test-fs-copyfile.c',
3637
'test-fs-event.c',
3738
'test-fs-poll.c',
@@ -43,6 +44,7 @@
4344
'test-gethostname.c',
4445
'test-getnameinfo.c',
4546
'test-getsockname.c',
47+
'test-gettimeofday.c',
4648
'test-handle-fileno.c',
4749
'test-homedir.c',
4850
'test-hrtime.c',

0 commit comments

Comments
 (0)
Please sign in to comment.