libuv 1.47.0.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4615 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										244
									
								
								deps/libuv/src/idna.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										244
									
								
								deps/libuv/src/idna.c
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| /* Copyright (c) 2011, 2018 Ben Noordhuis <info@bnoordhuis.nl> | ||||
| /* Copyright libuv contributors. All rights reserved. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and/or distribute this software for any | ||||
|  * purpose with or without fee is hereby granted, provided that the above | ||||
| @@ -18,11 +18,56 @@ | ||||
|  */ | ||||
|  | ||||
| #include "uv.h" | ||||
| #include "uv-common.h" | ||||
| #include "idna.h" | ||||
| #include <assert.h> | ||||
| #include <string.h> | ||||
| #include <limits.h> /* UINT_MAX */ | ||||
|  | ||||
|  | ||||
| static int32_t uv__wtf8_decode1(const char** input) { | ||||
|   uint32_t code_point; | ||||
|   uint8_t b1; | ||||
|   uint8_t b2; | ||||
|   uint8_t b3; | ||||
|   uint8_t b4; | ||||
|  | ||||
|   b1 = **input; | ||||
|   if (b1 <= 0x7F) | ||||
|     return b1; /* ASCII code point */ | ||||
|   if (b1 < 0xC2) | ||||
|     return -1; /* invalid: continuation byte */ | ||||
|   code_point = b1; | ||||
|  | ||||
|   b2 = *++*input; | ||||
|   if ((b2 & 0xC0) != 0x80) | ||||
|     return -1; /* invalid: not a continuation byte */ | ||||
|   code_point = (code_point << 6) | (b2 & 0x3F); | ||||
|   if (b1 <= 0xDF) | ||||
|     return 0x7FF & code_point; /* two-byte character */ | ||||
|  | ||||
|   b3 = *++*input; | ||||
|   if ((b3 & 0xC0) != 0x80) | ||||
|     return -1; /* invalid: not a continuation byte */ | ||||
|   code_point = (code_point << 6) | (b3 & 0x3F); | ||||
|   if (b1 <= 0xEF) | ||||
|     return 0xFFFF & code_point; /* three-byte character */ | ||||
|  | ||||
|   b4 = *++*input; | ||||
|   if ((b4 & 0xC0) != 0x80) | ||||
|     return -1; /* invalid: not a continuation byte */ | ||||
|   code_point = (code_point << 6) | (b4 & 0x3F); | ||||
|   if (b1 <= 0xF4) { | ||||
|     code_point &= 0x1FFFFF; | ||||
|     if (code_point <= 0x10FFFF) | ||||
|       return code_point; /* four-byte character */ | ||||
|   } | ||||
|  | ||||
|   /* code point too large */ | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| static unsigned uv__utf8_decode1_slow(const char** p, | ||||
|                                       const char* pe, | ||||
|                                       unsigned a) { | ||||
| @@ -89,6 +134,7 @@ static unsigned uv__utf8_decode1_slow(const char** p, | ||||
|   return a; | ||||
| } | ||||
|  | ||||
|  | ||||
| unsigned uv__utf8_decode1(const char** p, const char* pe) { | ||||
|   unsigned a; | ||||
|  | ||||
| @@ -102,6 +148,7 @@ unsigned uv__utf8_decode1(const char** p, const char* pe) { | ||||
|   return uv__utf8_decode1_slow(p, pe, a); | ||||
| } | ||||
|  | ||||
|  | ||||
| static int uv__idna_toascii_label(const char* s, const char* se, | ||||
|                                   char** d, char* de) { | ||||
|   static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789"; | ||||
| @@ -267,7 +314,8 @@ static int uv__idna_toascii_label(const char* s, const char* se, | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| long uv__idna_toascii(const char* s, const char* se, char* d, char* de) { | ||||
|  | ||||
| ssize_t uv__idna_toascii(const char* s, const char* se, char* d, char* de) { | ||||
|   const char* si; | ||||
|   const char* st; | ||||
|   unsigned c; | ||||
| @@ -313,3 +361,195 @@ long uv__idna_toascii(const char* s, const char* se, char* d, char* de) { | ||||
|  | ||||
|   return d - ds;  /* Number of bytes written. */ | ||||
| } | ||||
|  | ||||
|  | ||||
| ssize_t uv_wtf8_length_as_utf16(const char* source_ptr) { | ||||
|   size_t w_target_len = 0; | ||||
|   int32_t code_point; | ||||
|  | ||||
|   do { | ||||
|     code_point = uv__wtf8_decode1(&source_ptr); | ||||
|     if (code_point < 0) | ||||
|       return -1; | ||||
|     if (code_point > 0xFFFF) | ||||
|       w_target_len++; | ||||
|     w_target_len++; | ||||
|   } while (*source_ptr++); | ||||
|  | ||||
|   return w_target_len; | ||||
| } | ||||
|  | ||||
|  | ||||
| void uv_wtf8_to_utf16(const char* source_ptr, | ||||
|                       uint16_t* w_target, | ||||
|                       size_t w_target_len) { | ||||
|   int32_t code_point; | ||||
|  | ||||
|   do { | ||||
|     code_point = uv__wtf8_decode1(&source_ptr); | ||||
|     /* uv_wtf8_length_as_utf16 should have been called and checked first. */ | ||||
|     assert(code_point >= 0); | ||||
|     if (code_point > 0x10000) { | ||||
|       assert(code_point < 0x10FFFF); | ||||
|       *w_target++ = (((code_point - 0x10000) >> 10) + 0xD800); | ||||
|       *w_target++ = ((code_point - 0x10000) & 0x3FF) + 0xDC00; | ||||
|       w_target_len -= 2; | ||||
|     } else { | ||||
|       *w_target++ = code_point; | ||||
|       w_target_len -= 1; | ||||
|     } | ||||
|   } while (*source_ptr++); | ||||
|  | ||||
|   assert(w_target_len == 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| static int32_t uv__get_surrogate_value(const uint16_t* w_source_ptr, | ||||
|                                        ssize_t w_source_len) { | ||||
|   uint16_t u; | ||||
|   uint16_t next; | ||||
|  | ||||
|   u = w_source_ptr[0]; | ||||
|   if (u >= 0xD800 && u <= 0xDBFF && w_source_len != 1) { | ||||
|     next = w_source_ptr[1]; | ||||
|     if (next >= 0xDC00 && next <= 0xDFFF) | ||||
|       return 0x10000 + ((u - 0xD800) << 10) + (next - 0xDC00); | ||||
|   } | ||||
|   return u; | ||||
| } | ||||
|  | ||||
|  | ||||
| size_t uv_utf16_length_as_wtf8(const uint16_t* w_source_ptr, | ||||
|                                ssize_t w_source_len) { | ||||
|   size_t target_len; | ||||
|   int32_t code_point; | ||||
|  | ||||
|   target_len = 0; | ||||
|   while (w_source_len) { | ||||
|     code_point = uv__get_surrogate_value(w_source_ptr, w_source_len); | ||||
|     /* Can be invalid UTF-8 but must be valid WTF-8. */ | ||||
|     assert(code_point >= 0); | ||||
|     if (w_source_len < 0 && code_point == 0) | ||||
|       break; | ||||
|     if (code_point < 0x80) | ||||
|       target_len += 1; | ||||
|     else if (code_point < 0x800) | ||||
|       target_len += 2; | ||||
|     else if (code_point < 0x10000) | ||||
|       target_len += 3; | ||||
|     else { | ||||
|       target_len += 4; | ||||
|       w_source_ptr++; | ||||
|       if (w_source_len > 0) | ||||
|         w_source_len--; | ||||
|     } | ||||
|     w_source_ptr++; | ||||
|     if (w_source_len > 0) | ||||
|       w_source_len--; | ||||
|   } | ||||
|  | ||||
|   return target_len; | ||||
| } | ||||
|  | ||||
|  | ||||
| int uv_utf16_to_wtf8(const uint16_t* w_source_ptr, | ||||
|                      ssize_t w_source_len, | ||||
|                      char** target_ptr, | ||||
|                      size_t* target_len_ptr) { | ||||
|   size_t target_len; | ||||
|   char* target; | ||||
|   char* target_end; | ||||
|   int32_t code_point; | ||||
|  | ||||
|   /* If *target_ptr is provided, then *target_len_ptr must be its length | ||||
|    * (excluding space for NUL), otherwise we will compute the target_len_ptr | ||||
|    * length and may return a new allocation in *target_ptr if target_ptr is | ||||
|    * provided. */ | ||||
|   if (target_ptr == NULL || *target_ptr == NULL) { | ||||
|     target_len = uv_utf16_length_as_wtf8(w_source_ptr, w_source_len); | ||||
|     if (target_len_ptr != NULL) | ||||
|       *target_len_ptr = target_len; | ||||
|   } else { | ||||
|     target_len = *target_len_ptr; | ||||
|   } | ||||
|  | ||||
|   if (target_ptr == NULL) | ||||
|     return 0; | ||||
|  | ||||
|   if (*target_ptr == NULL) { | ||||
|     target = uv__malloc(target_len + 1); | ||||
|     if (target == NULL) { | ||||
|       return UV_ENOMEM; | ||||
|     } | ||||
|     *target_ptr = target; | ||||
|   } else { | ||||
|     target = *target_ptr; | ||||
|   } | ||||
|  | ||||
|   target_end = target + target_len; | ||||
|  | ||||
|   while (target != target_end && w_source_len) { | ||||
|     code_point = uv__get_surrogate_value(w_source_ptr, w_source_len); | ||||
|     /* Can be invalid UTF-8 but must be valid WTF-8. */ | ||||
|     assert(code_point >= 0); | ||||
|     if (w_source_len < 0 && code_point == 0) { | ||||
|       w_source_len = 0; | ||||
|       break; | ||||
|     } | ||||
|     if (code_point < 0x80) { | ||||
|       *target++ = code_point; | ||||
|     } else if (code_point < 0x800) { | ||||
|       *target++ = 0xC0 | (code_point >> 6); | ||||
|       if (target == target_end) | ||||
|         break; | ||||
|       *target++ = 0x80 | (code_point & 0x3F); | ||||
|     } else if (code_point < 0x10000) { | ||||
|       *target++ = 0xE0 | (code_point >> 12); | ||||
|       if (target == target_end) | ||||
|         break; | ||||
|       *target++ = 0x80 | ((code_point >> 6) & 0x3F); | ||||
|       if (target == target_end) | ||||
|         break; | ||||
|       *target++ = 0x80 | (code_point & 0x3F); | ||||
|     } else { | ||||
|       *target++ = 0xF0 | (code_point >> 18); | ||||
|       if (target == target_end) | ||||
|         break; | ||||
|       *target++ = 0x80 | ((code_point >> 12) & 0x3F); | ||||
|       if (target == target_end) | ||||
|         break; | ||||
|       *target++ = 0x80 | ((code_point >> 6) & 0x3F); | ||||
|       if (target == target_end) | ||||
|         break; | ||||
|       *target++ = 0x80 | (code_point & 0x3F); | ||||
|       /* uv__get_surrogate_value consumed 2 input characters */ | ||||
|       w_source_ptr++; | ||||
|       if (w_source_len > 0) | ||||
|         w_source_len--; | ||||
|     } | ||||
|     target_len = target - *target_ptr; | ||||
|     w_source_ptr++; | ||||
|     if (w_source_len > 0) | ||||
|       w_source_len--; | ||||
|   } | ||||
|  | ||||
|   if (target != target_end && target_len_ptr != NULL) | ||||
|     /* Did not fill all of the provided buffer, so update the target_len_ptr | ||||
|      * output with the space used. */ | ||||
|     *target_len_ptr = target - *target_ptr; | ||||
|  | ||||
|   /* Check if input fit into target exactly. */ | ||||
|   if (w_source_len < 0 && target == target_end && w_source_ptr[0] == 0) | ||||
|     w_source_len = 0; | ||||
|  | ||||
|   *target++ = '\0'; | ||||
|  | ||||
|   /* Characters remained after filling the buffer, compute the remaining length now. */ | ||||
|   if (w_source_len) { | ||||
|     if (target_len_ptr != NULL) | ||||
|       *target_len_ptr = target_len + uv_utf16_length_as_wtf8(w_source_ptr, w_source_len); | ||||
|     return UV_ENOBUFS; | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										4
									
								
								deps/libuv/src/idna.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/libuv/src/idna.h
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| /* Copyright (c) 2011, 2018 Ben Noordhuis <info@bnoordhuis.nl> | ||||
| /* Copyright libuv contributors. All rights reserved. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and/or distribute this software for any | ||||
|  * purpose with or without fee is hereby granted, provided that the above | ||||
| @@ -26,6 +26,6 @@ unsigned uv__utf8_decode1(const char** p, const char* pe); | ||||
|  * is the number of bytes written to |d|, including the trailing nul byte. | ||||
|  * A return value < 0 is a libuv error code. |s| and |d| can not overlap. | ||||
|  */ | ||||
| long uv__idna_toascii(const char* s, const char* se, char* d, char* de); | ||||
| ssize_t uv__idna_toascii(const char* s, const char* se, char* d, char* de); | ||||
|  | ||||
| #endif  /* UV_SRC_IDNA_H_ */ | ||||
|   | ||||
							
								
								
									
										4
									
								
								deps/libuv/src/unix/darwin.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/libuv/src/unix/darwin.c
									
									
									
									
										vendored
									
									
								
							| @@ -209,7 +209,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { | ||||
|   if (cpuspeed == 0) | ||||
|     /* If sysctl hw.cputype == CPU_TYPE_ARM64, the correct value is unavailable | ||||
|      * from Apple, but we can hard-code it here to a plausible value. */ | ||||
|     cpuspeed = 2400000000; | ||||
|     cpuspeed = 2400000000U; | ||||
|  | ||||
|   if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, | ||||
|                           (processor_info_array_t*)&info, | ||||
| @@ -235,7 +235,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { | ||||
|     cpu_info->cpu_times.irq = 0; | ||||
|  | ||||
|     cpu_info->model = uv__strdup(model); | ||||
|     cpu_info->speed = cpuspeed/1000000; | ||||
|     cpu_info->speed = (int)(cpuspeed / 1000000); | ||||
|   } | ||||
|   vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); | ||||
|  | ||||
|   | ||||
							
								
								
									
										240
									
								
								deps/libuv/src/unix/fs.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										240
									
								
								deps/libuv/src/unix/fs.c
									
									
									
									
										vendored
									
									
								
							| @@ -41,25 +41,10 @@ | ||||
| #include <sys/stat.h> | ||||
| #include <sys/time.h> | ||||
| #include <sys/uio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <poll.h> | ||||
|  | ||||
| #if defined(__DragonFly__)        ||                                      \ | ||||
|     defined(__FreeBSD__)          ||                                      \ | ||||
|     defined(__OpenBSD__)          ||                                      \ | ||||
|     defined(__NetBSD__) | ||||
| # define HAVE_PREADV 1 | ||||
| #else | ||||
| # define HAVE_PREADV 0 | ||||
| #endif | ||||
|  | ||||
| /* preadv() and pwritev() were added in Android N (level 24) */ | ||||
| #if defined(__linux__) && !(defined(__ANDROID__) && __ANDROID_API__ < 24) | ||||
| # define TRY_PREADV 1 | ||||
| #endif | ||||
|  | ||||
| #if defined(__linux__) | ||||
| # include <sys/sendfile.h> | ||||
| #endif | ||||
| @@ -97,6 +82,15 @@ | ||||
| # include <sys/statfs.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(__CYGWIN__) ||                                                    \ | ||||
|     (defined(__HAIKU__) && B_HAIKU_VERSION < B_HAIKU_VERSION_1_PRE_BETA_5) || \ | ||||
|     (defined(__sun) && !defined(__illumos__)) | ||||
| #define preadv(fd, bufs, nbufs, off)                                          \ | ||||
|   pread(fd, (bufs)->iov_base, (bufs)->iov_len, off) | ||||
| #define pwritev(fd, bufs, nbufs, off)                                         \ | ||||
|   pwrite(fd, (bufs)->iov_base, (bufs)->iov_len, off) | ||||
| #endif | ||||
|  | ||||
| #if defined(_AIX) && _XOPEN_SOURCE <= 600 | ||||
| extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */ | ||||
| #endif | ||||
| @@ -410,123 +404,57 @@ static ssize_t uv__fs_open(uv_fs_t* req) { | ||||
| } | ||||
|  | ||||
|  | ||||
| #if !HAVE_PREADV | ||||
| static ssize_t uv__fs_preadv(uv_file fd, | ||||
|                              uv_buf_t* bufs, | ||||
|                              unsigned int nbufs, | ||||
|                              off_t off) { | ||||
|   uv_buf_t* buf; | ||||
|   uv_buf_t* end; | ||||
|   ssize_t result; | ||||
|   ssize_t rc; | ||||
|   size_t pos; | ||||
|  | ||||
|   assert(nbufs > 0); | ||||
|  | ||||
|   result = 0; | ||||
|   pos = 0; | ||||
|   buf = bufs + 0; | ||||
|   end = bufs + nbufs; | ||||
|  | ||||
|   for (;;) { | ||||
|     do | ||||
|       rc = pread(fd, buf->base + pos, buf->len - pos, off + result); | ||||
|     while (rc == -1 && errno == EINTR); | ||||
|  | ||||
|     if (rc == 0) | ||||
|       break; | ||||
|  | ||||
|     if (rc == -1 && result == 0) | ||||
|       return UV__ERR(errno); | ||||
|  | ||||
|     if (rc == -1) | ||||
|       break;  /* We read some data so return that, ignore the error. */ | ||||
|  | ||||
|     pos += rc; | ||||
|     result += rc; | ||||
|  | ||||
|     if (pos < buf->len) | ||||
|       continue; | ||||
|  | ||||
|     pos = 0; | ||||
|     buf += 1; | ||||
|  | ||||
|     if (buf == end) | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   return result; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| static ssize_t uv__fs_read(uv_fs_t* req) { | ||||
| #if TRY_PREADV | ||||
|   static _Atomic int no_preadv; | ||||
| #endif | ||||
|   const struct iovec* bufs; | ||||
|   unsigned int iovmax; | ||||
|   ssize_t result; | ||||
|   size_t nbufs; | ||||
|   ssize_t r; | ||||
|   off_t off; | ||||
|   int fd; | ||||
|  | ||||
|   fd = req->file; | ||||
|   off = req->off; | ||||
|   bufs = (const struct iovec*) req->bufs; | ||||
|   nbufs = req->nbufs; | ||||
|  | ||||
|   iovmax = uv__getiovmax(); | ||||
|   if (req->nbufs > iovmax) | ||||
|     req->nbufs = iovmax; | ||||
|   if (nbufs > iovmax) | ||||
|     nbufs = iovmax; | ||||
|  | ||||
|   if (req->off < 0) { | ||||
|     if (req->nbufs == 1) | ||||
|       result = read(req->file, req->bufs[0].base, req->bufs[0].len); | ||||
|     else | ||||
|       result = readv(req->file, (struct iovec*) req->bufs, req->nbufs); | ||||
|   r = 0; | ||||
|   if (off < 0) { | ||||
|     if (nbufs == 1) | ||||
|       r = read(fd, bufs->iov_base, bufs->iov_len); | ||||
|     else if (nbufs > 1) | ||||
|       r = readv(fd, bufs, nbufs); | ||||
|   } else { | ||||
|     if (req->nbufs == 1) { | ||||
|       result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off); | ||||
|       goto done; | ||||
|     } | ||||
|  | ||||
| #if HAVE_PREADV | ||||
|     result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); | ||||
| #else | ||||
| # if TRY_PREADV | ||||
|     if (atomic_load_explicit(&no_preadv, memory_order_relaxed)) retry: | ||||
| # endif | ||||
|     { | ||||
|       result = uv__fs_preadv(req->file, req->bufs, req->nbufs, req->off); | ||||
|     } | ||||
| # if TRY_PREADV | ||||
|     else { | ||||
|       result = preadv(req->file, | ||||
|                       (struct iovec*) req->bufs, | ||||
|                       req->nbufs, | ||||
|                       req->off); | ||||
|       if (result == -1 && errno == ENOSYS) { | ||||
|         atomic_store_explicit(&no_preadv, 1, memory_order_relaxed); | ||||
|         goto retry; | ||||
|       } | ||||
|     } | ||||
| # endif | ||||
| #endif | ||||
|     if (nbufs == 1) | ||||
|       r = pread(fd, bufs->iov_base, bufs->iov_len, off); | ||||
|     else if (nbufs > 1) | ||||
|       r = preadv(fd, bufs, nbufs, off); | ||||
|   } | ||||
|  | ||||
| done: | ||||
|   /* Early cleanup of bufs allocation, since we're done with it. */ | ||||
|   if (req->bufs != req->bufsml) | ||||
|     uv__free(req->bufs); | ||||
|  | ||||
|   req->bufs = NULL; | ||||
|   req->nbufs = 0; | ||||
|  | ||||
| #ifdef __PASE__ | ||||
|   /* PASE returns EOPNOTSUPP when reading a directory, convert to EISDIR */ | ||||
|   if (result == -1 && errno == EOPNOTSUPP) { | ||||
|   if (r == -1 && errno == EOPNOTSUPP) { | ||||
|     struct stat buf; | ||||
|     ssize_t rc; | ||||
|     rc = uv__fstat(req->file, &buf); | ||||
|     rc = uv__fstat(fd, &buf); | ||||
|     if (rc == 0 && S_ISDIR(buf.st_mode)) { | ||||
|       errno = EISDIR; | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   return result; | ||||
|   /* We don't own the buffer list in the synchronous case. */ | ||||
|   if (req->cb != NULL) | ||||
|     if (req->bufs != req->bufsml) | ||||
|       uv__free(req->bufs); | ||||
|  | ||||
|   req->bufs = NULL; | ||||
|   req->nbufs = 0; | ||||
|  | ||||
|   return r; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1161,65 +1089,34 @@ static ssize_t uv__fs_lutime(uv_fs_t* req) { | ||||
|  | ||||
|  | ||||
| static ssize_t uv__fs_write(uv_fs_t* req) { | ||||
| #if TRY_PREADV | ||||
|   static _Atomic int no_pwritev; | ||||
| #endif | ||||
|   const struct iovec* bufs; | ||||
|   size_t nbufs; | ||||
|   ssize_t r; | ||||
|   off_t off; | ||||
|   int fd; | ||||
|  | ||||
|   /* Serialize writes on OS X, concurrent write() and pwrite() calls result in | ||||
|    * data loss. We can't use a per-file descriptor lock, the descriptor may be | ||||
|    * a dup(). | ||||
|    */ | ||||
| #if defined(__APPLE__) | ||||
|   static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; | ||||
|   fd = req->file; | ||||
|   off = req->off; | ||||
|   bufs = (const struct iovec*) req->bufs; | ||||
|   nbufs = req->nbufs; | ||||
|  | ||||
|   if (pthread_mutex_lock(&lock)) | ||||
|     abort(); | ||||
| #endif | ||||
|  | ||||
|   if (req->off < 0) { | ||||
|     if (req->nbufs == 1) | ||||
|       r = write(req->file, req->bufs[0].base, req->bufs[0].len); | ||||
|     else | ||||
|       r = writev(req->file, (struct iovec*) req->bufs, req->nbufs); | ||||
|   r = 0; | ||||
|   if (off < 0) { | ||||
|     if (nbufs == 1) | ||||
|       r = write(fd, bufs->iov_base, bufs->iov_len); | ||||
|     else if (nbufs > 1) | ||||
|       r = writev(fd, bufs, nbufs); | ||||
|   } else { | ||||
|     if (req->nbufs == 1) { | ||||
|       r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); | ||||
|       goto done; | ||||
|     } | ||||
| #if HAVE_PREADV | ||||
|     r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); | ||||
| #else | ||||
| # if TRY_PREADV | ||||
|     if (atomic_load_explicit(&no_pwritev, memory_order_relaxed)) retry: | ||||
| # endif | ||||
|     { | ||||
|       r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); | ||||
|     } | ||||
| # if TRY_PREADV | ||||
|     else { | ||||
|       r = pwritev(req->file, | ||||
|                   (struct iovec*) req->bufs, | ||||
|                   req->nbufs, | ||||
|                   req->off); | ||||
|       if (r == -1 && errno == ENOSYS) { | ||||
|         atomic_store_explicit(&no_pwritev, 1, memory_order_relaxed); | ||||
|         goto retry; | ||||
|       } | ||||
|     } | ||||
| # endif | ||||
| #endif | ||||
|     if (nbufs == 1) | ||||
|       r = pwrite(fd, bufs->iov_base, bufs->iov_len, off); | ||||
|     else if (nbufs > 1) | ||||
|       r = pwritev(fd, bufs, nbufs, off); | ||||
|   } | ||||
|  | ||||
| done: | ||||
| #if defined(__APPLE__) | ||||
|   if (pthread_mutex_unlock(&lock)) | ||||
|     abort(); | ||||
| #endif | ||||
|  | ||||
|   return r; | ||||
| } | ||||
|  | ||||
|  | ||||
| static ssize_t uv__fs_copyfile(uv_fs_t* req) { | ||||
|   uv_fs_t fs_req; | ||||
|   uv_file srcfd; | ||||
| @@ -1979,9 +1876,14 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, | ||||
|   if (bufs == NULL || nbufs == 0) | ||||
|     return UV_EINVAL; | ||||
|  | ||||
|   req->off = off; | ||||
|   req->file = file; | ||||
|  | ||||
|   req->bufs = (uv_buf_t*) bufs;  /* Safe, doesn't mutate |bufs| */ | ||||
|   req->nbufs = nbufs; | ||||
|  | ||||
|   if (cb == NULL) | ||||
|     goto post; | ||||
|  | ||||
|   req->bufs = req->bufsml; | ||||
|   if (nbufs > ARRAY_SIZE(req->bufsml)) | ||||
|     req->bufs = uv__malloc(nbufs * sizeof(*bufs)); | ||||
| @@ -1991,12 +1893,10 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, | ||||
|  | ||||
|   memcpy(req->bufs, bufs, nbufs * sizeof(*bufs)); | ||||
|  | ||||
|   req->off = off; | ||||
|  | ||||
|   if (cb != NULL) | ||||
|     if (uv__iou_fs_read_or_write(loop, req, /* is_read */ 1)) | ||||
|       return 0; | ||||
|   if (uv__iou_fs_read_or_write(loop, req, /* is_read */ 1)) | ||||
|     return 0; | ||||
|  | ||||
| post: | ||||
|   POST; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										18
									
								
								deps/libuv/src/unix/kqueue.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								deps/libuv/src/unix/kqueue.c
									
									
									
									
										vendored
									
									
								
							| @@ -30,6 +30,9 @@ | ||||
| #include <sys/types.h> | ||||
| #include <sys/event.h> | ||||
| #include <sys/time.h> | ||||
| #if defined(__FreeBSD__) | ||||
| #include <sys/user.h> | ||||
| #endif | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <time.h> | ||||
| @@ -262,6 +265,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { | ||||
|  | ||||
|     if (nfds == -1) | ||||
|       assert(errno == EINTR); | ||||
|     else if (nfds == 0) | ||||
|       /* Unlimited timeout should only return with events or signal. */ | ||||
|       assert(timeout != -1); | ||||
|  | ||||
|     if (pset != NULL) | ||||
|       pthread_sigmask(SIG_UNBLOCK, pset, NULL); | ||||
| @@ -286,8 +292,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { | ||||
|         timeout = user_timeout; | ||||
|         reset_timeout = 0; | ||||
|       } else if (nfds == 0) { | ||||
|         /* Reached the user timeout value. */ | ||||
|         assert(timeout != -1); | ||||
|         return; | ||||
|       } | ||||
|  | ||||
| @@ -479,6 +483,16 @@ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) { | ||||
|    */ | ||||
|   if (fcntl(handle->event_watcher.fd, F_GETPATH, pathbuf) == 0) | ||||
|     path = uv__basename_r(pathbuf); | ||||
| #elif defined(F_KINFO) | ||||
|   /* We try to get the file info reference from the file descriptor. | ||||
|    * the struct's kf_structsize must be initialised beforehand | ||||
|    * whether with the KINFO_FILE_SIZE constant or this way. | ||||
|    */ | ||||
|   struct kinfo_file kf; | ||||
|   kf.kf_structsize = sizeof(kf); | ||||
|  | ||||
|   if (fcntl(handle->event_watcher.fd, F_KINFO, &kf) == 0) | ||||
|     path = uv__basename_r(kf.kf_path); | ||||
| #endif | ||||
|   handle->cb(handle, path, events, 0); | ||||
|  | ||||
|   | ||||
							
								
								
									
										121
									
								
								deps/libuv/src/unix/linux.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										121
									
								
								deps/libuv/src/unix/linux.c
									
									
									
									
										vendored
									
									
								
							| @@ -79,6 +79,8 @@ | ||||
| #  define __NR_copy_file_range 379 | ||||
| # elif defined(__arc__) | ||||
| #  define __NR_copy_file_range 285 | ||||
| # elif defined(__riscv) | ||||
| #  define __NR_copy_file_range 285 | ||||
| # endif | ||||
| #endif /* __NR_copy_file_range */ | ||||
|  | ||||
| @@ -95,6 +97,8 @@ | ||||
| #  define __NR_statx 383 | ||||
| # elif defined(__s390__) | ||||
| #  define __NR_statx 379 | ||||
| # elif defined(__riscv) | ||||
| #  define __NR_statx 291 | ||||
| # endif | ||||
| #endif /* __NR_statx */ | ||||
|  | ||||
| @@ -111,6 +115,8 @@ | ||||
| #  define __NR_getrandom 359 | ||||
| # elif defined(__s390__) | ||||
| #  define __NR_getrandom 349 | ||||
| # elif defined(__riscv) | ||||
| #  define __NR_getrandom 278 | ||||
| # endif | ||||
| #endif /* __NR_getrandom */ | ||||
|  | ||||
| @@ -317,17 +323,64 @@ unsigned uv__kernel_version(void) { | ||||
|   unsigned major; | ||||
|   unsigned minor; | ||||
|   unsigned patch; | ||||
|   char v_sig[256]; | ||||
|   char* needle; | ||||
|  | ||||
|   version = atomic_load_explicit(&cached_version, memory_order_relaxed); | ||||
|   if (version != 0) | ||||
|     return version; | ||||
|  | ||||
|   /* Check /proc/version_signature first as it's the way to get the mainline | ||||
|    * kernel version in Ubuntu. The format is: | ||||
|    *   Ubuntu ubuntu_kernel_version mainline_kernel_version | ||||
|    * For example: | ||||
|    *   Ubuntu 5.15.0-79.86-generic 5.15.111 | ||||
|    */ | ||||
|   if (0 == uv__slurp("/proc/version_signature", v_sig, sizeof(v_sig))) | ||||
|     if (3 == sscanf(v_sig, "Ubuntu %*s %u.%u.%u", &major, &minor, &patch)) | ||||
|       goto calculate_version; | ||||
|  | ||||
|   if (-1 == uname(&u)) | ||||
|     return 0; | ||||
|  | ||||
|   /* In Debian we need to check `version` instead of `release` to extract the | ||||
|    * mainline kernel version. This is an example of how it looks like: | ||||
|    *  #1 SMP Debian 5.10.46-4 (2021-08-03) | ||||
|    */ | ||||
|   needle = strstr(u.version, "Debian "); | ||||
|   if (needle != NULL) | ||||
|     if (3 == sscanf(needle, "Debian %u.%u.%u", &major, &minor, &patch)) | ||||
|       goto calculate_version; | ||||
|  | ||||
|   if (3 != sscanf(u.release, "%u.%u.%u", &major, &minor, &patch)) | ||||
|     return 0; | ||||
|  | ||||
|   /* Handle it when the process runs under the UNAME26 personality: | ||||
|    * | ||||
|    * - kernels >= 3.x identify as 2.6.40+x | ||||
|    * - kernels >= 4.x identify as 2.6.60+x | ||||
|    * | ||||
|    * UNAME26 is a poorly conceived hack that doesn't let us distinguish | ||||
|    * between 4.x kernels and 5.x/6.x kernels so we conservatively assume | ||||
|    * that 2.6.60+x means 4.x. | ||||
|    * | ||||
|    * Fun fact of the day: it's technically possible to observe the actual | ||||
|    * kernel version for a brief moment because uname() first copies out the | ||||
|    * real release string before overwriting it with the backcompat string. | ||||
|    */ | ||||
|   if (major == 2 && minor == 6) { | ||||
|     if (patch >= 60) { | ||||
|       major = 4; | ||||
|       minor = patch - 60; | ||||
|       patch = 0; | ||||
|     } else if (patch >= 40) { | ||||
|       major = 3; | ||||
|       minor = patch - 40; | ||||
|       patch = 0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| calculate_version: | ||||
|   version = major * 65536 + minor * 256 + patch; | ||||
|   atomic_store_explicit(&cached_version, version, memory_order_relaxed); | ||||
|  | ||||
| @@ -422,6 +475,9 @@ int uv__io_uring_register(int fd, unsigned opcode, void* arg, unsigned nargs) { | ||||
| static int uv__use_io_uring(void) { | ||||
| #if defined(__ANDROID_API__) | ||||
|   return 0;  /* Possibly available but blocked by seccomp. */ | ||||
| #elif defined(__arm__) && __SIZEOF_POINTER__ == 4 | ||||
|   /* See https://github.com/libuv/libuv/issues/4158. */ | ||||
|   return 0;  /* All 32 bits kernels appear buggy. */ | ||||
| #else | ||||
|   /* Ternary: unknown=0, yes=1, no=-1 */ | ||||
|   static _Atomic int use_io_uring; | ||||
| @@ -431,8 +487,14 @@ static int uv__use_io_uring(void) { | ||||
|   use = atomic_load_explicit(&use_io_uring, memory_order_relaxed); | ||||
|  | ||||
|   if (use == 0) { | ||||
|     /* Older kernels have a bug where the sqpoll thread uses 100% CPU. */ | ||||
|     use = uv__kernel_version() >= /* 5.10.186 */ 0x050ABA ? 1 : -1; | ||||
|  | ||||
|     /* But users can still enable it if they so desire. */ | ||||
|     val = getenv("UV_USE_IO_URING"); | ||||
|     use = val == NULL || atoi(val) ? 1 : -1; | ||||
|     if (val != NULL) | ||||
|       use = atoi(val) ? 1 : -1; | ||||
|  | ||||
|     atomic_store_explicit(&use_io_uring, use, memory_order_relaxed); | ||||
|   } | ||||
|  | ||||
| @@ -756,7 +818,9 @@ static void uv__iou_submit(struct uv__iou* iou) { | ||||
| int uv__iou_fs_close(uv_loop_t* loop, uv_fs_t* req) { | ||||
|   struct uv__io_uring_sqe* sqe; | ||||
|   struct uv__iou* iou; | ||||
|   int kv; | ||||
|  | ||||
|   kv = uv__kernel_version(); | ||||
|   /* Work around a poorly understood bug in older kernels where closing a file | ||||
|    * descriptor pointing to /foo/bar results in ETXTBSY errors when trying to | ||||
|    * execve("/foo/bar") later on. The bug seems to have been fixed somewhere | ||||
| @@ -764,10 +828,17 @@ int uv__iou_fs_close(uv_loop_t* loop, uv_fs_t* req) { | ||||
|    * but good candidates are the several data race fixes. Interestingly, it | ||||
|    * seems to manifest only when running under Docker so the possibility of | ||||
|    * a Docker bug can't be completely ruled out either. Yay, computers. | ||||
|    * Also, disable on non-longterm versions between 5.16.0 (non-longterm) and | ||||
|    * 6.1.0 (longterm). Starting with longterm 6.1.x, the issue seems to be | ||||
|    * solved. | ||||
|    */ | ||||
|   if (uv__kernel_version() < /* 5.15.90 */ 0x050F5A) | ||||
|   if (kv < /* 5.15.90 */ 0x050F5A) | ||||
|     return 0; | ||||
|  | ||||
|   if (kv >= /* 5.16.0 */ 0x050A00 && kv < /* 6.1.0 */ 0x060100) | ||||
|     return 0; | ||||
|  | ||||
|  | ||||
|   iou = &uv__get_internal_fields(loop)->iou; | ||||
|  | ||||
|   sqe = uv__iou_get_sqe(iou, loop, req); | ||||
| @@ -1364,41 +1435,20 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { | ||||
|      */ | ||||
|     SAVE_ERRNO(uv__update_time(loop)); | ||||
|  | ||||
|     if (nfds == 0) { | ||||
|     if (nfds == -1) | ||||
|       assert(errno == EINTR); | ||||
|     else if (nfds == 0) | ||||
|       /* Unlimited timeout should only return with events or signal. */ | ||||
|       assert(timeout != -1); | ||||
|  | ||||
|     if (nfds == 0 || nfds == -1) { | ||||
|       if (reset_timeout != 0) { | ||||
|         timeout = user_timeout; | ||||
|         reset_timeout = 0; | ||||
|       } else if (nfds == 0) { | ||||
|         return; | ||||
|       } | ||||
|  | ||||
|       if (timeout == -1) | ||||
|         continue; | ||||
|  | ||||
|       if (timeout == 0) | ||||
|         break; | ||||
|  | ||||
|       /* We may have been inside the system call for longer than |timeout| | ||||
|        * milliseconds so we need to update the timestamp to avoid drift. | ||||
|        */ | ||||
|       goto update_timeout; | ||||
|     } | ||||
|  | ||||
|     if (nfds == -1) { | ||||
|       if (errno != EINTR) | ||||
|         abort(); | ||||
|  | ||||
|       if (reset_timeout != 0) { | ||||
|         timeout = user_timeout; | ||||
|         reset_timeout = 0; | ||||
|       } | ||||
|  | ||||
|       if (timeout == -1) | ||||
|         continue; | ||||
|  | ||||
|       if (timeout == 0) | ||||
|         break; | ||||
|  | ||||
|       /* Interrupted by a signal. Update timeout and poll again. */ | ||||
|       goto update_timeout; | ||||
|     } | ||||
| @@ -1509,13 +1559,13 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { | ||||
|       break; | ||||
|     } | ||||
|  | ||||
| update_timeout: | ||||
|     if (timeout == 0) | ||||
|       break; | ||||
|  | ||||
|     if (timeout == -1) | ||||
|       continue; | ||||
|  | ||||
| update_timeout: | ||||
|     assert(timeout > 0); | ||||
|  | ||||
|     real_timeout -= (loop->time - base); | ||||
| @@ -1718,7 +1768,8 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) { | ||||
|     return UV__ERR(errno); | ||||
|   } | ||||
|  | ||||
|   fgets(buf, sizeof(buf), fp);  /* Skip first line. */ | ||||
|   if (NULL == fgets(buf, sizeof(buf), fp)) | ||||
|     abort(); | ||||
|  | ||||
|   for (;;) { | ||||
|     memset(&t, 0, sizeof(t)); | ||||
| @@ -1729,7 +1780,8 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) { | ||||
|     if (n != 7) | ||||
|       break; | ||||
|  | ||||
|     fgets(buf, sizeof(buf), fp);  /* Skip rest of line. */ | ||||
|     if (NULL == fgets(buf, sizeof(buf), fp)) | ||||
|       abort(); | ||||
|  | ||||
|     if (cpu >= ARRAY_SIZE(*cpus)) | ||||
|       continue; | ||||
| @@ -1809,7 +1861,8 @@ nocpuinfo: | ||||
|     if (fp == NULL) | ||||
|       continue; | ||||
|  | ||||
|     fscanf(fp, "%llu", &(*cpus)[cpu].freq); | ||||
|     if (1 != fscanf(fp, "%llu", &(*cpus)[cpu].freq)) | ||||
|       abort(); | ||||
|     fclose(fp); | ||||
|     fp = NULL; | ||||
|   } | ||||
|   | ||||
							
								
								
									
										14
									
								
								deps/libuv/src/unix/os390.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								deps/libuv/src/unix/os390.c
									
									
									
									
										vendored
									
									
								
							| @@ -19,6 +19,7 @@ | ||||
|  * IN THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #include "uv.h" | ||||
| #include "internal.h" | ||||
| #include <sys/ioctl.h> | ||||
| #include <net/if.h> | ||||
| @@ -30,6 +31,7 @@ | ||||
| #include <sys/msg.h> | ||||
| #include <sys/resource.h> | ||||
| #include "zos-base.h" | ||||
| #include "zos-sys-info.h" | ||||
| #if defined(__clang__) | ||||
| #include "csrsic.h" | ||||
| #else | ||||
| @@ -66,9 +68,6 @@ | ||||
| /* Total number of frames currently on all available frame queues. */ | ||||
| #define RCEAFC_OFFSET     0x088 | ||||
|  | ||||
| /* CPC model length from the CSRSI Service. */ | ||||
| #define CPCMODEL_LENGTH   16 | ||||
|  | ||||
| /* Pointer to the home (current) ASCB. */ | ||||
| #define PSAAOLD           0x224 | ||||
|  | ||||
| @@ -258,9 +257,12 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { | ||||
|   idx = 0; | ||||
|   while (idx < *count) { | ||||
|     cpu_info->speed = *(int*)(info.siv1v2si22v1.si22v1cpucapability); | ||||
|     cpu_info->model = uv__malloc(CPCMODEL_LENGTH + 1); | ||||
|     memset(cpu_info->model, '\0', CPCMODEL_LENGTH + 1); | ||||
|     memcpy(cpu_info->model, info.siv1v2si11v1.si11v1cpcmodel, CPCMODEL_LENGTH); | ||||
|     cpu_info->model = uv__malloc(ZOSCPU_MODEL_LENGTH + 1); | ||||
|     if (cpu_info->model == NULL) { | ||||
|       uv_free_cpu_info(*cpu_infos, idx); | ||||
|       return UV_ENOMEM;  | ||||
|     } | ||||
|     __get_cpu_model(cpu_info->model, ZOSCPU_MODEL_LENGTH + 1); | ||||
|     cpu_info->cpu_times.user = cpu_usage_avg; | ||||
|     /* TODO: implement the following */ | ||||
|     cpu_info->cpu_times.sys = 0; | ||||
|   | ||||
							
								
								
									
										15
									
								
								deps/libuv/src/unix/signal.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								deps/libuv/src/unix/signal.c
									
									
									
									
										vendored
									
									
								
							| @@ -279,6 +279,8 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) { | ||||
|  | ||||
|  | ||||
| int uv__signal_loop_fork(uv_loop_t* loop) { | ||||
|   struct uv__queue* q; | ||||
|  | ||||
|   if (loop->signal_pipefd[0] == -1) | ||||
|     return 0; | ||||
|   uv__io_stop(loop, &loop->signal_io_watcher, POLLIN); | ||||
| @@ -286,6 +288,19 @@ int uv__signal_loop_fork(uv_loop_t* loop) { | ||||
|   uv__close(loop->signal_pipefd[1]); | ||||
|   loop->signal_pipefd[0] = -1; | ||||
|   loop->signal_pipefd[1] = -1; | ||||
|  | ||||
|   uv__queue_foreach(q, &loop->handle_queue) { | ||||
|     uv_handle_t* handle = uv__queue_data(q, uv_handle_t, handle_queue); | ||||
|     uv_signal_t* sh; | ||||
|  | ||||
|     if (handle->type != UV_SIGNAL) | ||||
|       continue; | ||||
|  | ||||
|     sh = (uv_signal_t*) handle; | ||||
|     sh->caught_signals = 0; | ||||
|     sh->dispatched_signals = 0; | ||||
|   } | ||||
|  | ||||
|   return uv__signal_loop_once_init(loop); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										101
									
								
								deps/libuv/src/unix/tcp.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										101
									
								
								deps/libuv/src/unix/tcp.c
									
									
									
									
										vendored
									
									
								
							| @@ -27,6 +27,17 @@ | ||||
| #include <assert.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
|  | ||||
| #if defined(__PASE__) | ||||
| #include <as400_protos.h> | ||||
| #define ifaddrs ifaddrs_pase | ||||
| #define getifaddrs Qp2getifaddrs | ||||
| #define freeifaddrs Qp2freeifaddrs | ||||
| #else | ||||
| #include <ifaddrs.h> | ||||
| #endif | ||||
|  | ||||
| static int maybe_bind_socket(int fd) { | ||||
|   union uv__sockaddr s; | ||||
| @@ -198,11 +209,50 @@ int uv__tcp_bind(uv_tcp_t* tcp, | ||||
| } | ||||
|  | ||||
|  | ||||
| static int uv__is_ipv6_link_local(const struct sockaddr* addr) { | ||||
|   const struct sockaddr_in6* a6; | ||||
|   uint8_t b[2]; | ||||
|  | ||||
|   if (addr->sa_family != AF_INET6) | ||||
|     return 0; | ||||
|  | ||||
|   a6 = (const struct sockaddr_in6*) addr; | ||||
|   memcpy(b, &a6->sin6_addr, sizeof(b)); | ||||
|  | ||||
|   return b[0] == 0xFE && b[1] == 0x80; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int uv__ipv6_link_local_scope_id(void) { | ||||
|   struct sockaddr_in6* a6; | ||||
|   struct ifaddrs* ifa; | ||||
|   struct ifaddrs* p; | ||||
|   int rv; | ||||
|  | ||||
|   if (getifaddrs(&ifa)) | ||||
|     return 0; | ||||
|  | ||||
|   for (p = ifa; p != NULL; p = p->ifa_next) | ||||
|     if (uv__is_ipv6_link_local(p->ifa_addr)) | ||||
|       break; | ||||
|  | ||||
|   rv = 0; | ||||
|   if (p != NULL) { | ||||
|     a6 = (struct sockaddr_in6*) p->ifa_addr; | ||||
|     rv = a6->sin6_scope_id; | ||||
|   } | ||||
|  | ||||
|   freeifaddrs(ifa); | ||||
|   return rv; | ||||
| } | ||||
|  | ||||
|  | ||||
| int uv__tcp_connect(uv_connect_t* req, | ||||
|                     uv_tcp_t* handle, | ||||
|                     const struct sockaddr* addr, | ||||
|                     unsigned int addrlen, | ||||
|                     uv_connect_cb cb) { | ||||
|   struct sockaddr_in6 tmp6; | ||||
|   int err; | ||||
|   int r; | ||||
|  | ||||
| @@ -220,6 +270,14 @@ int uv__tcp_connect(uv_connect_t* req, | ||||
|   if (err) | ||||
|     return err; | ||||
|  | ||||
|   if (uv__is_ipv6_link_local(addr)) { | ||||
|     memcpy(&tmp6, addr, sizeof(tmp6)); | ||||
|     if (tmp6.sin6_scope_id == 0) { | ||||
|       tmp6.sin6_scope_id = uv__ipv6_link_local_scope_id(); | ||||
|       addr = (void*) &tmp6; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   do { | ||||
|     errno = 0; | ||||
|     r = connect(uv__stream_fd(handle), addr, addrlen); | ||||
| @@ -374,28 +432,39 @@ int uv__tcp_nodelay(int fd, int on) { | ||||
|  | ||||
|  | ||||
| int uv__tcp_keepalive(int fd, int on, unsigned int delay) { | ||||
|   int intvl; | ||||
|   int cnt; | ||||
|  | ||||
|   (void) &intvl; | ||||
|   (void) &cnt; | ||||
|      | ||||
|   if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) | ||||
|     return UV__ERR(errno); | ||||
|  | ||||
|   if (!on) | ||||
|     return 0; | ||||
|  | ||||
| #ifdef TCP_KEEPIDLE | ||||
|   if (on) { | ||||
|     int intvl = 1;  /*  1 second; same as default on Win32 */ | ||||
|     int cnt = 10;  /* 10 retries; same as hardcoded on Win32 */ | ||||
|     if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) | ||||
|       return UV__ERR(errno); | ||||
|     if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) | ||||
|       return UV__ERR(errno); | ||||
|     if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt))) | ||||
|       return UV__ERR(errno); | ||||
|   } | ||||
|   if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) | ||||
|     return UV__ERR(errno); | ||||
| /* Solaris/SmartOS, if you don't support keep-alive, | ||||
|  * then don't advertise it in your system headers... | ||||
|  */ | ||||
| /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */ | ||||
| #elif defined(TCP_KEEPALIVE) && !defined(__sun) | ||||
|   if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay))) | ||||
|     return UV__ERR(errno); | ||||
| #endif | ||||
|  | ||||
|   /* Solaris/SmartOS, if you don't support keep-alive, | ||||
|    * then don't advertise it in your system headers... | ||||
|    */ | ||||
|   /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */ | ||||
| #if defined(TCP_KEEPALIVE) && !defined(__sun) | ||||
|   if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay))) | ||||
| #ifdef TCP_KEEPINTVL | ||||
|   intvl = 1;  /*  1 second; same as default on Win32 */ | ||||
|   if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) | ||||
|     return UV__ERR(errno); | ||||
| #endif | ||||
|  | ||||
| #ifdef TCP_KEEPCNT | ||||
|   cnt = 10;  /* 10 retries; same as hardcoded on Win32 */ | ||||
|   if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt))) | ||||
|     return UV__ERR(errno); | ||||
| #endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										22
									
								
								deps/libuv/src/unix/thread.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								deps/libuv/src/unix/thread.c
									
									
									
									
										vendored
									
									
								
							| @@ -789,11 +789,33 @@ void uv_cond_broadcast(uv_cond_t* cond) { | ||||
|     abort(); | ||||
| } | ||||
|  | ||||
| #if defined(__APPLE__) && defined(__MACH__) | ||||
|  | ||||
| void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { | ||||
|   int r; | ||||
|  | ||||
|   errno = 0; | ||||
|   r = pthread_cond_wait(cond, mutex); | ||||
|  | ||||
|   /* Workaround for a bug in OS X at least up to 13.6 | ||||
|    * See https://github.com/libuv/libuv/issues/4165 | ||||
|    */ | ||||
|   if (r == EINVAL) | ||||
|     if (errno == EBUSY) | ||||
|       return; | ||||
|  | ||||
|   if (r) | ||||
|     abort(); | ||||
| } | ||||
|  | ||||
| #else /* !(defined(__APPLE__) && defined(__MACH__)) */ | ||||
|  | ||||
| void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { | ||||
|   if (pthread_cond_wait(cond, mutex)) | ||||
|     abort(); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) { | ||||
|   int r; | ||||
|   | ||||
							
								
								
									
										3
									
								
								deps/libuv/src/uv-common.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								deps/libuv/src/uv-common.c
									
									
									
									
										vendored
									
									
								
							| @@ -559,6 +559,9 @@ static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) { | ||||
|   if (loop == NULL) | ||||
|     loop = uv_default_loop(); | ||||
|  | ||||
|   if (stream == NULL) | ||||
|     stream = stderr; | ||||
|  | ||||
|   uv__queue_foreach(q, &loop->handle_queue) { | ||||
|     h = uv__queue_data(q, uv_handle_t, handle_queue); | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								deps/libuv/src/win/dl.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								deps/libuv/src/win/dl.c
									
									
									
									
										vendored
									
									
								
							| @@ -27,18 +27,17 @@ static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno); | ||||
|  | ||||
| int uv_dlopen(const char* filename, uv_lib_t* lib) { | ||||
|   WCHAR filename_w[32768]; | ||||
|   ssize_t r; | ||||
|  | ||||
|   lib->handle = NULL; | ||||
|   lib->errmsg = NULL; | ||||
|  | ||||
|   if (!MultiByteToWideChar(CP_UTF8, | ||||
|                            0, | ||||
|                            filename, | ||||
|                            -1, | ||||
|                            filename_w, | ||||
|                            ARRAY_SIZE(filename_w))) { | ||||
|     return uv__dlerror(lib, filename, GetLastError()); | ||||
|   } | ||||
|   r = uv_wtf8_length_as_utf16(filename); | ||||
|   if (r < 0) | ||||
|     return uv__dlerror(lib, filename, ERROR_NO_UNICODE_TRANSLATION); | ||||
|   if ((size_t) r > ARRAY_SIZE(filename_w)) | ||||
|     return uv__dlerror(lib, filename, ERROR_INSUFFICIENT_BUFFER); | ||||
|   uv_wtf8_to_utf16(filename, filename_w, r); | ||||
|  | ||||
|   lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | ||||
|   if (lib->handle == NULL) { | ||||
|   | ||||
							
								
								
									
										28
									
								
								deps/libuv/src/win/fs-event.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								deps/libuv/src/win/fs-event.c
									
									
									
									
										vendored
									
									
								
							| @@ -157,7 +157,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, | ||||
|                       uv_fs_event_cb cb, | ||||
|                       const char* path, | ||||
|                       unsigned int flags) { | ||||
|   int name_size, is_path_dir, size; | ||||
|   int is_path_dir; | ||||
|   size_t size; | ||||
|   DWORD attr, last_error; | ||||
|   WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; | ||||
|   DWORD short_path_buffer_len; | ||||
| @@ -176,23 +177,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, | ||||
|  | ||||
|   uv__handle_start(handle); | ||||
|  | ||||
|   /* Convert name to UTF16. */ | ||||
|  | ||||
|   name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) * | ||||
|               sizeof(WCHAR); | ||||
|   pathw = (WCHAR*)uv__malloc(name_size); | ||||
|   if (!pathw) { | ||||
|     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); | ||||
|   } | ||||
|  | ||||
|   if (!MultiByteToWideChar(CP_UTF8, | ||||
|                            0, | ||||
|                            path, | ||||
|                            -1, | ||||
|                            pathw, | ||||
|                            name_size / sizeof(WCHAR))) { | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } | ||||
|   last_error = uv__convert_utf8_to_utf16(path, &pathw); | ||||
|   if (last_error) | ||||
|     goto error_uv; | ||||
|  | ||||
|   /* Determine whether path is a file or a directory. */ | ||||
|   attr = GetFileAttributesW(pathw); | ||||
| @@ -333,6 +320,9 @@ short_path_done: | ||||
|   return 0; | ||||
|  | ||||
| error: | ||||
|   last_error = uv_translate_sys_error(last_error); | ||||
|  | ||||
| error_uv: | ||||
|   if (handle->path) { | ||||
|     uv__free(handle->path); | ||||
|     handle->path = NULL; | ||||
| @@ -365,7 +355,7 @@ error: | ||||
|  | ||||
|   uv__free(short_path); | ||||
|  | ||||
|   return uv_translate_sys_error(last_error); | ||||
|   return last_error; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										381
									
								
								deps/libuv/src/win/fs.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										381
									
								
								deps/libuv/src/win/fs.c
									
									
									
									
										vendored
									
									
								
							| @@ -31,13 +31,16 @@ | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include "uv.h" | ||||
|  | ||||
| /* <winioctl.h> requires <windows.h>, included via "uv.h" above, but needs to | ||||
|    be included before our "winapi.h", included via "internal.h" below. */ | ||||
| #include <winioctl.h> | ||||
|  | ||||
| #include "internal.h" | ||||
| #include "req-inl.h" | ||||
| #include "handle-inl.h" | ||||
| #include "fs-fd-hash-inl.h" | ||||
|  | ||||
| #include <winioctl.h> | ||||
|  | ||||
|  | ||||
| #define UV_FS_FREE_PATHS         0x0002 | ||||
| #define UV_FS_FREE_PTR           0x0008 | ||||
| @@ -144,279 +147,6 @@ void uv__fs_init(void) { | ||||
| } | ||||
|  | ||||
|  | ||||
| static int32_t fs__decode_wtf8_char(const char** input) { | ||||
|   uint32_t code_point; | ||||
|   uint8_t b1; | ||||
|   uint8_t b2; | ||||
|   uint8_t b3; | ||||
|   uint8_t b4; | ||||
|  | ||||
|   b1 = **input; | ||||
|   if (b1 <= 0x7F) | ||||
|     return b1; /* ASCII code point */ | ||||
|   if (b1 < 0xC2) | ||||
|     return -1; /* invalid: continuation byte */ | ||||
|   code_point = b1; | ||||
|  | ||||
|   b2 = *++*input; | ||||
|   if ((b2 & 0xC0) != 0x80) | ||||
|     return -1; /* invalid: not a continuation byte */ | ||||
|   code_point = (code_point << 6) | (b2 & 0x3F); | ||||
|   if (b1 <= 0xDF) | ||||
|     return 0x7FF & code_point; /* two-byte character */ | ||||
|  | ||||
|   b3 = *++*input; | ||||
|   if ((b3 & 0xC0) != 0x80) | ||||
|     return -1; /* invalid: not a continuation byte */ | ||||
|   code_point = (code_point << 6) | (b3 & 0x3F); | ||||
|   if (b1 <= 0xEF) | ||||
|     return 0xFFFF & code_point; /* three-byte character */ | ||||
|  | ||||
|   b4 = *++*input; | ||||
|   if ((b4 & 0xC0) != 0x80) | ||||
|     return -1; /* invalid: not a continuation byte */ | ||||
|   code_point = (code_point << 6) | (b4 & 0x3F); | ||||
|   if (b1 <= 0xF4) | ||||
|     if (code_point <= 0x10FFFF) | ||||
|       return code_point; /* four-byte character */ | ||||
|  | ||||
|   /* code point too large */ | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| static ssize_t fs__get_length_wtf8(const char* source_ptr) { | ||||
|   size_t w_target_len = 0; | ||||
|   int32_t code_point; | ||||
|  | ||||
|   do { | ||||
|     code_point = fs__decode_wtf8_char(&source_ptr); | ||||
|     if (code_point < 0) | ||||
|       return -1; | ||||
|     if (code_point > 0xFFFF) | ||||
|       w_target_len++; | ||||
|     w_target_len++; | ||||
|   } while (*source_ptr++); | ||||
|   return w_target_len; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void fs__wtf8_to_wide(const char* source_ptr, WCHAR* w_target) { | ||||
|   int32_t code_point; | ||||
|  | ||||
|   do { | ||||
|     code_point = fs__decode_wtf8_char(&source_ptr); | ||||
|     /* fs__get_length_wtf8 should have been called and checked first. */ | ||||
|     assert(code_point >= 0); | ||||
|     if (code_point > 0x10000) { | ||||
|       assert(code_point < 0x10FFFF); | ||||
|       *w_target++ = (((code_point - 0x10000) >> 10) + 0xD800); | ||||
|       *w_target++ = ((code_point - 0x10000) & 0x3FF) + 0xDC00; | ||||
|     } else { | ||||
|       *w_target++ = code_point; | ||||
|     } | ||||
|   } while (*source_ptr++); | ||||
| } | ||||
|  | ||||
|  | ||||
| INLINE static int fs__capture_path(uv_fs_t* req, const char* path, | ||||
|     const char* new_path, const int copy_path) { | ||||
|   WCHAR* buf; | ||||
|   WCHAR* pos; | ||||
|   size_t buf_sz = 0; | ||||
|   size_t path_len = 0; | ||||
|   ssize_t pathw_len = 0; | ||||
|   ssize_t new_pathw_len = 0; | ||||
|  | ||||
|   /* new_path can only be set if path is also set. */ | ||||
|   assert(new_path == NULL || path != NULL); | ||||
|  | ||||
|   if (path != NULL) { | ||||
|     pathw_len = fs__get_length_wtf8(path); | ||||
|     if (pathw_len < 0) | ||||
|       return ERROR_INVALID_NAME; | ||||
|     buf_sz += pathw_len * sizeof(WCHAR); | ||||
|   } | ||||
|  | ||||
|   if (path != NULL && copy_path) { | ||||
|     path_len = 1 + strlen(path); | ||||
|     buf_sz += path_len; | ||||
|   } | ||||
|  | ||||
|   if (new_path != NULL) { | ||||
|     new_pathw_len = fs__get_length_wtf8(new_path); | ||||
|     if (new_pathw_len < 0) | ||||
|       return ERROR_INVALID_NAME; | ||||
|     buf_sz += new_pathw_len * sizeof(WCHAR); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   if (buf_sz == 0) { | ||||
|     req->file.pathw = NULL; | ||||
|     req->fs.info.new_pathw = NULL; | ||||
|     req->path = NULL; | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   buf = uv__malloc(buf_sz); | ||||
|   if (buf == NULL) { | ||||
|     return ERROR_OUTOFMEMORY; | ||||
|   } | ||||
|  | ||||
|   pos = buf; | ||||
|  | ||||
|   if (path != NULL) { | ||||
|     fs__wtf8_to_wide(path, pos); | ||||
|     req->file.pathw = pos; | ||||
|     pos += pathw_len; | ||||
|   } else { | ||||
|     req->file.pathw = NULL; | ||||
|   } | ||||
|  | ||||
|   if (new_path != NULL) { | ||||
|     fs__wtf8_to_wide(new_path, pos); | ||||
|     req->fs.info.new_pathw = pos; | ||||
|     pos += new_pathw_len; | ||||
|   } else { | ||||
|     req->fs.info.new_pathw = NULL; | ||||
|   } | ||||
|  | ||||
|   req->path = path; | ||||
|   if (path != NULL && copy_path) { | ||||
|     memcpy(pos, path, path_len); | ||||
|     assert(path_len == buf_sz - (pos - buf) * sizeof(WCHAR)); | ||||
|     req->path = (char*) pos; | ||||
|   } | ||||
|  | ||||
|   req->flags |= UV_FS_FREE_PATHS; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| INLINE static void uv__fs_req_init(uv_loop_t* loop, uv_fs_t* req, | ||||
|     uv_fs_type fs_type, const uv_fs_cb cb) { | ||||
|   uv__once_init(); | ||||
|   UV_REQ_INIT(req, UV_FS); | ||||
|   req->loop = loop; | ||||
|   req->flags = 0; | ||||
|   req->fs_type = fs_type; | ||||
|   req->sys_errno_ = 0; | ||||
|   req->result = 0; | ||||
|   req->ptr = NULL; | ||||
|   req->path = NULL; | ||||
|   req->cb = cb; | ||||
|   memset(&req->fs, 0, sizeof(req->fs)); | ||||
| } | ||||
|  | ||||
|  | ||||
| static int32_t fs__get_surrogate_value(const WCHAR* w_source_ptr, | ||||
|                                        size_t w_source_len) { | ||||
|   WCHAR u; | ||||
|   WCHAR next; | ||||
|  | ||||
|   u = w_source_ptr[0]; | ||||
|   if (u >= 0xD800 && u <= 0xDBFF && w_source_len > 1) { | ||||
|     next = w_source_ptr[1]; | ||||
|     if (next >= 0xDC00 && next <= 0xDFFF) | ||||
|       return 0x10000 + ((u - 0xD800) << 10) + (next - 0xDC00); | ||||
|   } | ||||
|   return u; | ||||
| } | ||||
|  | ||||
|  | ||||
| static size_t fs__get_length_wide(const WCHAR* w_source_ptr, | ||||
|                                   size_t w_source_len) { | ||||
|   size_t target_len; | ||||
|   int32_t code_point; | ||||
|  | ||||
|   target_len = 0; | ||||
|   for (; w_source_len; w_source_len--, w_source_ptr++) { | ||||
|     code_point = fs__get_surrogate_value(w_source_ptr, w_source_len); | ||||
|     /* Can be invalid UTF-8 but must be valid WTF-8. */ | ||||
|     assert(code_point >= 0); | ||||
|     if (code_point < 0x80) | ||||
|       target_len += 1; | ||||
|     else if (code_point < 0x800) | ||||
|       target_len += 2; | ||||
|     else if (code_point < 0x10000) | ||||
|       target_len += 3; | ||||
|     else { | ||||
|       target_len += 4; | ||||
|       w_source_ptr++; | ||||
|       w_source_len--; | ||||
|     } | ||||
|   } | ||||
|   return target_len; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int fs__wide_to_wtf8(WCHAR* w_source_ptr, | ||||
|                             size_t w_source_len, | ||||
|                             char** target_ptr, | ||||
|                             size_t* target_len_ptr) { | ||||
|   size_t target_len; | ||||
|   char* target; | ||||
|   int32_t code_point; | ||||
|  | ||||
|   /* If *target_ptr is provided, then *target_len_ptr must be its length | ||||
|    * (excluding space for null), otherwise we will compute the target_len_ptr | ||||
|    * length and may return a new allocation in *target_ptr if target_ptr is | ||||
|    * provided. */ | ||||
|   if (target_ptr == NULL || *target_ptr == NULL) { | ||||
|     target_len = fs__get_length_wide(w_source_ptr, w_source_len); | ||||
|     if (target_len_ptr != NULL) | ||||
|       *target_len_ptr = target_len; | ||||
|   } else { | ||||
|     target_len = *target_len_ptr; | ||||
|   } | ||||
|  | ||||
|   if (target_ptr == NULL) | ||||
|     return 0; | ||||
|  | ||||
|   if (*target_ptr == NULL) { | ||||
|     target = uv__malloc(target_len + 1); | ||||
|     if (target == NULL) { | ||||
|       SetLastError(ERROR_OUTOFMEMORY); | ||||
|       return -1; | ||||
|     } | ||||
|     *target_ptr = target; | ||||
|   } else { | ||||
|     target = *target_ptr; | ||||
|   } | ||||
|  | ||||
|   for (; w_source_len; w_source_len--, w_source_ptr++) { | ||||
|     code_point = fs__get_surrogate_value(w_source_ptr, w_source_len); | ||||
|     /* Can be invalid UTF-8 but must be valid WTF-8. */ | ||||
|     assert(code_point >= 0); | ||||
|  | ||||
|     if (code_point < 0x80) { | ||||
|       *target++ = code_point; | ||||
|     } else if (code_point < 0x800) { | ||||
|       *target++ = 0xC0 | (code_point >> 6); | ||||
|       *target++ = 0x80 | (code_point & 0x3F); | ||||
|     } else if (code_point < 0x10000) { | ||||
|       *target++ = 0xE0 | (code_point >> 12); | ||||
|       *target++ = 0x80 | ((code_point >> 6) & 0x3F); | ||||
|       *target++ = 0x80 | (code_point & 0x3F); | ||||
|     } else { | ||||
|       *target++ = 0xF0 | (code_point >> 18); | ||||
|       *target++ = 0x80 | ((code_point >> 12) & 0x3F); | ||||
|       *target++ = 0x80 | ((code_point >> 6) & 0x3F); | ||||
|       *target++ = 0x80 | (code_point & 0x3F); | ||||
|       w_source_ptr++; | ||||
|       w_source_len--; | ||||
|     } | ||||
|   } | ||||
|   assert((size_t) (target - *target_ptr) == target_len); | ||||
|  | ||||
|   *target++ = '\0'; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| INLINE static int fs__readlink_handle(HANDLE handle, | ||||
|                                       char** target_ptr, | ||||
|                                       size_t* target_len_ptr) { | ||||
| @@ -550,7 +280,98 @@ INLINE static int fs__readlink_handle(HANDLE handle, | ||||
|   } | ||||
|  | ||||
|   assert(target_ptr == NULL || *target_ptr == NULL); | ||||
|   return fs__wide_to_wtf8(w_target, w_target_len, target_ptr, target_len_ptr); | ||||
|   return uv_utf16_to_wtf8(w_target, w_target_len, target_ptr, target_len_ptr); | ||||
| } | ||||
|  | ||||
|  | ||||
| INLINE static int fs__capture_path(uv_fs_t* req, const char* path, | ||||
|     const char* new_path, const int copy_path) { | ||||
|   WCHAR* buf; | ||||
|   WCHAR* pos; | ||||
|   size_t buf_sz = 0; | ||||
|   size_t path_len = 0; | ||||
|   ssize_t pathw_len = 0; | ||||
|   ssize_t new_pathw_len = 0; | ||||
|  | ||||
|   /* new_path can only be set if path is also set. */ | ||||
|   assert(new_path == NULL || path != NULL); | ||||
|  | ||||
|   if (path != NULL) { | ||||
|     pathw_len = uv_wtf8_length_as_utf16(path); | ||||
|     if (pathw_len < 0) | ||||
|       return ERROR_INVALID_NAME; | ||||
|     buf_sz += pathw_len * sizeof(WCHAR); | ||||
|   } | ||||
|  | ||||
|   if (path != NULL && copy_path) { | ||||
|     path_len = 1 + strlen(path); | ||||
|     buf_sz += path_len; | ||||
|   } | ||||
|  | ||||
|   if (new_path != NULL) { | ||||
|     new_pathw_len = uv_wtf8_length_as_utf16(new_path); | ||||
|     if (new_pathw_len < 0) | ||||
|       return ERROR_INVALID_NAME; | ||||
|     buf_sz += new_pathw_len * sizeof(WCHAR); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   if (buf_sz == 0) { | ||||
|     req->file.pathw = NULL; | ||||
|     req->fs.info.new_pathw = NULL; | ||||
|     req->path = NULL; | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   buf = uv__malloc(buf_sz); | ||||
|   if (buf == NULL) { | ||||
|     return ERROR_OUTOFMEMORY; | ||||
|   } | ||||
|  | ||||
|   pos = buf; | ||||
|  | ||||
|   if (path != NULL) { | ||||
|     uv_wtf8_to_utf16(path, pos, pathw_len); | ||||
|     req->file.pathw = pos; | ||||
|     pos += pathw_len; | ||||
|   } else { | ||||
|     req->file.pathw = NULL; | ||||
|   } | ||||
|  | ||||
|   if (new_path != NULL) { | ||||
|     uv_wtf8_to_utf16(new_path, pos, new_pathw_len); | ||||
|     req->fs.info.new_pathw = pos; | ||||
|     pos += new_pathw_len; | ||||
|   } else { | ||||
|     req->fs.info.new_pathw = NULL; | ||||
|   } | ||||
|  | ||||
|   req->path = path; | ||||
|   if (path != NULL && copy_path) { | ||||
|     memcpy(pos, path, path_len); | ||||
|     assert(path_len == buf_sz - (pos - buf) * sizeof(WCHAR)); | ||||
|     req->path = (char*) pos; | ||||
|   } | ||||
|  | ||||
|   req->flags |= UV_FS_FREE_PATHS; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| INLINE static void uv__fs_req_init(uv_loop_t* loop, uv_fs_t* req, | ||||
|     uv_fs_type fs_type, const uv_fs_cb cb) { | ||||
|   uv__once_init(); | ||||
|   UV_REQ_INIT(req, UV_FS); | ||||
|   req->loop = loop; | ||||
|   req->flags = 0; | ||||
|   req->fs_type = fs_type; | ||||
|   req->sys_errno_ = 0; | ||||
|   req->result = 0; | ||||
|   req->ptr = NULL; | ||||
|   req->path = NULL; | ||||
|   req->cb = cb; | ||||
|   memset(&req->fs, 0, sizeof(req->fs)); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1569,7 +1390,7 @@ void fs__scandir(uv_fs_t* req) { | ||||
|         continue; | ||||
|  | ||||
|       /* Compute the space required to store the filename as WTF-8. */ | ||||
|       wtf8_len = fs__get_length_wide(&info->FileName[0], wchar_len); | ||||
|       wtf8_len = uv_utf16_length_as_wtf8(&info->FileName[0], wchar_len); | ||||
|  | ||||
|       /* Resize the dirent array if needed. */ | ||||
|       if (dirents_used >= dirents_size) { | ||||
| @@ -1597,8 +1418,8 @@ void fs__scandir(uv_fs_t* req) { | ||||
|  | ||||
|       /* Convert file name to UTF-8. */ | ||||
|       wtf8 = &dirent->d_name[0]; | ||||
|       if (fs__wide_to_wtf8(&info->FileName[0], wchar_len, &wtf8, &wtf8_len) == -1) | ||||
|         goto win32_error; | ||||
|       if (uv_utf16_to_wtf8(&info->FileName[0], wchar_len, &wtf8, &wtf8_len) != 0) | ||||
|         goto out_of_memory_error; | ||||
|  | ||||
|       /* Fill out the type field. */ | ||||
|       if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE) | ||||
| @@ -2824,7 +2645,7 @@ static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { | ||||
|   } | ||||
|  | ||||
|   assert(*realpath_ptr == NULL); | ||||
|   r = fs__wide_to_wtf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL); | ||||
|   r = uv_utf16_to_wtf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL); | ||||
|   uv__free(w_realpath_buf); | ||||
|   return r; | ||||
| } | ||||
|   | ||||
							
								
								
									
										156
									
								
								deps/libuv/src/win/getaddrinfo.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										156
									
								
								deps/libuv/src/win/getaddrinfo.c
									
									
									
									
										vendored
									
									
								
							| @@ -104,13 +104,14 @@ static void uv__getaddrinfo_work(struct uv__work* w) { | ||||
|  */ | ||||
| static void uv__getaddrinfo_done(struct uv__work* w, int status) { | ||||
|   uv_getaddrinfo_t* req; | ||||
|   int addrinfo_len = 0; | ||||
|   int name_len = 0; | ||||
|   size_t addrinfo_len = 0; | ||||
|   ssize_t name_len = 0; | ||||
|   size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); | ||||
|   struct addrinfoW* addrinfow_ptr; | ||||
|   struct addrinfo* addrinfo_ptr; | ||||
|   char* alloc_ptr = NULL; | ||||
|   char* cur_ptr = NULL; | ||||
|   int r; | ||||
|  | ||||
|   req = container_of(w, uv_getaddrinfo_t, work_req); | ||||
|  | ||||
| @@ -131,19 +132,12 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { | ||||
|       addrinfo_len += addrinfo_struct_len + | ||||
|           ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); | ||||
|       if (addrinfow_ptr->ai_canonname != NULL) { | ||||
|         name_len = WideCharToMultiByte(CP_UTF8, | ||||
|                                        0, | ||||
|                                        addrinfow_ptr->ai_canonname, | ||||
|                                        -1, | ||||
|                                        NULL, | ||||
|                                        0, | ||||
|                                        NULL, | ||||
|                                        NULL); | ||||
|         if (name_len == 0) { | ||||
|           req->retcode = uv_translate_sys_error(GetLastError()); | ||||
|         name_len = uv_utf16_length_as_wtf8(addrinfow_ptr->ai_canonname, -1); | ||||
|         if (name_len < 0) { | ||||
|           req->retcode = name_len; | ||||
|           goto complete; | ||||
|         } | ||||
|         addrinfo_len += ALIGNED_SIZE(name_len); | ||||
|         addrinfo_len += ALIGNED_SIZE(name_len + 1); | ||||
|       } | ||||
|       addrinfow_ptr = addrinfow_ptr->ai_next; | ||||
|     } | ||||
| @@ -182,27 +176,14 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { | ||||
|  | ||||
|         /* convert canonical name to UTF-8 */ | ||||
|         if (addrinfow_ptr->ai_canonname != NULL) { | ||||
|           name_len = WideCharToMultiByte(CP_UTF8, | ||||
|                                          0, | ||||
|                                          addrinfow_ptr->ai_canonname, | ||||
|                                          -1, | ||||
|                                          NULL, | ||||
|                                          0, | ||||
|                                          NULL, | ||||
|                                          NULL); | ||||
|           assert(name_len > 0); | ||||
|           assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); | ||||
|           name_len = WideCharToMultiByte(CP_UTF8, | ||||
|                                          0, | ||||
|                                          addrinfow_ptr->ai_canonname, | ||||
|                                          -1, | ||||
|                                          cur_ptr, | ||||
|                                          name_len, | ||||
|                                          NULL, | ||||
|                                          NULL); | ||||
|           assert(name_len > 0); | ||||
|           name_len = alloc_ptr + addrinfo_len - cur_ptr; | ||||
|           r = uv__copy_utf16_to_utf8(addrinfow_ptr->ai_canonname, | ||||
|                                      -1, | ||||
|                                      cur_ptr, | ||||
|                                      (size_t*)&name_len); | ||||
|           assert(r == 0); | ||||
|           addrinfo_ptr->ai_canonname = cur_ptr; | ||||
|           cur_ptr += ALIGNED_SIZE(name_len); | ||||
|           cur_ptr += ALIGNED_SIZE(name_len + 1); | ||||
|         } | ||||
|         assert(cur_ptr <= alloc_ptr + addrinfo_len); | ||||
|  | ||||
| @@ -261,12 +242,11 @@ int uv_getaddrinfo(uv_loop_t* loop, | ||||
|                    const char* service, | ||||
|                    const struct addrinfo* hints) { | ||||
|   char hostname_ascii[256]; | ||||
|   int nodesize = 0; | ||||
|   int servicesize = 0; | ||||
|   int hintssize = 0; | ||||
|   size_t nodesize = 0; | ||||
|   size_t servicesize = 0; | ||||
|   size_t hintssize = 0; | ||||
|   char* alloc_ptr = NULL; | ||||
|   int err; | ||||
|   long rc; | ||||
|   ssize_t rc; | ||||
|  | ||||
|   if (req == NULL || (node == NULL && service == NULL)) { | ||||
|     return UV_EINVAL; | ||||
| @@ -286,56 +266,36 @@ int uv_getaddrinfo(uv_loop_t* loop, | ||||
|                           hostname_ascii + sizeof(hostname_ascii)); | ||||
|     if (rc < 0) | ||||
|       return rc; | ||||
|     nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, hostname_ascii, | ||||
|                                                 -1, NULL, 0) * sizeof(WCHAR)); | ||||
|     if (nodesize == 0) { | ||||
|       err = GetLastError(); | ||||
|       goto error; | ||||
|     } | ||||
|     nodesize = strlen(hostname_ascii) + 1; | ||||
|     node = hostname_ascii; | ||||
|   } | ||||
|  | ||||
|   if (service != NULL) { | ||||
|     servicesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, | ||||
|                                                    0, | ||||
|                                                    service, | ||||
|                                                    -1, | ||||
|                                                    NULL, | ||||
|                                                    0) * | ||||
|                                sizeof(WCHAR)); | ||||
|     if (servicesize == 0) { | ||||
|       err = GetLastError(); | ||||
|       goto error; | ||||
|     } | ||||
|     rc = uv_wtf8_length_as_utf16(service); | ||||
|     if (rc < 0) | ||||
|        return rc; | ||||
|     servicesize = rc; | ||||
|   } | ||||
|   if (hints != NULL) { | ||||
|     hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW)); | ||||
|   } | ||||
|  | ||||
|   /* allocate memory for inputs, and partition it as needed */ | ||||
|   alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize); | ||||
|   if (!alloc_ptr) { | ||||
|     err = WSAENOBUFS; | ||||
|     goto error; | ||||
|   } | ||||
|   alloc_ptr = uv__malloc(ALIGNED_SIZE(nodesize * sizeof(WCHAR)) + | ||||
|                          ALIGNED_SIZE(servicesize * sizeof(WCHAR)) + | ||||
|                          hintssize); | ||||
|   if (!alloc_ptr) | ||||
|     return UV_ENOMEM; | ||||
|  | ||||
|   /* save alloc_ptr now so we can free if error */ | ||||
|   req->alloc = (void*)alloc_ptr; | ||||
|   req->alloc = (void*) alloc_ptr; | ||||
|  | ||||
|   /* Convert node string to UTF16 into allocated memory and save pointer in the | ||||
|    * request. */ | ||||
|    * request. The node here has been converted to ascii. */ | ||||
|   if (node != NULL) { | ||||
|     req->node = (WCHAR*)alloc_ptr; | ||||
|     if (MultiByteToWideChar(CP_UTF8, | ||||
|                             0, | ||||
|                             node, | ||||
|                             -1, | ||||
|                             (WCHAR*) alloc_ptr, | ||||
|                             nodesize / sizeof(WCHAR)) == 0) { | ||||
|       err = GetLastError(); | ||||
|       goto error; | ||||
|     } | ||||
|     alloc_ptr += nodesize; | ||||
|     req->node = (WCHAR*) alloc_ptr; | ||||
|     uv_wtf8_to_utf16(node, (WCHAR*) alloc_ptr, nodesize); | ||||
|     alloc_ptr += ALIGNED_SIZE(nodesize * sizeof(WCHAR)); | ||||
|   } else { | ||||
|     req->node = NULL; | ||||
|   } | ||||
| @@ -343,24 +303,16 @@ int uv_getaddrinfo(uv_loop_t* loop, | ||||
|   /* Convert service string to UTF16 into allocated memory and save pointer in | ||||
|    * the req. */ | ||||
|   if (service != NULL) { | ||||
|     req->service = (WCHAR*)alloc_ptr; | ||||
|     if (MultiByteToWideChar(CP_UTF8, | ||||
|                             0, | ||||
|                             service, | ||||
|                             -1, | ||||
|                             (WCHAR*) alloc_ptr, | ||||
|                             servicesize / sizeof(WCHAR)) == 0) { | ||||
|       err = GetLastError(); | ||||
|       goto error; | ||||
|     } | ||||
|     alloc_ptr += servicesize; | ||||
|     req->service = (WCHAR*) alloc_ptr; | ||||
|     uv_wtf8_to_utf16(service, (WCHAR*) alloc_ptr, servicesize); | ||||
|     alloc_ptr += ALIGNED_SIZE(servicesize * sizeof(WCHAR)); | ||||
|   } else { | ||||
|     req->service = NULL; | ||||
|   } | ||||
|  | ||||
|   /* copy hints to allocated memory and save pointer in req */ | ||||
|   if (hints != NULL) { | ||||
|     req->addrinfow = (struct addrinfoW*)alloc_ptr; | ||||
|     req->addrinfow = (struct addrinfoW*) alloc_ptr; | ||||
|     req->addrinfow->ai_family = hints->ai_family; | ||||
|     req->addrinfow->ai_socktype = hints->ai_socktype; | ||||
|     req->addrinfow->ai_protocol = hints->ai_protocol; | ||||
| @@ -387,19 +339,11 @@ int uv_getaddrinfo(uv_loop_t* loop, | ||||
|     uv__getaddrinfo_done(&req->work_req, 0); | ||||
|     return req->retcode; | ||||
|   } | ||||
|  | ||||
| error: | ||||
|   if (req != NULL) { | ||||
|     uv__free(req->alloc); | ||||
|     req->alloc = NULL; | ||||
|   } | ||||
|   return uv_translate_sys_error(err); | ||||
| } | ||||
|  | ||||
| int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) { | ||||
|   NET_LUID luid; | ||||
|   wchar_t wname[NDIS_IF_MAX_STRING_SIZE + 1]; /* Add one for the NUL. */ | ||||
|   DWORD bufsize; | ||||
|   int r; | ||||
|  | ||||
|   if (buffer == NULL || size == NULL || *size == 0) | ||||
| @@ -415,31 +359,7 @@ int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) { | ||||
|   if (r != 0) | ||||
|     return uv_translate_sys_error(r); | ||||
|  | ||||
|   /* Check how much space we need */ | ||||
|   bufsize = WideCharToMultiByte(CP_UTF8, 0, wname, -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, | ||||
|                                 wname, | ||||
|                                 -1, | ||||
|                                 buffer, | ||||
|                                 *size, | ||||
|                                 NULL, | ||||
|                                 NULL); | ||||
|  | ||||
|   if (bufsize == 0) | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|  | ||||
|   *size = bufsize - 1; | ||||
|   return 0; | ||||
|   return uv__copy_utf16_to_utf8(wname, -1, buffer, size); | ||||
| } | ||||
|  | ||||
| int uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) { | ||||
|   | ||||
							
								
								
									
										29
									
								
								deps/libuv/src/win/getnameinfo.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								deps/libuv/src/win/getnameinfo.c
									
									
									
									
										vendored
									
									
								
							| @@ -42,6 +42,7 @@ static void uv__getnameinfo_work(struct uv__work* w) { | ||||
|   uv_getnameinfo_t* req; | ||||
|   WCHAR host[NI_MAXHOST]; | ||||
|   WCHAR service[NI_MAXSERV]; | ||||
|   size_t size; | ||||
|   int ret; | ||||
|  | ||||
|   req = container_of(w, uv_getnameinfo_t, work_req); | ||||
| @@ -57,29 +58,17 @@ static void uv__getnameinfo_work(struct uv__work* w) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   ret = WideCharToMultiByte(CP_UTF8, | ||||
|                             0, | ||||
|                             host, | ||||
|                             -1, | ||||
|                             req->host, | ||||
|                             sizeof(req->host), | ||||
|                             NULL, | ||||
|                             NULL); | ||||
|   if (ret == 0) { | ||||
|     req->retcode = uv_translate_sys_error(GetLastError()); | ||||
|   size = sizeof(req->host); | ||||
|   ret = uv__copy_utf16_to_utf8(host, -1, req->host, &size); | ||||
|   if (ret < 0) { | ||||
|     req->retcode = ret; | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   ret = WideCharToMultiByte(CP_UTF8, | ||||
|                             0, | ||||
|                             service, | ||||
|                             -1, | ||||
|                             req->service, | ||||
|                             sizeof(req->service), | ||||
|                             NULL, | ||||
|                             NULL); | ||||
|   if (ret == 0) { | ||||
|     req->retcode = uv_translate_sys_error(GetLastError()); | ||||
|   size = sizeof(req->service); | ||||
|   ret = uv__copy_utf16_to_utf8(service, -1, req->service, &size); | ||||
|   if (ret < 0) { | ||||
|     req->retcode = ret; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										5
									
								
								deps/libuv/src/win/internal.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								deps/libuv/src/win/internal.h
									
									
									
									
										vendored
									
									
								
							| @@ -257,8 +257,9 @@ void uv__util_init(void); | ||||
|  | ||||
| uint64_t uv__hrtime(unsigned int scale); | ||||
| __declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); | ||||
| int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8); | ||||
| int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16); | ||||
| int uv__convert_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char** utf8); | ||||
| int uv__copy_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char* utf8, size_t *size); | ||||
| int uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16); | ||||
|  | ||||
| typedef int (WINAPI *uv__peersockfunc)(SOCKET, struct sockaddr*, int*); | ||||
|  | ||||
|   | ||||
							
								
								
									
										146
									
								
								deps/libuv/src/win/pipe.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										146
									
								
								deps/libuv/src/win/pipe.c
									
									
									
									
										vendored
									
									
								
							| @@ -49,7 +49,7 @@ static const int default_pending_pipe_instances = 4; | ||||
|  | ||||
| /* Pipe prefix */ | ||||
| static char pipe_prefix[] = "\\\\?\\pipe"; | ||||
| static const int pipe_prefix_len = sizeof(pipe_prefix) - 1; | ||||
| static const size_t pipe_prefix_len = sizeof(pipe_prefix) - 1; | ||||
|  | ||||
| /* IPC incoming xfer queue item. */ | ||||
| typedef struct { | ||||
| @@ -703,7 +703,7 @@ int uv_pipe_bind2(uv_pipe_t* handle, | ||||
|                   size_t namelen, | ||||
|                   unsigned int flags) { | ||||
|   uv_loop_t* loop = handle->loop; | ||||
|   int i, err, nameSize; | ||||
|   int i, err; | ||||
|   uv_pipe_accept_t* req; | ||||
|  | ||||
|   if (flags & ~UV_PIPE_NO_TRUNCATE) { | ||||
| @@ -742,9 +742,8 @@ int uv_pipe_bind2(uv_pipe_t* handle, | ||||
|  | ||||
|   handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*) | ||||
|     uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances); | ||||
|   if (!handle->pipe.serv.accept_reqs) { | ||||
|     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); | ||||
|   } | ||||
|   if (!handle->pipe.serv.accept_reqs) | ||||
|     return UV_ENOMEM; | ||||
|  | ||||
|   for (i = 0; i < handle->pipe.serv.pending_instances; i++) { | ||||
|     req = &handle->pipe.serv.accept_reqs[i]; | ||||
| @@ -754,22 +753,9 @@ int uv_pipe_bind2(uv_pipe_t* handle, | ||||
|     req->next_pending = NULL; | ||||
|   } | ||||
|  | ||||
|   /* Convert name to UTF16. */ | ||||
|   nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR); | ||||
|   handle->name = uv__malloc(nameSize); | ||||
|   if (!handle->name) { | ||||
|     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); | ||||
|   } | ||||
|  | ||||
|   if (!MultiByteToWideChar(CP_UTF8, | ||||
|                            0, | ||||
|                            name, | ||||
|                            -1, | ||||
|                            handle->name, | ||||
|                            nameSize / sizeof(WCHAR))) { | ||||
|     err = GetLastError(); | ||||
|     goto error; | ||||
|   } | ||||
|   err = uv__convert_utf8_to_utf16(name, &handle->name); | ||||
|   if (err) | ||||
|     return err; | ||||
|  | ||||
|   /* | ||||
|    * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE. | ||||
| @@ -795,10 +781,8 @@ int uv_pipe_bind2(uv_pipe_t* handle, | ||||
|   return 0; | ||||
|  | ||||
| error: | ||||
|   if (handle->name) { | ||||
|     uv__free(handle->name); | ||||
|     handle->name = NULL; | ||||
|   } | ||||
|   uv__free(handle->name); | ||||
|   handle->name = NULL; | ||||
|  | ||||
|   return uv_translate_sys_error(err); | ||||
| } | ||||
| @@ -861,7 +845,8 @@ int uv_pipe_connect2(uv_connect_t* req, | ||||
|                      unsigned int flags, | ||||
|                      uv_connect_cb cb) { | ||||
|   uv_loop_t* loop = handle->loop; | ||||
|   int err, nameSize; | ||||
|   int err; | ||||
|   size_t nameSize; | ||||
|   HANDLE pipeHandle = INVALID_HANDLE_VALUE; | ||||
|   DWORD duplex_flags; | ||||
|  | ||||
| @@ -904,26 +889,16 @@ int uv_pipe_connect2(uv_connect_t* req, | ||||
|   } | ||||
|   uv__pipe_connection_init(handle); | ||||
|  | ||||
|   /* Convert name to UTF16. */ | ||||
|   nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR); | ||||
|   handle->name = uv__malloc(nameSize); | ||||
|   if (!handle->name) { | ||||
|     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); | ||||
|   } | ||||
|  | ||||
|   if (!MultiByteToWideChar(CP_UTF8, | ||||
|                            0, | ||||
|                            name, | ||||
|                            -1, | ||||
|                            handle->name, | ||||
|                            nameSize / sizeof(WCHAR))) { | ||||
|     err = GetLastError(); | ||||
|   err = uv__convert_utf8_to_utf16(name, &handle->name); | ||||
|   if (err) { | ||||
|     err = ERROR_NO_UNICODE_TRANSLATION; | ||||
|     goto error; | ||||
|   } | ||||
|  | ||||
|   pipeHandle = open_named_pipe(handle->name, &duplex_flags); | ||||
|   if (pipeHandle == INVALID_HANDLE_VALUE) { | ||||
|     if (GetLastError() == ERROR_PIPE_BUSY) { | ||||
|       nameSize = (wcslen(handle->name) + 1) * sizeof(WCHAR); | ||||
|       req->u.connect.name = uv__malloc(nameSize); | ||||
|       if (!req->u.connect.name) { | ||||
|         uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); | ||||
| @@ -2439,7 +2414,6 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) | ||||
|   FILE_NAME_INFORMATION tmp_name_info; | ||||
|   FILE_NAME_INFORMATION* name_info; | ||||
|   WCHAR* name_buf; | ||||
|   unsigned int addrlen; | ||||
|   unsigned int name_size; | ||||
|   unsigned int name_len; | ||||
|   int err; | ||||
| @@ -2450,46 +2424,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) | ||||
|   if (handle->name != NULL) { | ||||
|     /* The user might try to query the name before we are connected, | ||||
|      * and this is just easier to return the cached value if we have it. */ | ||||
|     name_buf = handle->name; | ||||
|     name_len = wcslen(name_buf); | ||||
|  | ||||
|     /* check how much space we need */ | ||||
|     addrlen = WideCharToMultiByte(CP_UTF8, | ||||
|                                   0, | ||||
|                                   name_buf, | ||||
|                                   name_len, | ||||
|                                   NULL, | ||||
|                                   0, | ||||
|                                   NULL, | ||||
|                                   NULL); | ||||
|     if (!addrlen) { | ||||
|       *size = 0; | ||||
|       err = uv_translate_sys_error(GetLastError()); | ||||
|       return err; | ||||
|     } else if (addrlen >= *size) { | ||||
|       *size = addrlen + 1; | ||||
|       err = UV_ENOBUFS; | ||||
|       goto error; | ||||
|     } | ||||
|  | ||||
|     addrlen = WideCharToMultiByte(CP_UTF8, | ||||
|                                   0, | ||||
|                                   name_buf, | ||||
|                                   name_len, | ||||
|                                   buffer, | ||||
|                                   addrlen, | ||||
|                                   NULL, | ||||
|                                   NULL); | ||||
|     if (!addrlen) { | ||||
|       *size = 0; | ||||
|       err = uv_translate_sys_error(GetLastError()); | ||||
|       return err; | ||||
|     } | ||||
|  | ||||
|     *size = addrlen; | ||||
|     buffer[addrlen] = '\0'; | ||||
|  | ||||
|     return 0; | ||||
|     return uv__copy_utf16_to_utf8(handle->name, -1, buffer, size); | ||||
|   } | ||||
|  | ||||
|   if (handle->handle == INVALID_HANDLE_VALUE) { | ||||
| @@ -2517,8 +2452,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) | ||||
|     name_info = uv__malloc(name_size); | ||||
|     if (!name_info) { | ||||
|       *size = 0; | ||||
|       err = UV_ENOMEM; | ||||
|       goto cleanup; | ||||
|       return UV_ENOMEM; | ||||
|     } | ||||
|  | ||||
|     nt_status = pNtQueryInformationFile(handle->handle, | ||||
| @@ -2551,51 +2485,19 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) | ||||
|  | ||||
|   name_len /= sizeof(WCHAR); | ||||
|  | ||||
|   /* check how much space we need */ | ||||
|   addrlen = WideCharToMultiByte(CP_UTF8, | ||||
|                                 0, | ||||
|                                 name_buf, | ||||
|                                 name_len, | ||||
|                                 NULL, | ||||
|                                 0, | ||||
|                                 NULL, | ||||
|                                 NULL); | ||||
|   if (!addrlen) { | ||||
|   /* "\\\\.\\pipe" + name */ | ||||
|   if (*size < pipe_prefix_len) { | ||||
|     *size = 0; | ||||
|     err = uv_translate_sys_error(GetLastError()); | ||||
|     goto error; | ||||
|   } else if (pipe_prefix_len + addrlen >= *size) { | ||||
|     /* "\\\\.\\pipe" + name */ | ||||
|     *size = pipe_prefix_len + addrlen + 1; | ||||
|     err = UV_ENOBUFS; | ||||
|     goto error; | ||||
|   } | ||||
|  | ||||
|   memcpy(buffer, pipe_prefix, pipe_prefix_len); | ||||
|   addrlen = WideCharToMultiByte(CP_UTF8, | ||||
|                                 0, | ||||
|                                 name_buf, | ||||
|                                 name_len, | ||||
|                                 buffer+pipe_prefix_len, | ||||
|                                 *size-pipe_prefix_len, | ||||
|                                 NULL, | ||||
|                                 NULL); | ||||
|   if (!addrlen) { | ||||
|     *size = 0; | ||||
|     err = uv_translate_sys_error(GetLastError()); | ||||
|     goto error; | ||||
|   else { | ||||
|     memcpy(buffer, pipe_prefix, pipe_prefix_len); | ||||
|     *size -= pipe_prefix_len; | ||||
|   } | ||||
|  | ||||
|   addrlen += pipe_prefix_len; | ||||
|   *size = addrlen; | ||||
|   buffer[addrlen] = '\0'; | ||||
|  | ||||
|   err = 0; | ||||
|   err = uv__copy_utf16_to_utf8(name_buf, name_len, buffer+pipe_prefix_len, size); | ||||
|   *size += pipe_prefix_len; | ||||
|  | ||||
| error: | ||||
|   uv__free(name_info); | ||||
|  | ||||
| cleanup: | ||||
|   return err; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										192
									
								
								deps/libuv/src/win/process.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										192
									
								
								deps/libuv/src/win/process.c
									
									
									
									
										vendored
									
									
								
							| @@ -105,38 +105,26 @@ static void uv__init_global_job_handle(void) { | ||||
|                                &info, | ||||
|                                sizeof info)) | ||||
|     uv_fatal_error(GetLastError(), "SetInformationJobObject"); | ||||
|  | ||||
|  | ||||
|   if (!AssignProcessToJobObject(uv_global_job_handle_, GetCurrentProcess())) { | ||||
|     /* Make sure this handle is functional. The Windows kernel has a bug that | ||||
|      * if the first use of AssignProcessToJobObject is for a Windows Store | ||||
|      * program, subsequent attempts to use the handle with fail with | ||||
|      * INVALID_PARAMETER (87). This is possibly because all uses of the handle | ||||
|      * must be for the same Terminal Services session. We can ensure it is tied | ||||
|      * to our current session now by adding ourself to it. We could remove | ||||
|      * ourself afterwards, but there doesn't seem to be a reason to. | ||||
|      */ | ||||
|     DWORD err = GetLastError(); | ||||
|     if (err != ERROR_ACCESS_DENIED) | ||||
|       uv_fatal_error(err, "AssignProcessToJobObject"); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| static int uv__utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) { | ||||
|   int ws_len, r; | ||||
|   WCHAR* ws; | ||||
|  | ||||
|   ws_len = MultiByteToWideChar(CP_UTF8, | ||||
|                                0, | ||||
|                                s, | ||||
|                                -1, | ||||
|                                NULL, | ||||
|                                0); | ||||
|   if (ws_len <= 0) { | ||||
|     return GetLastError(); | ||||
|   } | ||||
|  | ||||
|   ws = (WCHAR*) uv__malloc(ws_len * sizeof(WCHAR)); | ||||
|   if (ws == NULL) { | ||||
|     return ERROR_OUTOFMEMORY; | ||||
|   } | ||||
|  | ||||
|   r = MultiByteToWideChar(CP_UTF8, | ||||
|                           0, | ||||
|                           s, | ||||
|                           -1, | ||||
|                           ws, | ||||
|                           ws_len); | ||||
|   assert(r == ws_len); | ||||
|  | ||||
|   *ws_ptr = ws; | ||||
|   return 0; | ||||
|   return uv__convert_utf8_to_utf16(s, ws_ptr); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -396,7 +384,7 @@ static WCHAR* search_path(const WCHAR *file, | ||||
|                                   name_has_ext); | ||||
|  | ||||
|     while (result == NULL) { | ||||
|       if (*dir_end == L'\0') { | ||||
|       if (dir_end == NULL || *dir_end == L'\0') { | ||||
|         break; | ||||
|       } | ||||
|  | ||||
| @@ -539,21 +527,15 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { | ||||
|  | ||||
|   /* Count the required size. */ | ||||
|   for (arg = args; *arg; arg++) { | ||||
|     DWORD arg_len; | ||||
|     ssize_t arg_len; | ||||
|  | ||||
|     arg_len = MultiByteToWideChar(CP_UTF8, | ||||
|                                   0, | ||||
|                                   *arg, | ||||
|                                   -1, | ||||
|                                   NULL, | ||||
|                                   0); | ||||
|     if (arg_len == 0) { | ||||
|       return GetLastError(); | ||||
|     } | ||||
|     arg_len = uv_wtf8_length_as_utf16(*arg); | ||||
|     if (arg_len < 0) | ||||
|       return arg_len; | ||||
|  | ||||
|     dst_len += arg_len; | ||||
|  | ||||
|     if (arg_len > temp_buffer_len) | ||||
|     if ((size_t) arg_len > temp_buffer_len) | ||||
|       temp_buffer_len = arg_len; | ||||
|  | ||||
|     arg_count++; | ||||
| @@ -564,34 +546,28 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { | ||||
|   dst_len = dst_len * 2 + arg_count * 2; | ||||
|  | ||||
|   /* Allocate buffer for the final command line. */ | ||||
|   dst = (WCHAR*) uv__malloc(dst_len * sizeof(WCHAR)); | ||||
|   dst = uv__malloc(dst_len * sizeof(WCHAR)); | ||||
|   if (dst == NULL) { | ||||
|     err = ERROR_OUTOFMEMORY; | ||||
|     err = UV_ENOMEM; | ||||
|     goto error; | ||||
|   } | ||||
|  | ||||
|   /* Allocate temporary working buffer. */ | ||||
|   temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR)); | ||||
|   temp_buffer = uv__malloc(temp_buffer_len * sizeof(WCHAR)); | ||||
|   if (temp_buffer == NULL) { | ||||
|     err = ERROR_OUTOFMEMORY; | ||||
|     err = UV_ENOMEM; | ||||
|     goto error; | ||||
|   } | ||||
|  | ||||
|   pos = dst; | ||||
|   for (arg = args; *arg; arg++) { | ||||
|     DWORD arg_len; | ||||
|     ssize_t arg_len; | ||||
|  | ||||
|     /* Convert argument to wide char. */ | ||||
|     arg_len = MultiByteToWideChar(CP_UTF8, | ||||
|                                   0, | ||||
|                                   *arg, | ||||
|                                   -1, | ||||
|                                   temp_buffer, | ||||
|                                   (int) (dst + dst_len - pos)); | ||||
|     if (arg_len == 0) { | ||||
|       err = GetLastError(); | ||||
|       goto error; | ||||
|     } | ||||
|     arg_len = uv_wtf8_length_as_utf16(*arg); | ||||
|     assert(arg_len > 0); | ||||
|     assert(temp_buffer_len >= (size_t) arg_len); | ||||
|     uv_wtf8_to_utf16(*arg, temp_buffer, arg_len); | ||||
|  | ||||
|     if (verbatim_arguments) { | ||||
|       /* Copy verbatim. */ | ||||
| @@ -603,6 +579,7 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { | ||||
|     } | ||||
|  | ||||
|     *pos++ = *(arg + 1) ? L' ' : L'\0'; | ||||
|     assert(pos <= dst + dst_len); | ||||
|   } | ||||
|  | ||||
|   uv__free(temp_buffer); | ||||
| @@ -688,55 +665,43 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { | ||||
|   WCHAR* ptr; | ||||
|   char** env; | ||||
|   size_t env_len = 0; | ||||
|   int len; | ||||
|   size_t len; | ||||
|   size_t i; | ||||
|   DWORD var_size; | ||||
|   size_t var_size; | ||||
|   size_t env_block_count = 1; /* 1 for null-terminator */ | ||||
|   WCHAR* dst_copy; | ||||
|   WCHAR** ptr_copy; | ||||
|   WCHAR** env_copy; | ||||
|   DWORD required_vars_value_len[ARRAY_SIZE(required_vars)]; | ||||
|   size_t required_vars_value_len[ARRAY_SIZE(required_vars)]; | ||||
|  | ||||
|   /* first pass: determine size in UTF-16 */ | ||||
|   for (env = env_block; *env; env++) { | ||||
|     int len; | ||||
|     ssize_t len; | ||||
|     if (strchr(*env, '=')) { | ||||
|       len = MultiByteToWideChar(CP_UTF8, | ||||
|                                 0, | ||||
|                                 *env, | ||||
|                                 -1, | ||||
|                                 NULL, | ||||
|                                 0); | ||||
|       if (len <= 0) { | ||||
|         return GetLastError(); | ||||
|       } | ||||
|       len = uv_wtf8_length_as_utf16(*env); | ||||
|       if (len < 0) | ||||
|         return len; | ||||
|       env_len += len; | ||||
|       env_block_count++; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* second pass: copy to UTF-16 environment block */ | ||||
|   dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR)); | ||||
|   dst_copy = uv__malloc(env_len * sizeof(WCHAR)); | ||||
|   if (dst_copy == NULL && env_len > 0) { | ||||
|     return ERROR_OUTOFMEMORY; | ||||
|     return UV_ENOMEM; | ||||
|   } | ||||
|   env_copy = alloca(env_block_count * sizeof(WCHAR*)); | ||||
|  | ||||
|   ptr = dst_copy; | ||||
|   ptr_copy = env_copy; | ||||
|   for (env = env_block; *env; env++) { | ||||
|     ssize_t len; | ||||
|     if (strchr(*env, '=')) { | ||||
|       len = MultiByteToWideChar(CP_UTF8, | ||||
|                                 0, | ||||
|                                 *env, | ||||
|                                 -1, | ||||
|                                 ptr, | ||||
|                                 (int) (env_len - (ptr - dst_copy))); | ||||
|       if (len <= 0) { | ||||
|         DWORD err = GetLastError(); | ||||
|         uv__free(dst_copy); | ||||
|         return err; | ||||
|       } | ||||
|       len = uv_wtf8_length_as_utf16(*env); | ||||
|       assert(len > 0); | ||||
|       assert((size_t) len <= env_len - (ptr - dst_copy)); | ||||
|       uv_wtf8_to_utf16(*env, ptr, len); | ||||
|       *ptr_copy++ = ptr; | ||||
|       ptr += len; | ||||
|     } | ||||
| @@ -754,7 +719,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { | ||||
|       cmp = -1; | ||||
|     } else { | ||||
|       cmp = env_strncmp(required_vars[i].wide_eq, | ||||
|                        required_vars[i].len, | ||||
|                         required_vars[i].len, | ||||
|                         *ptr_copy); | ||||
|     } | ||||
|     if (cmp < 0) { | ||||
| @@ -777,7 +742,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { | ||||
|   dst = uv__malloc((1+env_len) * sizeof(WCHAR)); | ||||
|   if (!dst) { | ||||
|     uv__free(dst_copy); | ||||
|     return ERROR_OUTOFMEMORY; | ||||
|     return UV_ENOMEM; | ||||
|   } | ||||
|  | ||||
|   for (ptr = dst, ptr_copy = env_copy, i = 0; | ||||
| @@ -975,26 +940,26 @@ int uv_spawn(uv_loop_t* loop, | ||||
|  | ||||
|   err = uv__utf8_to_utf16_alloc(options->file, &application); | ||||
|   if (err) | ||||
|     goto done; | ||||
|     goto done_uv; | ||||
|  | ||||
|   err = make_program_args( | ||||
|       options->args, | ||||
|       options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, | ||||
|       &arguments); | ||||
|   if (err) | ||||
|     goto done; | ||||
|     goto done_uv; | ||||
|  | ||||
|   if (options->env) { | ||||
|      err = make_program_env(options->env, &env); | ||||
|      if (err) | ||||
|        goto done; | ||||
|        goto done_uv; | ||||
|   } | ||||
|  | ||||
|   if (options->cwd) { | ||||
|     /* Explicit cwd */ | ||||
|     err = uv__utf8_to_utf16_alloc(options->cwd, &cwd); | ||||
|     if (err) | ||||
|       goto done; | ||||
|       goto done_uv; | ||||
|  | ||||
|   } else { | ||||
|     /* Inherit cwd */ | ||||
| @@ -1025,22 +990,19 @@ int uv_spawn(uv_loop_t* loop, | ||||
|     DWORD path_len, r; | ||||
|  | ||||
|     path_len = GetEnvironmentVariableW(L"PATH", NULL, 0); | ||||
|     if (path_len == 0) { | ||||
|       err = GetLastError(); | ||||
|       goto done; | ||||
|     } | ||||
|     if (path_len != 0) { | ||||
|       alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR)); | ||||
|       if (alloc_path == NULL) { | ||||
|         err = ERROR_OUTOFMEMORY; | ||||
|         goto done; | ||||
|       } | ||||
|       path = alloc_path; | ||||
|  | ||||
|     alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR)); | ||||
|     if (alloc_path == NULL) { | ||||
|       err = ERROR_OUTOFMEMORY; | ||||
|       goto done; | ||||
|     } | ||||
|     path = alloc_path; | ||||
|  | ||||
|     r = GetEnvironmentVariableW(L"PATH", path, path_len); | ||||
|     if (r == 0 || r >= path_len) { | ||||
|       err = GetLastError(); | ||||
|       goto done; | ||||
|       r = GetEnvironmentVariableW(L"PATH", path, path_len); | ||||
|       if (r == 0 || r >= path_len) { | ||||
|         err = GetLastError(); | ||||
|         goto done; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -1102,6 +1064,7 @@ int uv_spawn(uv_loop_t* loop, | ||||
|      * breakaway. | ||||
|      */ | ||||
|     process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; | ||||
|     process_flags |= CREATE_SUSPENDED; | ||||
|   } | ||||
|  | ||||
|   if (!CreateProcessW(application_path, | ||||
| @@ -1119,11 +1082,6 @@ int uv_spawn(uv_loop_t* loop, | ||||
|     goto done; | ||||
|   } | ||||
|  | ||||
|   /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */ | ||||
|  | ||||
|   process->process_handle = info.hProcess; | ||||
|   process->pid = info.dwProcessId; | ||||
|  | ||||
|   /* If the process isn't spawned as detached, assign to the global job object | ||||
|    * so windows will kill it when the parent process dies. */ | ||||
|   if (!(options->flags & UV_PROCESS_DETACHED)) { | ||||
| @@ -1146,6 +1104,19 @@ int uv_spawn(uv_loop_t* loop, | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (process_flags & CREATE_SUSPENDED) { | ||||
|     if (ResumeThread(info.hThread) == ((DWORD)-1)) { | ||||
|       err = GetLastError(); | ||||
|       TerminateProcess(info.hProcess, 1); | ||||
|       goto done; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */ | ||||
|  | ||||
|   process->process_handle = info.hProcess; | ||||
|   process->pid = info.dwProcessId; | ||||
|  | ||||
|   /* Set IPC pid to all IPC pipes. */ | ||||
|   for (i = 0; i < options->stdio_count; i++) { | ||||
|     const uv_stdio_container_t* fdopt = &options->stdio[i]; | ||||
| @@ -1173,8 +1144,13 @@ int uv_spawn(uv_loop_t* loop, | ||||
|    * made or the handle is closed, whichever happens first. */ | ||||
|   uv__handle_start(process); | ||||
|  | ||||
|   goto done_uv; | ||||
|  | ||||
|   /* Cleanup, whether we succeeded or failed. */ | ||||
|  done: | ||||
|   err = uv_translate_sys_error(err); | ||||
|  | ||||
|  done_uv: | ||||
|   uv__free(application); | ||||
|   uv__free(application_path); | ||||
|   uv__free(arguments); | ||||
| @@ -1188,7 +1164,7 @@ int uv_spawn(uv_loop_t* loop, | ||||
|     child_stdio_buffer = NULL; | ||||
|   } | ||||
|  | ||||
|   return uv_translate_sys_error(err); | ||||
|   return err; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										62
									
								
								deps/libuv/src/win/tty.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								deps/libuv/src/win/tty.c
									
									
									
									
										vendored
									
									
								
							| @@ -482,9 +482,11 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) { | ||||
|   uv_loop_t* loop; | ||||
|   uv_tty_t* handle; | ||||
|   uv_req_t* req; | ||||
|   DWORD bytes, read_bytes; | ||||
|   DWORD bytes; | ||||
|   size_t read_bytes; | ||||
|   WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3]; | ||||
|   DWORD chars, read_chars; | ||||
|   DWORD chars; | ||||
|   DWORD read_chars; | ||||
|   LONG status; | ||||
|   COORD pos; | ||||
|   BOOL read_console_success; | ||||
| @@ -525,16 +527,13 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) { | ||||
|                                       NULL); | ||||
|  | ||||
|   if (read_console_success) { | ||||
|     read_bytes = WideCharToMultiByte(CP_UTF8, | ||||
|                                      0, | ||||
|                                      utf16, | ||||
|                                      read_chars, | ||||
|                                      handle->tty.rd.read_line_buffer.base, | ||||
|                                      bytes, | ||||
|                                      NULL, | ||||
|                                      NULL); | ||||
|     read_bytes = bytes; | ||||
|     uv_utf16_to_wtf8(utf16, | ||||
|                      read_chars, | ||||
|                      &handle->tty.rd.read_line_buffer.base, | ||||
|                      &read_bytes); | ||||
|     SET_REQ_SUCCESS(req); | ||||
|     req->u.io.overlapped.InternalHigh = read_bytes; | ||||
|     req->u.io.overlapped.InternalHigh = (DWORD) read_bytes; | ||||
|   } else { | ||||
|     SET_REQ_ERROR(req, GetLastError()); | ||||
|   } | ||||
| @@ -798,7 +797,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, | ||||
|       } | ||||
|  | ||||
|       if (KEV.uChar.UnicodeChar != 0) { | ||||
|         int prefix_len, char_len; | ||||
|         int prefix_len; | ||||
|         size_t char_len; | ||||
|         char* last_key_buf; | ||||
|  | ||||
|         /* Character key pressed */ | ||||
|         if (KEV.uChar.UnicodeChar >= 0xD800 && | ||||
| @@ -819,38 +820,31 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, | ||||
|           prefix_len = 0; | ||||
|         } | ||||
|  | ||||
|         if (KEV.uChar.UnicodeChar >= 0xDC00 && | ||||
|             KEV.uChar.UnicodeChar < 0xE000) { | ||||
|         char_len = sizeof handle->tty.rd.last_key; | ||||
|         last_key_buf = &handle->tty.rd.last_key[prefix_len]; | ||||
|         if (handle->tty.rd.last_utf16_high_surrogate) { | ||||
|           /* UTF-16 surrogate pair */ | ||||
|           WCHAR utf16_buffer[2]; | ||||
|           utf16_buffer[0] = handle->tty.rd.last_utf16_high_surrogate; | ||||
|           utf16_buffer[1] = KEV.uChar.UnicodeChar; | ||||
|           char_len = WideCharToMultiByte(CP_UTF8, | ||||
|                                          0, | ||||
|                                          utf16_buffer, | ||||
|                                          2, | ||||
|                                          &handle->tty.rd.last_key[prefix_len], | ||||
|                                          sizeof handle->tty.rd.last_key, | ||||
|                                          NULL, | ||||
|                                          NULL); | ||||
|           if (uv_utf16_to_wtf8(utf16_buffer, | ||||
|                                2, | ||||
|                                &last_key_buf, | ||||
|                                &char_len)) | ||||
|             char_len = 0; | ||||
|           handle->tty.rd.last_utf16_high_surrogate = 0; | ||||
|         } else { | ||||
|           /* Single UTF-16 character */ | ||||
|           char_len = WideCharToMultiByte(CP_UTF8, | ||||
|                                          0, | ||||
|                                          &KEV.uChar.UnicodeChar, | ||||
|                                          1, | ||||
|                                          &handle->tty.rd.last_key[prefix_len], | ||||
|                                          sizeof handle->tty.rd.last_key, | ||||
|                                          NULL, | ||||
|                                          NULL); | ||||
|           if (uv_utf16_to_wtf8(&KEV.uChar.UnicodeChar, | ||||
|                                1, | ||||
|                                &last_key_buf, | ||||
|                                &char_len)) | ||||
|             char_len = 0; | ||||
|         } | ||||
|  | ||||
|         /* Whatever happened, the last character wasn't a high surrogate. */ | ||||
|         handle->tty.rd.last_utf16_high_surrogate = 0; | ||||
|  | ||||
|         /* If the utf16 character(s) couldn't be converted something must be | ||||
|          * wrong. */ | ||||
|         if (!char_len) { | ||||
|         if (char_len == 0) { | ||||
|           handle->flags &= ~UV_HANDLE_READING; | ||||
|           DECREASE_ACTIVE_COUNT(loop, handle); | ||||
|           handle->read_cb((uv_stream_t*) handle, | ||||
|   | ||||
							
								
								
									
										410
									
								
								deps/libuv/src/win/util.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										410
									
								
								deps/libuv/src/win/util.c
									
									
									
									
										vendored
									
									
								
							| @@ -95,7 +95,7 @@ void uv__util_init(void) { | ||||
|  | ||||
|  | ||||
| int uv_exepath(char* buffer, size_t* size_ptr) { | ||||
|   int utf8_len, utf16_buffer_len, utf16_len; | ||||
|   size_t utf8_len, utf16_buffer_len, utf16_len; | ||||
|   WCHAR* utf16_buffer; | ||||
|   int err; | ||||
|  | ||||
| @@ -123,25 +123,17 @@ int uv_exepath(char* buffer, size_t* size_ptr) { | ||||
|   } | ||||
|  | ||||
|   /* Convert to UTF-8 */ | ||||
|   utf8_len = WideCharToMultiByte(CP_UTF8, | ||||
|                                  0, | ||||
|                                  utf16_buffer, | ||||
|                                  -1, | ||||
|                                  buffer, | ||||
|                                  (int) *size_ptr, | ||||
|                                  NULL, | ||||
|                                  NULL); | ||||
|   if (utf8_len == 0) { | ||||
|     err = GetLastError(); | ||||
|     goto error; | ||||
|   utf8_len = *size_ptr - 1; /* Reserve space for NUL */ | ||||
|   err = uv_utf16_to_wtf8(utf16_buffer, utf16_len, &buffer, &utf8_len); | ||||
|   if (err == UV_ENOBUFS) { | ||||
|     utf8_len = *size_ptr - 1; | ||||
|     err = 0; | ||||
|   } | ||||
|   *size_ptr = utf8_len; | ||||
|  | ||||
|   uv__free(utf16_buffer); | ||||
|  | ||||
|   /* utf8_len *does* include the terminating null at this point, but the | ||||
|    * returned size shouldn't. */ | ||||
|   *size_ptr = utf8_len - 1; | ||||
|   return 0; | ||||
|   return err; | ||||
|  | ||||
|  error: | ||||
|   uv__free(utf16_buffer); | ||||
| @@ -204,45 +196,14 @@ int uv_cwd(char* buffer, size_t* size) { | ||||
|   } | ||||
|  | ||||
|   r = uv__cwd(&utf16_buffer, &utf16_len); | ||||
|   if (r < 0) { | ||||
|   if (r < 0) | ||||
|     return r; | ||||
|   } | ||||
|  | ||||
|   /* Check how much space we need */ | ||||
|   r = WideCharToMultiByte(CP_UTF8, | ||||
|                           0, | ||||
|                           utf16_buffer, | ||||
|                           -1, | ||||
|                           NULL, | ||||
|                           0, | ||||
|                           NULL, | ||||
|                           NULL); | ||||
|   if (r == 0) { | ||||
|     uv__free(utf16_buffer); | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } else if (r > (int) *size) { | ||||
|     uv__free(utf16_buffer); | ||||
|     *size = r; | ||||
|     return UV_ENOBUFS; | ||||
|   } | ||||
|   r = uv__copy_utf16_to_utf8(utf16_buffer, utf16_len, buffer, size); | ||||
|  | ||||
|   /* Convert to UTF-8 */ | ||||
|   r = WideCharToMultiByte(CP_UTF8, | ||||
|                           0, | ||||
|                           utf16_buffer, | ||||
|                           -1, | ||||
|                           buffer, | ||||
|                           *size > INT_MAX ? INT_MAX : (int) *size, | ||||
|                           NULL, | ||||
|                           NULL); | ||||
|   uv__free(utf16_buffer); | ||||
|  | ||||
|   if (r == 0) { | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } | ||||
|  | ||||
|   *size = r - 1; | ||||
|   return 0; | ||||
|   return r; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -252,33 +213,10 @@ int uv_chdir(const char* dir) { | ||||
|   WCHAR drive_letter, env_var[4]; | ||||
|   int r; | ||||
|  | ||||
|   if (dir == NULL) { | ||||
|     return UV_EINVAL; | ||||
|   } | ||||
|  | ||||
|   utf16_len = MultiByteToWideChar(CP_UTF8, | ||||
|                                   0, | ||||
|                                   dir, | ||||
|                                   -1, | ||||
|                                   NULL, | ||||
|                                   0); | ||||
|   if (utf16_len == 0) { | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } | ||||
|   utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR)); | ||||
|   if (utf16_buffer == NULL) { | ||||
|     return UV_ENOMEM; | ||||
|   } | ||||
|  | ||||
|   if (MultiByteToWideChar(CP_UTF8, | ||||
|                           0, | ||||
|                           dir, | ||||
|                           -1, | ||||
|                           utf16_buffer, | ||||
|                           utf16_len) == 0) { | ||||
|     uv__free(utf16_buffer); | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } | ||||
|   /* Convert to UTF-16 */ | ||||
|   r = uv__convert_utf8_to_utf16(dir, &utf16_buffer); | ||||
|   if (r) | ||||
|     return r; | ||||
|  | ||||
|   if (!SetCurrentDirectoryW(utf16_buffer)) { | ||||
|     uv__free(utf16_buffer); | ||||
| @@ -416,29 +354,14 @@ int uv_set_process_title(const char* title) { | ||||
|  | ||||
|   uv__once_init(); | ||||
|  | ||||
|   /* Find out how big the buffer for the wide-char title must be */ | ||||
|   length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); | ||||
|   if (!length) { | ||||
|     err = GetLastError(); | ||||
|     goto done; | ||||
|   } | ||||
|  | ||||
|   /* Convert to wide-char string */ | ||||
|   title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length); | ||||
|   if (!title_w) { | ||||
|     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); | ||||
|   } | ||||
|  | ||||
|   length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length); | ||||
|   if (!length) { | ||||
|     err = GetLastError(); | ||||
|     goto done; | ||||
|   } | ||||
|   err = uv__convert_utf8_to_utf16(title, &title_w); | ||||
|   if (err) | ||||
|     return err; | ||||
|  | ||||
|   /* If the title must be truncated insert a \0 terminator there */ | ||||
|   if (length > MAX_TITLE_LENGTH) { | ||||
|   length = wcslen(title_w); | ||||
|   if (length >= MAX_TITLE_LENGTH) | ||||
|     title_w[MAX_TITLE_LENGTH - 1] = L'\0'; | ||||
|   } | ||||
|  | ||||
|   if (!SetConsoleTitleW(title_w)) { | ||||
|     err = GetLastError(); | ||||
| @@ -460,20 +383,19 @@ done: | ||||
|  | ||||
| static int uv__get_process_title(void) { | ||||
|   WCHAR title_w[MAX_TITLE_LENGTH]; | ||||
|   DWORD wlen; | ||||
|  | ||||
|   if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { | ||||
|     return -1; | ||||
|   } | ||||
|   wlen = GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR)); | ||||
|   if (wlen == 0) | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|  | ||||
|   if (uv__convert_utf16_to_utf8(title_w, -1, &process_title) != 0) | ||||
|     return -1; | ||||
|  | ||||
|   return 0; | ||||
|   return uv__convert_utf16_to_utf8(title_w, wlen, &process_title); | ||||
| } | ||||
|  | ||||
|  | ||||
| int uv_get_process_title(char* buffer, size_t size) { | ||||
|   size_t len; | ||||
|   int r; | ||||
|  | ||||
|   if (buffer == NULL || size == 0) | ||||
|     return UV_EINVAL; | ||||
| @@ -485,9 +407,12 @@ int uv_get_process_title(char* buffer, size_t size) { | ||||
|    * If the process_title was never read before nor explicitly set, | ||||
|    * we must query it with getConsoleTitleW | ||||
|    */ | ||||
|   if (!process_title && uv__get_process_title() == -1) { | ||||
|     LeaveCriticalSection(&process_title_lock); | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   if (process_title == NULL) { | ||||
|     r = uv__get_process_title(); | ||||
|     if (r) { | ||||
|       LeaveCriticalSection(&process_title_lock); | ||||
|       return r; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   assert(process_title); | ||||
| @@ -833,19 +758,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, | ||||
|       continue; | ||||
|  | ||||
|     /* Compute the size of the interface name. */ | ||||
|     name_size = WideCharToMultiByte(CP_UTF8, | ||||
|                                     0, | ||||
|                                     adapter->FriendlyName, | ||||
|                                     -1, | ||||
|                                     NULL, | ||||
|                                     0, | ||||
|                                     NULL, | ||||
|                                     FALSE); | ||||
|     if (name_size <= 0) { | ||||
|       uv__free(win_address_buf); | ||||
|       return uv_translate_sys_error(GetLastError()); | ||||
|     } | ||||
|     uv_address_buf_size += name_size; | ||||
|     name_size = uv_utf16_length_as_wtf8(adapter->FriendlyName, -1); | ||||
|     uv_address_buf_size += name_size + 1; | ||||
|  | ||||
|     /* Count the number of addresses associated with this interface, and | ||||
|      * compute the size. */ | ||||
| @@ -875,30 +789,25 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, | ||||
|        adapter != NULL; | ||||
|        adapter = adapter->Next) { | ||||
|     IP_ADAPTER_UNICAST_ADDRESS* unicast_address; | ||||
|     int name_size; | ||||
|     size_t max_name_size; | ||||
|     size_t name_size; | ||||
|     int r; | ||||
|  | ||||
|     if (adapter->OperStatus != IfOperStatusUp || | ||||
|         adapter->FirstUnicastAddress == NULL) | ||||
|       continue; | ||||
|  | ||||
|     /* Convert the interface name to UTF8. */ | ||||
|     max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf; | ||||
|     if (max_name_size > (size_t) INT_MAX) | ||||
|       max_name_size = INT_MAX; | ||||
|     name_size = WideCharToMultiByte(CP_UTF8, | ||||
|                                     0, | ||||
|                                     adapter->FriendlyName, | ||||
|                                     -1, | ||||
|                                     name_buf, | ||||
|                                     (int) max_name_size, | ||||
|                                     NULL, | ||||
|                                     FALSE); | ||||
|     if (name_size <= 0) { | ||||
|     name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf; | ||||
|     r = uv__copy_utf16_to_utf8(adapter->FriendlyName, | ||||
|                                -1, | ||||
|                                name_buf, | ||||
|                                &name_size); | ||||
|     if (r) { | ||||
|       uv__free(win_address_buf); | ||||
|       uv__free(uv_address_buf); | ||||
|       return uv_translate_sys_error(GetLastError()); | ||||
|       return r; | ||||
|     } | ||||
|     name_size += 1; /* Add NUL byte. */ | ||||
|  | ||||
|     /* Add an uv_interface_address_t element for every unicast address. */ | ||||
|     for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) | ||||
| @@ -1061,7 +970,6 @@ int uv_os_homedir(char* buffer, size_t* size) { | ||||
|  | ||||
| int uv_os_tmpdir(char* buffer, size_t* size) { | ||||
|   wchar_t *path; | ||||
|   DWORD bufsize; | ||||
|   size_t len; | ||||
|  | ||||
|   if (buffer == NULL || size == NULL || *size == 0) | ||||
| @@ -1078,7 +986,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) { | ||||
|   if (path == NULL) { | ||||
|     return UV_ENOMEM; | ||||
|   } | ||||
|   len  = GetTempPathW(len, path); | ||||
|   len = GetTempPathW(len, path); | ||||
|  | ||||
|   if (len == 0) { | ||||
|     uv__free(path); | ||||
| @@ -1093,34 +1001,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) { | ||||
|     path[len] = L'\0'; | ||||
|   } | ||||
|  | ||||
|   /* Check how much space we need */ | ||||
|   bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL); | ||||
|  | ||||
|   if (bufsize == 0) { | ||||
|     uv__free(path); | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } else if (bufsize > *size) { | ||||
|     uv__free(path); | ||||
|     *size = bufsize; | ||||
|     return UV_ENOBUFS; | ||||
|   } | ||||
|  | ||||
|   /* Convert to UTF-8 */ | ||||
|   bufsize = WideCharToMultiByte(CP_UTF8, | ||||
|                                 0, | ||||
|                                 path, | ||||
|                                 -1, | ||||
|                                 buffer, | ||||
|                                 *size, | ||||
|                                 NULL, | ||||
|                                 NULL); | ||||
|   uv__free(path); | ||||
|  | ||||
|   if (bufsize == 0) | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|  | ||||
|   *size = bufsize - 1; | ||||
|   return 0; | ||||
|   return uv__copy_utf16_to_utf8(path, len, buffer, size); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1131,95 +1012,71 @@ int uv_os_tmpdir(char* buffer, size_t* size) { | ||||
|  * If utf16 is null terminated, utf16len can be set to -1, otherwise it must | ||||
|  * be specified. | ||||
|  */ | ||||
| int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) { | ||||
|   DWORD bufsize; | ||||
| int uv__convert_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char** utf8) { | ||||
|   size_t utf8_len = 0; | ||||
|  | ||||
|   if (utf16 == NULL) | ||||
|     return UV_EINVAL; | ||||
|  | ||||
|   /* Check how much space we need */ | ||||
|   bufsize = WideCharToMultiByte(CP_UTF8, | ||||
|                                 0, | ||||
|                                 utf16, | ||||
|                                 utf16len, | ||||
|                                 NULL, | ||||
|                                 0, | ||||
|                                 NULL, | ||||
|                                 NULL); | ||||
|  | ||||
|   if (bufsize == 0) | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|  | ||||
|   /* Allocate the destination buffer adding an extra byte for the terminating | ||||
|    * NULL. If utf16len is not -1 WideCharToMultiByte will not add it, so | ||||
|    * we do it ourselves always, just in case. */ | ||||
|   *utf8 = uv__malloc(bufsize + 1); | ||||
|  | ||||
|   if (*utf8 == NULL) | ||||
|     return UV_ENOMEM; | ||||
|  | ||||
|   /* Convert to UTF-8 */ | ||||
|   bufsize = WideCharToMultiByte(CP_UTF8, | ||||
|                                 0, | ||||
|                                 utf16, | ||||
|                                 utf16len, | ||||
|                                 *utf8, | ||||
|                                 bufsize, | ||||
|                                 NULL, | ||||
|                                 NULL); | ||||
|  | ||||
|   if (bufsize == 0) { | ||||
|     uv__free(*utf8); | ||||
|     *utf8 = NULL; | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } | ||||
|  | ||||
|   (*utf8)[bufsize] = '\0'; | ||||
|   return 0; | ||||
|    *utf8 = NULL; | ||||
|    return uv_utf16_to_wtf8(utf16, utf16len, utf8, &utf8_len); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Converts a UTF-8 string into a UTF-16 one. The resulting string is | ||||
|  * null-terminated. | ||||
|  * | ||||
|  * If utf8 is null terminated, utf8len can be set to -1, otherwise it must | ||||
|  * be specified. | ||||
|  */ | ||||
| int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) { | ||||
| int uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16) { | ||||
|   int bufsize; | ||||
|  | ||||
|   if (utf8 == NULL) | ||||
|     return UV_EINVAL; | ||||
|  | ||||
|   /* Check how much space we need */ | ||||
|   bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0); | ||||
|   /* Check how much space we need (including NUL). */ | ||||
|   bufsize = uv_wtf8_length_as_utf16(utf8); | ||||
|   if (bufsize < 0) | ||||
|     return UV__EINVAL; | ||||
|  | ||||
|   if (bufsize == 0) | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|  | ||||
|   /* Allocate the destination buffer adding an extra byte for the terminating | ||||
|    * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so | ||||
|    * we do it ourselves always, just in case. */ | ||||
|   *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1)); | ||||
|   /* Allocate the destination buffer. */ | ||||
|   *utf16 = uv__malloc(sizeof(WCHAR) * bufsize); | ||||
|  | ||||
|   if (*utf16 == NULL) | ||||
|     return UV_ENOMEM; | ||||
|  | ||||
|   /* Convert to UTF-16 */ | ||||
|   bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize); | ||||
|   uv_wtf8_to_utf16(utf8, *utf16, bufsize); | ||||
|  | ||||
|   if (bufsize == 0) { | ||||
|     uv__free(*utf16); | ||||
|     *utf16 = NULL; | ||||
|     return uv_translate_sys_error(GetLastError()); | ||||
|   } | ||||
|  | ||||
|   (*utf16)[bufsize] = L'\0'; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Converts a UTF-16 string into a UTF-8 one in an existing buffer. The | ||||
|  * resulting string is null-terminated. | ||||
|  * | ||||
|  * If utf16 is null terminated, utf16len can be set to -1, otherwise it must | ||||
|  * be specified. | ||||
|  */ | ||||
| int uv__copy_utf16_to_utf8(const WCHAR* utf16buffer, size_t utf16len, char* utf8, size_t *size) { | ||||
|   int r; | ||||
|  | ||||
|   if (utf8 == NULL || size == NULL) | ||||
|     return UV_EINVAL; | ||||
|  | ||||
|   if (*size == 0) { | ||||
|     *size = uv_utf16_length_as_wtf8(utf16buffer, utf16len); | ||||
|     r = UV_ENOBUFS; | ||||
|   } else { | ||||
|     *size -= 1; /* Reserve space for NUL. */ | ||||
|     r = uv_utf16_to_wtf8(utf16buffer, utf16len, &utf8, size); | ||||
|   } | ||||
|   if (r == UV_ENOBUFS) | ||||
|     *size += 1; /* Add space for NUL. */ | ||||
|   return r; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int uv__getpwuid_r(uv_passwd_t* pwd) { | ||||
|   HANDLE token; | ||||
|   wchar_t username[UNLEN + 1]; | ||||
| @@ -1384,14 +1241,13 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) { | ||||
|   wchar_t* var; | ||||
|   DWORD varlen; | ||||
|   wchar_t* name_w; | ||||
|   DWORD bufsize; | ||||
|   size_t len; | ||||
|   int r; | ||||
|  | ||||
|   if (name == NULL || buffer == NULL || size == NULL || *size == 0) | ||||
|     return UV_EINVAL; | ||||
|  | ||||
|   r = uv__convert_utf8_to_utf16(name, -1, &name_w); | ||||
|   r = uv__convert_utf8_to_utf16(name, &name_w); | ||||
|  | ||||
|   if (r != 0) | ||||
|     return r; | ||||
| @@ -1432,35 +1288,7 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* Check how much space we need */ | ||||
|   bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL); | ||||
|  | ||||
|   if (bufsize == 0) { | ||||
|     r = uv_translate_sys_error(GetLastError()); | ||||
|     goto fail; | ||||
|   } else if (bufsize > *size) { | ||||
|     *size = bufsize; | ||||
|     r = UV_ENOBUFS; | ||||
|     goto fail; | ||||
|   } | ||||
|  | ||||
|   /* Convert to UTF-8 */ | ||||
|   bufsize = WideCharToMultiByte(CP_UTF8, | ||||
|                                 0, | ||||
|                                 var, | ||||
|                                 -1, | ||||
|                                 buffer, | ||||
|                                 *size, | ||||
|                                 NULL, | ||||
|                                 NULL); | ||||
|  | ||||
|   if (bufsize == 0) { | ||||
|     r = uv_translate_sys_error(GetLastError()); | ||||
|     goto fail; | ||||
|   } | ||||
|  | ||||
|   *size = bufsize - 1; | ||||
|   r = 0; | ||||
|   r = uv__copy_utf16_to_utf8(var, len, buffer, size); | ||||
|  | ||||
| fail: | ||||
|  | ||||
| @@ -1482,12 +1310,12 @@ int uv_os_setenv(const char* name, const char* value) { | ||||
|   if (name == NULL || value == NULL) | ||||
|     return UV_EINVAL; | ||||
|  | ||||
|   r = uv__convert_utf8_to_utf16(name, -1, &name_w); | ||||
|   r = uv__convert_utf8_to_utf16(name, &name_w); | ||||
|  | ||||
|   if (r != 0) | ||||
|     return r; | ||||
|  | ||||
|   r = uv__convert_utf8_to_utf16(value, -1, &value_w); | ||||
|   r = uv__convert_utf8_to_utf16(value, &value_w); | ||||
|  | ||||
|   if (r != 0) { | ||||
|     uv__free(name_w); | ||||
| @@ -1512,7 +1340,7 @@ int uv_os_unsetenv(const char* name) { | ||||
|   if (name == NULL) | ||||
|     return UV_EINVAL; | ||||
|  | ||||
|   r = uv__convert_utf8_to_utf16(name, -1, &name_w); | ||||
|   r = uv__convert_utf8_to_utf16(name, &name_w); | ||||
|  | ||||
|   if (r != 0) | ||||
|     return r; | ||||
| @@ -1529,9 +1357,6 @@ int uv_os_unsetenv(const char* name) { | ||||
|  | ||||
| int uv_os_gethostname(char* buffer, size_t* size) { | ||||
|   WCHAR buf[UV_MAXHOSTNAMESIZE]; | ||||
|   size_t len; | ||||
|   char* utf8_str; | ||||
|   int convert_result; | ||||
|  | ||||
|   if (buffer == NULL || size == NULL || *size == 0) | ||||
|     return UV_EINVAL; | ||||
| @@ -1544,22 +1369,7 @@ int uv_os_gethostname(char* buffer, size_t* size) { | ||||
|   if (pGetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0) | ||||
|     return uv_translate_sys_error(WSAGetLastError()); | ||||
|  | ||||
|   convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str); | ||||
|  | ||||
|   if (convert_result != 0) | ||||
|     return convert_result; | ||||
|  | ||||
|   len = strlen(utf8_str); | ||||
|   if (len >= *size) { | ||||
|     *size = len + 1; | ||||
|     uv__free(utf8_str); | ||||
|     return UV_ENOBUFS; | ||||
|   } | ||||
|  | ||||
|   memcpy(buffer, utf8_str, len + 1); | ||||
|   uv__free(utf8_str); | ||||
|   *size = len; | ||||
|   return 0; | ||||
|   return uv__copy_utf16_to_utf8(buf, -1, buffer, size); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1665,7 +1475,7 @@ int uv_os_uname(uv_utsname_t* buffer) { | ||||
|   HKEY registry_key; | ||||
|   WCHAR product_name_w[256]; | ||||
|   DWORD product_name_w_size; | ||||
|   int version_size; | ||||
|   size_t version_size; | ||||
|   int processor_level; | ||||
|   int r; | ||||
|  | ||||
| @@ -1696,7 +1506,7 @@ int uv_os_uname(uv_utsname_t* buffer) { | ||||
|   r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, | ||||
|                     L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", | ||||
|                     0, | ||||
|                     KEY_QUERY_VALUE, | ||||
|                     KEY_QUERY_VALUE | KEY_WOW64_64KEY, | ||||
|                     ®istry_key); | ||||
|  | ||||
|   if (r == ERROR_SUCCESS) { | ||||
| @@ -1727,37 +1537,29 @@ int uv_os_uname(uv_utsname_t* buffer) { | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       version_size = WideCharToMultiByte(CP_UTF8, | ||||
|                                          0, | ||||
|                                          product_name_w, | ||||
|                                          -1, | ||||
|                                          buffer->version, | ||||
|                                          sizeof(buffer->version), | ||||
|                                          NULL, | ||||
|                                          NULL); | ||||
|       if (version_size == 0) { | ||||
|         r = uv_translate_sys_error(GetLastError()); | ||||
|       version_size = sizeof(buffer->version); | ||||
|       r = uv__copy_utf16_to_utf8(product_name_w, | ||||
|                                  -1, | ||||
|                                  buffer->version, | ||||
|                                  &version_size); | ||||
|       if (r) | ||||
|         goto error; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* Append service pack information to the version if present. */ | ||||
|   if (os_info.szCSDVersion[0] != L'\0') { | ||||
|     if (version_size > 0) | ||||
|       buffer->version[version_size - 1] = ' '; | ||||
|       buffer->version[version_size++] = ' '; | ||||
|  | ||||
|     if (WideCharToMultiByte(CP_UTF8, | ||||
|                             0, | ||||
|                             os_info.szCSDVersion, | ||||
|                             -1, | ||||
|                             buffer->version + version_size, | ||||
|                             sizeof(buffer->version) - version_size, | ||||
|                             NULL, | ||||
|                             NULL) == 0) { | ||||
|       r = uv_translate_sys_error(GetLastError()); | ||||
|     version_size = sizeof(buffer->version) - version_size; | ||||
|     r = uv__copy_utf16_to_utf8(os_info.szCSDVersion, | ||||
|                                -1, | ||||
|                                buffer->version +  | ||||
|                                  sizeof(buffer->version) - version_size, | ||||
|                                &version_size); | ||||
|     if (r) | ||||
|       goto error; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* Populate the sysname field. */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user