foolio 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. data/.gitignore +22 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +21 -0
  6. data/examples/timer.rb +20 -0
  7. data/ext/foolio/extconf.rb +34 -0
  8. data/ext/foolio/foolio_ext.c +921 -0
  9. data/ext/foolio/gen.rb +50 -0
  10. data/ext/foolio/make_table.rb +12 -0
  11. data/ext/foolio/templ +243 -0
  12. data/ext/libuv/.gitignore +33 -0
  13. data/ext/libuv/.mailmap +13 -0
  14. data/ext/libuv/.travis.yml +9 -0
  15. data/ext/libuv/AUTHORS +61 -0
  16. data/ext/libuv/LICENSE +44 -0
  17. data/ext/libuv/Makefile +71 -0
  18. data/ext/libuv/README.md +90 -0
  19. data/ext/libuv/common.gypi +178 -0
  20. data/ext/libuv/gyp_uv +73 -0
  21. data/ext/libuv/include/uv-private/eio.h +403 -0
  22. data/ext/libuv/include/uv-private/ev.h +838 -0
  23. data/ext/libuv/include/uv-private/ngx-queue.h +108 -0
  24. data/ext/libuv/include/uv-private/tree.h +768 -0
  25. data/ext/libuv/include/uv-private/uv-unix.h +324 -0
  26. data/ext/libuv/include/uv-private/uv-win.h +517 -0
  27. data/ext/libuv/include/uv.h +1838 -0
  28. data/ext/libuv/src/fs-poll.c +235 -0
  29. data/ext/libuv/src/inet.c +293 -0
  30. data/ext/libuv/src/unix/async.c +148 -0
  31. data/ext/libuv/src/unix/core.c +696 -0
  32. data/ext/libuv/src/unix/cygwin.c +83 -0
  33. data/ext/libuv/src/unix/darwin.c +342 -0
  34. data/ext/libuv/src/unix/dl.c +83 -0
  35. data/ext/libuv/src/unix/eio/Changes +63 -0
  36. data/ext/libuv/src/unix/eio/LICENSE +36 -0
  37. data/ext/libuv/src/unix/eio/Makefile.am +15 -0
  38. data/ext/libuv/src/unix/eio/aclocal.m4 +8957 -0
  39. data/ext/libuv/src/unix/eio/autogen.sh +3 -0
  40. data/ext/libuv/src/unix/eio/config.h.in +86 -0
  41. data/ext/libuv/src/unix/eio/config_cygwin.h +80 -0
  42. data/ext/libuv/src/unix/eio/config_darwin.h +141 -0
  43. data/ext/libuv/src/unix/eio/config_freebsd.h +81 -0
  44. data/ext/libuv/src/unix/eio/config_linux.h +94 -0
  45. data/ext/libuv/src/unix/eio/config_netbsd.h +81 -0
  46. data/ext/libuv/src/unix/eio/config_openbsd.h +137 -0
  47. data/ext/libuv/src/unix/eio/config_sunos.h +84 -0
  48. data/ext/libuv/src/unix/eio/configure.ac +22 -0
  49. data/ext/libuv/src/unix/eio/demo.c +194 -0
  50. data/ext/libuv/src/unix/eio/ecb.h +370 -0
  51. data/ext/libuv/src/unix/eio/eio.3 +3428 -0
  52. data/ext/libuv/src/unix/eio/eio.c +2593 -0
  53. data/ext/libuv/src/unix/eio/eio.pod +969 -0
  54. data/ext/libuv/src/unix/eio/libeio.m4 +195 -0
  55. data/ext/libuv/src/unix/eio/xthread.h +164 -0
  56. data/ext/libuv/src/unix/error.c +105 -0
  57. data/ext/libuv/src/unix/ev/Changes +388 -0
  58. data/ext/libuv/src/unix/ev/LICENSE +36 -0
  59. data/ext/libuv/src/unix/ev/Makefile.am +18 -0
  60. data/ext/libuv/src/unix/ev/Makefile.in +771 -0
  61. data/ext/libuv/src/unix/ev/README +58 -0
  62. data/ext/libuv/src/unix/ev/aclocal.m4 +8957 -0
  63. data/ext/libuv/src/unix/ev/autogen.sh +6 -0
  64. data/ext/libuv/src/unix/ev/config.guess +1526 -0
  65. data/ext/libuv/src/unix/ev/config.h.in +125 -0
  66. data/ext/libuv/src/unix/ev/config.sub +1658 -0
  67. data/ext/libuv/src/unix/ev/config_cygwin.h +123 -0
  68. data/ext/libuv/src/unix/ev/config_darwin.h +122 -0
  69. data/ext/libuv/src/unix/ev/config_freebsd.h +120 -0
  70. data/ext/libuv/src/unix/ev/config_linux.h +141 -0
  71. data/ext/libuv/src/unix/ev/config_netbsd.h +120 -0
  72. data/ext/libuv/src/unix/ev/config_openbsd.h +126 -0
  73. data/ext/libuv/src/unix/ev/config_sunos.h +122 -0
  74. data/ext/libuv/src/unix/ev/configure +13037 -0
  75. data/ext/libuv/src/unix/ev/configure.ac +18 -0
  76. data/ext/libuv/src/unix/ev/depcomp +630 -0
  77. data/ext/libuv/src/unix/ev/ev++.h +816 -0
  78. data/ext/libuv/src/unix/ev/ev.3 +5311 -0
  79. data/ext/libuv/src/unix/ev/ev.c +3925 -0
  80. data/ext/libuv/src/unix/ev/ev.pod +5243 -0
  81. data/ext/libuv/src/unix/ev/ev_epoll.c +266 -0
  82. data/ext/libuv/src/unix/ev/ev_kqueue.c +235 -0
  83. data/ext/libuv/src/unix/ev/ev_poll.c +148 -0
  84. data/ext/libuv/src/unix/ev/ev_port.c +179 -0
  85. data/ext/libuv/src/unix/ev/ev_select.c +310 -0
  86. data/ext/libuv/src/unix/ev/ev_vars.h +203 -0
  87. data/ext/libuv/src/unix/ev/ev_win32.c +153 -0
  88. data/ext/libuv/src/unix/ev/ev_wrap.h +196 -0
  89. data/ext/libuv/src/unix/ev/event.c +402 -0
  90. data/ext/libuv/src/unix/ev/event.h +170 -0
  91. data/ext/libuv/src/unix/ev/install-sh +294 -0
  92. data/ext/libuv/src/unix/ev/libev.m4 +39 -0
  93. data/ext/libuv/src/unix/ev/ltmain.sh +8413 -0
  94. data/ext/libuv/src/unix/ev/missing +336 -0
  95. data/ext/libuv/src/unix/ev/mkinstalldirs +111 -0
  96. data/ext/libuv/src/unix/freebsd.c +326 -0
  97. data/ext/libuv/src/unix/fs.c +739 -0
  98. data/ext/libuv/src/unix/internal.h +188 -0
  99. data/ext/libuv/src/unix/kqueue.c +120 -0
  100. data/ext/libuv/src/unix/linux/inotify.c +239 -0
  101. data/ext/libuv/src/unix/linux/linux-core.c +557 -0
  102. data/ext/libuv/src/unix/linux/syscalls.c +388 -0
  103. data/ext/libuv/src/unix/linux/syscalls.h +124 -0
  104. data/ext/libuv/src/unix/loop-watcher.c +62 -0
  105. data/ext/libuv/src/unix/loop.c +94 -0
  106. data/ext/libuv/src/unix/netbsd.c +108 -0
  107. data/ext/libuv/src/unix/openbsd.c +295 -0
  108. data/ext/libuv/src/unix/pipe.c +259 -0
  109. data/ext/libuv/src/unix/poll.c +114 -0
  110. data/ext/libuv/src/unix/process.c +495 -0
  111. data/ext/libuv/src/unix/signal.c +269 -0
  112. data/ext/libuv/src/unix/stream.c +990 -0
  113. data/ext/libuv/src/unix/sunos.c +481 -0
  114. data/ext/libuv/src/unix/tcp.c +393 -0
  115. data/ext/libuv/src/unix/thread.c +251 -0
  116. data/ext/libuv/src/unix/timer.c +136 -0
  117. data/ext/libuv/src/unix/tty.c +145 -0
  118. data/ext/libuv/src/unix/udp.c +659 -0
  119. data/ext/libuv/src/unix/uv-eio.c +107 -0
  120. data/ext/libuv/src/unix/uv-eio.h +13 -0
  121. data/ext/libuv/src/uv-common.c +380 -0
  122. data/ext/libuv/src/uv-common.h +170 -0
  123. data/ext/libuv/src/win/async.c +100 -0
  124. data/ext/libuv/src/win/atomicops-inl.h +56 -0
  125. data/ext/libuv/src/win/core.c +278 -0
  126. data/ext/libuv/src/win/dl.c +86 -0
  127. data/ext/libuv/src/win/error.c +155 -0
  128. data/ext/libuv/src/win/fs-event.c +510 -0
  129. data/ext/libuv/src/win/fs.c +1948 -0
  130. data/ext/libuv/src/win/getaddrinfo.c +365 -0
  131. data/ext/libuv/src/win/handle-inl.h +149 -0
  132. data/ext/libuv/src/win/handle.c +154 -0
  133. data/ext/libuv/src/win/internal.h +343 -0
  134. data/ext/libuv/src/win/loop-watcher.c +122 -0
  135. data/ext/libuv/src/win/pipe.c +1672 -0
  136. data/ext/libuv/src/win/poll.c +616 -0
  137. data/ext/libuv/src/win/process-stdio.c +500 -0
  138. data/ext/libuv/src/win/process.c +1013 -0
  139. data/ext/libuv/src/win/req-inl.h +220 -0
  140. data/ext/libuv/src/win/req.c +25 -0
  141. data/ext/libuv/src/win/signal.c +57 -0
  142. data/ext/libuv/src/win/stream-inl.h +67 -0
  143. data/ext/libuv/src/win/stream.c +167 -0
  144. data/ext/libuv/src/win/tcp.c +1394 -0
  145. data/ext/libuv/src/win/thread.c +372 -0
  146. data/ext/libuv/src/win/threadpool.c +74 -0
  147. data/ext/libuv/src/win/timer.c +224 -0
  148. data/ext/libuv/src/win/tty.c +1799 -0
  149. data/ext/libuv/src/win/udp.c +716 -0
  150. data/ext/libuv/src/win/util.c +864 -0
  151. data/ext/libuv/src/win/winapi.c +132 -0
  152. data/ext/libuv/src/win/winapi.h +4452 -0
  153. data/ext/libuv/src/win/winsock.c +557 -0
  154. data/ext/libuv/src/win/winsock.h +171 -0
  155. data/ext/libuv/test/benchmark-async-pummel.c +97 -0
  156. data/ext/libuv/test/benchmark-async.c +137 -0
  157. data/ext/libuv/test/benchmark-fs-stat.c +135 -0
  158. data/ext/libuv/test/benchmark-getaddrinfo.c +94 -0
  159. data/ext/libuv/test/benchmark-list.h +127 -0
  160. data/ext/libuv/test/benchmark-loop-count.c +88 -0
  161. data/ext/libuv/test/benchmark-million-timers.c +65 -0
  162. data/ext/libuv/test/benchmark-ping-pongs.c +213 -0
  163. data/ext/libuv/test/benchmark-pound.c +324 -0
  164. data/ext/libuv/test/benchmark-pump.c +462 -0
  165. data/ext/libuv/test/benchmark-sizes.c +44 -0
  166. data/ext/libuv/test/benchmark-spawn.c +162 -0
  167. data/ext/libuv/test/benchmark-tcp-write-batch.c +140 -0
  168. data/ext/libuv/test/benchmark-thread.c +64 -0
  169. data/ext/libuv/test/benchmark-udp-packet-storm.c +247 -0
  170. data/ext/libuv/test/blackhole-server.c +118 -0
  171. data/ext/libuv/test/dns-server.c +321 -0
  172. data/ext/libuv/test/echo-server.c +378 -0
  173. data/ext/libuv/test/fixtures/empty_file +0 -0
  174. data/ext/libuv/test/fixtures/load_error.node +1 -0
  175. data/ext/libuv/test/run-benchmarks.c +64 -0
  176. data/ext/libuv/test/run-tests.c +138 -0
  177. data/ext/libuv/test/runner-unix.c +295 -0
  178. data/ext/libuv/test/runner-unix.h +36 -0
  179. data/ext/libuv/test/runner-win.c +285 -0
  180. data/ext/libuv/test/runner-win.h +42 -0
  181. data/ext/libuv/test/runner.c +355 -0
  182. data/ext/libuv/test/runner.h +159 -0
  183. data/ext/libuv/test/task.h +112 -0
  184. data/ext/libuv/test/test-async.c +118 -0
  185. data/ext/libuv/test/test-callback-order.c +76 -0
  186. data/ext/libuv/test/test-callback-stack.c +203 -0
  187. data/ext/libuv/test/test-connection-fail.c +148 -0
  188. data/ext/libuv/test/test-cwd-and-chdir.c +64 -0
  189. data/ext/libuv/test/test-delayed-accept.c +188 -0
  190. data/ext/libuv/test/test-dlerror.c +58 -0
  191. data/ext/libuv/test/test-error.c +59 -0
  192. data/ext/libuv/test/test-fail-always.c +29 -0
  193. data/ext/libuv/test/test-fs-event.c +474 -0
  194. data/ext/libuv/test/test-fs-poll.c +146 -0
  195. data/ext/libuv/test/test-fs.c +1843 -0
  196. data/ext/libuv/test/test-get-currentexe.c +63 -0
  197. data/ext/libuv/test/test-get-loadavg.c +36 -0
  198. data/ext/libuv/test/test-get-memory.c +38 -0
  199. data/ext/libuv/test/test-getaddrinfo.c +122 -0
  200. data/ext/libuv/test/test-getsockname.c +342 -0
  201. data/ext/libuv/test/test-hrtime.c +54 -0
  202. data/ext/libuv/test/test-idle.c +81 -0
  203. data/ext/libuv/test/test-ipc-send-recv.c +209 -0
  204. data/ext/libuv/test/test-ipc.c +620 -0
  205. data/ext/libuv/test/test-list.h +427 -0
  206. data/ext/libuv/test/test-loop-handles.c +336 -0
  207. data/ext/libuv/test/test-multiple-listen.c +102 -0
  208. data/ext/libuv/test/test-mutexes.c +63 -0
  209. data/ext/libuv/test/test-pass-always.c +28 -0
  210. data/ext/libuv/test/test-ping-pong.c +253 -0
  211. data/ext/libuv/test/test-pipe-bind-error.c +140 -0
  212. data/ext/libuv/test/test-pipe-connect-error.c +96 -0
  213. data/ext/libuv/test/test-platform-output.c +87 -0
  214. data/ext/libuv/test/test-poll-close.c +72 -0
  215. data/ext/libuv/test/test-poll.c +573 -0
  216. data/ext/libuv/test/test-process-title.c +49 -0
  217. data/ext/libuv/test/test-ref.c +338 -0
  218. data/ext/libuv/test/test-run-once.c +48 -0
  219. data/ext/libuv/test/test-semaphore.c +111 -0
  220. data/ext/libuv/test/test-shutdown-close.c +103 -0
  221. data/ext/libuv/test/test-shutdown-eof.c +183 -0
  222. data/ext/libuv/test/test-signal.c +162 -0
  223. data/ext/libuv/test/test-spawn.c +863 -0
  224. data/ext/libuv/test/test-stdio-over-pipes.c +246 -0
  225. data/ext/libuv/test/test-tcp-bind-error.c +191 -0
  226. data/ext/libuv/test/test-tcp-bind6-error.c +154 -0
  227. data/ext/libuv/test/test-tcp-close-while-connecting.c +80 -0
  228. data/ext/libuv/test/test-tcp-close.c +129 -0
  229. data/ext/libuv/test/test-tcp-connect-error-after-write.c +95 -0
  230. data/ext/libuv/test/test-tcp-connect-error.c +70 -0
  231. data/ext/libuv/test/test-tcp-connect-timeout.c +85 -0
  232. data/ext/libuv/test/test-tcp-connect6-error.c +68 -0
  233. data/ext/libuv/test/test-tcp-flags.c +51 -0
  234. data/ext/libuv/test/test-tcp-shutdown-after-write.c +131 -0
  235. data/ext/libuv/test/test-tcp-unexpected-read.c +113 -0
  236. data/ext/libuv/test/test-tcp-write-error.c +168 -0
  237. data/ext/libuv/test/test-tcp-write-to-half-open-connection.c +135 -0
  238. data/ext/libuv/test/test-tcp-writealot.c +170 -0
  239. data/ext/libuv/test/test-thread.c +183 -0
  240. data/ext/libuv/test/test-threadpool.c +57 -0
  241. data/ext/libuv/test/test-timer-again.c +141 -0
  242. data/ext/libuv/test/test-timer.c +152 -0
  243. data/ext/libuv/test/test-tty.c +110 -0
  244. data/ext/libuv/test/test-udp-dgram-too-big.c +86 -0
  245. data/ext/libuv/test/test-udp-ipv6.c +156 -0
  246. data/ext/libuv/test/test-udp-multicast-join.c +139 -0
  247. data/ext/libuv/test/test-udp-multicast-ttl.c +86 -0
  248. data/ext/libuv/test/test-udp-options.c +86 -0
  249. data/ext/libuv/test/test-udp-send-and-recv.c +208 -0
  250. data/ext/libuv/test/test-util.c +97 -0
  251. data/ext/libuv/test/test-walk-handles.c +77 -0
  252. data/ext/libuv/uv.gyp +375 -0
  253. data/ext/libuv/vcbuild.bat +105 -0
  254. data/foolio.gemspec +18 -0
  255. data/lib/foolio.rb +9 -0
  256. data/lib/foolio/handle.rb +27 -0
  257. data/lib/foolio/listener.rb +26 -0
  258. data/lib/foolio/loop.rb +79 -0
  259. data/lib/foolio/stream.rb +109 -0
  260. data/lib/foolio/version.rb +3 -0
  261. metadata +309 -0
@@ -0,0 +1,864 @@
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to
5
+ * deal in the Software without restriction, including without limitation the
6
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ * sell copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
+ * IN THE SOFTWARE.
20
+ */
21
+
22
+ #include <assert.h>
23
+ #include <direct.h>
24
+ #include <limits.h>
25
+ #include <malloc.h>
26
+ #include <stdio.h>
27
+ #include <string.h>
28
+ #include <time.h>
29
+ #include <wchar.h>
30
+
31
+ #include "uv.h"
32
+ #include "internal.h"
33
+
34
+ #include <iphlpapi.h>
35
+ #include <psapi.h>
36
+ #include <tlhelp32.h>
37
+
38
+
39
+ /*
40
+ * Max title length; the only thing MSDN tells us about the maximum length
41
+ * of the console title is that it is smaller than 64K. However in practice
42
+ * it is much smaller, and there is no way to figure out what the exact length
43
+ * of the title is or can be, at least not on XP. To make it even more
44
+ * annoying, GetConsoleTitle failes when the buffer to be read into is bigger
45
+ * than the actual maximum length. So we make a conservative guess here;
46
+ * just don't put the novel you're writing in the title, unless the plot
47
+ * survives truncation.
48
+ */
49
+ #define MAX_TITLE_LENGTH 8192
50
+
51
+ /* The number of nanoseconds in one second. */
52
+ #undef NANOSEC
53
+ #define NANOSEC 1000000000
54
+
55
+
56
+ /* Cached copy of the process title, plus a mutex guarding it. */
57
+ static char *process_title;
58
+ static CRITICAL_SECTION process_title_lock;
59
+
60
+ /* The tick frequency of the high-resolution clock. */
61
+ static uint64_t hrtime_frequency_ = 0;
62
+
63
+
64
+ /*
65
+ * One-time intialization code for functionality defined in util.c.
66
+ */
67
+ void uv__util_init() {
68
+ /* Initialize process title access mutex. */
69
+ InitializeCriticalSection(&process_title_lock);
70
+
71
+ /* Retrieve high-resolution timer frequency. */
72
+ if (!QueryPerformanceFrequency((LARGE_INTEGER*) &hrtime_frequency_))
73
+ hrtime_frequency_ = 0;
74
+ }
75
+
76
+
77
+ int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
78
+ char* utf8Buffer, size_t utf8Size) {
79
+ return WideCharToMultiByte(CP_UTF8,
80
+ 0,
81
+ utf16Buffer,
82
+ utf16Size,
83
+ utf8Buffer,
84
+ utf8Size,
85
+ NULL,
86
+ NULL);
87
+ }
88
+
89
+
90
+ int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
91
+ size_t utf16Size) {
92
+ return MultiByteToWideChar(CP_UTF8,
93
+ 0,
94
+ utf8Buffer,
95
+ -1,
96
+ utf16Buffer,
97
+ utf16Size);
98
+ }
99
+
100
+
101
+ int uv_exepath(char* buffer, size_t* size_ptr) {
102
+ int utf8_len, utf16_buffer_len, utf16_len;
103
+ WCHAR* utf16_buffer;
104
+
105
+ if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) {
106
+ return -1;
107
+ }
108
+
109
+ if (*size_ptr > 32768) {
110
+ /* Windows paths can never be longer than this. */
111
+ utf16_buffer_len = 32768;
112
+ } else {
113
+ utf16_buffer_len = (int) *size_ptr;
114
+ }
115
+
116
+ utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len);
117
+ if (!utf16_buffer) {
118
+ return -1;
119
+ }
120
+
121
+ /* Get the path as UTF-16. */
122
+ utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
123
+ if (utf16_len <= 0) {
124
+ goto error;
125
+ }
126
+
127
+ /* utf16_len contains the length, *not* including the terminating null. */
128
+ utf16_buffer[utf16_len] = L'\0';
129
+
130
+ /* Convert to UTF-8 */
131
+ utf8_len = WideCharToMultiByte(CP_UTF8,
132
+ 0,
133
+ utf16_buffer,
134
+ -1,
135
+ buffer,
136
+ *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr,
137
+ NULL,
138
+ NULL);
139
+ if (utf8_len == 0) {
140
+ goto error;
141
+ }
142
+
143
+ free(utf16_buffer);
144
+
145
+ /* utf8_len *does* include the terminating null at this point, but the */
146
+ /* returned size shouldn't. */
147
+ *size_ptr = utf8_len - 1;
148
+ return 0;
149
+
150
+ error:
151
+ free(utf16_buffer);
152
+ return -1;
153
+ }
154
+
155
+
156
+ uv_err_t uv_cwd(char* buffer, size_t size) {
157
+ DWORD utf16_len;
158
+ WCHAR utf16_buffer[MAX_PATH];
159
+ int r;
160
+
161
+ if (buffer == NULL || size == 0) {
162
+ return uv__new_artificial_error(UV_EINVAL);
163
+ }
164
+
165
+ utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
166
+ if (utf16_len == 0) {
167
+ return uv__new_sys_error(GetLastError());
168
+ } else if (utf16_len > MAX_PATH) {
169
+ /* This should be impossible; however the CRT has a code path to deal */
170
+ /* with this scenario, so I added a check anyway. */
171
+ return uv__new_artificial_error(UV_EIO);
172
+ }
173
+
174
+ /* utf16_len contains the length, *not* including the terminating null. */
175
+ utf16_buffer[utf16_len] = L'\0';
176
+
177
+ /* The returned directory should not have a trailing slash, unless it */
178
+ /* points at a drive root, like c:\. Remove it if needed.*/
179
+ if (utf16_buffer[utf16_len - 1] == L'\\' &&
180
+ !(utf16_len == 3 && utf16_buffer[1] == L':')) {
181
+ utf16_len--;
182
+ utf16_buffer[utf16_len] = L'\0';
183
+ }
184
+
185
+ /* Convert to UTF-8 */
186
+ r = WideCharToMultiByte(CP_UTF8,
187
+ 0,
188
+ utf16_buffer,
189
+ -1,
190
+ buffer,
191
+ size > INT_MAX ? INT_MAX : (int) size,
192
+ NULL,
193
+ NULL);
194
+ if (r == 0) {
195
+ return uv__new_sys_error(GetLastError());
196
+ }
197
+
198
+ return uv_ok_;
199
+ }
200
+
201
+
202
+ uv_err_t uv_chdir(const char* dir) {
203
+ WCHAR utf16_buffer[MAX_PATH];
204
+ size_t utf16_len;
205
+ WCHAR drive_letter, env_var[4];
206
+
207
+ if (dir == NULL) {
208
+ return uv__new_artificial_error(UV_EINVAL);
209
+ }
210
+
211
+ if (MultiByteToWideChar(CP_UTF8,
212
+ 0,
213
+ dir,
214
+ -1,
215
+ utf16_buffer,
216
+ MAX_PATH) == 0) {
217
+ DWORD error = GetLastError();
218
+ /* The maximum length of the current working directory is 260 chars, */
219
+ /* including terminating null. If it doesn't fit, the path name must be */
220
+ /* too long. */
221
+ if (error == ERROR_INSUFFICIENT_BUFFER) {
222
+ return uv__new_artificial_error(UV_ENAMETOOLONG);
223
+ } else {
224
+ return uv__new_sys_error(error);
225
+ }
226
+ }
227
+
228
+ if (!SetCurrentDirectoryW(utf16_buffer)) {
229
+ return uv__new_sys_error(GetLastError());
230
+ }
231
+
232
+ /* Windows stores the drive-local path in an "hidden" environment variable, */
233
+ /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */
234
+ /* update this, so we'll have to do it. */
235
+ utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
236
+ if (utf16_len == 0) {
237
+ return uv__new_sys_error(GetLastError());
238
+ } else if (utf16_len > MAX_PATH) {
239
+ return uv__new_artificial_error(UV_EIO);
240
+ }
241
+
242
+ /* The returned directory should not have a trailing slash, unless it */
243
+ /* points at a drive root, like c:\. Remove it if needed. */
244
+ if (utf16_buffer[utf16_len - 1] == L'\\' &&
245
+ !(utf16_len == 3 && utf16_buffer[1] == L':')) {
246
+ utf16_len--;
247
+ utf16_buffer[utf16_len] = L'\0';
248
+ }
249
+
250
+ if (utf16_len < 2 || utf16_buffer[1] != L':') {
251
+ /* Doesn't look like a drive letter could be there - probably an UNC */
252
+ /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */
253
+ drive_letter = 0;
254
+ } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') {
255
+ drive_letter = utf16_buffer[0];
256
+ } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') {
257
+ /* Convert to uppercase. */
258
+ drive_letter = utf16_buffer[0] - L'a' + L'A';
259
+ } else {
260
+ /* Not valid. */
261
+ drive_letter = 0;
262
+ }
263
+
264
+ if (drive_letter != 0) {
265
+ /* Construct the environment variable name and set it. */
266
+ env_var[0] = L'=';
267
+ env_var[1] = drive_letter;
268
+ env_var[2] = L':';
269
+ env_var[3] = L'\0';
270
+
271
+ if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
272
+ return uv__new_sys_error(GetLastError());
273
+ }
274
+ }
275
+
276
+ return uv_ok_;
277
+ }
278
+
279
+
280
+ void uv_loadavg(double avg[3]) {
281
+ /* Can't be implemented */
282
+ avg[0] = avg[1] = avg[2] = 0;
283
+ }
284
+
285
+
286
+ uint64_t uv_get_free_memory(void) {
287
+ MEMORYSTATUSEX memory_status;
288
+ memory_status.dwLength = sizeof(memory_status);
289
+
290
+ if(!GlobalMemoryStatusEx(&memory_status))
291
+ {
292
+ return -1;
293
+ }
294
+
295
+ return (uint64_t)memory_status.ullAvailPhys;
296
+ }
297
+
298
+
299
+ uint64_t uv_get_total_memory(void) {
300
+ MEMORYSTATUSEX memory_status;
301
+ memory_status.dwLength = sizeof(memory_status);
302
+
303
+ if(!GlobalMemoryStatusEx(&memory_status))
304
+ {
305
+ return -1;
306
+ }
307
+
308
+ return (uint64_t)memory_status.ullTotalPhys;
309
+ }
310
+
311
+
312
+ int uv_parent_pid() {
313
+ int parent_pid = -1;
314
+ HANDLE handle;
315
+ PROCESSENTRY32 pe;
316
+ int current_pid = GetCurrentProcessId();
317
+
318
+ pe.dwSize = sizeof(PROCESSENTRY32);
319
+ handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
320
+
321
+ if (Process32First(handle, &pe)) {
322
+ do {
323
+ if (pe.th32ProcessID == current_pid) {
324
+ parent_pid = pe.th32ParentProcessID;
325
+ break;
326
+ }
327
+ } while( Process32Next(handle, &pe));
328
+ }
329
+
330
+ CloseHandle(handle);
331
+ return parent_pid;
332
+ }
333
+
334
+
335
+ char** uv_setup_args(int argc, char** argv) {
336
+ return argv;
337
+ }
338
+
339
+
340
+ uv_err_t uv_set_process_title(const char* title) {
341
+ uv_err_t err;
342
+ int length;
343
+ WCHAR* title_w = NULL;
344
+
345
+ uv__once_init();
346
+
347
+ /* Find out how big the buffer for the wide-char title must be */
348
+ length = uv_utf8_to_utf16(title, NULL, 0);
349
+ if (!length) {
350
+ err = uv__new_sys_error(GetLastError());
351
+ goto done;
352
+ }
353
+
354
+ /* Convert to wide-char string */
355
+ title_w = (WCHAR*)malloc(sizeof(WCHAR) * length);
356
+ if (!title_w) {
357
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
358
+ }
359
+
360
+ length = uv_utf8_to_utf16(title, title_w, length);
361
+ if (!length) {
362
+ err = uv__new_sys_error(GetLastError());
363
+ goto done;
364
+ };
365
+
366
+ /* If the title must be truncated insert a \0 terminator there */
367
+ if (length > MAX_TITLE_LENGTH) {
368
+ title_w[MAX_TITLE_LENGTH - 1] = L'\0';
369
+ }
370
+
371
+ if (!SetConsoleTitleW(title_w)) {
372
+ err = uv__new_sys_error(GetLastError());
373
+ goto done;
374
+ }
375
+
376
+ EnterCriticalSection(&process_title_lock);
377
+ free(process_title);
378
+ process_title = strdup(title);
379
+ LeaveCriticalSection(&process_title_lock);
380
+
381
+ err = uv_ok_;
382
+
383
+ done:
384
+ free(title_w);
385
+ return err;
386
+ }
387
+
388
+
389
+ static int uv__get_process_title() {
390
+ WCHAR title_w[MAX_TITLE_LENGTH];
391
+ int length;
392
+
393
+ if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
394
+ return -1;
395
+ }
396
+
397
+ /* Find out what the size of the buffer is that we need */
398
+ length = uv_utf16_to_utf8(title_w, -1, NULL, 0);
399
+ if (!length) {
400
+ return -1;
401
+ }
402
+
403
+ assert(!process_title);
404
+ process_title = (char*)malloc(length);
405
+ if (!process_title) {
406
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
407
+ }
408
+
409
+ /* Do utf16 -> utf8 conversion here */
410
+ if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
411
+ free(process_title);
412
+ return -1;
413
+ }
414
+
415
+ return 0;
416
+ }
417
+
418
+
419
+ uv_err_t uv_get_process_title(char* buffer, size_t size) {
420
+ uv__once_init();
421
+
422
+ EnterCriticalSection(&process_title_lock);
423
+ /*
424
+ * If the process_title was never read before nor explicitly set,
425
+ * we must query it with getConsoleTitleW
426
+ */
427
+ if (!process_title && uv__get_process_title() == -1) {
428
+ return uv__new_sys_error(GetLastError());
429
+ }
430
+
431
+ assert(process_title);
432
+ strncpy(buffer, process_title, size);
433
+ LeaveCriticalSection(&process_title_lock);
434
+
435
+ return uv_ok_;
436
+ }
437
+
438
+
439
+ uint64_t uv_hrtime(void) {
440
+ LARGE_INTEGER counter;
441
+
442
+ uv__once_init();
443
+
444
+ /* If the performance frequency is zero, there's no support. */
445
+ if (!hrtime_frequency_) {
446
+ /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
447
+ return 0;
448
+ }
449
+
450
+ if (!QueryPerformanceCounter(&counter)) {
451
+ /* uv__set_sys_error(loop, GetLastError()); */
452
+ return 0;
453
+ }
454
+
455
+ /* Because we have no guarantee about the order of magnitude of the */
456
+ /* performance counter frequency, and there may not be much headroom to */
457
+ /* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
458
+ return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) +
459
+ (((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_)
460
+ << 32);
461
+ }
462
+
463
+
464
+ uv_err_t uv_resident_set_memory(size_t* rss) {
465
+ HANDLE current_process;
466
+ PROCESS_MEMORY_COUNTERS pmc;
467
+
468
+ current_process = GetCurrentProcess();
469
+
470
+ if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) {
471
+ return uv__new_sys_error(GetLastError());
472
+ }
473
+
474
+ *rss = pmc.WorkingSetSize;
475
+
476
+ return uv_ok_;
477
+ }
478
+
479
+
480
+ uv_err_t uv_uptime(double* uptime) {
481
+ BYTE stack_buffer[4096];
482
+ BYTE* malloced_buffer = NULL;
483
+ BYTE* buffer = (BYTE*) stack_buffer;
484
+ size_t buffer_size = sizeof(stack_buffer);
485
+ DWORD data_size;
486
+
487
+ PERF_DATA_BLOCK* data_block;
488
+ PERF_OBJECT_TYPE* object_type;
489
+ PERF_COUNTER_DEFINITION* counter_definition;
490
+
491
+ DWORD i;
492
+
493
+ for (;;) {
494
+ LONG result;
495
+
496
+ data_size = (DWORD) buffer_size;
497
+ result = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
498
+ L"2",
499
+ NULL,
500
+ NULL,
501
+ buffer,
502
+ &data_size);
503
+ if (result == ERROR_SUCCESS) {
504
+ break;
505
+ } else if (result != ERROR_MORE_DATA) {
506
+ *uptime = 0;
507
+ return uv__new_sys_error(result);
508
+ }
509
+
510
+ free(malloced_buffer);
511
+
512
+ buffer_size *= 2;
513
+ /* Don't let the buffer grow infinitely. */
514
+ if (buffer_size > 1 << 20) {
515
+ goto internalError;
516
+ }
517
+
518
+ buffer = malloced_buffer = (BYTE*) malloc(buffer_size);
519
+ if (malloced_buffer == NULL) {
520
+ *uptime = 0;
521
+ return uv__new_artificial_error(UV_ENOMEM);
522
+ }
523
+ }
524
+
525
+ if (data_size < sizeof(*data_block))
526
+ goto internalError;
527
+
528
+ data_block = (PERF_DATA_BLOCK*) buffer;
529
+
530
+ if (wmemcmp(data_block->Signature, L"PERF", 4) != 0)
531
+ goto internalError;
532
+
533
+ if (data_size < data_block->HeaderLength + sizeof(*object_type))
534
+ goto internalError;
535
+
536
+ object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength);
537
+
538
+ if (object_type->NumInstances != PERF_NO_INSTANCES)
539
+ goto internalError;
540
+
541
+ counter_definition = (PERF_COUNTER_DEFINITION*) (buffer +
542
+ data_block->HeaderLength + object_type->HeaderLength);
543
+ for (i = 0; i < object_type->NumCounters; i++) {
544
+ if ((BYTE*) counter_definition + sizeof(*counter_definition) >
545
+ buffer + data_size) {
546
+ break;
547
+ }
548
+
549
+ if (counter_definition->CounterNameTitleIndex == 674 &&
550
+ counter_definition->CounterSize == sizeof(uint64_t)) {
551
+ if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size ||
552
+ !(counter_definition->CounterType & PERF_OBJECT_TIMER)) {
553
+ goto internalError;
554
+ } else {
555
+ BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
556
+ counter_definition->CounterOffset;
557
+ uint64_t value = *((uint64_t*) address);
558
+ *uptime = (double) (object_type->PerfTime.QuadPart - value) /
559
+ (double) object_type->PerfFreq.QuadPart;
560
+ free(malloced_buffer);
561
+ return uv_ok_;
562
+ }
563
+ }
564
+
565
+ counter_definition = (PERF_COUNTER_DEFINITION*)
566
+ ((BYTE*) counter_definition + counter_definition->ByteLength);
567
+ }
568
+
569
+ /* If we get here, the uptime value was not found. */
570
+ free(malloced_buffer);
571
+ *uptime = 0;
572
+ return uv__new_artificial_error(UV_ENOSYS);
573
+
574
+ internalError:
575
+ free(malloced_buffer);
576
+ *uptime = 0;
577
+ return uv__new_artificial_error(UV_EIO);
578
+ }
579
+
580
+
581
+ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
582
+ SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
583
+ DWORD sppi_size;
584
+ SYSTEM_INFO system_info;
585
+ DWORD cpu_count, i, r;
586
+ ULONG result_size;
587
+ size_t size;
588
+ uv_err_t err;
589
+ uv_cpu_info_t* cpu_info;
590
+
591
+ *cpu_infos = NULL;
592
+ *count = 0;
593
+
594
+ uv__once_init();
595
+
596
+ GetSystemInfo(&system_info);
597
+ cpu_count = system_info.dwNumberOfProcessors;
598
+
599
+ size = cpu_count * sizeof(uv_cpu_info_t);
600
+ *cpu_infos = (uv_cpu_info_t*) malloc(size);
601
+ if (*cpu_infos == NULL) {
602
+ err = uv__new_artificial_error(UV_ENOMEM);
603
+ goto out;
604
+ }
605
+ memset(*cpu_infos, 0, size);
606
+
607
+ sppi_size = sizeof(*sppi) * cpu_count;
608
+ sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) malloc(sppi_size);
609
+ if (!sppi) {
610
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
611
+ }
612
+
613
+ r = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
614
+ sppi,
615
+ sppi_size,
616
+ &result_size);
617
+ if (r != ERROR_SUCCESS || result_size != sppi_size) {
618
+ err = uv__new_sys_error(GetLastError());
619
+ goto out;
620
+ }
621
+
622
+ for (i = 0; i < cpu_count; i++) {
623
+ WCHAR key_name[128];
624
+ HKEY processor_key;
625
+ DWORD cpu_speed;
626
+ DWORD cpu_speed_size = sizeof(cpu_speed);
627
+ WCHAR cpu_brand[256];
628
+ DWORD cpu_brand_size = sizeof(cpu_brand);
629
+
630
+ _snwprintf(key_name,
631
+ ARRAY_SIZE(key_name),
632
+ L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
633
+ i);
634
+
635
+ r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
636
+ key_name,
637
+ 0,
638
+ KEY_QUERY_VALUE,
639
+ &processor_key);
640
+ if (r != ERROR_SUCCESS) {
641
+ err = uv__new_sys_error(GetLastError());
642
+ goto out;
643
+ }
644
+
645
+ if (RegQueryValueExW(processor_key,
646
+ L"~MHz",
647
+ NULL, NULL,
648
+ (BYTE*) &cpu_speed,
649
+ &cpu_speed_size) != ERROR_SUCCESS) {
650
+ err = uv__new_sys_error(GetLastError());
651
+ RegCloseKey(processor_key);
652
+ goto out;
653
+ }
654
+
655
+ if (RegQueryValueExW(processor_key,
656
+ L"ProcessorNameString",
657
+ NULL, NULL,
658
+ (BYTE*) &cpu_brand,
659
+ &cpu_brand_size) != ERROR_SUCCESS) {
660
+ err = uv__new_sys_error(GetLastError());
661
+ RegCloseKey(processor_key);
662
+ goto out;
663
+ }
664
+
665
+ RegCloseKey(processor_key);
666
+
667
+ cpu_info = &(*cpu_infos)[i];
668
+ cpu_info->speed = cpu_speed;
669
+ cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
670
+ cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
671
+ sppi[i].IdleTime.QuadPart) / 10000;
672
+ cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
673
+ cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
674
+ cpu_info->cpu_times.nice = 0;
675
+
676
+ size = uv_utf16_to_utf8(cpu_brand,
677
+ cpu_brand_size / sizeof(WCHAR),
678
+ NULL,
679
+ 0);
680
+ if (size == 0) {
681
+ err = uv__new_sys_error(GetLastError());
682
+ goto out;
683
+ }
684
+
685
+ /* Allocate 1 extra byte for the null terminator. */
686
+ cpu_info->model = (char*) malloc(size + 1);
687
+ if (cpu_info->model == NULL) {
688
+ err = uv__new_artificial_error(UV_ENOMEM);
689
+ goto out;
690
+ }
691
+
692
+ if (uv_utf16_to_utf8(cpu_brand,
693
+ cpu_brand_size / sizeof(WCHAR),
694
+ cpu_info->model,
695
+ size) == 0) {
696
+ err = uv__new_sys_error(GetLastError());
697
+ goto out;
698
+ }
699
+
700
+ /* Ensure that cpu_info->model is null terminated. */
701
+ cpu_info->model[size] = '\0';
702
+
703
+ (*count)++;
704
+ }
705
+
706
+ err = uv_ok_;
707
+
708
+ out:
709
+ if (sppi) {
710
+ free(sppi);
711
+ }
712
+
713
+ if (err.code != UV_OK &&
714
+ *cpu_infos != NULL) {
715
+ int i;
716
+
717
+ for (i = 0; i < *count; i++) {
718
+ /* This is safe because the cpu_infos memory area is zeroed out */
719
+ /* immediately after allocating it. */
720
+ free((*cpu_infos)[i].model);
721
+ }
722
+ free(*cpu_infos);
723
+
724
+ *cpu_infos = NULL;
725
+ *count = 0;
726
+ }
727
+
728
+ return err;
729
+ }
730
+
731
+
732
+ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
733
+ int i;
734
+
735
+ for (i = 0; i < count; i++) {
736
+ free(cpu_infos[i].model);
737
+ }
738
+
739
+ free(cpu_infos);
740
+ }
741
+
742
+
743
+ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
744
+ int* count) {
745
+ unsigned long size = 0;
746
+ IP_ADAPTER_ADDRESSES* adapter_addresses;
747
+ IP_ADAPTER_ADDRESSES* adapter_address;
748
+ uv_interface_address_t* address;
749
+ struct sockaddr* sock_addr;
750
+ int length;
751
+ char* name;
752
+ /* Use IP_ADAPTER_UNICAST_ADDRESS_XP to retain backwards compatibility */
753
+ /* with Windows XP */
754
+ IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
755
+
756
+ if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size)
757
+ != ERROR_BUFFER_OVERFLOW) {
758
+ return uv__new_sys_error(GetLastError());
759
+ }
760
+
761
+ adapter_addresses = (IP_ADAPTER_ADDRESSES*)malloc(size);
762
+ if (!adapter_addresses) {
763
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
764
+ }
765
+
766
+ if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapter_addresses, &size)
767
+ != ERROR_SUCCESS) {
768
+ return uv__new_sys_error(GetLastError());
769
+ }
770
+
771
+ /* Count the number of interfaces */
772
+ *count = 0;
773
+
774
+ for (adapter_address = adapter_addresses;
775
+ adapter_address != NULL;
776
+ adapter_address = adapter_address->Next) {
777
+
778
+ if (adapter_address->OperStatus != IfOperStatusUp)
779
+ continue;
780
+
781
+ unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
782
+ adapter_address->FirstUnicastAddress;
783
+
784
+ while (unicast_address) {
785
+ (*count)++;
786
+ unicast_address = unicast_address->Next;
787
+ }
788
+ }
789
+
790
+ *addresses = (uv_interface_address_t*)
791
+ malloc(*count * sizeof(uv_interface_address_t));
792
+ if (!(*addresses)) {
793
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
794
+ }
795
+
796
+ address = *addresses;
797
+
798
+ for (adapter_address = adapter_addresses;
799
+ adapter_address != NULL;
800
+ adapter_address = adapter_address->Next) {
801
+
802
+ if (adapter_address->OperStatus != IfOperStatusUp)
803
+ continue;
804
+
805
+ name = NULL;
806
+ unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
807
+ adapter_address->FirstUnicastAddress;
808
+
809
+ while (unicast_address) {
810
+ sock_addr = unicast_address->Address.lpSockaddr;
811
+ if (sock_addr->sa_family == AF_INET6) {
812
+ address->address.address6 = *((struct sockaddr_in6 *)sock_addr);
813
+ } else {
814
+ address->address.address4 = *((struct sockaddr_in *)sock_addr);
815
+ }
816
+
817
+ address->is_internal =
818
+ adapter_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK ? 1 : 0;
819
+
820
+ if (!name) {
821
+ /* Convert FriendlyName to utf8 */
822
+ length = uv_utf16_to_utf8(adapter_address->FriendlyName, -1, NULL, 0);
823
+ if (length) {
824
+ name = (char*)malloc(length);
825
+ if (!name) {
826
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
827
+ }
828
+
829
+ if (!uv_utf16_to_utf8(adapter_address->FriendlyName, -1, name,
830
+ length)) {
831
+ free(name);
832
+ name = NULL;
833
+ }
834
+ }
835
+ }
836
+
837
+ assert(name);
838
+ address->name = name;
839
+
840
+ unicast_address = unicast_address->Next;
841
+ address++;
842
+ }
843
+ }
844
+
845
+ free(adapter_addresses);
846
+
847
+ return uv_ok_;
848
+ }
849
+
850
+
851
+ void uv_free_interface_addresses(uv_interface_address_t* addresses,
852
+ int count) {
853
+ int i;
854
+ char* freed_name = NULL;
855
+
856
+ for (i = 0; i < count; i++) {
857
+ if (freed_name != addresses[i].name) {
858
+ freed_name = addresses[i].name;
859
+ free(freed_name);
860
+ }
861
+ }
862
+
863
+ free(addresses);
864
+ }