From 91ae279e8f448c709862ce175d57c1c32ac6812c Mon Sep 17 00:00:00 2001 From: Raymond Pasco Date: Tue, 13 Dec 2016 14:44:49 -0800 Subject: [PATCH 1/2] Unbundle libuv --- Makefile | 60 +- outside/libuv-v1.7.5/.gitignore | 75 - outside/libuv-v1.7.5/.mailmap | 38 - outside/libuv-v1.7.5/AUTHORS | 227 - outside/libuv-v1.7.5/CONTRIBUTING.md | 166 - outside/libuv-v1.7.5/ChangeLog | 2273 -------- outside/libuv-v1.7.5/LICENSE | 46 - outside/libuv-v1.7.5/MAINTAINERS.md | 36 - outside/libuv-v1.7.5/Makefile.am | 343 -- outside/libuv-v1.7.5/Makefile.mingw | 84 - outside/libuv-v1.7.5/README.md | 245 - outside/libuv-v1.7.5/android-configure | 20 - outside/libuv-v1.7.5/appveyor.yml | 36 - outside/libuv-v1.7.5/autogen.sh | 46 - outside/libuv-v1.7.5/checksparse.sh | 234 - outside/libuv-v1.7.5/common.gypi | 211 - outside/libuv-v1.7.5/configure.ac | 68 - outside/libuv-v1.7.5/docs/Makefile | 178 - outside/libuv-v1.7.5/docs/make.bat | 243 - outside/libuv-v1.7.5/docs/src/async.rst | 57 - outside/libuv-v1.7.5/docs/src/check.rst | 46 - outside/libuv-v1.7.5/docs/src/conf.py | 348 -- outside/libuv-v1.7.5/docs/src/design.rst | 137 - outside/libuv-v1.7.5/docs/src/dll.rst | 44 - outside/libuv-v1.7.5/docs/src/dns.rst | 108 - outside/libuv-v1.7.5/docs/src/errors.rst | 331 -- outside/libuv-v1.7.5/docs/src/fs.rst | 290 - outside/libuv-v1.7.5/docs/src/fs_event.rst | 108 - outside/libuv-v1.7.5/docs/src/fs_poll.rst | 72 - outside/libuv-v1.7.5/docs/src/handle.rst | 181 - outside/libuv-v1.7.5/docs/src/idle.rst | 54 - outside/libuv-v1.7.5/docs/src/index.rst | 95 - outside/libuv-v1.7.5/docs/src/loop.rst | 166 - .../docs/src/migration_010_100.rst | 244 - outside/libuv-v1.7.5/docs/src/misc.rst | 290 - outside/libuv-v1.7.5/docs/src/pipe.rst | 104 - outside/libuv-v1.7.5/docs/src/poll.rst | 103 - outside/libuv-v1.7.5/docs/src/prepare.rst | 46 - outside/libuv-v1.7.5/docs/src/process.rst | 225 - outside/libuv-v1.7.5/docs/src/request.rst | 82 - outside/libuv-v1.7.5/docs/src/signal.rst | 77 - .../docs/src/sphinx-plugins/manpage.py | 46 - .../docs/src/static/architecture.png | Bin 206767 -> 0 bytes .../src/static/diagrams.key/Data/st0-311.jpg | Bin 19328 -> 0 bytes .../src/static/diagrams.key/Data/st1-475.jpg | Bin 12655 -> 0 bytes .../docs/src/static/diagrams.key/Index.zip | Bin 71160 -> 0 bytes .../Metadata/BuildVersionHistory.plist | 8 - .../diagrams.key/Metadata/DocumentIdentifier | 1 - .../diagrams.key/Metadata/Properties.plist | Bin 340 -> 0 bytes .../src/static/diagrams.key/preview-micro.jpg | Bin 1425 -> 0 bytes .../src/static/diagrams.key/preview-web.jpg | Bin 8106 -> 0 bytes .../docs/src/static/diagrams.key/preview.jpg | Bin 107456 -> 0 bytes .../libuv-v1.7.5/docs/src/static/favicon.ico | Bin 15086 -> 0 bytes outside/libuv-v1.7.5/docs/src/static/logo.png | Bin 33545 -> 0 bytes .../docs/src/static/loop_iteration.png | Bin 80528 -> 0 bytes outside/libuv-v1.7.5/docs/src/stream.rst | 219 - outside/libuv-v1.7.5/docs/src/tcp.rst | 108 - outside/libuv-v1.7.5/docs/src/threading.rst | 160 - outside/libuv-v1.7.5/docs/src/threadpool.rst | 67 - outside/libuv-v1.7.5/docs/src/timer.rst | 76 - outside/libuv-v1.7.5/docs/src/tty.rst | 93 - outside/libuv-v1.7.5/docs/src/udp.rst | 295 -- outside/libuv-v1.7.5/docs/src/version.rst | 60 - outside/libuv-v1.7.5/gyp_uv.py | 96 - outside/libuv-v1.7.5/img/banner.png | Bin 44102 -> 0 bytes outside/libuv-v1.7.5/img/logos.svg | 152 - .../libuv-v1.7.5/include/android-ifaddrs.h | 54 - outside/libuv-v1.7.5/include/pthread-fixes.h | 72 - .../libuv-v1.7.5/include/stdint-msvc2008.h | 247 - outside/libuv-v1.7.5/include/tree.h | 768 --- outside/libuv-v1.7.5/include/uv-aix.h | 32 - outside/libuv-v1.7.5/include/uv-bsd.h | 34 - outside/libuv-v1.7.5/include/uv-darwin.h | 61 - outside/libuv-v1.7.5/include/uv-errno.h | 418 -- outside/libuv-v1.7.5/include/uv-linux.h | 34 - outside/libuv-v1.7.5/include/uv-sunos.h | 44 - outside/libuv-v1.7.5/include/uv-threadpool.h | 37 - outside/libuv-v1.7.5/include/uv-unix.h | 383 -- outside/libuv-v1.7.5/include/uv-version.h | 43 - outside/libuv-v1.7.5/include/uv-win.h | 653 --- outside/libuv-v1.7.5/include/uv.h | 1472 ------ outside/libuv-v1.7.5/libuv.nsi | 86 - outside/libuv-v1.7.5/libuv.pc.in | 11 - outside/libuv-v1.7.5/m4/.gitignore | 4 - outside/libuv-v1.7.5/m4/as_case.m4 | 21 - outside/libuv-v1.7.5/m4/libuv-check-flags.m4 | 319 -- outside/libuv-v1.7.5/samples/.gitignore | 22 - .../samples/socks5-proxy/.gitignore | 21 - .../libuv-v1.7.5/samples/socks5-proxy/LICENSE | 53 - .../samples/socks5-proxy/Makefile | 46 - .../samples/socks5-proxy/build.gyp | 46 - .../samples/socks5-proxy/client.c | 737 --- .../libuv-v1.7.5/samples/socks5-proxy/defs.h | 139 - .../samples/socks5-proxy/getopt.c | 131 - .../libuv-v1.7.5/samples/socks5-proxy/main.c | 99 - .../libuv-v1.7.5/samples/socks5-proxy/s5.c | 271 - .../libuv-v1.7.5/samples/socks5-proxy/s5.h | 94 - .../samples/socks5-proxy/server.c | 241 - .../libuv-v1.7.5/samples/socks5-proxy/util.c | 72 - outside/libuv-v1.7.5/src/fs-poll.c | 255 - outside/libuv-v1.7.5/src/heap-inl.h | 245 - outside/libuv-v1.7.5/src/inet.c | 313 -- outside/libuv-v1.7.5/src/queue.h | 94 - outside/libuv-v1.7.5/src/threadpool.c | 308 -- outside/libuv-v1.7.5/src/unix/aix.c | 1158 ---- .../libuv-v1.7.5/src/unix/android-ifaddrs.c | 703 --- outside/libuv-v1.7.5/src/unix/async.c | 284 - outside/libuv-v1.7.5/src/unix/atomic-ops.h | 72 - outside/libuv-v1.7.5/src/unix/core.c | 1091 ---- .../libuv-v1.7.5/src/unix/darwin-proctitle.c | 206 - outside/libuv-v1.7.5/src/unix/darwin.c | 333 -- outside/libuv-v1.7.5/src/unix/dl.c | 83 - outside/libuv-v1.7.5/src/unix/freebsd.c | 448 -- outside/libuv-v1.7.5/src/unix/fs.c | 1255 ----- outside/libuv-v1.7.5/src/unix/fsevents.c | 899 ---- outside/libuv-v1.7.5/src/unix/getaddrinfo.c | 202 - outside/libuv-v1.7.5/src/unix/getnameinfo.c | 120 - outside/libuv-v1.7.5/src/unix/internal.h | 316 -- outside/libuv-v1.7.5/src/unix/kqueue.c | 426 -- outside/libuv-v1.7.5/src/unix/linux-core.c | 897 ---- outside/libuv-v1.7.5/src/unix/linux-inotify.c | 257 - .../libuv-v1.7.5/src/unix/linux-syscalls.c | 471 -- .../libuv-v1.7.5/src/unix/linux-syscalls.h | 158 - outside/libuv-v1.7.5/src/unix/loop-watcher.c | 63 - outside/libuv-v1.7.5/src/unix/loop.c | 155 - outside/libuv-v1.7.5/src/unix/netbsd.c | 368 -- outside/libuv-v1.7.5/src/unix/openbsd.c | 384 -- outside/libuv-v1.7.5/src/unix/pipe.c | 288 - outside/libuv-v1.7.5/src/unix/poll.c | 113 - outside/libuv-v1.7.5/src/unix/process.c | 552 -- outside/libuv-v1.7.5/src/unix/proctitle.c | 102 - outside/libuv-v1.7.5/src/unix/pthread-fixes.c | 104 - outside/libuv-v1.7.5/src/unix/signal.c | 465 -- outside/libuv-v1.7.5/src/unix/spinlock.h | 53 - outside/libuv-v1.7.5/src/unix/stream.c | 1615 ------ outside/libuv-v1.7.5/src/unix/sunos.c | 763 --- outside/libuv-v1.7.5/src/unix/tcp.c | 362 -- outside/libuv-v1.7.5/src/unix/thread.c | 525 -- outside/libuv-v1.7.5/src/unix/timer.c | 172 - outside/libuv-v1.7.5/src/unix/tty.c | 270 - outside/libuv-v1.7.5/src/unix/udp.c | 871 --- outside/libuv-v1.7.5/src/uv-common.c | 626 --- outside/libuv-v1.7.5/src/uv-common.h | 223 - outside/libuv-v1.7.5/src/version.c | 45 - outside/libuv-v1.7.5/src/win/async.c | 99 - outside/libuv-v1.7.5/src/win/atomicops-inl.h | 56 - outside/libuv-v1.7.5/src/win/core.c | 457 -- outside/libuv-v1.7.5/src/win/dl.c | 113 - outside/libuv-v1.7.5/src/win/error.c | 169 - outside/libuv-v1.7.5/src/win/fs-event.c | 543 -- outside/libuv-v1.7.5/src/win/fs.c | 2349 -------- outside/libuv-v1.7.5/src/win/getaddrinfo.c | 361 -- outside/libuv-v1.7.5/src/win/getnameinfo.c | 150 - outside/libuv-v1.7.5/src/win/handle-inl.h | 179 - outside/libuv-v1.7.5/src/win/handle.c | 154 - outside/libuv-v1.7.5/src/win/internal.h | 381 -- outside/libuv-v1.7.5/src/win/loop-watcher.c | 122 - outside/libuv-v1.7.5/src/win/pipe.c | 2114 -------- outside/libuv-v1.7.5/src/win/poll.c | 635 --- outside/libuv-v1.7.5/src/win/process-stdio.c | 510 -- outside/libuv-v1.7.5/src/win/process.c | 1247 ----- outside/libuv-v1.7.5/src/win/req-inl.h | 224 - outside/libuv-v1.7.5/src/win/req.c | 25 - outside/libuv-v1.7.5/src/win/signal.c | 356 -- outside/libuv-v1.7.5/src/win/stream-inl.h | 56 - outside/libuv-v1.7.5/src/win/stream.c | 249 - outside/libuv-v1.7.5/src/win/tcp.c | 1507 ------ outside/libuv-v1.7.5/src/win/thread.c | 697 --- outside/libuv-v1.7.5/src/win/timer.c | 200 - outside/libuv-v1.7.5/src/win/tty.c | 2084 -------- outside/libuv-v1.7.5/src/win/udp.c | 926 ---- outside/libuv-v1.7.5/src/win/util.c | 1220 ----- outside/libuv-v1.7.5/src/win/winapi.c | 142 - outside/libuv-v1.7.5/src/win/winapi.h | 4703 ----------------- outside/libuv-v1.7.5/src/win/winsock.c | 561 -- outside/libuv-v1.7.5/src/win/winsock.h | 190 - .../test/benchmark-async-pummel.c | 119 - outside/libuv-v1.7.5/test/benchmark-async.c | 141 - outside/libuv-v1.7.5/test/benchmark-fs-stat.c | 136 - .../libuv-v1.7.5/test/benchmark-getaddrinfo.c | 92 - outside/libuv-v1.7.5/test/benchmark-list.h | 163 - .../libuv-v1.7.5/test/benchmark-loop-count.c | 92 - .../test/benchmark-million-async.c | 112 - .../test/benchmark-million-timers.c | 86 - .../test/benchmark-multi-accept.c | 447 -- .../libuv-v1.7.5/test/benchmark-ping-pongs.c | 221 - outside/libuv-v1.7.5/test/benchmark-pound.c | 351 -- outside/libuv-v1.7.5/test/benchmark-pump.c | 476 -- outside/libuv-v1.7.5/test/benchmark-sizes.c | 46 - outside/libuv-v1.7.5/test/benchmark-spawn.c | 164 - .../test/benchmark-tcp-write-batch.c | 144 - outside/libuv-v1.7.5/test/benchmark-thread.c | 64 - .../libuv-v1.7.5/test/benchmark-udp-pummel.c | 243 - outside/libuv-v1.7.5/test/blackhole-server.c | 121 - outside/libuv-v1.7.5/test/dns-server.c | 340 -- outside/libuv-v1.7.5/test/echo-server.c | 378 -- outside/libuv-v1.7.5/test/fixtures/empty_file | 0 .../test/fixtures/load_error.node | 1 - outside/libuv-v1.7.5/test/run-benchmarks.c | 65 - outside/libuv-v1.7.5/test/run-tests.c | 181 - outside/libuv-v1.7.5/test/runner-unix.c | 400 -- outside/libuv-v1.7.5/test/runner-unix.h | 36 - outside/libuv-v1.7.5/test/runner-win.c | 371 -- outside/libuv-v1.7.5/test/runner-win.h | 43 - outside/libuv-v1.7.5/test/runner.c | 464 -- outside/libuv-v1.7.5/test/runner.h | 178 - outside/libuv-v1.7.5/test/task.h | 250 - outside/libuv-v1.7.5/test/test-active.c | 84 - .../libuv-v1.7.5/test/test-async-null-cb.c | 55 - outside/libuv-v1.7.5/test/test-async.c | 134 - outside/libuv-v1.7.5/test/test-barrier.c | 106 - .../libuv-v1.7.5/test/test-callback-order.c | 77 - .../libuv-v1.7.5/test/test-callback-stack.c | 205 - outside/libuv-v1.7.5/test/test-close-fd.c | 76 - outside/libuv-v1.7.5/test/test-close-order.c | 80 - outside/libuv-v1.7.5/test/test-condvar.c | 173 - .../libuv-v1.7.5/test/test-connection-fail.c | 151 - .../libuv-v1.7.5/test/test-cwd-and-chdir.c | 51 - .../test/test-default-loop-close.c | 59 - .../libuv-v1.7.5/test/test-delayed-accept.c | 189 - outside/libuv-v1.7.5/test/test-dlerror.c | 55 - outside/libuv-v1.7.5/test/test-embed.c | 138 - outside/libuv-v1.7.5/test/test-emfile.c | 111 - outside/libuv-v1.7.5/test/test-error.c | 50 - outside/libuv-v1.7.5/test/test-fail-always.c | 29 - outside/libuv-v1.7.5/test/test-fs-event.c | 883 ---- outside/libuv-v1.7.5/test/test-fs-poll.c | 186 - outside/libuv-v1.7.5/test/test-fs.c | 2540 --------- .../libuv-v1.7.5/test/test-get-currentexe.c | 86 - outside/libuv-v1.7.5/test/test-get-loadavg.c | 36 - outside/libuv-v1.7.5/test/test-get-memory.c | 38 - outside/libuv-v1.7.5/test/test-getaddrinfo.c | 182 - outside/libuv-v1.7.5/test/test-getnameinfo.c | 101 - outside/libuv-v1.7.5/test/test-getsockname.c | 361 -- .../libuv-v1.7.5/test/test-handle-fileno.c | 121 - outside/libuv-v1.7.5/test/test-homedir.c | 49 - outside/libuv-v1.7.5/test/test-hrtime.c | 54 - outside/libuv-v1.7.5/test/test-idle.c | 99 - outside/libuv-v1.7.5/test/test-ip4-addr.c | 46 - outside/libuv-v1.7.5/test/test-ip6-addr.c | 141 - .../libuv-v1.7.5/test/test-ipc-send-recv.c | 236 - outside/libuv-v1.7.5/test/test-ipc.c | 779 --- outside/libuv-v1.7.5/test/test-list.h | 722 --- outside/libuv-v1.7.5/test/test-loop-alive.c | 67 - outside/libuv-v1.7.5/test/test-loop-close.c | 53 - .../libuv-v1.7.5/test/test-loop-configure.c | 38 - outside/libuv-v1.7.5/test/test-loop-handles.c | 337 -- outside/libuv-v1.7.5/test/test-loop-stop.c | 71 - outside/libuv-v1.7.5/test/test-loop-time.c | 63 - .../libuv-v1.7.5/test/test-multiple-listen.c | 109 - outside/libuv-v1.7.5/test/test-mutexes.c | 122 - outside/libuv-v1.7.5/test/test-osx-select.c | 140 - outside/libuv-v1.7.5/test/test-pass-always.c | 28 - outside/libuv-v1.7.5/test/test-ping-pong.c | 270 - .../libuv-v1.7.5/test/test-pipe-bind-error.c | 136 - .../test/test-pipe-close-stdout-read-stdin.c | 104 - .../test/test-pipe-connect-error.c | 95 - .../test/test-pipe-connect-multiple.c | 104 - .../test/test-pipe-connect-prepare.c | 83 - .../libuv-v1.7.5/test/test-pipe-getsockname.c | 263 - .../test/test-pipe-pending-instances.c | 59 - outside/libuv-v1.7.5/test/test-pipe-sendmsg.c | 169 - .../test/test-pipe-server-close.c | 91 - .../test/test-pipe-set-non-blocking.c | 99 - .../libuv-v1.7.5/test/test-platform-output.c | 126 - .../test-poll-close-doesnt-corrupt-stack.c | 114 - outside/libuv-v1.7.5/test/test-poll-close.c | 73 - .../libuv-v1.7.5/test/test-poll-closesocket.c | 89 - outside/libuv-v1.7.5/test/test-poll.c | 560 -- .../libuv-v1.7.5/test/test-process-title.c | 53 - outside/libuv-v1.7.5/test/test-ref.c | 442 -- outside/libuv-v1.7.5/test/test-run-nowait.c | 45 - outside/libuv-v1.7.5/test/test-run-once.c | 48 - outside/libuv-v1.7.5/test/test-semaphore.c | 111 - .../libuv-v1.7.5/test/test-shutdown-close.c | 108 - outside/libuv-v1.7.5/test/test-shutdown-eof.c | 182 - .../libuv-v1.7.5/test/test-shutdown-twice.c | 84 - .../test/test-signal-multiple-loops.c | 290 - outside/libuv-v1.7.5/test/test-signal.c | 152 - .../test/test-socket-buffer-size.c | 77 - outside/libuv-v1.7.5/test/test-spawn.c | 1706 ------ .../libuv-v1.7.5/test/test-stdio-over-pipes.c | 255 - .../libuv-v1.7.5/test/test-tcp-bind-error.c | 216 - .../libuv-v1.7.5/test/test-tcp-bind6-error.c | 176 - .../libuv-v1.7.5/test/test-tcp-close-accept.c | 188 - .../test/test-tcp-close-while-connecting.c | 86 - outside/libuv-v1.7.5/test/test-tcp-close.c | 136 - .../test/test-tcp-connect-error-after-write.c | 98 - .../test/test-tcp-connect-error.c | 73 - .../test/test-tcp-connect-timeout.c | 91 - .../test/test-tcp-connect6-error.c | 71 - .../test/test-tcp-create-socket-early.c | 206 - outside/libuv-v1.7.5/test/test-tcp-flags.c | 52 - outside/libuv-v1.7.5/test/test-tcp-oob.c | 128 - outside/libuv-v1.7.5/test/test-tcp-open.c | 220 - .../libuv-v1.7.5/test/test-tcp-read-stop.c | 76 - .../test/test-tcp-shutdown-after-write.c | 138 - .../libuv-v1.7.5/test/test-tcp-try-write.c | 130 - .../test/test-tcp-unexpected-read.c | 117 - .../test/test-tcp-write-after-connect.c | 68 - .../libuv-v1.7.5/test/test-tcp-write-fail.c | 115 - .../test/test-tcp-write-queue-order.c | 137 - .../test-tcp-write-to-half-open-connection.c | 141 - .../libuv-v1.7.5/test/test-tcp-writealot.c | 176 - outside/libuv-v1.7.5/test/test-thread-equal.c | 45 - outside/libuv-v1.7.5/test/test-thread.c | 211 - .../test/test-threadpool-cancel.c | 361 -- outside/libuv-v1.7.5/test/test-threadpool.c | 76 - outside/libuv-v1.7.5/test/test-timer-again.c | 141 - .../libuv-v1.7.5/test/test-timer-from-check.c | 80 - outside/libuv-v1.7.5/test/test-timer.c | 303 -- outside/libuv-v1.7.5/test/test-tty.c | 181 - outside/libuv-v1.7.5/test/test-udp-bind.c | 93 - .../test/test-udp-create-socket-early.c | 132 - .../test/test-udp-dgram-too-big.c | 91 - outside/libuv-v1.7.5/test/test-udp-ipv6.c | 172 - .../test/test-udp-multicast-interface.c | 99 - .../test/test-udp-multicast-interface6.c | 103 - .../test/test-udp-multicast-join.c | 150 - .../test/test-udp-multicast-join6.c | 161 - .../test/test-udp-multicast-ttl.c | 94 - outside/libuv-v1.7.5/test/test-udp-open.c | 204 - outside/libuv-v1.7.5/test/test-udp-options.c | 126 - .../test/test-udp-send-and-recv.c | 214 - .../test/test-udp-send-immediate.c | 148 - .../test/test-udp-send-unreachable.c | 150 - outside/libuv-v1.7.5/test/test-udp-try-send.c | 133 - outside/libuv-v1.7.5/test/test-walk-handles.c | 77 - .../test/test-watcher-cross-stop.c | 103 - outside/libuv-v1.7.5/uv.gyp | 500 -- outside/libuv-v1.7.5/vcbuild.bat | 153 - 331 files changed, 7 insertions(+), 86032 deletions(-) delete mode 100644 outside/libuv-v1.7.5/.gitignore delete mode 100644 outside/libuv-v1.7.5/.mailmap delete mode 100644 outside/libuv-v1.7.5/AUTHORS delete mode 100644 outside/libuv-v1.7.5/CONTRIBUTING.md delete mode 100644 outside/libuv-v1.7.5/ChangeLog delete mode 100644 outside/libuv-v1.7.5/LICENSE delete mode 100644 outside/libuv-v1.7.5/MAINTAINERS.md delete mode 100644 outside/libuv-v1.7.5/Makefile.am delete mode 100644 outside/libuv-v1.7.5/Makefile.mingw delete mode 100644 outside/libuv-v1.7.5/README.md delete mode 100755 outside/libuv-v1.7.5/android-configure delete mode 100644 outside/libuv-v1.7.5/appveyor.yml delete mode 100755 outside/libuv-v1.7.5/autogen.sh delete mode 100755 outside/libuv-v1.7.5/checksparse.sh delete mode 100644 outside/libuv-v1.7.5/common.gypi delete mode 100644 outside/libuv-v1.7.5/configure.ac delete mode 100644 outside/libuv-v1.7.5/docs/Makefile delete mode 100644 outside/libuv-v1.7.5/docs/make.bat delete mode 100644 outside/libuv-v1.7.5/docs/src/async.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/check.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/conf.py delete mode 100644 outside/libuv-v1.7.5/docs/src/design.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/dll.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/dns.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/errors.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/fs.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/fs_event.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/fs_poll.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/handle.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/idle.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/index.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/loop.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/migration_010_100.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/misc.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/pipe.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/poll.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/prepare.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/process.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/request.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/signal.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/sphinx-plugins/manpage.py delete mode 100644 outside/libuv-v1.7.5/docs/src/static/architecture.png delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/Data/st0-311.jpg delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/Data/st1-475.jpg delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/Index.zip delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/DocumentIdentifier delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/Properties.plist delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/preview-micro.jpg delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/preview-web.jpg delete mode 100644 outside/libuv-v1.7.5/docs/src/static/diagrams.key/preview.jpg delete mode 100644 outside/libuv-v1.7.5/docs/src/static/favicon.ico delete mode 100644 outside/libuv-v1.7.5/docs/src/static/logo.png delete mode 100644 outside/libuv-v1.7.5/docs/src/static/loop_iteration.png delete mode 100644 outside/libuv-v1.7.5/docs/src/stream.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/tcp.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/threading.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/threadpool.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/timer.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/tty.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/udp.rst delete mode 100644 outside/libuv-v1.7.5/docs/src/version.rst delete mode 100755 outside/libuv-v1.7.5/gyp_uv.py delete mode 100644 outside/libuv-v1.7.5/img/banner.png delete mode 100644 outside/libuv-v1.7.5/img/logos.svg delete mode 100644 outside/libuv-v1.7.5/include/android-ifaddrs.h delete mode 100644 outside/libuv-v1.7.5/include/pthread-fixes.h delete mode 100644 outside/libuv-v1.7.5/include/stdint-msvc2008.h delete mode 100644 outside/libuv-v1.7.5/include/tree.h delete mode 100644 outside/libuv-v1.7.5/include/uv-aix.h delete mode 100644 outside/libuv-v1.7.5/include/uv-bsd.h delete mode 100644 outside/libuv-v1.7.5/include/uv-darwin.h delete mode 100644 outside/libuv-v1.7.5/include/uv-errno.h delete mode 100644 outside/libuv-v1.7.5/include/uv-linux.h delete mode 100644 outside/libuv-v1.7.5/include/uv-sunos.h delete mode 100644 outside/libuv-v1.7.5/include/uv-threadpool.h delete mode 100644 outside/libuv-v1.7.5/include/uv-unix.h delete mode 100644 outside/libuv-v1.7.5/include/uv-version.h delete mode 100644 outside/libuv-v1.7.5/include/uv-win.h delete mode 100644 outside/libuv-v1.7.5/include/uv.h delete mode 100644 outside/libuv-v1.7.5/libuv.nsi delete mode 100644 outside/libuv-v1.7.5/libuv.pc.in delete mode 100644 outside/libuv-v1.7.5/m4/.gitignore delete mode 100644 outside/libuv-v1.7.5/m4/as_case.m4 delete mode 100644 outside/libuv-v1.7.5/m4/libuv-check-flags.m4 delete mode 100644 outside/libuv-v1.7.5/samples/.gitignore delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/.gitignore delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/LICENSE delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/Makefile delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/build.gyp delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/client.c delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/defs.h delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/getopt.c delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/main.c delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/s5.c delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/s5.h delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/server.c delete mode 100644 outside/libuv-v1.7.5/samples/socks5-proxy/util.c delete mode 100644 outside/libuv-v1.7.5/src/fs-poll.c delete mode 100644 outside/libuv-v1.7.5/src/heap-inl.h delete mode 100644 outside/libuv-v1.7.5/src/inet.c delete mode 100644 outside/libuv-v1.7.5/src/queue.h delete mode 100644 outside/libuv-v1.7.5/src/threadpool.c delete mode 100644 outside/libuv-v1.7.5/src/unix/aix.c delete mode 100644 outside/libuv-v1.7.5/src/unix/android-ifaddrs.c delete mode 100644 outside/libuv-v1.7.5/src/unix/async.c delete mode 100644 outside/libuv-v1.7.5/src/unix/atomic-ops.h delete mode 100644 outside/libuv-v1.7.5/src/unix/core.c delete mode 100644 outside/libuv-v1.7.5/src/unix/darwin-proctitle.c delete mode 100644 outside/libuv-v1.7.5/src/unix/darwin.c delete mode 100644 outside/libuv-v1.7.5/src/unix/dl.c delete mode 100644 outside/libuv-v1.7.5/src/unix/freebsd.c delete mode 100644 outside/libuv-v1.7.5/src/unix/fs.c delete mode 100644 outside/libuv-v1.7.5/src/unix/fsevents.c delete mode 100644 outside/libuv-v1.7.5/src/unix/getaddrinfo.c delete mode 100644 outside/libuv-v1.7.5/src/unix/getnameinfo.c delete mode 100644 outside/libuv-v1.7.5/src/unix/internal.h delete mode 100644 outside/libuv-v1.7.5/src/unix/kqueue.c delete mode 100644 outside/libuv-v1.7.5/src/unix/linux-core.c delete mode 100644 outside/libuv-v1.7.5/src/unix/linux-inotify.c delete mode 100644 outside/libuv-v1.7.5/src/unix/linux-syscalls.c delete mode 100644 outside/libuv-v1.7.5/src/unix/linux-syscalls.h delete mode 100644 outside/libuv-v1.7.5/src/unix/loop-watcher.c delete mode 100644 outside/libuv-v1.7.5/src/unix/loop.c delete mode 100644 outside/libuv-v1.7.5/src/unix/netbsd.c delete mode 100644 outside/libuv-v1.7.5/src/unix/openbsd.c delete mode 100644 outside/libuv-v1.7.5/src/unix/pipe.c delete mode 100644 outside/libuv-v1.7.5/src/unix/poll.c delete mode 100644 outside/libuv-v1.7.5/src/unix/process.c delete mode 100644 outside/libuv-v1.7.5/src/unix/proctitle.c delete mode 100644 outside/libuv-v1.7.5/src/unix/pthread-fixes.c delete mode 100644 outside/libuv-v1.7.5/src/unix/signal.c delete mode 100644 outside/libuv-v1.7.5/src/unix/spinlock.h delete mode 100644 outside/libuv-v1.7.5/src/unix/stream.c delete mode 100644 outside/libuv-v1.7.5/src/unix/sunos.c delete mode 100644 outside/libuv-v1.7.5/src/unix/tcp.c delete mode 100644 outside/libuv-v1.7.5/src/unix/thread.c delete mode 100644 outside/libuv-v1.7.5/src/unix/timer.c delete mode 100644 outside/libuv-v1.7.5/src/unix/tty.c delete mode 100644 outside/libuv-v1.7.5/src/unix/udp.c delete mode 100644 outside/libuv-v1.7.5/src/uv-common.c delete mode 100644 outside/libuv-v1.7.5/src/uv-common.h delete mode 100644 outside/libuv-v1.7.5/src/version.c delete mode 100644 outside/libuv-v1.7.5/src/win/async.c delete mode 100644 outside/libuv-v1.7.5/src/win/atomicops-inl.h delete mode 100644 outside/libuv-v1.7.5/src/win/core.c delete mode 100644 outside/libuv-v1.7.5/src/win/dl.c delete mode 100644 outside/libuv-v1.7.5/src/win/error.c delete mode 100644 outside/libuv-v1.7.5/src/win/fs-event.c delete mode 100644 outside/libuv-v1.7.5/src/win/fs.c delete mode 100644 outside/libuv-v1.7.5/src/win/getaddrinfo.c delete mode 100644 outside/libuv-v1.7.5/src/win/getnameinfo.c delete mode 100644 outside/libuv-v1.7.5/src/win/handle-inl.h delete mode 100644 outside/libuv-v1.7.5/src/win/handle.c delete mode 100644 outside/libuv-v1.7.5/src/win/internal.h delete mode 100644 outside/libuv-v1.7.5/src/win/loop-watcher.c delete mode 100644 outside/libuv-v1.7.5/src/win/pipe.c delete mode 100644 outside/libuv-v1.7.5/src/win/poll.c delete mode 100644 outside/libuv-v1.7.5/src/win/process-stdio.c delete mode 100644 outside/libuv-v1.7.5/src/win/process.c delete mode 100644 outside/libuv-v1.7.5/src/win/req-inl.h delete mode 100644 outside/libuv-v1.7.5/src/win/req.c delete mode 100644 outside/libuv-v1.7.5/src/win/signal.c delete mode 100644 outside/libuv-v1.7.5/src/win/stream-inl.h delete mode 100644 outside/libuv-v1.7.5/src/win/stream.c delete mode 100644 outside/libuv-v1.7.5/src/win/tcp.c delete mode 100644 outside/libuv-v1.7.5/src/win/thread.c delete mode 100644 outside/libuv-v1.7.5/src/win/timer.c delete mode 100644 outside/libuv-v1.7.5/src/win/tty.c delete mode 100644 outside/libuv-v1.7.5/src/win/udp.c delete mode 100644 outside/libuv-v1.7.5/src/win/util.c delete mode 100644 outside/libuv-v1.7.5/src/win/winapi.c delete mode 100644 outside/libuv-v1.7.5/src/win/winapi.h delete mode 100644 outside/libuv-v1.7.5/src/win/winsock.c delete mode 100644 outside/libuv-v1.7.5/src/win/winsock.h delete mode 100644 outside/libuv-v1.7.5/test/benchmark-async-pummel.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-async.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-fs-stat.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-getaddrinfo.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-list.h delete mode 100644 outside/libuv-v1.7.5/test/benchmark-loop-count.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-million-async.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-million-timers.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-multi-accept.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-ping-pongs.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-pound.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-pump.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-sizes.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-spawn.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-tcp-write-batch.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-thread.c delete mode 100644 outside/libuv-v1.7.5/test/benchmark-udp-pummel.c delete mode 100644 outside/libuv-v1.7.5/test/blackhole-server.c delete mode 100644 outside/libuv-v1.7.5/test/dns-server.c delete mode 100644 outside/libuv-v1.7.5/test/echo-server.c delete mode 100644 outside/libuv-v1.7.5/test/fixtures/empty_file delete mode 100644 outside/libuv-v1.7.5/test/fixtures/load_error.node delete mode 100644 outside/libuv-v1.7.5/test/run-benchmarks.c delete mode 100644 outside/libuv-v1.7.5/test/run-tests.c delete mode 100644 outside/libuv-v1.7.5/test/runner-unix.c delete mode 100644 outside/libuv-v1.7.5/test/runner-unix.h delete mode 100644 outside/libuv-v1.7.5/test/runner-win.c delete mode 100644 outside/libuv-v1.7.5/test/runner-win.h delete mode 100644 outside/libuv-v1.7.5/test/runner.c delete mode 100644 outside/libuv-v1.7.5/test/runner.h delete mode 100644 outside/libuv-v1.7.5/test/task.h delete mode 100644 outside/libuv-v1.7.5/test/test-active.c delete mode 100644 outside/libuv-v1.7.5/test/test-async-null-cb.c delete mode 100644 outside/libuv-v1.7.5/test/test-async.c delete mode 100644 outside/libuv-v1.7.5/test/test-barrier.c delete mode 100644 outside/libuv-v1.7.5/test/test-callback-order.c delete mode 100644 outside/libuv-v1.7.5/test/test-callback-stack.c delete mode 100644 outside/libuv-v1.7.5/test/test-close-fd.c delete mode 100644 outside/libuv-v1.7.5/test/test-close-order.c delete mode 100644 outside/libuv-v1.7.5/test/test-condvar.c delete mode 100644 outside/libuv-v1.7.5/test/test-connection-fail.c delete mode 100644 outside/libuv-v1.7.5/test/test-cwd-and-chdir.c delete mode 100644 outside/libuv-v1.7.5/test/test-default-loop-close.c delete mode 100644 outside/libuv-v1.7.5/test/test-delayed-accept.c delete mode 100644 outside/libuv-v1.7.5/test/test-dlerror.c delete mode 100644 outside/libuv-v1.7.5/test/test-embed.c delete mode 100644 outside/libuv-v1.7.5/test/test-emfile.c delete mode 100644 outside/libuv-v1.7.5/test/test-error.c delete mode 100644 outside/libuv-v1.7.5/test/test-fail-always.c delete mode 100644 outside/libuv-v1.7.5/test/test-fs-event.c delete mode 100644 outside/libuv-v1.7.5/test/test-fs-poll.c delete mode 100644 outside/libuv-v1.7.5/test/test-fs.c delete mode 100644 outside/libuv-v1.7.5/test/test-get-currentexe.c delete mode 100644 outside/libuv-v1.7.5/test/test-get-loadavg.c delete mode 100644 outside/libuv-v1.7.5/test/test-get-memory.c delete mode 100644 outside/libuv-v1.7.5/test/test-getaddrinfo.c delete mode 100644 outside/libuv-v1.7.5/test/test-getnameinfo.c delete mode 100644 outside/libuv-v1.7.5/test/test-getsockname.c delete mode 100644 outside/libuv-v1.7.5/test/test-handle-fileno.c delete mode 100644 outside/libuv-v1.7.5/test/test-homedir.c delete mode 100644 outside/libuv-v1.7.5/test/test-hrtime.c delete mode 100644 outside/libuv-v1.7.5/test/test-idle.c delete mode 100644 outside/libuv-v1.7.5/test/test-ip4-addr.c delete mode 100644 outside/libuv-v1.7.5/test/test-ip6-addr.c delete mode 100644 outside/libuv-v1.7.5/test/test-ipc-send-recv.c delete mode 100644 outside/libuv-v1.7.5/test/test-ipc.c delete mode 100644 outside/libuv-v1.7.5/test/test-list.h delete mode 100644 outside/libuv-v1.7.5/test/test-loop-alive.c delete mode 100644 outside/libuv-v1.7.5/test/test-loop-close.c delete mode 100644 outside/libuv-v1.7.5/test/test-loop-configure.c delete mode 100644 outside/libuv-v1.7.5/test/test-loop-handles.c delete mode 100644 outside/libuv-v1.7.5/test/test-loop-stop.c delete mode 100644 outside/libuv-v1.7.5/test/test-loop-time.c delete mode 100644 outside/libuv-v1.7.5/test/test-multiple-listen.c delete mode 100644 outside/libuv-v1.7.5/test/test-mutexes.c delete mode 100644 outside/libuv-v1.7.5/test/test-osx-select.c delete mode 100644 outside/libuv-v1.7.5/test/test-pass-always.c delete mode 100644 outside/libuv-v1.7.5/test/test-ping-pong.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-bind-error.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-close-stdout-read-stdin.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-connect-error.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-connect-multiple.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-connect-prepare.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-getsockname.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-pending-instances.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-sendmsg.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-server-close.c delete mode 100644 outside/libuv-v1.7.5/test/test-pipe-set-non-blocking.c delete mode 100644 outside/libuv-v1.7.5/test/test-platform-output.c delete mode 100644 outside/libuv-v1.7.5/test/test-poll-close-doesnt-corrupt-stack.c delete mode 100644 outside/libuv-v1.7.5/test/test-poll-close.c delete mode 100644 outside/libuv-v1.7.5/test/test-poll-closesocket.c delete mode 100644 outside/libuv-v1.7.5/test/test-poll.c delete mode 100644 outside/libuv-v1.7.5/test/test-process-title.c delete mode 100644 outside/libuv-v1.7.5/test/test-ref.c delete mode 100644 outside/libuv-v1.7.5/test/test-run-nowait.c delete mode 100644 outside/libuv-v1.7.5/test/test-run-once.c delete mode 100644 outside/libuv-v1.7.5/test/test-semaphore.c delete mode 100644 outside/libuv-v1.7.5/test/test-shutdown-close.c delete mode 100644 outside/libuv-v1.7.5/test/test-shutdown-eof.c delete mode 100644 outside/libuv-v1.7.5/test/test-shutdown-twice.c delete mode 100644 outside/libuv-v1.7.5/test/test-signal-multiple-loops.c delete mode 100644 outside/libuv-v1.7.5/test/test-signal.c delete mode 100644 outside/libuv-v1.7.5/test/test-socket-buffer-size.c delete mode 100644 outside/libuv-v1.7.5/test/test-spawn.c delete mode 100644 outside/libuv-v1.7.5/test/test-stdio-over-pipes.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-bind-error.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-bind6-error.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-close-accept.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-close-while-connecting.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-close.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-connect-error-after-write.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-connect-error.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-connect-timeout.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-connect6-error.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-create-socket-early.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-flags.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-oob.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-open.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-read-stop.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-shutdown-after-write.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-try-write.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-unexpected-read.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-write-after-connect.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-write-fail.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-write-queue-order.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-write-to-half-open-connection.c delete mode 100644 outside/libuv-v1.7.5/test/test-tcp-writealot.c delete mode 100644 outside/libuv-v1.7.5/test/test-thread-equal.c delete mode 100644 outside/libuv-v1.7.5/test/test-thread.c delete mode 100644 outside/libuv-v1.7.5/test/test-threadpool-cancel.c delete mode 100644 outside/libuv-v1.7.5/test/test-threadpool.c delete mode 100644 outside/libuv-v1.7.5/test/test-timer-again.c delete mode 100644 outside/libuv-v1.7.5/test/test-timer-from-check.c delete mode 100644 outside/libuv-v1.7.5/test/test-timer.c delete mode 100644 outside/libuv-v1.7.5/test/test-tty.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-bind.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-create-socket-early.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-dgram-too-big.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-ipv6.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-multicast-interface.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-multicast-interface6.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-multicast-join.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-multicast-join6.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-multicast-ttl.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-open.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-options.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-send-and-recv.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-send-immediate.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-send-unreachable.c delete mode 100644 outside/libuv-v1.7.5/test/test-udp-try-send.c delete mode 100644 outside/libuv-v1.7.5/test/test-walk-handles.c delete mode 100644 outside/libuv-v1.7.5/test/test-watcher-cross-stop.c delete mode 100644 outside/libuv-v1.7.5/uv.gyp delete mode 100644 outside/libuv-v1.7.5/vcbuild.bat diff --git a/Makefile b/Makefile index 5fc8507cac..b8c8d841f9 100644 --- a/Makefile +++ b/Makefile @@ -91,9 +91,9 @@ ifeq ($(OS),bsd) endif ifeq ($(STATIC),yes) -LIBS=-lssl -lcrypto -lncurses /usr/local/lib/libsigsegv.a /usr/local/lib/libgmp.a $(CURLLIB) $(OSLIBS) +LIBS=-lssl -lcrypto -luv -lncurses /usr/local/lib/libsigsegv.a /usr/local/lib/libgmp.a $(CURLLIB) $(OSLIBS) else -LIBS=-lssl -lcrypto -lgmp -lncurses -lsigsegv $(CURLLIB) $(OSLIBS) +LIBS=-lssl -lcrypto -luv -lgmp -lncurses -lsigsegv $(CURLLIB) $(OSLIBS) endif INCLUDE=include @@ -107,10 +107,6 @@ else CFLAGS?=-O3 endif -LIBUV_VER=libuv-v1.7.5 - -LIBUV_CONFIGURE_OPTIONS= - # NOTFORCHECKIN - restore -O3 # -DGHETTO \ # -DHUSH @@ -121,7 +117,6 @@ CFLAGS+= $(COSFLAGS) -ffast-math \ $(OPENSSLIFLAGS) \ $(CURLINC) \ -I$(INCLUDE) \ - -Ioutside/$(LIBUV_VER)/include \ -Ioutside/anachronism/include \ -Ioutside/ed25519/src \ -Ioutside/commonmark/src \ @@ -384,25 +379,6 @@ VERE_DFILES=$(VERE_OFILES:%.o=.d/%.d) -include $(VERE_DFILES) -# This is a silly hack necessitated by the fact that libuv uses configure -# -# * Making 'all' obviously requires outside/libuv, -# which requires the libuv Makefile to be created. -# * Making distclean on outside/libuv destroys the makefile. -# * ...so configuring outside/libuv is parodoxically required -# in order to distclean it! -# * But what if developer types 'make distclean all' ? -# * first target makes libuv Makefile, then destroys it...and -# second target knows that it was made. -# * ...so second target borks. -# * Solution: make libuv not only depend on its own Makefile, -# but on a side effect of creating its own makefile. -# -LIBUV_MAKEFILE=outside/$(LIBUV_VER)/Makefile -LIBUV_MAKEFILE2=outside/$(LIBUV_VER)/config.log - -LIBUV=outside/$(LIBUV_VER)/.libs/libuv.a - LIBED25519=outside/ed25519/ed25519.a LIBANACHRONISM=outside/anachronism/build/libanachronism.a @@ -430,27 +406,6 @@ all: urbit urbit: $(BIN)/urbit -$(LIBUV_MAKEFILE) $(LIBUV_MAKEFILE2): - cd outside/$(LIBUV_VER) ; sh autogen.sh ; ./configure $(LIBUV_CONFIGURE_OPTIONS) - -# [h]act II: the plot thickens -# -# * Specifying two targets that each configure libuv works -# when the rules are executed sequentially, -# * but when attempting a parallel build, it is likely Make -# will try to configure libuv simultaneously. -# * We can specify a dependency between the two targets so -# that execution of their rule(s) is serialized. -# * Further, libuv does not seem to be friendly towards -# parallel builds either. A true fix is out of scope here -# * ...so we must instruct Make to only use one job when it -# attempts to build libuv. -# -$(LIBUV_MAKEFILE2): $(LIBUV_MAKEFILE) - -$(LIBUV): $(LIBUV_MAKEFILE) $(LIBUV_MAKEFILE2) - $(MAKE) -C outside/$(LIBUV_VER) all-am -j1 - $(LIBED25519): $(MAKE) -C outside/ed25519 @@ -469,14 +424,14 @@ $(LIBSOFTFLOAT): $(V_OFILES): include/vere/vere.h ifdef NO_SILENT_RULES -$(BIN)/urbit: $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBUV) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT) $(LIBSOFTFLOAT) +$(BIN)/urbit: $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT) $(LIBSOFTFLOAT) mkdir -p $(BIN) - $(CLD) $(CLDOSFLAGS) -o $(BIN)/urbit $(VERE_OFILES) $(LIBUV) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT) $(LIBSOFTFLOAT) + $(CLD) $(CLDOSFLAGS) -o $(BIN)/urbit $(VERE_OFILES) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT) $(LIBSOFTFLOAT) else -$(BIN)/urbit: $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBUV) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT) $(LIBSOFTFLOAT) +$(BIN)/urbit: $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT) $(LIBSOFTFLOAT) @echo " CCLD $(BIN)/urbit" @mkdir -p $(BIN) - @$(CLD) $(CLDOSFLAGS) -o $(BIN)/urbit $(VERE_OFILES) $(LIBUV) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT) $(LIBSOFTFLOAT) + @$(CLD) $(CLDOSFLAGS) -o $(BIN)/urbit $(VERE_OFILES) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT) $(LIBSOFTFLOAT) endif tags: ctags etags gtags cscope @@ -516,8 +471,7 @@ clean: # 'make distclean all -jn' ∀ n>1 still does not work because it is possible # Make will attempt to build urbit while it is also cleaning urbit.. -distclean: clean $(LIBUV_MAKEFILE) - $(MAKE) -C outside/$(LIBUV_VER) distclean +distclean: clean $(MAKE) -C outside/ed25519 clean $(MAKE) -C outside/anachronism clean $(MAKE) -C outside/scrypt clean diff --git a/outside/libuv-v1.7.5/.gitignore b/outside/libuv-v1.7.5/.gitignore deleted file mode 100644 index 86a8a5b7b8..0000000000 --- a/outside/libuv-v1.7.5/.gitignore +++ /dev/null @@ -1,75 +0,0 @@ -*.swp -*.[oa] -*.l[oa] -*.opensdf -*.orig -*.pyc -*.sdf -*.suo -core -vgcore.* -.buildstamp -.dirstamp -.deps/ -/.libs/ -/aclocal.m4 -/ar-lib -/autom4te.cache/ -/compile -/config.guess -/config.log -/config.status -/config.sub -/configure -/depcomp -/install-sh -/libtool -/libuv.a -/libuv.dylib -/libuv.pc -/libuv.so -/ltmain.sh -/missing -/test-driver -Makefile -Makefile.in - -# Generated by gyp for android -*.target.mk - -/out/ -/build/gyp - -/test/.libs/ -/test/run-tests -/test/run-tests.exe -/test/run-tests.dSYM -/test/run-benchmarks -/test/run-benchmarks.exe -/test/run-benchmarks.dSYM - -*.sln -*.sln.cache -*.ncb -*.vcproj -*.vcproj*.user -*.vcxproj -*.vcxproj.filters -*.vcxproj.user -_UpgradeReport_Files/ -UpgradeLog*.XML -Debug -Release -ipch - -# sphinx generated files -/docs/build/ - -# Clion / IntelliJ project files -/.idea/ - -*.xcodeproj -*.xcworkspace - -# make dist output -libuv-*.tar.* diff --git a/outside/libuv-v1.7.5/.mailmap b/outside/libuv-v1.7.5/.mailmap deleted file mode 100644 index eb9b5e0d90..0000000000 --- a/outside/libuv-v1.7.5/.mailmap +++ /dev/null @@ -1,38 +0,0 @@ -Aaron Bieber -Alan Gutierrez -Andrius Bentkus -Bert Belder -Bert Belder -Brandon Philips -Brian White -Brian White -Caleb James DeLisle -Christoph Iserlohn -Devchandra Meetei Leishangthem -Fedor Indutny -Frank Denis -Isaac Z. Schlueter -Jason Williams -Justin Venus -Keno Fischer -Keno Fischer -Leith Bade -Leonard Hecker -Maciej Małecki -Marc Schlaich -Michael -Michael Neumann -Rasmus Christian Pedersen -Rasmus Christian Pedersen -Robert Mustacchi -Ryan Dahl -Ryan Emery -Sam Roberts -San-Tai Hsu -Santiago Gimeno -Saúl Ibarra Corretgé -Shigeki Ohtsu -Timothy J. Fontaine -Yasuhiro Matsumoto -Yazhong Liu -Yuki Okumura diff --git a/outside/libuv-v1.7.5/AUTHORS b/outside/libuv-v1.7.5/AUTHORS deleted file mode 100644 index b2397e2df6..0000000000 --- a/outside/libuv-v1.7.5/AUTHORS +++ /dev/null @@ -1,227 +0,0 @@ -# Authors ordered by first contribution. -Ryan Dahl -Bert Belder -Josh Roesslein -Alan Gutierrez -Joshua Peek -Igor Zinkovsky -San-Tai Hsu -Ben Noordhuis -Henry Rawas -Robert Mustacchi -Matt Stevens -Paul Querna -Shigeki Ohtsu -Tom Hughes -Peter Bright -Jeroen Janssen -Andrea Lattuada -Augusto Henrique Hentz -Clifford Heath -Jorge Chamorro Bieling -Luis Lavena -Matthew Sporleder -Erick Tryzelaar -Isaac Z. Schlueter -Pieter Noordhuis -Marek Jelen -Fedor Indutny -Saúl Ibarra Corretgé -Felix Geisendörfer -Yuki Okumura -Roman Shtylman -Frank Denis -Carter Allen -Tj Holowaychuk -Shimon Doodkin -Ryan Emery -Bruce Mitchener -Maciej Małecki -Yasuhiro Matsumoto -Daisuke Murase -Paddy Byers -Dan VerWeire -Brandon Benvie -Brandon Philips -Nathan Rajlich -Charlie McConnell -Vladimir Dronnikov -Aaron Bieber -Bulat Shakirzyanov -Brian White -Erik Dubbelboer -Keno Fischer -Ira Cooper -Andrius Bentkus -Iñaki Baz Castillo -Mark Cavage -George Yohng -Xidorn Quan -Roman Neuhauser -Shuhei Tanuma -Bryan Cantrill -Trond Norbye -Tim Holy -Prancesco Pertugio -Leonard Hecker -Andrew Paprocki -Luigi Grilli -Shannen Saez -Artur Adib -Hiroaki Nakamura -Ting-Yu Lin -Stephen Gallagher -Shane Holloway -Andrew Shaffer -Vlad Tudose -Ben Leslie -Tim Bradshaw -Timothy J. Fontaine -Marc Schlaich -Brian Mazza -Elliot Saba -Ben Kelly -Nils Maier -Nicholas Vavilov -Miroslav Bajtoš -Sean Silva -Wynn Wilkes -Andrei Sedoi -Alex Crichton -Brent Cook -Brian Kaisner -Luca Bruno -Reini Urban -Maks Naumov -Sean Farrell -Chris Bank -Geert Jansen -Christoph Iserlohn -Steven Kabbes -Alex Gaynor -huxingyi -Tenor Biel -Andrej Manduch -Joshua Neuheisel -Alexis Campailla -Yazhong Liu -Sam Roberts -River Tarnell -Nathan Sweet -Trevor Norris -Oguz Bastemur -Dylan Cali -Austin Foxley -Benjamin Saunders -Geoffry Song -Rasmus Christian Pedersen -William Light -Oleg Efimov -Lars Gierth -Rasmus Christian Pedersen -Justin Venus -Kristian Evensen -Linus Mårtensson -Navaneeth Kedaram Nambiathan -Yorkie -StarWing -thierry-FreeBSD -Isaiah Norton -Raul Martins -David Capello -Paul Tan -Javier Hernández -Tonis Tiigi -Norio Kobota -李港平 -Chernyshev Viacheslav -Stephen von Takach -JD Ballard -Luka Perkov -Ryan Cole -HungMingWu -Jay Satiro -Leith Bade -Peter Atashian -Tim Cooper -Caleb James DeLisle -Jameson Nash -Graham Lee -Andrew Low -Pavel Platto -Tony Kelman -John Firebaugh -lilohuang -Paul Goldsmith -Julien Gilli -Michael Hudson-Doyle -Recep ASLANTAS -Rob Adams -Zachary Newman -Robin Hahling -Jeff Widman -cjihrig -Tomasz Kołodziejski -Unknown W. Brackets -Emmanuel Odeke -Mikhail Mukovnikov -Thorsten Lorenz -Yuri D'Elia -Manos Nikolaidis -Elijah Andrews -Michael Ira Krufky -Helge Deller -Joey Geralnik -Tim Caswell -Logan Rosen -Kenneth Perry -John Marino -Alexey Melnichuk -Johan Bergström -Alex Mo -Luis Martinez de Bartolome -Michael Penick -Michael -Massimiliano Torromeo -TomCrypto -Brett Vickers -Ole André Vadla Ravnås -Kazuho Oku -Ryan Phillips -Brian Green -Devchandra Meetei Leishangthem -Corey Farrell -Per Nilsson -Alan Rogers -Daryl Haresign -Rui Abreu Ferreira -João Reis -farblue68 -Jason Williams -Igor Soarez -Miodrag Milanovic -Cheng Zhao -Michael Neumann -Stefano Cristiano -heshamsafi -A. Hauptmann -John McNamee -Yosuke Furukawa -Santiago Gimeno -guworks -RossBencina -Roger A. Light -chenttuuvv -Richard Lau -ronkorving -Corbin Simpson -Zachary Hamm -Karl Skomski -Jeremy Whitlock -Willem Thiart -Ben Trask -Jianghua Yang -Colin Snover -Sakthipriyan Vairamani -Eli Skeggs -nmushell diff --git a/outside/libuv-v1.7.5/CONTRIBUTING.md b/outside/libuv-v1.7.5/CONTRIBUTING.md deleted file mode 100644 index b46edd492a..0000000000 --- a/outside/libuv-v1.7.5/CONTRIBUTING.md +++ /dev/null @@ -1,166 +0,0 @@ -# CONTRIBUTING - -The libuv project welcomes new contributors. This document will guide you -through the process. - - -### FORK - -Fork the project [on GitHub](https://github.com/libuv/libuv) and check out -your copy. - -``` -$ git clone https://github.com/username/libuv.git -$ cd libuv -$ git remote add upstream https://github.com/libuv/libuv.git -``` - -Now decide if you want your feature or bug fix to go into the master branch -or the stable branch. As a rule of thumb, bug fixes go into the stable branch -while new features go into the master branch. - -The stable branch is effectively frozen; patches that change the libuv -API/ABI or affect the run-time behavior of applications get rejected. - -In case of doubt, open an issue in the [issue tracker][], post your question -to the [libuv mailing list], or contact one of project maintainers -(@bnoordhuis, @piscisaureus, @indutny or @saghul) on [IRC][]. - -Especially do so if you plan to work on something big. Nothing is more -frustrating than seeing your hard work go to waste because your vision -does not align with that of a project maintainers. - - -### BRANCH - -Okay, so you have decided on the proper branch. Create a feature branch -and start hacking: - -``` -$ git checkout -b my-feature-branch -t origin/v1.x -``` - -(Where v1.x is the latest stable branch as of this writing.) - -### CODE - -Please adhere to libuv's code style. In general it follows the conventions from -the [Google C/C++ style guide]. Some of the key points, as well as some -additional guidelines, are enumerated below. - -* Code that is specific to unix-y platforms should be placed in `src/unix`, and - declarations go into `include/uv-unix.h`. - -* Source code that is Windows-specific goes into `src/win`, and related - publicly exported types, functions and macro declarations should generally - be declared in `include/uv-win.h`. - -* Names should be descriptive and concise. - -* All the symbols and types that libuv makes available publicly should be - prefixed with `uv_` (or `UV_` in case of macros). - -* Internal, non-static functions should be prefixed with `uv__`. - -* Use two spaces and no tabs. - -* Lines should be wrapped at 80 characters. - -* Ensure that lines have no trailing whitespace, and use unix-style (LF) line - endings. - -* Use C89-compliant syntax. In other words, variables can only be declared at - the top of a scope (function, if/for/while-block). - -* When writing comments, use properly constructed sentences, including - punctuation. - -* When documenting APIs and/or source code, don't make assumptions or make - implications about race, gender, religion, political orientation or anything - else that isn't relevant to the project. - -* Remember that source code usually gets written once and read often: ensure - the reader doesn't have to make guesses. Make sure that the purpose and inner - logic are either obvious to a reasonably skilled professional, or add a - comment that explains it. - - -### COMMIT - -Make sure git knows your name and email address: - -``` -$ git config --global user.name "J. Random User" -$ git config --global user.email "j.random.user@example.com" -``` - -Writing good commit logs is important. A commit log should describe what -changed and why. Follow these guidelines when writing one: - -1. The first line should be 50 characters or less and contain a short - description of the change prefixed with the name of the changed - subsystem (e.g. "net: add localAddress and localPort to Socket"). -2. Keep the second line blank. -3. Wrap all other lines at 72 columns. - -A good commit log looks like this: - -``` -subsystem: explaining the commit in one line - -Body of commit message is a few lines of text, explaining things -in more detail, possibly giving some background about the issue -being fixed, etc etc. - -The body of the commit message can be several paragraphs, and -please do proper word-wrap and keep columns shorter than about -72 characters or so. That way `git log` will show things -nicely even when it is indented. -``` - -The header line should be meaningful; it is what other people see when they -run `git shortlog` or `git log --oneline`. - -Check the output of `git log --oneline files_that_you_changed` to find out -what subsystem (or subsystems) your changes touch. - - -### REBASE - -Use `git rebase` (not `git merge`) to sync your work from time to time. - -``` -$ git fetch upstream -$ git rebase upstream/v1.x # or upstream/master -``` - - -### TEST - -Bug fixes and features should come with tests. Add your tests in the -`test/` directory. Tests also need to be registered in `test/test-list.h`. -Look at other tests to see how they should be structured (license boilerplate, -the way entry points are declared, etc.). - -Check README.md file to find out how to run the test suite and make sure that -there are no test regressions. - -### PUSH - -``` -$ git push origin my-feature-branch -``` - -Go to https://github.com/username/libuv and select your feature branch. Click -the 'Pull Request' button and fill out the form. - -Pull requests are usually reviewed within a few days. If there are comments -to address, apply your changes in a separate commit and push that to your -feature branch. Post a comment in the pull request afterwards; GitHub does -not send out notifications when you add commits. - - -[issue tracker]: https://github.com/libuv/libuv/issues -[libuv mailing list]: http://groups.google.com/group/libuv -[IRC]: http://webchat.freelibuv.net/?channels=libuv -[Google C/C++ style guide]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml diff --git a/outside/libuv-v1.7.5/ChangeLog b/outside/libuv-v1.7.5/ChangeLog deleted file mode 100644 index aae7ad6f80..0000000000 --- a/outside/libuv-v1.7.5/ChangeLog +++ /dev/null @@ -1,2273 +0,0 @@ -2015.09.23, Version 1.7.5 (Stable) - -Changes since version 1.7.4: - -* unix: Support atomic compare & swap xlC on AIX (nmushell) - -* unix: Fix including uv-aix.h on AIX (nmushell) - -* unix: consolidate rwlock tryrdlock trywrlock errors (Saúl Ibarra Corretgé) - -* unix, win: consolidate mutex trylock errors (Saúl Ibarra Corretgé) - -* darwin: fix memory leak in uv_cpu_info (Jianghua Yang) - -* test: add tests for the uv_rwlock implementation (Bert Belder) - -* win: redo/fix the uv_rwlock APIs (Bert Belder) - -* win: don't fetch function pointers to SRWLock APIs (Bert Belder) - - -2015.09.12, Version 1.7.4 (Stable), a7ad4f52189d89cfcba35f78bfc5ff3b1f4105c4 - -Changes since version 1.7.3: - -* doc: uv_read_start and uv_read_cb clarifications (Ben Trask) - -* freebsd: obtain true uptime through clock_gettime() (Jianghua Yang) - -* win, tty: do not convert \r to \r\n (Colin Snover) - -* build,gyp: add DragonFly to the list of OSes (Michael Neumann) - -* fs: fix bug in sendfile for DragonFly (Michael Neumann) - -* doc: add uv_dlsym() return type (Brian White) - -* tests: fix fs tests run w/o full getdents support (Jeremy Whitlock) - -* doc: fix typo (Devchandra Meetei Leishangthem) - -* doc: fix uv-unix.h location (Sakthipriyan Vairamani) - -* unix: fix error check when closing process pipe fd (Ben Noordhuis) - -* test,freebsd: fix ipc_listen_xx_write tests (Santiago Gimeno) - -* win: fix unsavory rwlock fallback implementation (Bert Belder) - -* doc: clarify repeat timer behavior (Eli Skeggs) - - -2015.08.28, Version 1.7.3 (Stable), 93877b11c8b86e0a6befcda83a54555c1e36e4f0 - -Changes since version 1.7.2: - -* threadpool: fix thread starvation bug (Ben Noordhuis) - - -2015.08.25, Version 1.7.2 (Stable), 4d13a013fcfa72311f0102751fdc7951873f466c - -Changes since version 1.7.1: - -* unix, win: make uv_loop_init return on error (Willem Thiart) - -* win: reset pipe handle for pipe servers (Saúl Ibarra Corretgé) - -* win: fix replacing pipe handle for pipe servers (Saúl Ibarra Corretgé) - -* win: fix setting pipe pending instances after bind (Saúl Ibarra Corretgé) - - -2015.08.20, Version 1.7.1 (Stable), 44f4b6bd82d8ae4583ccc4768a83af778ef69f85 - -Changes since version 1.7.0: - -* doc: document the procedure for verifying releases (Saúl Ibarra Corretgé) - -* doc: add note about Windows binaries to the README (Saúl Ibarra Corretgé) - -* doc: use long GPG IDs in MAINTAINERS.md (Saúl Ibarra Corretgé) - -* Revert "stream: squelch ECONNRESET error if already closed" (Saúl Ibarra - Corretgé) - -* doc: clarify uv_read_stop() is idempotent (Corbin Simpson) - -* unix: OpenBSD's setsockopt needs an unsigned char for multicast (Zachary - Hamm) - -* test: Fix two memory leaks (Karl Skomski) - -* unix,win: return EINVAL on nullptr args in uv_fs_{read,write} (Karl Skomski) - -* win: set accepted TCP sockets as non-inheritable (Saúl Ibarra Corretgé) - -* unix: remove superfluous parentheses in fs macros (Ben Noordhuis) - -* unix: don't copy arguments for sync fs requests (Ben Noordhuis) - -* test: plug small memory leak in unix test runner (Ben Noordhuis) - -* unix,windows: allow NULL loop for sync fs requests (Ben Noordhuis) - -* unix,windows: don't assert on unknown error code (Ben Noordhuis) - -* stream: retry write on EPROTOTYPE on OSX (Brian White) - -* common: fix use of snprintf on Windows (Saúl Ibarra Corretgé) - -* tests: refactored fs watch_dir tests for stability (Jeremy Whitlock) - - -2015.08.06, Version 1.7.0 (Stable), 415a865d6365ba58d02b92b89d46ba5d7744ec8b - -Changes since version 1.6.1: - -* win,stream: add slot to remember CRT fd (Bert Belder) - -* win,pipe: properly close when created from CRT fd (Bert Belder) - -* win,pipe: don't close fd 0-2 (Bert Belder) - -* win,tty: convert fd -> handle safely (Bert Belder) - -* win,tty: properly close when created from CRT fd (Bert Belder) - -* win,tty: don't close fd 0-2 (Bert Belder) - -* win,fs: don't close fd 0-2 (Bert Belder) - -* win: include "malloc.h" (Cheng Zhao) - -* windows: MSVC 2015 has C99 inline (Jason Williams) - -* dragonflybsd: fixes for nonblocking and cloexec (Michael Neumann) - -* dragonflybsd: use sendfile(2) for uv_fs_sendfile (Michael Neumann) - -* dragonflybsd: fix uv_exepath (Michael Neumann) - -* win,fs: Fixes align(8) directive on mingw (Stefano Cristiano) - -* unix, win: prevent replacing fd in uv_{udp,tcp,pipe}_t (Saúl Ibarra Corretgé) - -* win: move logic to set socket non-inheritable to uv_tcp_set_socket (Saúl - Ibarra Corretgé) - -* unix, win: add ability to create tcp/udp sockets early (Saúl Ibarra Corretgé) - -* test: retry select() on EINTR, honor milliseconds (Ben Noordhuis) - -* unix: consolidate tcp and udp bind error (Saúl Ibarra Corretgé) - -* test: conditionally skip udp_ipv6_multicast_join6 (heshamsafi) - -* core: add UV_VERSION_HEX macro (Saúl Ibarra Corretgé) - -* doc: add section with version-checking macros and functions (Saúl Ibarra - Corretgé) - -* tty: cleanup handle if uv_tty_init fails (Saúl Ibarra Corretgé) - -* darwin: save a fd when FSEvents is used (Saúl Ibarra Corretgé) - -* win: fix returning thread id in uv_thread_self (Saúl Ibarra Corretgé) - -* common: use offsetof for QUEUE_DATA (Saúl Ibarra Corretgé) - -* win: remove UV_HANDLE_CONNECTED (A. Hauptmann) - -* docs: add Windows specific note for uv_fs_open (Saúl Ibarra Corretgé) - -* doc: add note about uv_fs_scandir (Saúl Ibarra Corretgé) - -* test,unix: reduce stack size of watchdog threads (Ben Noordhuis) - -* win: add support for recursive file watching (Saúl Ibarra Corretgé) - -* win,tty: support consoles with non-default colors (John McNamee) - -* doc: add missing variable name (Yosuke Furukawa) - -* stream: squelch ECONNRESET error if already closed (Santiago Gimeno) - -* build: remove ancient condition from common.gypi (Saúl Ibarra Corretgé) - -* tests: skip some tests when network is unreachable (Luca Bruno) - -* build: proper support for android cross compilation (guworks) - -* android: add missing include to pthread-fixes.c (RossBencina) - -* test: fix compilation warning (Saúl Ibarra Corretgé) - -* doc: add a note about uv_dirent_t.type (Saúl Ibarra Corretgé) - -* win,test: fix shared library build (Saúl Ibarra Corretgé) - -* test: fix compilation warning (Santiago Gimeno) - -* build: add experimental Windows installer (Roger A. Light) - -* threadpool: send signal only when queue is empty (chenttuuvv) - -* aix: fix uv_exepath with relative paths (Richard Lau) - -* build: fix version syntax in AppVeyor file (Saúl Ibarra Corretgé) - -* unix: allow nbufs > IOV_MAX in uv_fs_{read,write} (ronkorving) - - -2015.06.06, Version 1.6.1 (Stable), 30c8be07bb78a66fdee5141626bf53a49a17094a - -Changes since version 1.6.0: - -* unix: handle invalid _SC_GETPW_R_SIZE_MAX values (cjihrig) - - -2015.06.04, Version 1.6.0 (Stable), adfccad76456061dfcf79b8df8e7dbfee51791d7 - -Changes since version 1.5.0: - -* aix: fix setsockopt for multicast options (Michael) - -* unix: don't block for io if any io handle is primed (Saúl Ibarra Corretgé) - -* windows: MSVC 2015 has snprintf() (Rui Abreu Ferreira) - -* windows: Add VS2015 support to vcbuild.bat (Jason Williams) - -* doc: fix typo in tcp.rst (Igor Soarez) - -* linux: work around epoll bug in kernels < 2.6.37 (Ben Noordhuis) - -* unix,win: add uv_os_homedir() (cjihrig) - -* stream: fix `select()` race condition (Fedor Indutny) - -* unix: prevent infinite loop in uv__run_pending (Saúl Ibarra Corretgé) - -* unix: make sure UDP send callbacks are asynchronous (Saúl Ibarra Corretgé) - -* test: fix `platform_output` netmask printing. (Andrew Paprocki) - -* aix: add ahafs autoconf detection and README notes (Andrew Paprocki) - -* core: add ability to customize memory allocator (Saúl Ibarra Corretgé) - - -2015.05.07, Version 1.5.0 (Stable), 4e77f74c7b95b639b3397095db1bc5bcc016c203 - -Changes since version 1.4.2: - -* doc: clarify that the thread pool primites are not thread safe (Andrius - Bentkus) - -* aix: always deregister closing fds from epoll (Michael) - -* unix: fix glibc-2.20+ macro incompatibility (Massimiliano Torromeo) - -* doc: add Sphinx plugin for generating links to man pages (Saúl Ibarra - Corretgé) - -* doc: link system and library calls to man pages (Saúl Ibarra Corretgé) - -* doc: document uv_getnameinfo_t.{host|service} (Saúl Ibarra Corretgé) - -* build: update the location of gyp (Stephen von Takach) - -* win: name all anonymous structs and unions (TomCrypto) - -* linux: work around epoll bug in kernels 3.10-3.19 (Ben Noordhuis) - -* darwin: fix size calculation in select() fallback (Ole André Vadla Ravnås) - -* solaris: fix setsockopt for multicast options (Julien Gilli) - -* test: fix race condition in multithreaded test (Ben Noordhuis) - -* doc: fix long lines in tty.rst (Ben Noordhuis) - -* test: use UV_TTY_MODE_* values in tty test (Ben Noordhuis) - -* unix: don't clobber errno in uv_tty_reset_mode() (Ben Noordhuis) - -* unix: reject non-tty fds in uv_tty_init() (Ben Noordhuis) - -* win: fix pipe blocking writes (Alexis Campailla) - -* build: fix cross-compiling for iOS (Steven Kabbes) - -* win: remove unnecessary malloc.h - -* include: use `extern "c++"` for defining C++ code (Kazuho Oku) - -* unix: reap child on execvp() failure (Ryan Phillips) - -* windows: fix handle leak on EMFILE (Brian Green) - -* test: fix tty_file, close handle if initialized (Saúl Ibarra Corretgé) - -* doc: clarify what uv_*_open accepts (Saúl Ibarra Corretgé) - -* doc: clarify that we don't maintain external doc resources (Saúl Ibarra - Corretgé) - -* build: add documentation for ninja support (Devchandra Meetei Leishangthem) - -* doc: document uv_buf_t members (Corey Farrell) - -* linux: fix epoll_pwait() fallback on arm64 (Ben Noordhuis) - -* android: fix compilation warning (Saúl Ibarra Corretgé) - -* unix: don't close the fds we just setup (Sam Roberts) - -* test: spawn child replacing std{out,err} to stderr (Saúl Ibarra Corretgé) - -* unix: fix swapping fds order in uv_spawn (Saúl Ibarra Corretgé) - -* unix: fix potential bug if dup2 fails in uv_spawn (Saúl Ibarra Corretgé) - -* test: remove LOG and LOGF variadic macros (Saúl Ibarra Corretgé) - -* win: fix uv_fs_access on directories (Saúl Ibarra Corretgé) - -* win: fix of double free in uv_uptime (Per Nilsson) - -* unix: open "/dev/null" instead of "/" for emfile_fd (Alan Rogers) - -* docs: add some missing words (Daryl Haresign) - -* unix: clean up uv_fs_open() O_CLOEXEC logic (Ben Noordhuis) - -* build: set SONAME for shared library in uv.gyp (Rui Abreu Ferreira) - -* windows: define snprintf replacement as inline instead of static (Rui Abreu - Ferreira) - -* win: fix unlink of readonly files (João Reis) - -* doc: fix uv_run(UV_RUN_DEFAULT) description (Ben Noordhuis) - -* linux: intercept syscall when running under memory sanitizer (Keno Fischer) - -* aix: fix uv_interface_addresses return value (farblue68) - -* windows: defer reporting TCP write failure until next tick (Saúl Ibarra - Corretgé) - -* test: add test for deferred TCP write failure (Saúl Ibarra Corretgé) - - -2015.02.27, Version 1.4.2 (Stable), 1a7391348a11d5450c0f69c828d5302e2cb842eb - -Changes since version 1.4.1: - -* stream: ignore EINVAL for SO_OOBINLINE on OS X (Fedor Indutny) - - -2015.02.25, Version 1.4.1 (Stable), e8e3fc5789cc0f02937879d141cca0411274093c - -Changes since version 1.4.0: - -* win: don't use inline keyword in thread.c (Ben Noordhuis) - -* windows: fix setting dirent types on uv_fs_scandir_next (Saúl Ibarra - Corretgé) - -* unix,windows: make uv_thread_create() return errno (Ben Noordhuis) - -* tty: fix build for SmartOS (Julien Gilli) - -* unix: fix for uv_async data race (Michael Penick) - -* unix, windows: map EHOSTDOWN errno (Ben Noordhuis) - -* stream: use SO_OOBINLINE on OS X (Fedor Indutny) - - -2015.02.10, Version 1.4.0 (Stable), 19fb8a90648f3763240db004b77ab984264409be - -Changes since version 1.3.0: - -* unix: check Android support for pthread_cond_timedwait_monotonic_np (Leith - Bade) - -* test: use modified path in test (cjihrig) - -* unix: implement uv_stream_set_blocking() (Ben Noordhuis) - - -2015.01.29, Version 1.3.0 (Stable), 165685b2a9a42cf96501d79cd6d48a18aaa16e3b - -Changes since version 1.2.1: - -* unix, windows: set non-block mode in uv_poll_init (Saúl Ibarra Corretgé) - -* doc: clarify which flags are supported in uv_fs_event_start (Saúl Ibarra - Corretgé) - -* win,unix: move loop functions which have identical implementations (Andrius - Bentkus) - -* doc: explain how the threadpool is allocated (Alex Mo) - -* doc: clarify uv_default_loop (Saúl Ibarra Corretgé) - -* unix: fix implicit declaration compiler warning (Ben Noordhuis) - -* unix: fix long line introduced in commit 94e628fa (Ben Noordhuis) - -* unix, win: add synchronous uv_get{addr,name}info (Saúl Ibarra Corretgé) - -* linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis) - -* build: compile -D_GNU_SOURCE on linux (Ben Noordhuis) - -* build: use -fvisibility=hidden in autotools build (Ben Noordhuis) - -* fs, pipe: no trailing terminator in exact sized buffers (Andrius Bentkus) - -* style: rename buf to buffer and len to size for consistency (Andrius Bentkus) - -* test: fix test-spawn on MinGW32 (Luis Martinez de Bartolome) - -* win, pipe: fix assertion when destroying timer (Andrius Bentkus) - -* win, unix: add pipe_peername implementation (Andrius Bentkus) - - -2015.01.29, Version 0.10.33 (Stable), 7a2253d33ad8215a26c1b34f1952aee7242dd687 - -Changes since version 0.10.32: - -* linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis) - -* test: back-port uv_loop_configure() test (Ben Noordhuis) - - -2015.01.15, Version 1.2.1 (Stable), 4ca78e989062a1099dc4b9ad182a98e8374134b1 - -Changes since version 1.2.0: - -* unix: remove unused dtrace file (Saúl Ibarra Corretgé) - -* test: skip TTY select test if /dev/tty can't be opened (Saúl Ibarra Corretgé) - -* doc: clarify the behavior of uv_tty_init (Saúl Ibarra Corretgé) - -* doc: clarify how uv_async_send behaves (Saúl Ibarra Corretgé) - -* build: make dist now generates a full tarball (Johan Bergström) - -* freebsd: make uv_exepath more resilient (Saúl Ibarra Corretgé) - -* unix: make setting the tty mode to the same value a no-op (Saúl Ibarra - Corretgé) - -* win,tcp: support uv_try_write (Bert Belder) - -* test: enable test-tcp-try-write on windows (Bert Belder) - -* win,tty: support uv_try_write (Bert Belder) - -* unix: set non-block mode in uv_{pipe,tcp,udp}_open (Ben Noordhuis) - - -2015.01.06, Version 1.2.0 (Stable), 09f25b13cd149c7981108fc1a75611daf1277f83 - -Changes since version 1.1.0: - -* linux: fix epoll_pwait() sigmask size calculation (Ben Noordhuis) - -* tty: implement binary I/O terminal mode (Yuri D'Elia) - -* test: fix spawn test with autotools build (Ben Noordhuis) - -* test: skip ipv6 tests when ipv6 is not supported (Ben Noordhuis) - -* common: move STATIC_ASSERT to uv-common.h (Alexey Melnichuk) - -* win/thread: store thread handle in a TLS slot (Alexey Melnichuk) - -* unix: fix ttl, multicast ttl and loop options on IPv6 (Saúl Ibarra Corretgé) - -* linux: fix support for preadv/pwritev-less kernels (Ben Noordhuis) - -* unix: make uv_exepath(size=0) return UV_EINVAL (Ben Noordhuis) - -* darwin: fix uv_exepath(smallbuf) UV_EPERM error (Ben Noordhuis) - -* openbsd: fix uv_exepath(smallbuf) UV_EINVAL error (Ben Noordhuis) - -* linux: fix uv_exepath(size=1) UV_EINVAL error (Ben Noordhuis) - -* sunos: preemptively fix uv_exepath(size=1) (Ben Noordhuis) - -* win: fix and clarify comments in winapi.h (Bert Belder) - -* win: make available NtQueryDirectoryFile (Bert Belder) - -* win: add definitions for directory information types (Bert Belder) - -* win: use NtQueryDirectoryFile to implement uv_fs_scandir (Bert Belder) - -* unix: don't unlink unix socket on bind error (Ben Noordhuis) - -* build: fix bad comment in autogen.sh (Ben Noordhuis) - -* build: add AC_PROG_LIBTOOL to configure.ac (Ben Noordhuis) - -* test: skip udp_options6 if there no IPv6 support (Saúl Ibarra Corretgé) - -* win: add definitions for MUI errors mingw lacks (Bert Belder) - -* build: enable warnings in autotools build (Ben Noordhuis) - -* build: remove -Wno-dollar-in-identifier-extension (Ben Noordhuis) - -* build: move flags from Makefile.am to configure.ac (Ben Noordhuis) - - -2015.01.06, Version 0.10.32 (Stable), 378de30c59aef5fdb6d130fa5cfcb0a68fce571c - -Changes since version 0.10.31: - -* linux: fix epoll_pwait() sigmask size calculation (Ben Noordhuis) - - -2014.12.25, Version 1.1.0 (Stable), 9572f3e74a167f59a8017e57ca3ebe91ffd88e18 - -Changes since version 1.0.2: - -* test: test that closing a poll handle doesn't corrupt the stack (Bert Belder) - -* win: fix compilation of tests (Marc Schlaich) - -* Revert "win: keep a reference to AFD_POLL_INFO in cancel poll" (Bert Belder) - -* win: avoid stack corruption when closing a poll handle (Bert Belder) - -* test: fix test-fs-file-loop on Windows (Bert Belder) - -* test: fix test-cwd-and-chdir (Bert Belder) - -* doc: indicate what version uv_loop_configure was added on (Saúl Ibarra - Corretgé) - -* doc: fix sphinx warning (Saúl Ibarra Corretgé) - -* test: skip spawn_setuid_setgid if we get EACCES (Saúl Ibarra Corretgé) - -* test: silence some Clang warnings (Saúl Ibarra Corretgé) - -* test: relax osx_select_many_fds (Saúl Ibarra Corretgé) - -* test: fix compilation warnings when building with Clang (Saúl Ibarra - Corretgé) - -* win: fix autotools build of tests (Luis Lavena) - -* gitignore: ignore Visual Studio files (Marc Schlaich) - -* win: set fallback message if FormatMessage fails (Marc Schlaich) - -* win: fall back to default language in uv_dlerror (Marc Schlaich) - -* test: improve compatibility for dlerror test (Marc Schlaich) - -* test: check dlerror is "no error" in no error case (Marc Schlaich) - -* unix: change uv_cwd not to return a trailing slash (Saúl Ibarra Corretgé) - -* test: fix cwd_and_chdir test on Unix (Saúl Ibarra Corretgé) - -* test: add uv_cwd output to platform_output test (Saúl Ibarra Corretgé) - -* build: fix dragonflybsd autotools build (John Marino) - -* win: scandir use 'ls' for formatting long strings (Kenneth Perry) - -* build: remove clang and gcc_version gyp defines (Ben Noordhuis) - -* unix, windows: don't treat uv_run_mode as a bitmask (Saúl Ibarra Corretgé) - -* unix, windows: fix UV_RUN_ONCE mode if progress was made (Saúl Ibarra - Corretgé) - - -2014.12.25, Version 0.10.31 (Stable), 4dbd27e2219069a6daa769fb37f98673b77b4261 - -Changes since version 0.10.30: - -* test: test that closing a poll handle doesn't corrupt the stack (Bert Belder) - -* win: fix compilation of tests (Marc Schlaich) - -* Revert "win: keep a reference to AFD_POLL_INFO in cancel poll" (Bert Belder) - -* win: avoid stack corruption when closing a poll handle (Bert Belder) - -* gitignore: ignore Visual Studio files (Marc Schlaich) - -* win: set fallback message if FormatMessage fails (Marc Schlaich) - -* win: fall back to default language in uv_dlerror (Marc Schlaich) - -* test: improve compatibility for dlerror test (Marc Schlaich) - -* test: check dlerror is "no error" in no error case (Marc Schlaich) - -* build: link against -pthread (Logan Rosen) - -* win: scandir use 'ls' for formatting long strings (Kenneth Perry) - - -2014.12.10, Version 1.0.2 (Stable), eec671f0059953505f9a3c9aeb7f9f31466dd7cd - -Changes since version 1.0.1: - -* linux: fix sigmask size arg in epoll_pwait() call (Ben Noordhuis) - -* linux: handle O_NONBLOCK != SOCK_NONBLOCK case (Helge Deller) - -* doc: fix spelling (Joey Geralnik) - -* unix, windows: fix typos in comments (Joey Geralnik) - -* test: canonicalize test runner path (Ben Noordhuis) - -* test: fix compilation warnings (Saúl Ibarra Corretgé) - -* test: skip tty test if detected width and height are 0 (Saúl Ibarra Corretgé) - -* doc: update README with IRC channel (Saúl Ibarra Corretgé) - -* Revert "unix: use cfmakeraw() for setting raw TTY mode" (Ben Noordhuis) - -* doc: document how to get result of uv_fs_mkdtemp (Tim Caswell) - -* unix: add flag for blocking SIGPROF during poll (Ben Noordhuis) - -* unix, windows: add uv_loop_configure() function (Ben Noordhuis) - -* win: keep a reference to AFD_POLL_INFO in cancel poll (Marc Schlaich) - -* test: raise fd limit for OSX select test (Saúl Ibarra Corretgé) - -* unix: remove overzealous assert in uv_read_stop (Saúl Ibarra Corretgé) - -* unix: reset the reading flag when a stream gets EOF (Saúl Ibarra Corretgé) - -* unix: stop reading if an error is produced (Saúl Ibarra Corretgé) - -* cleanup: remove all dead assignments (Maciej Małecki) - -* linux: return early if we have no interfaces (Maciej Małecki) - -* cleanup: remove a dead increment (Maciej Małecki) - - -2014.12.10, Version 0.10.30 (Stable), 5a63f5e9546dca482eeebc3054139b21f509f21f - -Changes since version 0.10.29: - -* linux: fix sigmask size arg in epoll_pwait() call (Ben Noordhuis) - -* linux: handle O_NONBLOCK != SOCK_NONBLOCK case (Helge Deller) - -* doc: update project links (Ben Noordhuis) - -* windows: fix compilation of tests (Marc Schlaich) - -* unix: add flag for blocking SIGPROF during poll (Ben Noordhuis) - -* unix, windows: add uv_loop_configure() function (Ben Noordhuis) - -* win: keep a reference to AFD_POLL_INFO in cancel poll (Marc Schlaich) - - -2014.11.27, Version 1.0.1 (Stable), 0a8e81374e861d425b56c45c8599595d848911d2 - -Changes since version 1.0.0: - -* readme: remove Rust from users (Elijah Andrews) - -* doc,build,include: update project links (Ben Noordhuis) - -* doc: fix typo: Strcutures -> Structures (Michael Ira Krufky) - -* unix: fix processing process handles queue (Saúl Ibarra Corretgé) - -* win: replace non-ansi characters in source file (Bert Belder) - - -2014.11.21, Version 1.0.0 (Stable), feb2a9e6947d892f449b2770c4090f7d8c88381b - -Changes since version 1.0.0-rc2: - -* doc: fix git/svn url for gyp repo in README (Emmanuel Odeke) - -* windows: fix fs_read with nbufs > 1 and offset (Unknown W. Brackets) - -* win: add missing IP_ADAPTER_UNICAST_ADDRESS_LH definition for MinGW - (huxingyi) - -* doc: mention homebrew in README (Mikhail Mukovnikov) - -* doc: add learnuv workshop to README (Thorsten Lorenz) - -* doc: fix parameter name in uv_fs_access (Saúl Ibarra Corretgé) - -* unix: use cfmakeraw() for setting raw TTY mode (Yuri D'Elia) - -* win: fix uv_thread_self() (Alexis Campailla) - -* build: add x32 support to gyp build (Ben Noordhuis) - -* build: remove dtrace probes (Ben Noordhuis) - -* doc: fix link in misc.rst (Manos Nikolaidis) - -* mailmap: remove duplicated entries (Saúl Ibarra Corretgé) - -* gyp: fix comment regarding version info location (Saúl Ibarra Corretgé) - - -2014.10.21, Version 1.0.0-rc2 (Pre-release) - -Changes since version 1.0.0-rc1: - -* build: add missing fixtures to distribution tarball (Rob Adams) - -* doc: update references to current stable branch (Zachary Newman) - -* fs: fix readdir on empty directory (Fedor Indutny) - -* fs: rename uv_fs_readdir to uv_fs_scandir (Saúl Ibarra Corretgé) - -* doc: document uv_alloc_cb (Saúl Ibarra Corretgé) - -* doc: add migration guide from version 0.10 (Saúl Ibarra Corretgé) - -* build: add DragonFly BSD support in autotools (Robin Hahling) - -* doc: document missing stream related structures (Saúl Ibarra Corretgé) - -* doc: clarify uv_loop_t.data field lifetime (Saúl Ibarra Corretgé) - -* doc: add documentation for missing functions and structures (Saúl Ibarra - Corretgé) - -* doc: fix punctuation and grammar in README (Jeff Widman) - -* windows: return libuv error codes in uv_poll_init() (cjihrig) - -* unix, windows: add uv_fs_access() (cjihrig) - -* windows: fix netmask detection (Alexis Campailla) - -* unix, windows: don't include null byte in uv_cwd size (Saúl Ibarra Corretgé) - -* unix, windows: add uv_thread_equal (Tomasz Kołodziejski) - -* windows: fix fs_write with nbufs > 1 and offset (Unknown W. Brackets) - - -2014.10.21, Version 0.10.29 (Stable), 2d728542d3790183417f8f122a110693cd85db14 - -Changes since version 0.10.28: - -* darwin: allocate enough space for select() hack (Fedor Indutny) - -* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle) - -* windows: map ERROR_INVALID_DRIVE to UV_ENOENT (Saúl Ibarra Corretgé) - - -2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49 - -Changes since version 0.11.29: - -* windows: improve timer precision (Alexis Campailla) - -* build, gyp: set xcode flags (Recep ASLANTAS) - -* ignore: include m4 files which are created manually (Recep ASLANTAS) - -* build: add m4 for feature/flag-testing (Recep ASLANTAS) - -* ignore: ignore Xcode project and workspace files (Recep ASLANTAS) - -* unix: fix warnings about dollar symbol usage in identifiers (Recep ASLANTAS) - -* unix: fix warnings when loading functions with dlsym (Recep ASLANTAS) - -* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle) - -* test: add test for closing and recreating default loop (Saúl Ibarra Corretgé) - -* windows: properly close the default loop (Saúl Ibarra Corretgé) - -* version: add ability to specify a version suffix (Saúl Ibarra Corretgé) - -* doc: add API documentation (Saúl Ibarra Corretgé) - -* test: don't close connection on write error (Trevor Norris) - -* windows: further simplify the code for timers (Saúl Ibarra Corretgé) - -* gyp: remove UNLIMITED_SELECT from dependent define (Fedor Indutny) - -* darwin: allocate enough space for select() hack (Fedor Indutny) - -* unix, windows: don't allow a NULL callback on timers (Saúl Ibarra Corretgé) - -* windows: simplify code in uv_timer_again (Saúl Ibarra Corretgé) - -* test: use less requests on tcp-write-queue-order (Saúl Ibarra Corretgé) - -* unix: stop child process watcher after last one exits (Saúl Ibarra Corretgé) - -* unix: simplify how process handle queue is managed (Saúl Ibarra Corretgé) - -* windows: remove duplicated field (mattn) - -* core: add a reserved field to uv_handle_t and uv_req_t (Saúl Ibarra Corretgé) - -* windows: fix buffer leak after failed udp send (Bert Belder) - -* windows: make sure sockets and handles are reset on close (Saúl Ibarra Corretgé) - -* unix, windows: add uv_fileno (Saúl Ibarra Corretgé) - -* build: use same CFLAGS in autotools build as in gyp (Saúl Ibarra Corretgé) - -* build: remove unneeded define in uv.gyp (Saúl Ibarra Corretgé) - -* test: fix watcher_cross_stop on Windows (Saúl Ibarra Corretgé) - -* unix, windows: move includes for EAI constants (Saúl Ibarra Corretgé) - -* unix: fix exposing EAI_* glibc-isms (Saúl Ibarra Corretgé) - -* unix: fix tcp write after bad connect freezing (Andrius Bentkus) - - -2014.08.20, Version 0.11.29 (Unstable), 35451fed830807095bbae8ef981af004a4b9259e - -Changes since version 0.11.28: - -* windows: make uv_read_stop immediately stop reading (Jameson Nash) - -* windows: fix uv__getaddrinfo_translate_error (Alexis Campailla) - -* netbsd: fix build (Saúl Ibarra Corretgé) - -* unix, windows: add uv_recv_buffer_size and uv_send_buffer_size (Andrius - Bentkus) - -* windows: add support for UNC paths on uv_spawn (Paul Goldsmith) - -* windows: replace use of inet_addr with uv_inet_pton (Saúl Ibarra Corretgé) - -* unix: replace some asserts with returning errors (Andrius Bentkus) - -* windows: use OpenBSD implementation for uv_fs_mkdtemp (Pavel Platto) - -* windows: fix GetNameInfoW error handling (Alexis Campailla) - -* fs: introduce uv_readdir_next() and report types (Fedor Indutny) - -* fs: extend reported types in uv_fs_readdir_next (Saúl Ibarra Corretgé) - -* unix: read on stream even when UV__POLLHUP set. (Julien Gilli) - - -2014.08.08, Version 0.11.28 (Unstable), fc9e2a0bc487b299c0cd3b2c9a23aeb554b5d8d1 - -Changes since version 0.11.27: - -* unix, windows: const-ify handle in uv_udp_getsockname (Rasmus Pedersen) - -* windows: use UV_ECANCELED for aborted TCP writes (Saúl Ibarra Corretgé) - -* windows: add more required environment variables (Jameson Nash) - -* windows: sort environment variables before calling CreateProcess (Jameson - Nash) - -* unix, windows: move uv_loop_close out of assert (John Firebaugh) - -* windows: fix buffer overflow on uv__getnameinfo_work() (lilohuang) - -* windows: add uv_backend_timeout (Jameson Nash) - -* test: disable tcp_close_accept on Windows (Saúl Ibarra Corretgé) - -* windows: read the PATH env var of the child (Alex Crichton) - -* include: avoid using C++ 'template' reserved word (Iñaki Baz Castillo) - -* include: fix version number (Saúl Ibarra Corretgé) - - -2014.07.32, Version 0.11.27 (Unstable), ffe24f955032d060968ea0289af365006afed55e - -Changes since version 0.11.26: - -* unix, windows: use the same threadpool implementation (Saúl Ibarra Corretgé) - -* unix: use struct sockaddr_storage for target UDP addr (Saúl Ibarra Corretgé) - -* doc: add documentation to uv_udp_start_recv (Andrius Bentkus) - -* common: use common uv__count_bufs code (Andrius Bentkus) - -* unix, win: add send_queue_size and send_queue_count to uv_udp_t (Andrius - Bentkus) - -* unix, win: add uv_udp_try_send (Andrius Bentkus) - -* unix: return UV_EAGAIN if uv_try_write cannot write any data (Saúl Ibarra - Corretgé) - -* windows: fix compatibility with cygwin pipes (Jameson Nash) - -* windows: count queued bytes even if request completed immediately (Saúl - Ibarra Corretgé) - -* windows: disable CRT debug handler on MinGW32 (Saúl Ibarra Corretgé) - -* windows: map ERROR_INVALID_DRIVE to UV_ENOENT (Saúl Ibarra Corretgé) - -* unix: try to write immediately in uv_udp_send (Saúl Ibarra Corretgé) - -* unix: remove incorrect assert (Saúl Ibarra Corretgé) - -* openbsd: avoid requiring privileges for uv_resident_set_memory (Aaron Bieber) - -* unix: guarantee write queue cb execution order in streams (Andrius Bentkus) - -* img: add logo files (Saúl Ibarra Corretgé) - -* aix: improve AIX compatibility (Andrew Low) - -* windows: return bind error immediately when implicitly binding (Saúl Ibarra - Corretgé) - -* windows: don't use atexit for cleaning up the threadpool (Saúl Ibarra - Corretgé) - -* windows: destroy work queue elements when colsing a loop (Saúl Ibarra - Corretgé) - -* unix, windows: add uv_fs_mkdtemp (Pavel Platto) - -* build: handle platforms without multiprocessing.synchronize (Saúl Ibarra - Corretgé) - -* windows: change GENERIC_ALL to GENERIC_WRITE in fs__create_junction (Tony - Kelman) - -* windows: relay TCP bind errors via ipc (Alexis Campailla) - - -2014.07.32, Version 0.10.28 (Stable), 9c14b616f5fb84bfd7d45707bab4bbb85894443e - -Changes since version 0.10.27: - -* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra - Corretgé) - -* unix: return system error on EAI_SYSTEM (Saúl Ibarra Corretgé) - -* unix: fix bogus structure field name (Saúl Ibarra Corretgé) - -* darwin: invoke `mach_timebase_info` only once (Fedor Indutny) - - -2014.06.28, Version 0.11.26 (Unstable), 115281a1058c4034d5c5ccedacb667fe3f6327ea - -Changes since version 0.11.25: - -* windows: add VT100 codes ?25l and ?25h (JD Ballard) - -* windows: add invert ANSI (7 / 27) emulation (JD Ballard) - -* unix: fix handling error on UDP socket creation (Saúl Ibarra Corretgé) - -* unix, windows: getnameinfo implementation (Rasmus Pedersen) - -* heap: fix `heap_remove()` (Fedor Indutny) - -* unix, windows: fix parsing scoped IPv6 addresses (Saúl Ibarra Corretgé) - -* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra - Corretgé) - -* thread: barrier functions (Ben Noordhuis) - -* windows: fix PYTHON environment variable usage (Jay Satiro) - -* unix, windows: return system error on EAI_SYSTEM (Saúl Ibarra Corretgé) - -* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra - Corretgé) - -* unix: don't run i/o callbacks after prepare callbacks (Saúl Ibarra Corretgé) - -* windows: add tty unicode support for input (Peter Atashian) - -* header: introduce `uv_loop_size()` (Andrius Bentkus) - -* darwin: invoke `mach_timebase_info` only once (Fedor Indutny) - - -2014.05.02, Version 0.11.25 (Unstable), 2acd544cff7142e06aa3b09ec64b4a33dd9ab996 - -Changes since version 0.11.24: - -* osx: pass const handle pointer to uv___stream_fd (Chernyshev Viacheslav) - -* unix, windows: pass const handle ptr to uv_tcp_get*name (Chernyshev - Viacheslav) - -* common: pass const sockaddr ptr to uv_ip*_name (Chernyshev Viacheslav) - -* unix, windows: validate flags on uv_udp|tcp_bind (Saúl Ibarra Corretgé) - -* unix: handle case when addr is not initialized after recvmsg (Saúl Ibarra - Corretgé) - -* unix, windows: uv_now constness (Rasmus Pedersen) - - -2014.04.15, Version 0.11.24 (Unstable), ed948c29f6e8c290f79325a6f0bc9ef35bcde644 - -Changes since version 0.11.23: - -* linux: reduce file descriptor count of async pipe (Ben Noordhuis) - -* sunos: support IPv6 qualified link-local addresses (Saúl Ibarra Corretgé) - -* windows: fix opening of read-only stdin pipes (Alexis Campailla) - -* windows: Fix an infinite loop in uv_spawn (Alex Crichton) - -* windows: fix console signal handler refcount (李港平) - -* inet: allow scopeid in uv_inet_pton (Fedor Indutny) - - -2014.04.07, Version 0.11.23 (Unstable), e54de537efcacd593f36fcaaf8b4cb9e64313275 - -Changes since version 0.11.22: - -* fs: avoid using readv/writev where possible (Fedor Indutny) - -* mingw: fix build with autotools (Saúl Ibarra Corretgé) - -* bsd: support IPv6 qualified link-local addresses (Saúl Ibarra Corretgé) - -* unix: add UV_HANDLE_IPV6 flag to tcp and udp handles (Saúl Ibarra Corretgé) - -* unix, windows: do not set SO_REUSEADDR by default on udp (Saúl Ibarra - Corretgé) - -* windows: fix check in uv_tty_endgame() (Maks Naumov) - -* unix, windows: add IPv6 support for uv_udp_multicast_interface (Saúl Ibarra - Corretgé) - -* unix: fallback to blocking writes if reopening a tty fails (Saúl Ibarra - Corretgé) - -* unix: fix handling uv__open_cloexec failure (Saúl Ibarra Corretgé) - -* unix, windows: add IPv6 support to uv_udp_set_membership (Saúl Ibarra - Corretgé) - -* unix, windows: removed unused status parameter (Saúl Ibarra Corretgé) - -* android: add support of ifaddrs in android (Javier Hernández) - -* build: fix SunOS and AIX build with autotools (Saúl Ibarra Corretgé) - -* build: freebsd link with libelf if dtrace enabled (Saúl Ibarra Corretgé) - -* stream: do not leak `alloc_cb` buffers on error (Fedor Indutny) - -* unix: fix setting written size on uv_wd (Saúl Ibarra Corretgé) - - -2014.03.11, Version 0.11.22 (Unstable), cd0c19b1d3c56acf0ade7687006e12e75fbda36d - -Changes since version 0.11.21: - -* unix, windows: map ERANGE errno (Saúl Ibarra Corretgé) - -* unix, windows: make uv_cwd be consistent with uv_exepath (Saúl Ibarra - Corretgé) - -* process: remove debug perror() prints (Fedor Indutny) - -* windows: fall back for volume info query (Isaiah Norton) - -* pipe: allow queueing pending handles (Fedor Indutny) - -* windows: fix winsock status codes for address errors (Raul Martins) - -* windows: Remove unused variable from uv__pipe_insert_pending_socket (David - Capello) - -* unix: workaround broken pthread_sigmask on Android (Paul Tan) - -* error: add ENXIO for O_NONBLOCK FIFO open() (Fedor Indutny) - -* freebsd: use accept4, introduced in version 10 (Saúl Ibarra Corretgé) - -* windows: fix warnings of MinGW -Wall -O3 (StarWing) - -* openbsd, osx: fix compilation warning on scandir (Saúl Ibarra Corretgé) - -* linux: always deregister closing fds from epoll (Geoffry Song) - -* unix: reopen tty as /dev/tty (Saúl Ibarra Corretgé) - -* kqueue: invalidate fd in uv_fs_event_t (Fedor Indutny) - - -2014.02.28, Version 0.11.21 (Unstable), 3ef958158ae1019e027ebaa93114160099db5206 - -Changes since version 0.11.20: - -* unix: fix uv_fs_write when using an empty buffer (Saúl Ibarra Corretgé) - -* unix, windows: add assertion in uv_loop_delete (Saúl Ibarra Corretgé) - - -2014.02.27, Version 0.11.20 (Unstable), 88355e081b51c69ee1e2b6b0015a4e3d38bd0579 - -Changes since version 0.11.19: - -* stream: start thread after assignments (Oguz Bastemur) - -* fs: `uv__cloexec()` opened fd (Fedor Indutny) - -* gyp: qualify `library` variable (Fedor Indutny) - -* unix, win: add uv_udp_set_multicast_interface() (Austin Foxley) - -* unix: fix uv_tcp_nodelay return value in case of error (Saúl Ibarra Corretgé) - -* unix: call setgoups before calling setuid/setgid (Saúl Ibarra Corretgé) - -* include: mark close_cb field as private (Saúl Ibarra Corretgé) - -* unix, windows: map EFBIG errno (Saúl Ibarra Corretgé) - -* unix: correct error when calling uv_shutdown twice (Keno Fischer) - -* windows: fix building on MinGW (Alex Crichton) - -* windows: always initialize uv_process_t (Alex Crichton) - -* include: expose libuv version in header files (Saúl Ibarra Corretgé) - -* fs: vectored IO API for filesystem read/write (Benjamin Saunders) - -* windows: freeze in uv_tcp_endgame (Alexis Campailla) - -* sunos: handle rearm errors (Fedor Indutny) - -* unix: use a heap for timers (Ben Noordhuis) - -* linux: always deregister closing fds from epoll (Geoffry Song) - -* linux: include grp.h for setgroups() (William Light) - -* unix, windows: add uv_loop_init and uv_loop_close (Saúl Ibarra Corretgé) - -* unix, windows: add uv_getrusage() function (Oleg Efimov) - -* win: minor error handle fix to uv_pipe_write_impl (Rasmus Pedersen) - -* heap: fix node removal (Keno Fischer) - -* win: fix C99/C++ comment (Rasmus Pedersen) - -* fs: vectored IO API for filesystem read/write (Benjamin Saunders) - -* unix, windows: add uv_pipe_getsockname (Saúl Ibarra Corretgé) - -* unix, windows: map ENOPROTOOPT errno (Saúl Ibarra Corretgé) - -* errno: add ETXTBSY (Fedor Indutny) - -* fsevent: rename filename field to path (Saúl Ibarra Corretgé) - -* unix, windows: add uv_fs_event_getpath (Saúl Ibarra Corretgé) - -* unix, windows: add uv_fs_poll_getpath (Saúl Ibarra Corretgé) - -* unix, windows: map ERANGE errno (Saúl Ibarra Corretgé) - -* unix, windows: set required size on UV_ENOBUFS (Saúl Ibarra Corretgé) - -* unix, windows: clarify what uv_stream_set_blocking does (Saúl Ibarra - Corretgé) - -* fs: use preadv on Linux if available (Brian White) - - -2014.01.30, Version 0.11.19 (Unstable), 336a1825309744f920230ec3e427e78571772347 - -Changes since version 0.11.18: - -* linux: move sscanf() out of the assert() (Trevor Norris) - -* linux: fix C99/C++ comment (Fedor Indutny) - - -2014.05.02, Version 0.10.27 (Stable), 6e24ce23b1e7576059f85a608eca13b766458a01 - -Changes since version 0.10.26: - -* windows: fix console signal handler refcount (Saúl Ibarra Corretgé) - -* win: always leave crit section in get_proc_title (Fedor Indutny) - - -2014.04.07, Version 0.10.26 (Stable), d864907611c25ec986c5e77d4d6d6dee88f26926 - -Changes since version 0.10.25: - -* process: don't close stdio fds during spawn (Tonis Tiigi) - -* build, windows: do not fail on Windows SDK Prompt (Marc Schlaich) - -* build, windows: fix x64 configuration issue (Marc Schlaich) - -* win: fix buffer leak on error in pipe.c (Fedor Indutny) - -* kqueue: invalidate fd in uv_fs_event_t (Fedor Indutny) - -* linux: always deregister closing fds from epoll (Geoffry Song) - -* error: add ENXIO for O_NONBLOCK FIFO open() (Fedor Indutny) - - -2014.02.19, Version 0.10.25 (Stable), d778dc588507588b12b9f9d2905078db542ed751 - -Changes since version 0.10.24: - -* stream: start thread after assignments (Oguz Bastemur) - -* unix: correct error when calling uv_shutdown twice (Saúl Ibarra Corretgé) - -2014.01.30, Version 0.10.24 (Stable), aecd296b6bce9b40f06a61c5c94e43d45ac7308a - -Changes since version 0.10.23: - -* linux: move sscanf() out of the assert() (Trevor Norris) - -* linux: fix C99/C++ comment (Fedor Indutny) - - -2014.01.23, Version 0.11.18 (Unstable), d47962e9d93d4a55a9984623feaf546406c9cdbb - -Changes since version 0.11.17: - -* osx: Fix a possible segfault in uv__io_poll (Alex Crichton) - -* windows: improved handling of invalid FDs (Alexis Campailla) - -* doc: adding ARCHS flag to OS X build command (Nathan Sweet) - -* tcp: reveal bind-time errors before listen (Alexis Campailla) - -* tcp: uv_tcp_dualstack() (Fedor Indutny) - -* linux: relax assumption on /proc/stat parsing (Luca Bruno) - -* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny) - -* process: close stdio after dup2'ing it (Fedor Indutny) - -* linux: move sscanf() out of the assert() (Trevor Norris) - - -2014.01.23, Version 0.10.23 (Stable), dbd218e699fec8be311d85e4788be9e28ae884f8 - -Changes since version 0.10.22: - -* linux: relax assumption on /proc/stat parsing (Luca Bruno) - -* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny) - -* process: close stdio after dup2'ing it (Fedor Indutny) - - -2014.01.08, Version 0.10.22 (Stable), f526c90eeff271d9323a9107b9a64a4671fd3103 - -Changes since version 0.10.21: - -* windows: avoid assertion failure when pipe server is closed (Bert Belder) - - -2013.12.32, Version 0.11.17 (Unstable), 589c224d4c2e79fec65db01d361948f1e4976858 - -Changes since version 0.11.16: - -* stream: allow multiple buffers for uv_try_write (Fedor Indutny) - -* unix: fix a possible memory leak in uv_fs_readdir (Alex Crichton) - -* unix, windows: add uv_loop_alive() function (Sam Roberts) - -* windows: avoid assertion failure when pipe server is closed (Bert Belder) - -* osx: Fix a possible segfault in uv__io_poll (Alex Crichton) - -* stream: fix uv__stream_osx_select (Fedor Indutny) - - -2013.12.14, Version 0.11.16 (Unstable), ae0ed8c49d0d313c935c22077511148b6e8408a4 - -Changes since version 0.11.15: - -* fsevents: remove kFSEventStreamCreateFlagNoDefer polyfill (ci-innoq) - -* libuv: add more getaddrinfo errors (Steven Kabbes) - -* unix: fix accept() EMFILE error handling (Ben Noordhuis) - -* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis) - -* fsevents: fix subfolder check (Fedor Indutny) - -* fsevents: fix invalid memory access (huxingyi) - -* windows/timer: fix uv_hrtime discontinuity (Bert Belder) - -* unix: fix various memory leaks and undef behavior (Fedor Indutny) - -* unix, windows: always update loop time (Saúl Ibarra Corretgé) - -* windows: translate system errors in uv_spawn (Alexis Campailla) - -* windows: uv_spawn code refactor (Alexis Campailla) - -* unix, windows: detect errors in uv_ip4/6_addr (Yorkie) - -* stream: introduce uv_try_write(...) (Fedor Indutny) - - -2013.12.13, Version 0.10.20 (Stable), 04141464dd0fba90ace9aa6f7003ce139b888a40 - -Changes since version 0.10.19: - -* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis) - -* fs-event: fix invalid memory access (huxingyi) - - -2013.11.21, Version 0.11.15 (Unstable), bfe645ed7e99ca5670d9279ad472b604c129d2e5 - -Changes since version 0.11.14: - -* fsevents: report errors to user (Fedor Indutny) - -* include: UV_FS_EVENT_RECURSIVE is a flag (Fedor Indutny) - -* linux: use CLOCK_MONOTONIC_COARSE if available (Ben Noordhuis) - -* build: make systemtap probes work with gyp build (Ben Noordhuis) - -* unix: update events from pevents between polls (Fedor Indutny) - -* fsevents: support japaneese characters in path (Chris Bank) - -* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis) - -* queue: strengthen type checks (Ben Noordhuis) - -* include: remove uv_strlcat() and uv_strlcpy() (Ben Noordhuis) - -* build: fix windows smp build with gyp (Geert Jansen) - -* unix: return exec errors from uv_spawn, not async (Alex Crichton) - -* fsevents: use native character encoding file paths (Ben Noordhuis) - -* linux: handle EPOLLHUP without EPOLLIN/EPOLLOUT (Ben Noordhuis) - -* windows: use _snwprintf(), not swprintf() (Ben Noordhuis) - -* fsevents: use FlagNoDefer for FSEventStreamCreate (Fedor Indutny) - -* unix: fix reopened fd bug (Fedor Indutny) - -* core: fix fake watcher list and count preservation (Fedor Indutny) - -* unix: set close-on-exec flag on received fds (Ben Noordhuis) - -* netbsd, openbsd: enable futimes() wrapper (Ben Noordhuis) - -* unix: nicer error message when kqueue() fails (Ben Noordhuis) - -* samples: add socks5 proxy sample application (Ben Noordhuis) - - -2013.11.13, Version 0.10.19 (Stable), 33959f7524090b8d2c6c41e2400ca77e31755059 - -Changes since version 0.10.18: - -* darwin: avoid calling GetCurrentProcess (Fedor Indutny) - -* unix: update events from pevents between polls (Fedor Indutny) - -* fsevents: support japaneese characters in path (Chris Bank) - -* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis) - -* build: fix windows smp build with gyp (Geert Jansen) - -* linux: handle EPOLLHUP without EPOLLIN/EPOLLOUT (Ben Noordhuis) - -* unix: fix reopened fd bug (Fedor Indutny) - -* core: fix fake watcher list and count preservation (Fedor Indutny) - - -2013.10.30, Version 0.11.14 (Unstable), d7a6482f45c1b4eb4a853dbe1a9ce8090a35633a - -Changes since version 0.11.13: - -* darwin: create fsevents thread on demand (Ben Noordhuis) - -* fsevents: FSEvents is most likely not thread-safe (Fedor Indutny) - -* fsevents: use shared FSEventStream (Fedor Indutny) - -* windows: make uv_fs_chmod() report errors correctly (Bert Belder) - -* windows: make uv_shutdown() for write-only pipes work (Bert Belder) - -* windows/fs: wrap multi-statement macros in do..while block (Bert Belder) - -* windows/fs: make uv_fs_open() report EINVAL correctly (Bert Belder) - -* windows/fs: handle _open_osfhandle() failure correctly (Bert Belder) - -* windows/fs: wrap multi-statement macros in do..while block (Bert Belder) - -* windows/fs: make uv_fs_open() report EINVAL correctly (Bert Belder) - -* windows/fs: handle _open_osfhandle() failure correctly (Bert Belder) - -* build: clarify instructions for Windows (Brian Kaisner) - -* build: remove GCC_WARN_ABOUT_MISSING_NEWLINE (Ben Noordhuis) - -* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis) - -* windows: run close callbacks after polling for i/o (Saúl Ibarra Corretgé) - -* include: clarify uv_tcp_bind() behavior (Ben Noordhuis) - -* include: clean up includes in uv.h (Ben Noordhuis) - -* include: remove UV_IO_PRIVATE_FIELDS macro (Ben Noordhuis) - -* include: fix typo in comment in uv.h (Ben Noordhuis) - -* include: update uv_is_active() documentation (Ben Noordhuis) - -* include: make uv_process_options_t.cwd const (Ben Noordhuis) - -* unix: wrap long lines at 80 columns (Ben Noordhuis) - -* unix, windows: make uv_is_*() always return 0 or 1 (Ben Noordhuis) - -* bench: measure total/init/dispatch/cleanup times (Ben Noordhuis) - -* build: use -pthread on sunos (Timothy J. Fontaine) - -* windows: remove duplicate check in stream.c (Ben Noordhuis) - -* unix: sanity-check fds before closing (Ben Noordhuis) - -* unix: remove uv__pipe_accept() (Ben Noordhuis) - -* unix: fix uv_spawn() NULL pointer deref on ENOMEM (Ben Noordhuis) - -* unix: don't close inherited fds on uv_spawn() fail (Ben Noordhuis) - -* unix: revert recent FSEvent changes (Ben Noordhuis) - -* fsevents: fix clever rescheduling (Fedor Indutny) - -* linux: ignore fractional time in uv_uptime() (Ben Noordhuis) - -* unix: fix SIGCHLD waitpid() race in process.c (Ben Noordhuis) - -* unix, windows: add uv_fs_event_start/stop functions (Saúl Ibarra Corretgé) - -* unix: fix non-synchronized access in signal.c (Ben Noordhuis) - -* unix: add atomic-ops.h (Ben Noordhuis) - -* unix: add spinlock.h (Ben Noordhuis) - -* unix: clean up uv_tty_set_mode() a little (Ben Noordhuis) - -* unix: make uv_tty_reset_mode() async signal-safe (Ben Noordhuis) - -* include: add E2BIG status code mapping (Ben Noordhuis) - -* windows: fix duplicate case build error (Ben Noordhuis) - -* windows: remove unneeded check (Saúl Ibarra Corretgé) - -* include: document pipe path truncation behavior (Ben Noordhuis) - -* fsevents: increase stack size for OSX 10.9 (Fedor Indutny) - -* windows: _snprintf expected wrong parameter type in string (Maks Naumov) - -* windows: "else" keyword is missing (Maks Naumov) - -* windows: incorrect check for SOCKET_ERROR (Maks Naumov) - -* windows: add stdlib.h to satisfy reference to abort (Sean Farrell) - -* build: fix check target for mingw (Sean Farrell) - -* unix: move uv_shutdown() assertion (Keno Fischer) - -* darwin: avoid calling GetCurrentProcess (Fedor Indutny) - - -2013.10.19, Version 0.10.18 (Stable), 9ec52963b585e822e87bdc5de28d6143aff0d2e5 - -Changes since version 0.10.17: - -* unix: fix uv_spawn() NULL pointer deref on ENOMEM (Ben Noordhuis) - -* unix: don't close inherited fds on uv_spawn() fail (Ben Noordhuis) - -* unix: revert recent FSEvent changes (Ben Noordhuis) - -* unix: fix non-synchronized access in signal.c (Ben Noordhuis) - - -2013.09.25, Version 0.10.17 (Stable), 9670e0a93540c2f0d86c84a375f2303383c11e7e - -Changes since version 0.10.16: - -* build: remove GCC_WARN_ABOUT_MISSING_NEWLINE (Ben Noordhuis) - -* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis) - - -2013.09.06, Version 0.10.16 (Stable), 2bce230d81f4853a23662cbeb26fe98010b1084b - -Changes since version 0.10.15: - -* windows: make uv_shutdown() for write-only pipes work (Bert Belder) - -* windows: make uv_fs_open() report EINVAL when invalid arguments are passed - (Bert Belder) - -* windows: make uv_fs_open() report _open_osfhandle() failure correctly (Bert - Belder) - -* windows: make uv_fs_chmod() report errors correctly (Bert Belder) - -* windows: wrap multi-statement macros in do..while block (Bert Belder) - - -2013.09.05, Version 0.11.13 (Unstable), f5b6db6c1d7f93d28281207fd47c3841c9a9792e - -Changes since version 0.11.12: - -* unix: define _GNU_SOURCE, exposes glibc-isms (Ben Noordhuis) - -* windows: check for nonconforming swprintf arguments (Brent Cook) - -* build: include internal headers in source list (Brent Cook) - -* include: merge uv_tcp_bind and uv_tcp_bind6 (Ben Noordhuis) - -* include: merge uv_tcp_connect and uv_tcp_connect6 (Ben Noordhuis) - -* include: merge uv_udp_bind and uv_udp_bind6 (Ben Noordhuis) - -* include: merge uv_udp_send and uv_udp_send6 (Ben Noordhuis) - - -2013.09.03, Version 0.11.12 (Unstable), 82d01d5f6780d178f5176a01425ec297583c0811 - -Changes since version 0.11.11: - -* test: fix epoll_wait() usage in test-embed.c (Ben Noordhuis) - -* include: uv_alloc_cb now takes uv_buf_t* (Ben Noordhuis) - -* include: uv_read{2}_cb now takes const uv_buf_t* (Ben Noordhuis) - -* include: uv_ip[46]_addr now takes sockaddr_in* (Ben Noordhuis) - -* include: uv_tcp_bind{6} now takes sockaddr_in* (Ben Noordhuis) - -* include: uv_tcp_connect{6} now takes sockaddr_in* (Ben Noordhuis) - -* include: uv_udp_recv_cb now takes const uv_buf_t* (Ben Noordhuis) - -* include: uv_udp_bind{6} now takes sockaddr_in* (Ben Noordhuis) - -* include: uv_udp_send{6} now takes sockaddr_in* (Ben Noordhuis) - -* include: uv_spawn takes const uv_process_options_t* (Ben Noordhuis) - -* include: make uv_write{2} const correct (Ben Noordhuis) - -* windows: fix flags assignment in uv_fs_readdir() (Ben Noordhuis) - -* windows: fix stray comments (Ben Noordhuis) - -* windows: remove unused is_path_dir() function (Ben Noordhuis) - - -2013.08.30, Version 0.11.11 (Unstable), ba876d53539ed0427c52039012419cd9374c6f0d - -Changes since version 0.11.10: - -* unix, windows: add thread-local storage API (Ben Noordhuis) - -* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis) - -* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis) - -* windows: make uv_shutdown() for write-only pipes work (Bert Belder) - -* include: update uv_udp_open() / uv_udp_bind() docs (Ben Noordhuis) - -* unix: req queue must be empty when destroying loop (Ben Noordhuis) - -* unix: move loop functions from core.c to loop.c (Ben Noordhuis) - -* darwin: remove CoreFoundation dependency (Ben Noordhuis) - -* windows: make autotools build system work with mingw (Keno Fischer) - -* windows: fix mingw build (Alex Crichton) - -* windows: tweak Makefile.mingw for easier usage (Alex Crichton) - -* build: remove _GNU_SOURCE macro definition (Ben Noordhuis) - - -2013.08.25, Version 0.11.10 (Unstable), 742dadcb7154cc7bb89c0c228a223b767a36cf0d - -* windows: Re-implement uv_fs_stat. The st_ctime field now contains the change - time, not the creation time, like on unix systems. st_dev, st_ino, st_blocks - and st_blksize are now also filled out. (Bert Belder) - -* linux: fix setsockopt(SO_REUSEPORT) error handling (Ben Noordhuis) - -* windows: report uv_process_t exit code correctly (Bert Belder) - -* windows: make uv_fs_chmod() report errors correctly (Bert Belder) - -* windows: make some more NT apis available for libuv's internal use (Bert - Belder) - -* windows: squelch some compiler warnings (Bert Belder) - - -2013.08.24, Version 0.11.9 (Unstable), a2d29b5b068cbac93dc16138fb30a74e2669daad - -Changes since version 0.11.8: - -* fsevents: share FSEventStream between multiple FS watchers, which removes a - limit on the maximum number of file watchers that can be created on OS X. - (Fedor Indutny) - -* process: the `exit_status` parameter for a uv_process_t's exit callback now - is an int64_t, and no longer an int. (Bert Belder) - -* process: make uv_spawn() return some types of errors immediately on windows, - instead of passing the error code the the exit callback. This brings it on - par with libuv's behavior on unix. (Bert Belder) - - -2013.08.24, Version 0.10.15 (Stable), 221078a8fdd9b853c6b557b3d9a5dd744b4fdd6b - -Changes since version 0.10.14: - -* fsevents: create FSEvents thread on demand (Ben Noordhuis) - -* fsevents: use a single thread for interacting with FSEvents, because it's not - thread-safe. (Fedor Indutny) - -* fsevents: share FSEventStream between multiple FS watchers, which removes a - limit on the maximum number of file watchers that can be created on OS X. - (Fedor Indutny) - - -2013.08.22, Version 0.11.8 (Unstable), a5260462db80ab0deab6b9e6a8991dd8f5a9a2f8 - -Changes since version 0.11.7: - -* unix: fix missing return value warning in stream.c (Ben Noordhuis) - -* build: serial-tests was added in automake v1.12 (Ben Noordhuis) - -* windows: fix uninitialized local variable warning (Ben Noordhuis) - -* windows: fix missing return value warning (Ben Noordhuis) - -* build: fix string comparisons in autogen.sh (Ben Noordhuis) - -* windows: move INLINE macro, remove UNUSED (Ben Noordhuis) - -* unix: clean up __attribute__((quux)) usage (Ben Noordhuis) - -* sunos: remove futimes() macro (Ben Noordhuis) - -* unix: fix uv__signal_unlock() prototype (Ben Noordhuis) - -* unix, windows: allow NULL async callback (Ben Noordhuis) - -* build: apply dtrace -G to all object files (Timothy J. Fontaine) - -* darwin: fix indentation in uv__hrtime() (Ben Noordhuis) - -* darwin: create fsevents thread on demand (Ben Noordhuis) - -* darwin: reduce fsevents thread stack size (Ben Noordhuis) - -* darwin: call pthread_setname_np() if available (Ben Noordhuis) - -* build: fix automake serial-tests check again (Ben Noordhuis) - -* unix: retry waitpid() on EINTR (Ben Noordhuis) - -* darwin: fix ios build error (Ben Noordhuis) - -* darwin: fix ios compiler warning (Ben Noordhuis) - -* test: simplify test-ip6-addr.c (Ben Noordhuis) - -* unix, windows: fix ipv6 link-local address parsing (Ben Noordhuis) - -* fsevents: FSEvents is most likely not thread-safe (Fedor Indutny) - -* windows: omit stdint.h, fix msvc 2008 build error (Ben Noordhuis) - - -2013.08.22, Version 0.10.14 (Stable), 15d64132151c18b26346afa892444b95e2addad0 - -Changes since version 0.10.13: - -* unix: retry waitpid() on EINTR (Ben Noordhuis) - - -2013.08.07, Version 0.11.7 (Unstable), 3cad361f8776f70941b39d65bd9426bcb1aa817b - -Changes since version 0.11.6: - -* unix, windows: fix uv_fs_chown() function prototype (Ben Noordhuis) - -* unix, windows: remove unused variables (Brian White) - -* test: fix signed/unsigned comparison warnings (Ben Noordhuis) - -* build: dtrace shouldn't break out of tree builds (Timothy J. Fontaine) - -* unix, windows: don't read/recv if buf.len==0 (Ben Noordhuis) - -* build: add mingw makefile (Ben Noordhuis) - -* unix, windows: add MAC to uv_interface_addresses() (Brian White) - -* build: enable AM_INIT_AUTOMAKE([subdir-objects]) (Ben Noordhuis) - -* unix, windows: make buf arg to uv_fs_write const (Ben Noordhuis) - -* sunos: fix build breakage introduced in e3a657c (Ben Noordhuis) - -* aix: fix build breakage introduced in 3ee4d3f (Ben Noordhuis) - -* windows: fix mingw32 build, define JOB_OBJECT_XXX (Yasuhiro Matsumoto) - -* windows: fix mingw32 build, include limits.h (Yasuhiro Matsumoto) - -* test: replace sprintf() with snprintf() (Ben Noordhuis) - -* test: replace strcpy() with strncpy() (Ben Noordhuis) - -* openbsd: fix uv_ip6_addr() unused variable warnings (Ben Noordhuis) - -* openbsd: fix dlerror() const correctness warning (Ben Noordhuis) - -* openbsd: fix uv_fs_sendfile() unused variable warnings (Ben Noordhuis) - -* build: disable parallel automake tests (Ben Noordhuis) - -* test: add windows-only snprintf() function (Ben Noordhuis) - -* build: add automake serial-tests version check (Ben Noordhuis) - - -2013.07.26, Version 0.10.13 (Stable), 381312e1fe6fecbabc943ccd56f0e7d114b3d064 - -Changes since version 0.10.12: - -* unix, windows: fix uv_fs_chown() function prototype (Ben Noordhuis) - - -2013.07.21, Version 0.11.6 (Unstable), 6645b93273e0553d23823c576573b82b129bf28c - -Changes since version 0.11.5: - -* test: open stdout fd in write-only mode (Ben Noordhuis) - -* windows: uv_spawn shouldn't reject reparse points (Bert Belder) - -* windows: use WSAGetLastError(), not errno (Ben Noordhuis) - -* build: darwin: disable -fstrict-aliasing warnings (Ben Noordhuis) - -* test: fix signed/unsigned compiler warning (Ben Noordhuis) - -* test: add 'start timer from check handle' test (Ben Noordhuis) - -* build: `all` now builds static and dynamic lib (Ben Noordhuis) - -* unix, windows: add extra fields to uv_stat_t (Saúl Ibarra Corretgé) - -* build: add install target to the makefile (Navaneeth Kedaram Nambiathan) - -* build: switch to autotools (Ben Noordhuis) - -* build: use AM_PROG_AR conditionally (Ben Noordhuis) - -* test: fix fs_fstat test on sunos (Ben Noordhuis) - -* test: fix fs_chown when running as root (Ben Noordhuis) - -* test: fix spawn_setgid_fails and spawn_setuid_fails (Ben Noordhuis) - -* build: use AM_SILENT_RULES conditionally (Ben Noordhuis) - -* build: add DTrace detection for autotools (Timothy J. Fontaine) - -* linux,darwin,win: link-local IPv6 addresses (Miroslav Bajtoš) - -* unix: fix build when !defined(PTHREAD_MUTEX_ERRORCHECK) (Ben Noordhuis) - -* unix, windows: return error codes directly (Ben Noordhuis) - - -2013.07.10, Version 0.10.12 (Stable), 58a46221bba726746887a661a9f36fe9ff204209 - -Changes since version 0.10.11: - -* linux: add support for MIPS (Andrei Sedoi) - -* windows: uv_spawn shouldn't reject reparse points (Bert Belder) - -* windows: use WSAGetLastError(), not errno (Ben Noordhuis) - -* build: darwin: disable -fstrict-aliasing warnings (Ben Noordhuis) - -* build: `all` now builds static and dynamic lib (Ben Noordhuis) - -* unix: fix build when !defined(PTHREAD_MUTEX_ERRORCHECK) (Ben Noordhuis) - - -2013.06.27, Version 0.11.5 (Unstable), e3c63ff1627a14e96f54c1c62b0d68b446d8425b - -Changes since version 0.11.4: - -* build: remove CSTDFLAG, use only CFLAGS (Ben Noordhuis) - -* unix: support for android builds (Linus Mårtensson) - -* unix: avoid extra read, short-circuit on POLLHUP (Ben Noordhuis) - -* uv: support android libuv standalone build (Linus Mårtensson) - -* src: make queue.h c++ compatible (Ben Noordhuis) - -* unix: s/ngx-queue.h/queue.h/ in checksparse.sh (Ben Noordhuis) - -* unix: unconditionally stop handle on close (Ben Noordhuis) - -* freebsd: don't enable dtrace if it's not available (Brian White) - -* build: make HAVE_DTRACE=0 should disable dtrace (Timothy J. Fontaine) - -* unix: remove overzealous assert (Ben Noordhuis) - -* unix: remove unused function uv_fatal_error() (Ben Noordhuis) - -* unix, windows: clean up uv_thread_create() (Ben Noordhuis) - -* queue: fix pointer truncation on LLP64 platforms (Bert Belder) - -* build: set OS=="android" for android builds (Linus Mårtensson) - -* windows: don't use uppercase in include filename (Ben Noordhuis) - -* stream: add an API to make streams do blocking writes (Henry Rawas) - -* windows: use WSAGetLastError(), not errno (Ben Noordhuis) - - -2013.06.13, Version 0.10.11 (Stable), c3b75406a66a10222a589cb173e8f469e9665c7e - -Changes since version 0.10.10: - -* unix: unconditionally stop handle on close (Ben Noordhuis) - -* freebsd: don't enable dtrace if it's not available (Brian White) - -* build: make HAVE_DTRACE=0 should disable dtrace (Timothy J. Fontaine) - -* unix: remove overzealous assert (Ben Noordhuis) - -* unix: clear UV_STREAM_SHUTTING after shutdown() (Ben Noordhuis) - -* unix: fix busy loop, write if POLLERR or POLLHUP (Ben Noordhuis) - - -2013.06.05, Version 0.10.10 (Stable), 0d95a88bd35fce93863c57a460be613aea34d2c5 - -Changes since version 0.10.9: - -* include: document uv_update_time() and uv_now() (Ben Noordhuis) - -* linux: fix cpu model parsing on newer arm kernels (Ben Noordhuis) - -* linux: fix a memory leak in uv_cpu_info() error path (Ben Noordhuis) - -* linux: don't ignore out-of-memory errors in uv_cpu_info() (Ben Noordhuis) - -* unix, windows: move uv_now() to uv-common.c (Ben Noordhuis) - -* test: fix a compilation problem in test-osx-select.c that was caused by the - use of c-style comments (Bert Belder) - -* darwin: use uv_fs_sendfile() use the sendfile api correctly (Wynn Wilkes) - - -2013.05.30, Version 0.11.4 (Unstable), e43e5b3d954a0989db5588aa110e1fe4fe6e0219 - -Changes since version 0.11.3: - -* windows: make uv_spawn not fail when the libuv embedding application is run - under external job control (Bert Belder) - -* darwin: assume CFRunLoopStop() isn't thread-safe, fixing a race condition - when stopping the 'stdin select hack' thread (Fedor Indutny) - -* win: fix UV_EALREADY not being reported correctly to the libuv user in some - cases (Bert Belder) - -* darwin: make the uv__cf_loop_runner and uv__cf_loop_cb functions static (Ben - Noordhuis) - -* darwin: task_info() cannot fail (Ben Noordhuis) - -* unix: add error mapping for ENETDOWN (Ben Noordhuis) - -* unix: implicitly signal write errors to the libuv user (Ben Noordhuis) - -* unix: fix assertion error on signal pipe overflow (Bert Belder) - -* unix: turn off POLLOUT after stream connect (Ben Noordhuis) - -* unix: fix stream refcounting buglet (Ben Noordhuis) - -* unix: remove assert statements that are no longer correct (Ben Noordhuis) - -* unix: appease warning about non-standard `inline` (Sean Silva) - -* unix: add uv__is_closing() macro (Ben Noordhuis) - -* unix: stop stream POLLOUT watcher on write error (Ben Noordhuis) - -* include: document uv_update_time() and uv_now() (Ben Noordhuis) - -* linux: fix cpu model parsing on newer arm kernels (Ben Noordhuis) - -* linux: fix a memory leak in uv_cpu_info() error path (Ben Noordhuis) - -* linux: don't ignore out-of-memory errors in uv_cpu_info() (Ben Noordhuis) - -* unix, windows: move uv_now() to uv-common.c (Ben Noordhuis) - -* test: fix a compilation problem in test-osx-select.c that was caused by the - use of c-style comments (Bert Belder) - -* darwin: use uv_fs_sendfile() use the sendfile api correctly (Wynn Wilkes) - -* windows: call idle handles on every loop iteration, something the unix - implementation already did (Bert Belder) - -* test: update the idle-starvation test to verify that idle handles are called - in every loop iteration (Bert Belder) - -* unix, windows: ensure that uv_run() in RUN_ONCE mode calls timers that expire - after blocking (Ben Noordhuis) - - -2013.05.29, Version 0.10.9 (Stable), a195f9ace23d92345baf57582678bfc3017e6632 - -Changes since version 0.10.8: - -* unix: fix stream refcounting buglet (Ben Noordhuis) - -* unix: remove erroneous asserts (Ben Noordhuis) - -* unix: add uv__is_closing() macro (Ben Noordhuis) - -* unix: stop stream POLLOUT watcher on write error (Ben Noordhuis) - - -2013.05.25, Version 0.10.8 (Stable), 0f39be12926fe2d8766a9f025797a473003e6504 - -Changes since version 0.10.7: - -* windows: make uv_spawn not fail under job control (Bert Belder) - -* darwin: assume CFRunLoopStop() isn't thread-safe (Fedor Indutny) - -* win: fix UV_EALREADY incorrectly set (Bert Belder) - -* darwin: make two uv__cf_*() functions static (Ben Noordhuis) - -* darwin: task_info() cannot fail (Ben Noordhuis) - -* unix: add mapping for ENETDOWN (Ben Noordhuis) - -* unix: implicitly signal write errors to libuv user (Ben Noordhuis) - -* unix: fix assert on signal pipe overflow (Bert Belder) - -* unix: turn off POLLOUT after stream connect (Ben Noordhuis) - - -2013.05.16, Version 0.11.3 (Unstable), 0a48c05b5988aea84c605751900926fa25443b34 - -Changes since version 0.11.2: - -* unix: clean up uv_accept() (Ben Noordhuis) - -* unix: remove errno preserving code (Ben Noordhuis) - -* darwin: fix ios build, don't require ApplicationServices (Ben Noordhuis) - -* windows: kill child processes when the parent dies (Bert Belder) - -* build: set soname in shared library (Ben Noordhuis) - -* build: make `make test` link against .a again (Ben Noordhuis) - -* build: only set soname on shared object builds (Timothy J. Fontaine) - -* build: convert predefined $PLATFORM to lower case (Elliot Saba) - -* test: fix process_title failing on linux (Miroslav Bajtoš) - -* test, sunos: disable process_title test (Miroslav Bajtoš) - -* test: add error logging to tty unit test (Miroslav Bajtoš) - - -2013.05.15, Version 0.10.7 (Stable), 028baaf0846b686a81e992cb2f2f5a9b8e841fcf - -Changes since version 0.10.6: - -* windows: kill child processes when the parent dies (Bert Belder) - - -2013.05.15, Version 0.10.6 (Stable), 11e6613e6260d95c8cf11bf89a2759c24649319a - -Changes since version 0.10.5: - -* stream: fix osx select hack (Fedor Indutny) - -* stream: fix small nit in select hack, add test (Fedor Indutny) - -* build: link with libkvm on openbsd (Ben Noordhuis) - -* stream: use harder sync restrictions for osx-hack (Fedor Indutny) - -* unix: fix EMFILE error handling (Ben Noordhuis) - -* darwin: fix unnecessary include headers (Daisuke Murase) - -* darwin: rename darwin-getproctitle.m (Ben Noordhuis) - -* build: convert predefined $PLATFORM to lower case (Elliot Saba) - -* build: set soname in shared library (Ben Noordhuis) - -* build: make `make test` link against .a again (Ben Noordhuis) - -* darwin: fix ios build, don't require ApplicationServices (Ben Noordhuis) - -* build: only set soname on shared object builds (Timothy J. Fontaine) - - -2013.05.11, Version 0.11.2 (Unstable), 3fba0bf65f091b91a9760530c05c6339c658d88b - -Changes since version 0.11.1: - -* darwin: look up file path with F_GETPATH (Ben Noordhuis) - -* unix, windows: add uv_has_ref() function (Saúl Ibarra Corretgé) - -* build: avoid double / in paths for dtrace (Timothy J. Fontaine) - -* unix: remove src/unix/cygwin.c (Ben Noordhuis) - -* windows: deal with the fact that GetTickCount might lag (Bert Belder) - -* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis) - -* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis) - - -2013.04.24, Version 0.10.5 (Stable), 6595a7732c52eb4f8e57c88655f72997a8567a67 - -Changes since version 0.10.4: - -* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis) - -* windows: make timers handle large timeouts (Miroslav Bajtoš) - -* windows: remove superfluous assert statement (Bert Belder) - -* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis) - -* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis) - - -2013.04.12, Version 0.10.4 (Stable), 85827e26403ac6dfa331af8ec9916ea7e27bd833 - -Changes since version 0.10.3: - -* include: update uv_backend_fd() documentation (Ben Noordhuis) - -* unix: include uv.h in src/version.c (Ben Noordhuis) - -* unix: don't write more than IOV_MAX iovecs (Fedor Indutny) - -* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier) - -* build: gyp disable thin archives (Timothy J. Fontaine) - -* sunos: re-export entire library when static (Timothy J. Fontaine) - -* unix: dtrace probes for tick-start and tick-stop (Timothy J. Fontaine) - -* windows: fix memory leak in fs__sendfile (Shannen Saez) - -* windows: remove double initialization in uv_tty_init (Shannen Saez) - -* build: fix dtrace-enabled out of tree build (Ben Noordhuis) - -* build: squelch -Wdollar-in-identifier-extension warnings (Ben Noordhuis) - -* inet: snprintf returns int, not size_t (Brian White) - -* win: refactor uv_cpu_info (Bert Belder) - -* build: add support for Visual Studio 2012 (Nicholas Vavilov) - -* build: -Wno-dollar-in-identifier-extension is clang only (Ben Noordhuis) - - -2013.04.11, Version 0.11.1 (Unstable), 5c10e82ae0bc99eff86d4b9baff1f1aa0bf84c0a - -This is the first versioned release from the current unstable libuv branch. - -Changes since Node.js v0.11.0: - -* all platforms: nanosecond resolution support for uv_fs_[fl]stat (Timothy J. - Fontaine) - -* all platforms: add netmask to uv_interface_address (Ben Kelly) - -* unix: make sure the `status` parameter passed to the `uv_getaddrinfo` is 0 or - -1 (Ben Noordhuis) - -* unix: limit the number of iovecs written in a single `writev` syscall to - IOV_MAX (Fedor Indutny) - -* unix: add dtrace probes for tick-start and tick-stop (Timothy J. Fontaine) - -* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier) - -* windows: fix memory leak in fs__sendfile (Shannen Saez) - -* windows: fix edge case bugs in uv_cpu_info (Bert Belder) - -* include: no longer ship with / include ngx-queue.h (Ben Noordhuis) - -* include: remove UV_VERSION_* macros from uv.h (Ben Noordhuis) - -* documentation updates (Kristian Evensen, Ben Kelly, Ben Noordhuis) - -* build: fix dtrace-enabled builds (Ben Noordhuis, Timothy J. Fontaine) - -* build: gyp disable thin archives (Timothy J. Fontaine) - -* build: add support for Visual Studio 2012 (Nicholas Vavilov) - - -2013.03.28, Version 0.10.3 (Stable), 31ebe23973dd98fd8a24c042b606f37a794e99d0 - -Changes since version 0.10.2: - -* include: remove extraneous const from uv_version() (Ben Noordhuis) - -* doc: update README, replace `OS` by `PLATFORM` (Ben Noordhuis) - -* build: simplify .buildstamp rule (Ben Noordhuis) - -* build: disable -Wstrict-aliasing on darwin (Ben Noordhuis) - -* darwin: don't select(&exceptfds) in fallback path (Ben Noordhuis) - -* unix: don't clear flags after closing UDP handle (Saúl Ibarra Corretgé) - - -2013.03.25, Version 0.10.2 (Stable), 0f36a00568f3e7608f97f6c6cdb081f4800a50c9 - -This is the first officially versioned release of libuv. Starting now -libuv will make releases independently of Node.js. - -Changes since Node.js v0.10.0: - -* test: add tap output for windows (Timothy J. Fontaine) - -* unix: fix uv_tcp_simultaneous_accepts() logic (Ben Noordhuis) - -* include: bump UV_VERSION_MINOR (Ben Noordhuis) - -* unix: improve uv_guess_handle() implementation (Ben Noordhuis) - -* stream: run try_select only for pipes and ttys (Fedor Indutny) - -Changes since Node.js v0.10.1: - -* build: rename OS to PLATFORM (Ben Noordhuis) - -* unix: make uv_timer_init() initialize repeat (Brian Mazza) - -* unix: make timers handle large timeouts (Ben Noordhuis) - -* build: add OBJC makefile var (Ben Noordhuis) - -* Add `uv_version()` and `uv_version_string()` APIs (Bert Belder) diff --git a/outside/libuv-v1.7.5/LICENSE b/outside/libuv-v1.7.5/LICENSE deleted file mode 100644 index 4d411670e3..0000000000 --- a/outside/libuv-v1.7.5/LICENSE +++ /dev/null @@ -1,46 +0,0 @@ -libuv is part of the Node project: http://nodejs.org/ -libuv may be distributed alone under Node's license: - -==== - -Copyright Joyent, Inc. and other Node contributors. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. - -==== - -This license applies to all parts of libuv that are not externally -maintained libraries. - -The externally maintained libraries used by libuv are: - - - tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license. - - - inet_pton and inet_ntop implementations, contained in src/inet.c, are - copyright the Internet Systems Consortium, Inc., and licensed under the ISC - license. - - - stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three - clause BSD license. - - - pthread-fixes.h, pthread-fixes.c, copyright Google Inc. and Sony Mobile - Communications AB. Three clause BSD license. - - - android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design - Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement - n° 289016). Three clause BSD license. diff --git a/outside/libuv-v1.7.5/MAINTAINERS.md b/outside/libuv-v1.7.5/MAINTAINERS.md deleted file mode 100644 index 4db2f5130c..0000000000 --- a/outside/libuv-v1.7.5/MAINTAINERS.md +++ /dev/null @@ -1,36 +0,0 @@ - -# Project Maintainers - -libuv is currently managed by the following individuals: - -* **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis)) - - GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis) -* **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus)) -* **Fedor Indutny** ([@indutny](https://github.com/indutny)) - - GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny) -* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul)) - - GPG key: FDF5 1936 4458 319F A823 3DC9 410E 5553 AE9B C059 (pubkey-saghul) - -## Storing a maintainer key in Git - -It's quite handy to store a maintainer's signature as a git blob, and have -that object tagged and signed with such key. - -Export your public key: - - $ gpg --armor --export saghul@gmail.com > saghul.asc - -Store it as a blob on the repo: - - $ git hash-object -w saghul.asc - -The previous command returns a hash, copy it. For the sake of this explanation, -we'll assume it's 'abcd1234'. Storing the blob in git is not enough, it could -be garbage collected since nothing references it, so we'll create a tag for it: - - $ git tag -s pubkey-saghul abcd1234 - -Commit the changes and push: - - $ git push origin pubkey-saghul - diff --git a/outside/libuv-v1.7.5/Makefile.am b/outside/libuv-v1.7.5/Makefile.am deleted file mode 100644 index fbf9527ae9..0000000000 --- a/outside/libuv-v1.7.5/Makefile.am +++ /dev/null @@ -1,343 +0,0 @@ -# Copyright (c) 2013, Ben Noordhuis -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -ACLOCAL_AMFLAGS = -I m4 - -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_srcdir)/src - -include_HEADERS=include/uv.h include/uv-errno.h include/uv-threadpool.h include/uv-version.h - -CLEANFILES = - -lib_LTLIBRARIES = libuv.la -libuv_la_CFLAGS = @CFLAGS@ -libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0 -libuv_la_SOURCES = src/fs-poll.c \ - src/heap-inl.h \ - src/inet.c \ - src/queue.h \ - src/threadpool.c \ - src/uv-common.c \ - src/uv-common.h \ - src/version.c - -if SUNOS -# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers -# on other platforms complain that the argument is unused during compilation. -libuv_la_CFLAGS += -pthread -endif - -if WINNT - -include_HEADERS += include/uv-win.h include/tree.h -AM_CPPFLAGS += -I$(top_srcdir)/src/win \ - -DWIN32_LEAN_AND_MEAN \ - -D_WIN32_WINNT=0x0600 -LIBS += -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -libuv_la_SOURCES += src/win/async.c \ - src/win/atomicops-inl.h \ - src/win/core.c \ - src/win/dl.c \ - src/win/error.c \ - src/win/fs-event.c \ - src/win/fs.c \ - src/win/getaddrinfo.c \ - src/win/getnameinfo.c \ - src/win/handle.c \ - src/win/handle-inl.h \ - src/win/internal.h \ - src/win/loop-watcher.c \ - src/win/pipe.c \ - src/win/poll.c \ - src/win/process-stdio.c \ - src/win/process.c \ - src/win/req.c \ - src/win/req-inl.h \ - src/win/signal.c \ - src/win/stream.c \ - src/win/stream-inl.h \ - src/win/tcp.c \ - src/win/thread.c \ - src/win/timer.c \ - src/win/tty.c \ - src/win/udp.c \ - src/win/util.c \ - src/win/winapi.c \ - src/win/winapi.h \ - src/win/winsock.c \ - src/win/winsock.h - -else # WINNT - -include_HEADERS += include/uv-unix.h -AM_CPPFLAGS += -I$(top_srcdir)/src/unix -libuv_la_SOURCES += src/unix/async.c \ - src/unix/atomic-ops.h \ - src/unix/core.c \ - src/unix/dl.c \ - src/unix/fs.c \ - src/unix/getaddrinfo.c \ - src/unix/getnameinfo.c \ - src/unix/internal.h \ - src/unix/loop-watcher.c \ - src/unix/loop.c \ - src/unix/pipe.c \ - src/unix/poll.c \ - src/unix/process.c \ - src/unix/signal.c \ - src/unix/spinlock.h \ - src/unix/stream.c \ - src/unix/tcp.c \ - src/unix/thread.c \ - src/unix/timer.c \ - src/unix/tty.c \ - src/unix/udp.c - -endif # WINNT - -EXTRA_DIST = test/fixtures/empty_file \ - test/fixtures/load_error.node \ - include \ - test \ - docs \ - img \ - samples \ - android-configure \ - CONTRIBUTING.md \ - LICENSE \ - README.md \ - checksparse.sh \ - vcbuild.bat \ - Makefile.mingw \ - common.gypi \ - gyp_uv.py \ - uv.gyp - - - -TESTS = test/run-tests -check_PROGRAMS = test/run-tests -test_run_tests_CFLAGS = -test_run_tests_SOURCES = test/blackhole-server.c \ - test/dns-server.c \ - test/echo-server.c \ - test/run-tests.c \ - test/runner.c \ - test/runner.h \ - test/task.h \ - test/test-active.c \ - test/test-async.c \ - test/test-async-null-cb.c \ - test/test-barrier.c \ - test/test-callback-order.c \ - test/test-callback-stack.c \ - test/test-close-fd.c \ - test/test-close-order.c \ - test/test-condvar.c \ - test/test-connection-fail.c \ - test/test-cwd-and-chdir.c \ - test/test-default-loop-close.c \ - test/test-delayed-accept.c \ - test/test-dlerror.c \ - test/test-embed.c \ - test/test-emfile.c \ - test/test-error.c \ - test/test-fail-always.c \ - test/test-fs-event.c \ - test/test-fs-poll.c \ - test/test-fs.c \ - test/test-get-currentexe.c \ - test/test-get-loadavg.c \ - test/test-get-memory.c \ - test/test-getaddrinfo.c \ - test/test-getnameinfo.c \ - test/test-getsockname.c \ - test/test-handle-fileno.c \ - test/test-homedir.c \ - test/test-hrtime.c \ - test/test-idle.c \ - test/test-ip4-addr.c \ - test/test-ip6-addr.c \ - test/test-ipc-send-recv.c \ - test/test-ipc.c \ - test/test-list.h \ - test/test-loop-handles.c \ - test/test-loop-alive.c \ - test/test-loop-close.c \ - test/test-loop-stop.c \ - test/test-loop-time.c \ - test/test-loop-configure.c \ - test/test-multiple-listen.c \ - test/test-mutexes.c \ - test/test-osx-select.c \ - test/test-pass-always.c \ - test/test-ping-pong.c \ - test/test-pipe-bind-error.c \ - test/test-pipe-connect-error.c \ - test/test-pipe-connect-multiple.c \ - test/test-pipe-connect-prepare.c \ - test/test-pipe-getsockname.c \ - test/test-pipe-pending-instances.c \ - test/test-pipe-sendmsg.c \ - test/test-pipe-server-close.c \ - test/test-pipe-close-stdout-read-stdin.c \ - test/test-pipe-set-non-blocking.c \ - test/test-platform-output.c \ - test/test-poll-close.c \ - test/test-poll-close-doesnt-corrupt-stack.c \ - test/test-poll-closesocket.c \ - test/test-poll.c \ - test/test-process-title.c \ - test/test-ref.c \ - test/test-run-nowait.c \ - test/test-run-once.c \ - test/test-semaphore.c \ - test/test-shutdown-close.c \ - test/test-shutdown-eof.c \ - test/test-shutdown-twice.c \ - test/test-signal-multiple-loops.c \ - test/test-signal.c \ - test/test-socket-buffer-size.c \ - test/test-spawn.c \ - test/test-stdio-over-pipes.c \ - test/test-tcp-bind-error.c \ - test/test-tcp-bind6-error.c \ - test/test-tcp-close-accept.c \ - test/test-tcp-close-while-connecting.c \ - test/test-tcp-close.c \ - test/test-tcp-create-socket-early.c \ - test/test-tcp-connect-error-after-write.c \ - test/test-tcp-connect-error.c \ - test/test-tcp-connect-timeout.c \ - test/test-tcp-connect6-error.c \ - test/test-tcp-flags.c \ - test/test-tcp-open.c \ - test/test-tcp-read-stop.c \ - test/test-tcp-shutdown-after-write.c \ - test/test-tcp-unexpected-read.c \ - test/test-tcp-oob.c \ - test/test-tcp-write-to-half-open-connection.c \ - test/test-tcp-write-after-connect.c \ - test/test-tcp-writealot.c \ - test/test-tcp-write-fail.c \ - test/test-tcp-try-write.c \ - test/test-tcp-write-queue-order.c \ - test/test-thread-equal.c \ - test/test-thread.c \ - test/test-threadpool-cancel.c \ - test/test-threadpool.c \ - test/test-timer-again.c \ - test/test-timer-from-check.c \ - test/test-timer.c \ - test/test-tty.c \ - test/test-udp-bind.c \ - test/test-udp-create-socket-early.c \ - test/test-udp-dgram-too-big.c \ - test/test-udp-ipv6.c \ - test/test-udp-multicast-interface.c \ - test/test-udp-multicast-interface6.c \ - test/test-udp-multicast-join.c \ - test/test-udp-multicast-join6.c \ - test/test-udp-multicast-ttl.c \ - test/test-udp-open.c \ - test/test-udp-options.c \ - test/test-udp-send-and-recv.c \ - test/test-udp-send-immediate.c \ - test/test-udp-send-unreachable.c \ - test/test-udp-try-send.c \ - test/test-walk-handles.c \ - test/test-watcher-cross-stop.c -test_run_tests_LDADD = libuv.la - -if WINNT -test_run_tests_SOURCES += test/runner-win.c \ - test/runner-win.h -else -test_run_tests_SOURCES += test/runner-unix.c \ - test/runner-unix.h -endif - -if AIX -test_run_tests_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT -endif - -if SUNOS -test_run_tests_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 -endif - - -if AIX -libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT -include_HEADERS += include/uv-aix.h -libuv_la_SOURCES += src/unix/aix.c -endif - -if ANDROID -include_HEADERS += include/android-ifaddrs.h \ - include/pthread-fixes.h -libuv_la_SOURCES += src/unix/android-ifaddrs.c \ - src/unix/pthread-fixes.c -endif - -if DARWIN -include_HEADERS += include/uv-darwin.h -libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 -libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1 -libuv_la_SOURCES += src/unix/darwin.c \ - src/unix/darwin-proctitle.c \ - src/unix/fsevents.c \ - src/unix/kqueue.c \ - src/unix/proctitle.c -endif - -if DRAGONFLY -include_HEADERS += include/uv-bsd.h -endif - -if FREEBSD -include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c -endif - -if LINUX -include_HEADERS += include/uv-linux.h -libuv_la_CFLAGS += -D_GNU_SOURCE -libuv_la_SOURCES += src/unix/linux-core.c \ - src/unix/linux-inotify.c \ - src/unix/linux-syscalls.c \ - src/unix/linux-syscalls.h \ - src/unix/proctitle.c -endif - -if NETBSD -include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/kqueue.c src/unix/netbsd.c -endif - -if OPENBSD -include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/kqueue.c src/unix/openbsd.c -endif - -if SUNOS -include_HEADERS += include/uv-sunos.h -libuv_la_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 -libuv_la_SOURCES += src/unix/sunos.c -endif - -if HAVE_PKG_CONFIG -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = @PACKAGE_NAME@.pc -endif diff --git a/outside/libuv-v1.7.5/Makefile.mingw b/outside/libuv-v1.7.5/Makefile.mingw deleted file mode 100644 index 156f15dab1..0000000000 --- a/outside/libuv-v1.7.5/Makefile.mingw +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (c) 2013, Ben Noordhuis -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -CC ?= gcc - -CFLAGS += -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -Iinclude \ - -Isrc \ - -Isrc/win \ - -DWIN32_LEAN_AND_MEAN \ - -D_WIN32_WINNT=0x0600 - -INCLUDES = include/stdint-msvc2008.h \ - include/tree.h \ - include/uv-errno.h \ - include/uv-threadpool.h \ - include/uv-version.h \ - include/uv-win.h \ - include/uv.h \ - src/heap-inl.h \ - src/queue.h \ - src/uv-common.h \ - src/win/atomicops-inl.h \ - src/win/handle-inl.h \ - src/win/internal.h \ - src/win/req-inl.h \ - src/win/stream-inl.h \ - src/win/winapi.h \ - src/win/winsock.h - -OBJS = src/fs-poll.o \ - src/inet.o \ - src/threadpool.o \ - src/uv-common.o \ - src/version.o \ - src/win/async.o \ - src/win/core.o \ - src/win/dl.o \ - src/win/error.o \ - src/win/fs-event.o \ - src/win/fs.o \ - src/win/getaddrinfo.o \ - src/win/getnameinfo.o \ - src/win/handle.o \ - src/win/loop-watcher.o \ - src/win/pipe.o \ - src/win/poll.o \ - src/win/process-stdio.o \ - src/win/process.o \ - src/win/req.o \ - src/win/signal.o \ - src/win/stream.o \ - src/win/tcp.o \ - src/win/thread.o \ - src/win/timer.o \ - src/win/tty.o \ - src/win/udp.o \ - src/win/util.o \ - src/win/winapi.o \ - src/win/winsock.o - -all: libuv.a - -clean: - -$(RM) $(OBJS) libuv.a - -libuv.a: $(OBJS) - $(AR) crs $@ $^ - -$(OBJS): %.o : %.c $(INCLUDES) - $(CC) $(CFLAGS) -c -o $@ $< diff --git a/outside/libuv-v1.7.5/README.md b/outside/libuv-v1.7.5/README.md deleted file mode 100644 index 0ce2669971..0000000000 --- a/outside/libuv-v1.7.5/README.md +++ /dev/null @@ -1,245 +0,0 @@ -![libuv][libuv_banner] - -## Overview - -libuv is a multi-platform support library with a focus on asynchronous I/O. It -was primarily developed for use by [Node.js](http://nodejs.org), but it's also -used by [Luvit](http://luvit.io/), [Julia](http://julialang.org/), -[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/wiki/Projects-that-use-libuv). - -## Feature highlights - - * Full-featured event loop backed by epoll, kqueue, IOCP, event ports. - - * Asynchronous TCP and UDP sockets - - * Asynchronous DNS resolution - - * Asynchronous file and file system operations - - * File system events - - * ANSI escape code controlled TTY - - * IPC with socket sharing, using Unix domain sockets or named pipes (Windows) - - * Child processes - - * Thread pool - - * Signal handling - - * High resolution clock - - * Threading and synchronization primitives - -## Versioning - -Starting with version 1.0.0 libuv follows the [semantic versioning](http://semver.org/) -scheme. The API change and backwards compatibility rules are those indicated by -SemVer. libuv will keep a stable ABI across major releases. - -## Community - - * [Mailing list](http://groups.google.com/group/libuv) - * [IRC chatroom (#libuv@irc.freenode.org)](http://webchat.freenode.net?channels=libuv&uio=d4) - -## Documentation - -### Official API documentation - -Located in the docs/ subdirectory. It uses the [Sphinx](http://sphinx-doc.org/) -framework, which makes it possible to build the documentation in multiple -formats. - -Show different supported building options: - - $ make help - -Build documentation as HTML: - - $ make html - -Build documentation as man pages: - - $ make man - -Build documentation as ePub: - - $ make epub - -NOTE: Windows users need to use make.bat instead of plain 'make'. - -Documentation can be browsed online [here](http://docs.libuv.org). - -The [tests and benchmarks](https://github.com/libuv/libuv/tree/master/test) -also serve as API specification and usage examples. - -### Other resources - - * [An Introduction to libuv](http://nikhilm.github.com/uvbook/) - — An overview of libuv with tutorials. - * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4) - — High-level introductory talk about libuv. - * [libuv-dox](https://github.com/thlorenz/libuv-dox) - — Documenting types and methods of libuv, mostly by reading uv.h. - * [learnuv](https://github.com/thlorenz/learnuv) - — Learn uv for fun and profit, a self guided workshop to libuv. - -These resources are not handled by libuv maintainers and might be out of -date. Please verify it before opening new issues. - -## Downloading - -libuv can be downloaded either from the -[GitHub repository](https://github.com/libuv/libuv) -or from the [downloads site](http://dist.libuv.org/dist/). - -Starting with libuv 1.7.0, binaries for Windows are also provided. This is to -be considered EXPERIMENTAL. - -Before verifying the git tags or signature files, importing the relevant keys -is necessary. Key IDs are listed in the -[MAINTAINERS](https://github.com/libuv/libuv/blob/master/MAINTAINERS.md) -file, but are also available as git blob objects for easier use. - -Importing a key the usual way: - - $ gpg --keyserver pool.sks-keyservers.net \ - --recv-keys AE9BC059 - -Importing a key from a git blob object: - - $ git show pubkey-saghul | gpg --import - -### Verifying releases - -Git tags are signed with the developer's key, they can be verified as follows: - - $ git verify-tag v1.6.1 - -Starting with libuv 1.7.0, the tarballs stored in the -[downloads site](http://dist.libuv.org/dist/) are signed and an accomanying -signature file sit alongside each. Once both the release tarball and the -signature file are downloaded, the file can be verified as follows: - - $ gpg --verify libuv-1.7.0.tar.gz.sign - -## Build Instructions - -For GCC there are two build methods: via autotools or via [GYP][]. -GYP is a meta-build system which can generate MSVS, Makefile, and XCode -backends. It is best used for integration into other projects. - -To build with autotools: - - $ sh autogen.sh - $ ./configure - $ make - $ make check - $ make install - -### Windows - -First, [Python][] 2.6 or 2.7 must be installed as it is required by [GYP][]. -If python is not in your path, set the environment variable `PYTHON` to its -location. For example: `set PYTHON=C:\Python27\python.exe` - -To build with Visual Studio, launch a git shell (e.g. Cmd or PowerShell) -and run vcbuild.bat which will checkout the GYP code into build/gyp and -generate uv.sln as well as related project files. - -To have GYP generate build script for another system, checkout GYP into the -project tree manually: - - $ git clone https://chromium.googlesource.com/external/gyp.git build/gyp - -### Unix - -Run: - - $ ./gyp_uv.py -f make - $ make -C out - -Run `./gyp_uv.py -f make -Dtarget_arch=x32` to build [x32][] binaries. - -### OS X - -Run: - - $ ./gyp_uv.py -f xcode - $ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \ - -configuration Release -target All - -Using Homebrew: - - $ brew install --HEAD libuv - -Note to OS X users: - -Make sure that you specify the architecture you wish to build for in the -"ARCHS" flag. You can specify more than one by delimiting with a space -(e.g. "x86_64 i386"). - -### Android - -Run: - - $ source ./android-configure NDK_PATH gyp - $ make -C out - -Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and -`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically. - -### Using Ninja - -To use ninja for build on ninja supported platforms, run: - - $ ./gyp_uv.py -f ninja - $ ninja -C out/Debug #for debug build OR - $ ninja -C out/Release - - -### Running tests - -Run: - - $ ./gyp_uv.py -f make - $ make -C out - $ ./out/Debug/run-tests - -## Supported Platforms - -Microsoft Windows operating systems since Windows XP SP2. It can be built -with either Visual Studio or MinGW. Consider using -[Visual Studio Express 2010][] or later if you do not have a full Visual -Studio license. - -Linux using the GCC toolchain. - -OS X using the GCC or XCode toolchain. - -Solaris 121 and later using GCC toolchain. - -AIX 6 and later using GCC toolchain (see notes). - -### AIX Notes - -AIX support for filesystem events requires the non-default IBM `bos.ahafs` -package to be installed. This package provides the AIX Event Infrastructure -that is detected by `autoconf`. -[IBM documentation](http://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/) -describes the package in more detail. - -AIX support for filesystem events is not compiled when building with `gyp`. - -## Patches - -See the [guidelines for contributing][]. - -[node.js]: http://nodejs.org/ -[GYP]: http://code.google.com/p/gyp/ -[Python]: https://www.python.org/downloads/ -[Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express -[guidelines for contributing]: https://github.com/libuv/libuv/blob/master/CONTRIBUTING.md -[libuv_banner]: https://raw.githubusercontent.com/libuv/libuv/master/img/banner.png diff --git a/outside/libuv-v1.7.5/android-configure b/outside/libuv-v1.7.5/android-configure deleted file mode 100755 index e0b250fb63..0000000000 --- a/outside/libuv-v1.7.5/android-configure +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -export TOOLCHAIN=$PWD/android-toolchain -mkdir -p $TOOLCHAIN -$1/build/tools/make-standalone-toolchain.sh \ - --toolchain=arm-linux-androideabi-4.8 \ - --arch=arm \ - --install-dir=$TOOLCHAIN \ - --platform=android-21 -export PATH=$TOOLCHAIN/bin:$PATH -export AR=arm-linux-androideabi-ar -export CC=arm-linux-androideabi-gcc -export CXX=arm-linux-androideabi-g++ -export LINK=arm-linux-androideabi-g++ -export PLATFORM=android - -if [ $2 -a $2 == 'gyp' ] - then - ./gyp_uv.py -Dtarget_arch=arm -DOS=android -f make-android -fi diff --git a/outside/libuv-v1.7.5/appveyor.yml b/outside/libuv-v1.7.5/appveyor.yml deleted file mode 100644 index c9f55134e5..0000000000 --- a/outside/libuv-v1.7.5/appveyor.yml +++ /dev/null @@ -1,36 +0,0 @@ -version: v1.7.5.build{build} - -install: - - cinst -y nsis - -matrix: - fast_finish: true - allow_failures: - - platform: x86 - configuration: Release - - platform: x64 - configuration: Release - -platform: - - x86 - - x64 - -configuration: - - Release - -build_script: - # Fixed tag version number if using a tag. - - cmd: if "%APPVEYOR_REPO_TAG%" == "true" set APPVEYOR_BUILD_VERSION=%APPVEYOR_REPO_TAG_NAME% - # vcbuild overwrites the platform variable. - - cmd: set ARCH=%platform% - - cmd: vcbuild.bat release %ARCH% shared - -after_build: - - '"%PROGRAMFILES(x86)%\NSIS\makensis" /DVERSION=%APPVEYOR_BUILD_VERSION% /DARCH=%ARCH% libuv.nsi' - -artifacts: - - name: Installer - path: 'libuv-*.exe' - -cache: - - C:\projects\libuv\build\gyp diff --git a/outside/libuv-v1.7.5/autogen.sh b/outside/libuv-v1.7.5/autogen.sh deleted file mode 100755 index 0574778a4e..0000000000 --- a/outside/libuv-v1.7.5/autogen.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2013, Ben Noordhuis -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -cd `dirname "$0"` - -if [ "$LIBTOOLIZE" = "" ] && [ "`uname`" = "Darwin" ]; then - LIBTOOLIZE=glibtoolize -fi - -ACLOCAL=${ACLOCAL:-aclocal} -AUTOCONF=${AUTOCONF:-autoconf} -AUTOMAKE=${AUTOMAKE:-automake} -LIBTOOLIZE=${LIBTOOLIZE:-libtoolize} - -automake_version=`"$AUTOMAKE" --version | head -n 1 | sed 's/[^.0-9]//g'` -automake_version_major=`echo "$automake_version" | cut -d. -f1` -automake_version_minor=`echo "$automake_version" | cut -d. -f2` - -UV_EXTRA_AUTOMAKE_FLAGS= -if test "$automake_version_major" -gt 1 || \ - test "$automake_version_major" -eq 1 && \ - test "$automake_version_minor" -gt 11; then - # serial-tests is available in v1.12 and newer. - UV_EXTRA_AUTOMAKE_FLAGS="$UV_EXTRA_AUTOMAKE_FLAGS serial-tests" -fi -echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \ - > m4/libuv-extra-automake-flags.m4 - -set -ex -"$LIBTOOLIZE" -"$ACLOCAL" -I m4 -"$AUTOCONF" -"$AUTOMAKE" --add-missing --copy diff --git a/outside/libuv-v1.7.5/checksparse.sh b/outside/libuv-v1.7.5/checksparse.sh deleted file mode 100755 index 619cf6f8b6..0000000000 --- a/outside/libuv-v1.7.5/checksparse.sh +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2013, Ben Noordhuis -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -SPARSE=${SPARSE:-sparse} - -SPARSE_FLAGS=${SPARSE_FLAGS:-" --D__POSIX__ --Wsparse-all --Wno-do-while --Wno-transparent-union --Iinclude --Isrc -"} - -SOURCES=" -include/tree.h -include/uv-unix.h -include/uv.h -src/fs-poll.c -src/inet.c -src/queue.h -src/unix/async.c -src/unix/core.c -src/unix/dl.c -src/unix/fs.c -src/unix/getaddrinfo.c -src/unix/internal.h -src/unix/loop-watcher.c -src/unix/loop.c -src/unix/pipe.c -src/unix/poll.c -src/unix/process.c -src/unix/signal.c -src/unix/stream.c -src/unix/tcp.c -src/unix/thread.c -src/unix/threadpool.c -src/unix/timer.c -src/unix/tty.c -src/unix/udp.c -src/uv-common.c -src/uv-common.h -" - -TESTS=" -test/benchmark-async-pummel.c -test/benchmark-async.c -test/benchmark-fs-stat.c -test/benchmark-getaddrinfo.c -test/benchmark-loop-count.c -test/benchmark-million-async.c -test/benchmark-million-timers.c -test/benchmark-multi-accept.c -test/benchmark-ping-pongs.c -test/benchmark-pound.c -test/benchmark-pump.c -test/benchmark-sizes.c -test/benchmark-spawn.c -test/benchmark-tcp-write-batch.c -test/benchmark-thread.c -test/benchmark-udp-pummel.c -test/blackhole-server.c -test/dns-server.c -test/echo-server.c -test/run-benchmarks.c -test/run-tests.c -test/runner-unix.c -test/runner-unix.h -test/runner.c -test/runner.h -test/task.h -test/test-active.c -test/test-async.c -test/test-barrier.c -test/test-callback-order.c -test/test-callback-stack.c -test/test-condvar.c -test/test-connection-fail.c -test/test-cwd-and-chdir.c -test/test-delayed-accept.c -test/test-dlerror.c -test/test-embed.c -test/test-error.c -test/test-fail-always.c -test/test-fs-event.c -test/test-fs-poll.c -test/test-fs.c -test/test-get-currentexe.c -test/test-get-loadavg.c -test/test-get-memory.c -test/test-getaddrinfo.c -test/test-getsockname.c -test/test-homedir.c -test/test-hrtime.c -test/test-idle.c -test/test-ip6-addr.c -test/test-ipc-send-recv.c -test/test-ipc.c -test/test-loop-handles.c -test/test-multiple-listen.c -test/test-mutexes.c -test/test-pass-always.c -test/test-ping-pong.c -test/test-pipe-bind-error.c -test/test-pipe-connect-error.c -test/test-pipe-sendmsg.c -test/test-pipe-server-close.c -test/test-platform-output.c -test/test-poll-close.c -test/test-poll.c -test/test-process-title.c -test/test-ref.c -test/test-run-nowait.c -test/test-run-once.c -test/test-semaphore.c -test/test-shutdown-close.c -test/test-shutdown-eof.c -test/test-signal-multiple-loops.c -test/test-signal.c -test/test-spawn.c -test/test-stdio-over-pipes.c -test/test-tcp-bind-error.c -test/test-tcp-bind6-error.c -test/test-tcp-close-while-connecting.c -test/test-tcp-close-accept.c -test/test-tcp-close.c -test/test-tcp-connect-error-after-write.c -test/test-tcp-connect-error.c -test/test-tcp-connect-timeout.c -test/test-tcp-connect6-error.c -test/test-tcp-flags.c -test/test-tcp-open.c -test/test-tcp-read-stop.c -test/test-tcp-shutdown-after-write.c -test/test-tcp-unexpected-read.c -test/test-tcp-oob.c -test/test-tcp-write-error.c -test/test-tcp-write-to-half-open-connection.c -test/test-tcp-writealot.c -test/test-thread.c -test/test-threadpool-cancel.c -test/test-threadpool.c -test/test-timer-again.c -test/test-timer.c -test/test-tty.c -test/test-udp-dgram-too-big.c -test/test-udp-ipv6.c -test/test-udp-multicast-join.c -test/test-udp-multicast-ttl.c -test/test-udp-open.c -test/test-udp-options.c -test/test-udp-send-and-recv.c -test/test-walk-handles.c -test/test-watcher-cross-stop.c -" - -case `uname -s` in -AIX) - SPARSE_FLAGS="$SPARSE_FLAGS -D_AIX=1" - SOURCES="$SOURCES - src/unix/aix.c" - ;; -Darwin) - SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1" - SOURCES="$SOURCES - include/uv-bsd.h - src/unix/darwin.c - src/unix/kqueue.c - src/unix/fsevents.c" - ;; -DragonFly) - SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1" - SOURCES="$SOURCES - include/uv-bsd.h - src/unix/kqueue.c - src/unix/freebsd.c" - ;; -FreeBSD) - SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1" - SOURCES="$SOURCES - include/uv-bsd.h - src/unix/kqueue.c - src/unix/freebsd.c" - ;; -Linux) - SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1" - SOURCES="$SOURCES - include/uv-linux.h - src/unix/linux-inotify.c - src/unix/linux-core.c - src/unix/linux-syscalls.c - src/unix/linux-syscalls.h" - ;; -NetBSD) - SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1" - SOURCES="$SOURCES - include/uv-bsd.h - src/unix/kqueue.c - src/unix/netbsd.c" - ;; -OpenBSD) - SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1" - SOURCES="$SOURCES - include/uv-bsd.h - src/unix/kqueue.c - src/unix/openbsd.c" - ;; -SunOS) - SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1" - SOURCES="$SOURCES - include/uv-sunos.h - src/unix/sunos.c" - ;; -esac - -for ARCH in __i386__ __x86_64__ __arm__ __mips__; do - $SPARSE $SPARSE_FLAGS -D$ARCH=1 $SOURCES -done - -# Tests are architecture independent. -$SPARSE $SPARSE_FLAGS -Itest $TESTS diff --git a/outside/libuv-v1.7.5/common.gypi b/outside/libuv-v1.7.5/common.gypi deleted file mode 100644 index 392c85951e..0000000000 --- a/outside/libuv-v1.7.5/common.gypi +++ /dev/null @@ -1,211 +0,0 @@ -{ - 'variables': { - 'visibility%': 'hidden', # V8's visibility setting - 'target_arch%': 'ia32', # set v8's target architecture - 'host_arch%': 'ia32', # set v8's host architecture - 'uv_library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds - 'component%': 'static_library', # NB. these names match with what V8 expects - 'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way - }, - - 'target_defaults': { - 'default_configuration': 'Debug', - 'configurations': { - 'Debug': { - 'defines': [ 'DEBUG', '_DEBUG' ], - 'cflags': [ '-g', '-O0', '-fwrapv' ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'target_conditions': [ - ['uv_library=="static_library"', { - 'RuntimeLibrary': 1, # static debug - }, { - 'RuntimeLibrary': 3, # DLL debug - }], - ], - 'Optimization': 0, # /Od, no optimization - 'MinimalRebuild': 'false', - 'OmitFramePointers': 'false', - 'BasicRuntimeChecks': 3, # /RTC1 - }, - 'VCLinkerTool': { - 'LinkIncremental': 2, # enable incremental linking - }, - }, - 'xcode_settings': { - 'GCC_OPTIMIZATION_LEVEL': '0', - 'OTHER_CFLAGS': [ '-Wno-strict-aliasing' ], - }, - 'conditions': [ - ['OS == "android"', { - 'cflags': [ '-fPIE' ], - 'ldflags': [ '-fPIE', '-pie' ] - }] - ] - }, - 'Release': { - 'defines': [ 'NDEBUG' ], - 'cflags': [ - '-O3', - '-fstrict-aliasing', - '-fomit-frame-pointer', - '-fdata-sections', - '-ffunction-sections', - ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'target_conditions': [ - ['uv_library=="static_library"', { - 'RuntimeLibrary': 0, # static release - }, { - 'RuntimeLibrary': 2, # debug release - }], - ], - 'Optimization': 3, # /Ox, full optimization - 'FavorSizeOrSpeed': 1, # /Ot, favour speed over size - 'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible - 'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG - 'OmitFramePointers': 'true', - 'EnableFunctionLevelLinking': 'true', - 'EnableIntrinsicFunctions': 'true', - }, - 'VCLibrarianTool': { - 'AdditionalOptions': [ - '/LTCG', # link time code generation - ], - }, - 'VCLinkerTool': { - 'LinkTimeCodeGeneration': 1, # link-time code generation - 'OptimizeReferences': 2, # /OPT:REF - 'EnableCOMDATFolding': 2, # /OPT:ICF - 'LinkIncremental': 1, # disable incremental linking - }, - }, - } - }, - 'msvs_settings': { - 'VCCLCompilerTool': { - 'StringPooling': 'true', # pool string literals - 'DebugInformationFormat': 3, # Generate a PDB - 'WarningLevel': 3, - 'BufferSecurityCheck': 'true', - 'ExceptionHandling': 1, # /EHsc - 'SuppressStartupBanner': 'true', - 'WarnAsError': 'false', - 'AdditionalOptions': [ - '/MP', # compile across multiple CPUs - ], - }, - 'VCLibrarianTool': { - }, - 'VCLinkerTool': { - 'GenerateDebugInformation': 'true', - 'RandomizedBaseAddress': 2, # enable ASLR - 'DataExecutionPrevention': 2, # enable DEP - 'AllowIsolation': 'true', - 'SuppressStartupBanner': 'true', - 'target_conditions': [ - ['_type=="executable"', { - 'SubSystem': 1, # console executable - }], - ], - }, - }, - 'conditions': [ - ['OS == "win"', { - 'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin - 'defines': [ - 'WIN32', - # we don't really want VC++ warning us about - # how dangerous C functions are... - '_CRT_SECURE_NO_DEPRECATE', - # ... or that C implementations shouldn't use - # POSIX names - '_CRT_NONSTDC_NO_DEPRECATE', - ], - 'target_conditions': [ - ['target_arch=="x64"', { - 'msvs_configuration_platform': 'x64' - }] - ] - }], - ['OS in "freebsd dragonflybsd linux openbsd solaris android"', { - 'cflags': [ '-Wall' ], - 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ], - 'target_conditions': [ - ['_type=="static_library"', { - 'standalone_static_library': 1, # disable thin archive which needs binutils >= 2.19 - }], - ], - 'conditions': [ - [ 'host_arch != target_arch and target_arch=="ia32"', { - 'cflags': [ '-m32' ], - 'ldflags': [ '-m32' ], - }], - [ 'target_arch=="x32"', { - 'cflags': [ '-mx32' ], - 'ldflags': [ '-mx32' ], - }], - [ 'OS=="linux"', { - 'cflags': [ '-ansi' ], - }], - [ 'OS=="solaris"', { - 'cflags': [ '-pthreads' ], - 'ldflags': [ '-pthreads' ], - }], - [ 'OS not in "solaris android"', { - 'cflags': [ '-pthread' ], - 'ldflags': [ '-pthread' ], - }], - [ 'visibility=="hidden"', { - 'cflags': [ '-fvisibility=hidden' ], - }], - ], - }], - ['OS=="mac"', { - 'xcode_settings': { - 'ALWAYS_SEARCH_USER_PATHS': 'NO', - 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks - 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic - # (Equivalent to -fPIC) - 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions - 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti - 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings - # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden - 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES', - 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden - 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics - 'PREBINDING': 'NO', # No -Wl,-prebind - 'USE_HEADERMAP': 'NO', - 'OTHER_CFLAGS': [ - '-fstrict-aliasing', - ], - 'WARNING_CFLAGS': [ - '-Wall', - '-Wendif-labels', - '-W', - '-Wno-unused-parameter', - ], - }, - 'conditions': [ - ['target_arch=="ia32"', { - 'xcode_settings': {'ARCHS': ['i386']}, - }], - ['target_arch=="x64"', { - 'xcode_settings': {'ARCHS': ['x86_64']}, - }], - ], - 'target_conditions': [ - ['_type!="static_library"', { - 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']}, - }], - ], - }], - ['OS=="solaris"', { - 'cflags': [ '-fno-omit-frame-pointer' ], - # pull in V8's postmortem metadata - 'ldflags': [ '-Wl,-z,allextract' ] - }], - ], - }, -} diff --git a/outside/libuv-v1.7.5/configure.ac b/outside/libuv-v1.7.5/configure.ac deleted file mode 100644 index c55a11847e..0000000000 --- a/outside/libuv-v1.7.5/configure.ac +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2013, Ben Noordhuis -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -AC_PREREQ(2.57) -AC_INIT([libuv], [1.7.5], [https://github.com/libuv/libuv/issues]) -AC_CONFIG_MACRO_DIR([m4]) -m4_include([m4/libuv-extra-automake-flags.m4]) -m4_include([m4/as_case.m4]) -m4_include([m4/libuv-check-flags.m4]) -AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS) -AC_CANONICAL_HOST -AC_ENABLE_SHARED -AC_ENABLE_STATIC -AC_PROG_CC -AM_PROG_CC_C_O -CC_CHECK_CFLAGS_APPEND([-fvisibility=hidden]) -CC_CHECK_CFLAGS_APPEND([-g]) -CC_CHECK_CFLAGS_APPEND([-std=gnu89]) -CC_CHECK_CFLAGS_APPEND([-pedantic]) -CC_CHECK_CFLAGS_APPEND([-Wall]) -CC_CHECK_CFLAGS_APPEND([-Wextra]) -CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter]) -# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12. -m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) -# autoconf complains if AC_PROG_LIBTOOL precedes AM_PROG_AR. -AC_PROG_LIBTOOL -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -LT_INIT -# TODO(bnoordhuis) Check for -pthread vs. -pthreads -AC_CHECK_LIB([dl], [dlopen]) -AC_CHECK_LIB([kstat], [kstat_lookup]) -AC_CHECK_LIB([kvm], [kvm_open]) -AC_CHECK_LIB([nsl], [gethostbyname]) -AC_CHECK_LIB([perfstat], [perfstat_cpu]) -AC_CHECK_LIB([pthread], [pthread_mutex_init]) -AC_CHECK_LIB([rt], [clock_gettime]) -AC_CHECK_LIB([sendfile], [sendfile]) -AC_CHECK_LIB([socket], [socket]) -AC_SYS_LARGEFILE -AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])]) -AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])]) -AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])]) -AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])]) -AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[freebsd*], [true], [false])]) -AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])]) -AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])]) -AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os],[openbsd*], [true], [false])]) -AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])]) -AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])]) -AC_CHECK_HEADERS([sys/ahafs_evProds.h]) -AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes) -AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"]) -AS_IF([test "x$PKG_CONFIG" != "x"], [ - AC_CONFIG_FILES([libuv.pc]) -]) -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/outside/libuv-v1.7.5/docs/Makefile b/outside/libuv-v1.7.5/docs/Makefile deleted file mode 100644 index 1e0fc8f022..0000000000 --- a/outside/libuv-v1.7.5/docs/Makefile +++ /dev/null @@ -1,178 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build -SRCDIR = src - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR) -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR) - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/libuv.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/libuv.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/libuv" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/libuv" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/outside/libuv-v1.7.5/docs/make.bat b/outside/libuv-v1.7.5/docs/make.bat deleted file mode 100644 index aa7089ab5c..0000000000 --- a/outside/libuv-v1.7.5/docs/make.bat +++ /dev/null @@ -1,243 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=build -set SRCDIR=src -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SRCDIR% -set I18NSPHINXOPTS=%SPHINXOPTS% %SRCDIR% -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libuv.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libuv.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/outside/libuv-v1.7.5/docs/src/async.rst b/outside/libuv-v1.7.5/docs/src/async.rst deleted file mode 100644 index 5c40045824..0000000000 --- a/outside/libuv-v1.7.5/docs/src/async.rst +++ /dev/null @@ -1,57 +0,0 @@ - -.. _async: - -:c:type:`uv_async_t` --- Async handle -===================================== - -Async handles allow the user to "wakeup" the event loop and get a callback -called from another thread. - - -Data types ----------- - -.. c:type:: uv_async_t - - Async handle type. - -.. c:type:: void (*uv_async_cb)(uv_async_t* handle) - - Type definition for callback passed to :c:func:`uv_async_init`. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) - - Initialize the handle. A NULL callback is allowed. - - .. note:: - Unlike other handle initialization functions, it immediately starts the handle. - -.. c:function:: int uv_async_send(uv_async_t* async) - - Wakeup the event loop and call the async handle's callback. - - .. note:: - It's safe to call this function from any thread. The callback will be called on the - loop thread. - - .. warning:: - libuv will coalesce calls to :c:func:`uv_async_send`, that is, not every call to it will - yield an execution of the callback. For example: if :c:func:`uv_async_send` is called 5 - times in a row before the callback is called, the callback will only be called once. If - :c:func:`uv_async_send` is called again after the callback was called, it will be called - again. - -.. seealso:: - The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/check.rst b/outside/libuv-v1.7.5/docs/src/check.rst deleted file mode 100644 index 36c93cf03d..0000000000 --- a/outside/libuv-v1.7.5/docs/src/check.rst +++ /dev/null @@ -1,46 +0,0 @@ - -.. _check: - -:c:type:`uv_check_t` --- Check handle -===================================== - -Check handles will run the given callback once per loop iteration, right -after polling for i/o. - - -Data types ----------- - -.. c:type:: uv_check_t - - Check handle type. - -.. c:type:: void (*uv_check_cb)(uv_check_t* handle) - - Type definition for callback passed to :c:func:`uv_check_start`. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_check_init(uv_loop_t* loop, uv_check_t* check) - - Initialize the handle. - -.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb) - - Start the handle with the given callback. - -.. c:function:: int uv_check_stop(uv_check_t* check) - - Stop the handle, the callback will no longer be called. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/conf.py b/outside/libuv-v1.7.5/docs/src/conf.py deleted file mode 100644 index b9eaa13743..0000000000 --- a/outside/libuv-v1.7.5/docs/src/conf.py +++ /dev/null @@ -1,348 +0,0 @@ -# -*- coding: utf-8 -*- -# -# libuv API documentation documentation build configuration file, created by -# sphinx-quickstart on Sun Jul 27 11:47:51 2014. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import os -import re -import sys - - -def get_libuv_version(): - with open('../../include/uv-version.h') as f: - data = f.read() - try: - m = re.search(r"""^#define UV_VERSION_MAJOR (\d)$""", data, re.MULTILINE) - major = int(m.group(1)) - m = re.search(r"""^#define UV_VERSION_MINOR (\d)$""", data, re.MULTILINE) - minor = int(m.group(1)) - m = re.search(r"""^#define UV_VERSION_PATCH (\d)$""", data, re.MULTILINE) - patch = int(m.group(1)) - m = re.search(r"""^#define UV_VERSION_IS_RELEASE (\d)$""", data, re.MULTILINE) - is_release = int(m.group(1)) - m = re.search(r"""^#define UV_VERSION_SUFFIX \"(\w*)\"$""", data, re.MULTILINE) - suffix = m.group(1) - return '%d.%d.%d%s' % (major, minor, patch, '-%s' % suffix if not is_release else '') - except Exception: - return 'unknown' - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('sphinx-plugins')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ['manpage'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'libuv API documentation' -copyright = u'libuv contributors' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = get_libuv_version() -# The full version, including alpha/beta/rc tags. -release = version - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'nature' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -html_title = 'libuv API documentation' - -# A shorter title for the navigation bar. Default is the same as html_title. -html_short_title = 'libuv %s API documentation' % version - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = 'static/logo.png' - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -html_favicon = 'static/favicon.ico' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'libuv' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'libuv.tex', u'libuv API documentation', - u'libuv contributors', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'libuv', u'libuv API documentation', - [u'libuv contributors'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'libuv', u'libuv API documentation', - u'libuv contributors', 'libuv', 'Cross-platform asynchronous I/O', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -# -- Options for Epub output ---------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = u'libuv API documentation' -epub_author = u'libuv contributors' -epub_publisher = u'libuv contributors' -epub_copyright = u'2014, libuv contributors' - -# The basename for the epub file. It defaults to the project name. -epub_basename = u'libuv' - -# The HTML theme for the epub output. Since the default themes are not optimized -# for small screen space, using the same theme for HTML and epub output is -# usually not wise. This defaults to 'epub', a theme designed to save visual -# space. -#epub_theme = 'epub' - -# The language of the text. It defaults to the language option -# or en if the language is not set. -#epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -#epub_identifier = '' - -# A unique identification for the text. -#epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -#epub_cover = () - -# A sequence of (type, uri, title) tuples for the guide element of content.opf. -#epub_guide = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_pre_files = [] - -# HTML files shat should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_post_files = [] - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] - -# The depth of the table of contents in toc.ncx. -#epub_tocdepth = 3 - -# Allow duplicate toc entries. -#epub_tocdup = True - -# Choose between 'default' and 'includehidden'. -#epub_tocscope = 'default' - -# Fix unsupported image types using the PIL. -#epub_fix_images = False - -# Scale large images. -#epub_max_image_width = 0 - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#epub_show_urls = 'inline' - -# If false, no index is generated. -#epub_use_index = True diff --git a/outside/libuv-v1.7.5/docs/src/design.rst b/outside/libuv-v1.7.5/docs/src/design.rst deleted file mode 100644 index 34c3cff68e..0000000000 --- a/outside/libuv-v1.7.5/docs/src/design.rst +++ /dev/null @@ -1,137 +0,0 @@ - -.. _design: - -Design overview -=============== - -libuv is cross-platform support library which was originally written for NodeJS. It's designed -around the event-driven asynchronous I/O model. - -The library provides much more than simply abstraction over different I/O polling mechanisms: -'handles' and 'streams' provide a high level abstraction for sockets and other entities; -cross-platform file I/O and threading functionality is also provided, amongst other things. - -Here is a diagram illustrating the different parts that compose libuv and what subsystem they -relate to: - -.. image:: static/architecture.png - :scale: 75% - :align: center - - -Handles and requests -^^^^^^^^^^^^^^^^^^^^ - -libuv provides users with 2 abstractions to work with, in combination with the event loop: -handles and requests. - -Handles represent long-lived objects capable of performing certain operations while active. Some -examples: a prepare handle gets its callback called once every loop iteration when active, and -a TCP server handle get its connection callback called every time there is a new connection. - -Requests represent (typically) short-lived operations. These operations can be performed over a -handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests -don't need a handle they run directly on the loop. - - -The I/O loop -^^^^^^^^^^^^ - -The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O -operations, and it's meant to be tied to a single thread. One can run multiple event loops -as long as each runs in a different thread. The libuv event loop (or any other API involving -the loop or handles, for that matter) **is not thread-safe** except where stated otherwise. - -The event loop follows the rather usual single threaded asynchronous I/O approach: all (network) -I/O is performed on non-blocking sockets which are polled using the best mechanism available -on the given platform: epoll on Linux, kqueue on OSX and other BSDs, event ports on SunOS and IOCP -on Windows. As part of a loop iteration the loop will block waiting for I/O activity on sockets -which have been added to the poller and callbacks will be fired indicating socket conditions -(readable, writable hangup) so handles can read, write or perform the desired I/O operation. - -In order to better understand how the event loop operates, the following diagram illustrates all -stages of a loop iteration: - -.. image:: static/loop_iteration.png - :scale: 75% - :align: center - - -#. The loop concept of 'now' is updated. The event loop caches the current time at the start of - the event loop tick in order to reduce the number of time-related system calls. - -#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So, - when is a loop considered to be *alive*? If a loop has active and ref'd handles, active - requests or closing handles it's considered to be *alive*. - -#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now* - get their callbacks called. - -#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the - most part. There are cases, however, in which calling such a callback is deferred for the next - loop iteration. If the previous iteration deferred any I/O callback it will be run at this point. - -#. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every - loop iteration, if they are active. - -#. Prepare handle callbacks are called. Prepare handles get their callbacks called right before - the loop will block for I/O. - -#. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should - block. These are the rules when calculating the timeout: - - * If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0. - * If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0. - * If there are no active handles or requests, the timeout is 0. - * If there are any idle handles active, the timeout is 0. - * If there are any handles pending to be closed, the timeout is 0. - * If none of the above cases was matched, the timeout of the closest timer is taken, or - if there are no active timers, infinity. - -#. The loop blocks for I/O. At this point the loop will block for I/O for the timeout calculated - on the previous step. All I/O related handles that were monitoring a given file descriptor - for a read or write operation get their callbacks called at this point. - -#. Check handle callbacks are called. Check handles get their callbacks called right after the - loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles. - -#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will - get the close callback called. - -#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress. - It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed - so there might be timers which are due, those timers get their callbacks called. - -#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the - iteration is ended and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT`` - it will continue from the start if it's still *alive*, otherwise it will also end. - - -.. important:: - libuv uses a thread pool to make asynchronous file I/O operations possible, but - network I/O is **always** performed in a single thread, each loop's thread. - -.. note:: - While the polling mechanism is different, libuv makes the execution model consistent - across Unix systems and Windows. - - -File I/O -^^^^^^^^ - -Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on, -so the current approach is to run blocking file I/O operations in a thread pool. - -For a thorough explanation of the cross-platform file I/O landscape, checkout -`this post `_. - -libuv currently uses a global thread pool on which all loops can queue work on. 3 types of -operations are currently run on this pool: - - * Filesystem operations - * DNS functions (getaddrinfo and getnameinfo) - * User specified code via :c:func:`uv_queue_work` - -.. warning:: - See the :c:ref:`threadpool` section for more details, but keep in mind the thread pool size - is quite limited. diff --git a/outside/libuv-v1.7.5/docs/src/dll.rst b/outside/libuv-v1.7.5/docs/src/dll.rst deleted file mode 100644 index fb13f90815..0000000000 --- a/outside/libuv-v1.7.5/docs/src/dll.rst +++ /dev/null @@ -1,44 +0,0 @@ - -.. _dll: - -Shared library handling -======================= - -libuv provides cross platform utilities for loading shared libraries and -retrieving symbols from them, using the following API. - - -Data types ----------- - -.. c:type:: uv_lib_t - - Shared library data type. - - -Public members -^^^^^^^^^^^^^^ - -N/A - - -API ---- - -.. c:function:: int uv_dlopen(const char* filename, uv_lib_t* lib) - - Opens a shared library. The filename is in utf-8. Returns 0 on success and - -1 on error. Call :c:func:`uv_dlerror` to get the error message. - -.. c:function:: void uv_dlclose(uv_lib_t* lib) - - Close the shared library. - -.. c:function:: int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) - - Retrieves a data pointer from a dynamic library. It is legal for a symbol - to map to NULL. Returns 0 on success and -1 if the symbol was not found. - -.. c:function:: const char* uv_dlerror(const uv_lib_t* lib) - - Returns the last uv_dlopen() or uv_dlsym() error message. diff --git a/outside/libuv-v1.7.5/docs/src/dns.rst b/outside/libuv-v1.7.5/docs/src/dns.rst deleted file mode 100644 index 1d88158096..0000000000 --- a/outside/libuv-v1.7.5/docs/src/dns.rst +++ /dev/null @@ -1,108 +0,0 @@ - -.. _dns: - -DNS utility functions -===================== - -libuv provides asynchronous variants of `getaddrinfo` and `getnameinfo`. - - -Data types ----------- - -.. c:type:: uv_getaddrinfo_t - - `getaddrinfo` request type. - -.. c:type:: void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, int status, struct addrinfo* res) - - Callback which will be called with the getaddrinfo request result once - complete. In case it was cancelled, `status` will have a value of - ``UV_ECANCELED``. - -.. c:type:: uv_getnameinfo_t - - `getnameinfo` request type. - -.. c:type:: void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service) - - Callback which will be called with the getnameinfo request result once - complete. In case it was cancelled, `status` will have a value of - ``UV_ECANCELED``. - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: uv_loop_t* uv_getaddrinfo_t.loop - - Loop that started this getaddrinfo request and where completion will be - reported. Readonly. - -.. c:member:: struct addrinfo* uv_getaddrinfo_t.addrinfo - - Pointer to a `struct addrinfo` containing the result. Must be freed by the user - with :c:func:`uv_freeaddrinfo`. - - .. versionchanged:: 1.3.0 the field is declared as public. - -.. c:member:: uv_loop_t* uv_getnameinfo_t.loop - - Loop that started this getnameinfo request and where completion will be - reported. Readonly. - -.. c:member:: char[NI_MAXHOST] uv_getnameinfo_t.host - - Char array containing the resulting host. It's null terminated. - - .. versionchanged:: 1.3.0 the field is declared as public. - -.. c:member:: char[NI_MAXSERV] uv_getnameinfo_t.service - - Char array containing the resulting service. It's null terminated. - - .. versionchanged:: 1.3.0 the field is declared as public. - -.. seealso:: The :c:type:`uv_req_t` members also apply. - - -API ---- - -.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints) - - Asynchronous :man:`getaddrinfo(3)`. - - Either node or service may be NULL but not both. - - `hints` is a pointer to a struct addrinfo with additional address type - constraints, or NULL. Consult `man -s 3 getaddrinfo` for more details. - - Returns 0 on success or an error code < 0 on failure. If successful, the - callback will get called sometime in the future with the lookup result, - which is either: - - * status == 0, the res argument points to a valid `struct addrinfo`, or - * status < 0, the res argument is NULL. See the UV_EAI_* constants. - - Call :c:func:`uv_freeaddrinfo` to free the addrinfo structure. - - .. versionchanged:: 1.3.0 the callback parameter is now allowed to be NULL, - in which case the request will run **synchronously**. - -.. c:function:: void uv_freeaddrinfo(struct addrinfo* ai) - - Free the struct addrinfo. Passing NULL is allowed and is a no-op. - -.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags) - - Asynchronous :man:`getnameinfo(3)`. - - Returns 0 on success or an error code < 0 on failure. If successful, the - callback will get called sometime in the future with the lookup result. - Consult `man -s 3 getnameinfo` for more details. - - .. versionchanged:: 1.3.0 the callback parameter is now allowed to be NULL, - in which case the request will run **synchronously**. - -.. seealso:: The :c:type:`uv_req_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/errors.rst b/outside/libuv-v1.7.5/docs/src/errors.rst deleted file mode 100644 index cec25f5187..0000000000 --- a/outside/libuv-v1.7.5/docs/src/errors.rst +++ /dev/null @@ -1,331 +0,0 @@ - -.. _errors: - -Error handling -============== - -In libuv errors are negative numbered constants. As a rule of thumb, whenever -there is a status parameter, or an API functions returns an integer, a negative -number will imply an error. - -.. note:: - Implementation detail: on Unix error codes are the negated `errno` (or `-errno`), while on - Windows they are defined by libuv to arbitrary negative numbers. - - -Error constants ---------------- - -.. c:macro:: UV_E2BIG - - argument list too long - -.. c:macro:: UV_EACCES - - permission denied - -.. c:macro:: UV_EADDRINUSE - - address already in use - -.. c:macro:: UV_EADDRNOTAVAIL - - address not available - -.. c:macro:: UV_EAFNOSUPPORT - - address family not supported - -.. c:macro:: UV_EAGAIN - - resource temporarily unavailable - -.. c:macro:: UV_EAI_ADDRFAMILY - - address family not supported - -.. c:macro:: UV_EAI_AGAIN - - temporary failure - -.. c:macro:: UV_EAI_BADFLAGS - - bad ai_flags value - -.. c:macro:: UV_EAI_BADHINTS - - invalid value for hints - -.. c:macro:: UV_EAI_CANCELED - - request canceled - -.. c:macro:: UV_EAI_FAIL - - permanent failure - -.. c:macro:: UV_EAI_FAMILY - - ai_family not supported - -.. c:macro:: UV_EAI_MEMORY - - out of memory - -.. c:macro:: UV_EAI_NODATA - - no address - -.. c:macro:: UV_EAI_NONAME - - unknown node or service - -.. c:macro:: UV_EAI_OVERFLOW - - argument buffer overflow - -.. c:macro:: UV_EAI_PROTOCOL - - resolved protocol is unknown - -.. c:macro:: UV_EAI_SERVICE - - service not available for socket type - -.. c:macro:: UV_EAI_SOCKTYPE - - socket type not supported - -.. c:macro:: UV_EALREADY - - connection already in progress - -.. c:macro:: UV_EBADF - - bad file descriptor - -.. c:macro:: UV_EBUSY - - resource busy or locked - -.. c:macro:: UV_ECANCELED - - operation canceled - -.. c:macro:: UV_ECHARSET - - invalid Unicode character - -.. c:macro:: UV_ECONNABORTED - - software caused connection abort - -.. c:macro:: UV_ECONNREFUSED - - connection refused - -.. c:macro:: UV_ECONNRESET - - connection reset by peer - -.. c:macro:: UV_EDESTADDRREQ - - destination address required - -.. c:macro:: UV_EEXIST - - file already exists - -.. c:macro:: UV_EFAULT - - bad address in system call argument - -.. c:macro:: UV_EFBIG - - file too large - -.. c:macro:: UV_EHOSTUNREACH - - host is unreachable - -.. c:macro:: UV_EINTR - - interrupted system call - -.. c:macro:: UV_EINVAL - - invalid argument - -.. c:macro:: UV_EIO - - i/o error - -.. c:macro:: UV_EISCONN - - socket is already connected - -.. c:macro:: UV_EISDIR - - illegal operation on a directory - -.. c:macro:: UV_ELOOP - - too many symbolic links encountered - -.. c:macro:: UV_EMFILE - - too many open files - -.. c:macro:: UV_EMSGSIZE - - message too long - -.. c:macro:: UV_ENAMETOOLONG - - name too long - -.. c:macro:: UV_ENETDOWN - - network is down - -.. c:macro:: UV_ENETUNREACH - - network is unreachable - -.. c:macro:: UV_ENFILE - - file table overflow - -.. c:macro:: UV_ENOBUFS - - no buffer space available - -.. c:macro:: UV_ENODEV - - no such device - -.. c:macro:: UV_ENOENT - - no such file or directory - -.. c:macro:: UV_ENOMEM - - not enough memory - -.. c:macro:: UV_ENONET - - machine is not on the network - -.. c:macro:: UV_ENOPROTOOPT - - protocol not available - -.. c:macro:: UV_ENOSPC - - no space left on device - -.. c:macro:: UV_ENOSYS - - function not implemented - -.. c:macro:: UV_ENOTCONN - - socket is not connected - -.. c:macro:: UV_ENOTDIR - - not a directory - -.. c:macro:: UV_ENOTEMPTY - - directory not empty - -.. c:macro:: UV_ENOTSOCK - - socket operation on non-socket - -.. c:macro:: UV_ENOTSUP - - operation not supported on socket - -.. c:macro:: UV_EPERM - - operation not permitted - -.. c:macro:: UV_EPIPE - - broken pipe - -.. c:macro:: UV_EPROTO - - protocol error - -.. c:macro:: UV_EPROTONOSUPPORT - - protocol not supported - -.. c:macro:: UV_EPROTOTYPE - - protocol wrong type for socket - -.. c:macro:: UV_ERANGE - - result too large - -.. c:macro:: UV_EROFS - - read-only file system - -.. c:macro:: UV_ESHUTDOWN - - cannot send after transport endpoint shutdown - -.. c:macro:: UV_ESPIPE - - invalid seek - -.. c:macro:: UV_ESRCH - - no such process - -.. c:macro:: UV_ETIMEDOUT - - connection timed out - -.. c:macro:: UV_ETXTBSY - - text file is busy - -.. c:macro:: UV_EXDEV - - cross-device link not permitted - -.. c:macro:: UV_UNKNOWN - - unknown error - -.. c:macro:: UV_EOF - - end of file - -.. c:macro:: UV_ENXIO - - no such device or address - -.. c:macro:: UV_EMLINK - - too many links - - -API ---- - -.. c:function:: const char* uv_strerror(int err) - - Returns the error message for the given error code. Leaks a few bytes - of memory when you call it with an unknown error code. - -.. c:function:: const char* uv_err_name(int err) - - Returns the error name for the given error code. Leaks a few bytes - of memory when you call it with an unknown error code. diff --git a/outside/libuv-v1.7.5/docs/src/fs.rst b/outside/libuv-v1.7.5/docs/src/fs.rst deleted file mode 100644 index 33c04406f1..0000000000 --- a/outside/libuv-v1.7.5/docs/src/fs.rst +++ /dev/null @@ -1,290 +0,0 @@ - -.. _fs: - -Filesystem operations -===================== - -libuv provides a wide variety of cross-platform sync and async filesystem -operations. All functions defined in this document take a callback, which is -allowed to be NULL. If the callback is NULL the request is completed synchronously, -otherwise it will be performed asynchronously. - -All file operations are run on the threadpool, see :ref:`threadpool` for information -on the threadpool size. - - -Data types ----------- - -.. c:type:: uv_fs_t - - Filesystem request type. - -.. c:type:: uv_timespec_t - - Portable equivalent of ``struct timespec``. - - :: - - typedef struct { - long tv_sec; - long tv_nsec; - } uv_timespec_t; - -.. c:type:: uv_stat_t - - Portable equivalent of ``struct stat``. - - :: - - typedef struct { - uint64_t st_dev; - uint64_t st_mode; - uint64_t st_nlink; - uint64_t st_uid; - uint64_t st_gid; - uint64_t st_rdev; - uint64_t st_ino; - uint64_t st_size; - uint64_t st_blksize; - uint64_t st_blocks; - uint64_t st_flags; - uint64_t st_gen; - uv_timespec_t st_atim; - uv_timespec_t st_mtim; - uv_timespec_t st_ctim; - uv_timespec_t st_birthtim; - } uv_stat_t; - -.. c:type:: uv_fs_type - - Filesystem request type. - - :: - - typedef enum { - UV_FS_UNKNOWN = -1, - UV_FS_CUSTOM, - UV_FS_OPEN, - UV_FS_CLOSE, - UV_FS_READ, - UV_FS_WRITE, - UV_FS_SENDFILE, - UV_FS_STAT, - UV_FS_LSTAT, - UV_FS_FSTAT, - UV_FS_FTRUNCATE, - UV_FS_UTIME, - UV_FS_FUTIME, - UV_FS_ACCESS, - UV_FS_CHMOD, - UV_FS_FCHMOD, - UV_FS_FSYNC, - UV_FS_FDATASYNC, - UV_FS_UNLINK, - UV_FS_RMDIR, - UV_FS_MKDIR, - UV_FS_MKDTEMP, - UV_FS_RENAME, - UV_FS_SCANDIR, - UV_FS_LINK, - UV_FS_SYMLINK, - UV_FS_READLINK, - UV_FS_CHOWN, - UV_FS_FCHOWN - } uv_fs_type; - -.. c:type:: uv_dirent_t - - Cross platform (reduced) equivalent of ``struct dirent``. - Used in :c:func:`uv_fs_scandir_next`. - - :: - - typedef enum { - UV_DIRENT_UNKNOWN, - UV_DIRENT_FILE, - UV_DIRENT_DIR, - UV_DIRENT_LINK, - UV_DIRENT_FIFO, - UV_DIRENT_SOCKET, - UV_DIRENT_CHAR, - UV_DIRENT_BLOCK - } uv_dirent_type_t; - - typedef struct uv_dirent_s { - const char* name; - uv_dirent_type_t type; - } uv_dirent_t; - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: uv_loop_t* uv_fs_t.loop - - Loop that started this request and where completion will be reported. - Readonly. - -.. c:member:: uv_fs_type uv_fs_t.fs_type - - FS request type. - -.. c:member:: const char* uv_fs_t.path - - Path affecting the request. - -.. c:member:: ssize_t uv_fs_t.result - - Result of the request. < 0 means error, success otherwise. On requests such - as :c:func:`uv_fs_read` or :c:func:`uv_fs_write` it indicates the amount of - data that was read or written, respectively. - -.. c:member:: uv_stat_t uv_fs_t.statbuf - - Stores the result of :c:func:`uv_fs_stat` and other stat requests. - -.. c:member:: void* uv_fs_t.ptr - - Stores the result of :c:func:`uv_fs_readlink` and serves as an alias to - `statbuf`. - -.. seealso:: The :c:type:`uv_req_t` members also apply. - - -API ---- - -.. c:function:: void uv_fs_req_cleanup(uv_fs_t* req) - - Cleanup request. Must be called after a request is finished to deallocate - any memory libuv might have allocated. - -.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) - - Equivalent to :man:`close(2)`. - -.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) - - Equivalent to :man:`open(2)`. - - .. note:: - On Windows libuv uses `CreateFileW` and thus the file is always opened - in binary mode. Because of this the O_BINARY and O_TEXT flags are not - supported. - -.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) - - Equivalent to :man:`preadv(2)`. - -.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) - - Equivalent to :man:`unlink(2)`. - -.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) - - Equivalent to :man:`pwritev(2)`. - -.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) - - Equivalent to :man:`mkdir(2)`. - - .. note:: - `mode` is currently not implemented on Windows. - -.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) - - Equivalent to :man:`mkdtemp(3)`. - - .. note:: - The result can be found as a null terminated string at `req->path`. - -.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) - - Equivalent to :man:`rmdir(2)`. - -.. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) -.. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) - - Equivalent to :man:`scandir(3)`, with a slightly different API. Once the callback - for the request is called, the user can use :c:func:`uv_fs_scandir_next` to - get `ent` populated with the next directory entry data. When there are no - more entries ``UV_EOF`` will be returned. - - .. note:: - Unlike `scandir(3)`, this function does not return the "." and ".." entries. - - .. note:: - On Linux, getting the type of an entry is only supported by some filesystems (btrfs, ext2, - ext3 and ext4 at the time of this writing), check the :man:`getdents(2)` man page. - -.. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) -.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) -.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) - - Equivalent to :man:`stat(2)`, :man:`fstat(2)` and :man:`fstat(2)` respectively. - -.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) - - Equivalent to :man:`rename(2)`. - -.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) - - Equivalent to :man:`fsync(2)`. - -.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) - - Equivalent to :man:`fdatasync(2)`. - -.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb) - - Equivalent to :man:`ftruncate(2)`. - -.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) - - Limited equivalent to :man:`sendfile(2)`. - -.. c:function:: int uv_fs_access(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) - - Equivalent to :man:`access(2)` on Unix. Windows uses ``GetFileAttributesW()``. - -.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) -.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) - - Equivalent to :man:`chmod(2)` and :man:`fchmod(2)` respectively. - -.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) -.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) - - Equivalent to :man:`utime(2)` and :man:`futime(2)` respectively. - -.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) - - Equivalent to :man:`link(2)`. - -.. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb) - - Equivalent to :man:`symlink(2)`. - - .. note:: - On Windows the `flags` parameter can be specified to control how the symlink will - be created: - - * ``UV_FS_SYMLINK_DIR``: indicates that `path` points to a directory. - - * ``UV_FS_SYMLINK_JUNCTION``: request that the symlink is created - using junction points. - -.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) - - Equivalent to :man:`readlink(2)`. - -.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) -.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) - - Equivalent to :man:`chown(2)` and :man:`fchown(2)` respectively. - - .. note:: - These functions are not implemented on Windows. - -.. seealso:: The :c:type:`uv_req_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/fs_event.rst b/outside/libuv-v1.7.5/docs/src/fs_event.rst deleted file mode 100644 index c2d7f52023..0000000000 --- a/outside/libuv-v1.7.5/docs/src/fs_event.rst +++ /dev/null @@ -1,108 +0,0 @@ - -.. _fs_event: - -:c:type:`uv_fs_event_t` --- FS Event handle -=========================================== - -FS Event handles allow the user to monitor a given path for changes, for example, -if the file was renamed or there was a generic change in it. This handle uses -the best backend for the job on each platform. - - -Data types ----------- - -.. c:type:: uv_fs_event_t - - FS Event handle type. - -.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status) - - Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly - after the handle is started. If the handle was started with a directory the - `filename` parameter will be a relative path to a file contained in the directory. - The `events` parameter is an ORed mask of :c:type:`uv_fs_event` elements. - -.. c:type:: uv_fs_event - - Event types that :c:type:`uv_fs_event_t` handles monitor. - - :: - - enum uv_fs_event { - UV_RENAME = 1, - UV_CHANGE = 2 - }; - -.. c:type:: uv_fs_event_flags - - Flags that can be passed to :c:func:`uv_fs_event_start` to control its - behavior. - - :: - - enum uv_fs_event_flags { - /* - * By default, if the fs event watcher is given a directory name, we will - * watch for all events in that directory. This flags overrides this behavior - * and makes fs_event report only changes to the directory entry itself. This - * flag does not affect individual files watched. - * This flag is currently not implemented yet on any backend. - */ - UV_FS_EVENT_WATCH_ENTRY = 1, - /* - * By default uv_fs_event will try to use a kernel interface such as inotify - * or kqueue to detect events. This may not work on remote filesystems such - * as NFS mounts. This flag makes fs_event fall back to calling stat() on a - * regular interval. - * This flag is currently not implemented yet on any backend. - */ - UV_FS_EVENT_STAT = 2, - /* - * By default, event watcher, when watching directory, is not registering - * (is ignoring) changes in it's subdirectories. - * This flag will override this behaviour on platforms that support it. - */ - UV_FS_EVENT_RECURSIVE = 4 - }; - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) - - Initialize the handle. - -.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) - - Start the handle with the given callback, which will watch the specified - `path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`. - - .. note:: Currently the only supported flag is ``UV_FS_EVENT_RECURSIVE`` and - only on OSX and Windows. - -.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle) - - Stop the handle, the callback will no longer be called. - -.. c:function:: int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) - - Get the path being monitored by the handle. The buffer must be preallocated - by the user. Returns 0 on success or an error code < 0 in case of failure. - On success, `buffer` will contain the path and `size` its length. If the buffer - is not big enough UV_ENOBUFS will be returned and len will be set to the - required size. - - .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, - and the buffer is not null terminated. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/fs_poll.rst b/outside/libuv-v1.7.5/docs/src/fs_poll.rst deleted file mode 100644 index 4efb2440e0..0000000000 --- a/outside/libuv-v1.7.5/docs/src/fs_poll.rst +++ /dev/null @@ -1,72 +0,0 @@ - -.. _fs_poll: - -:c:type:`uv_fs_poll_t` --- FS Poll handle -========================================= - -FS Poll handles allow the user to monitor a given path for changes. Unlike -:c:type:`uv_fs_event_t`, fs poll handles use `stat` to detect when a file has -changed so they can work on file systems where fs event handles can't. - - -Data types ----------- - -.. c:type:: uv_fs_poll_t - - FS Poll handle type. - -.. c:type:: void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr) - - Callback passed to :c:func:`uv_fs_poll_start` which will be called repeatedly - after the handle is started, when any change happens to the monitored path. - - The callback is invoked with `status < 0` if `path` does not exist - or is inaccessible. The watcher is *not* stopped but your callback is - not called again until something changes (e.g. when the file is created - or the error reason changes). - - When `status == 0`, the callback receives pointers to the old and new - :c:type:`uv_stat_t` structs. They are valid for the duration of the - callback only. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) - - Initialize the handle. - -.. c:function:: int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb poll_cb, const char* path, unsigned int interval) - - Check the file at `path` for changes every `interval` milliseconds. - - .. note:: - For maximum portability, use multi-second intervals. Sub-second intervals will not detect - all changes on many file systems. - -.. c:function:: int uv_fs_poll_stop(uv_fs_poll_t* handle) - - Stop the handle, the callback will no longer be called. - -.. c:function:: int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) - - Get the path being monitored by the handle. The buffer must be preallocated - by the user. Returns 0 on success or an error code < 0 in case of failure. - On success, `buffer` will contain the path and `size` its length. If the buffer - is not big enough UV_ENOBUFS will be returned and len will be set to the - required size. - - .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, - and the buffer is not null terminated. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/handle.rst b/outside/libuv-v1.7.5/docs/src/handle.rst deleted file mode 100644 index 6ba597a21a..0000000000 --- a/outside/libuv-v1.7.5/docs/src/handle.rst +++ /dev/null @@ -1,181 +0,0 @@ - -.. _handle: - -:c:type:`uv_handle_t` --- Base handle -===================================== - -`uv_handle_t` is the base type for all libuv handle types. - -Structures are aligned so that any libuv handle can be cast to `uv_handle_t`. -All API functions defined here work with any handle type. - - -Data types ----------- - -.. c:type:: uv_handle_t - - The base libuv handle type. - -.. c:type:: uv_any_handle - - Union of all handle types. - -.. c:type:: void (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) - - Type definition for callback passed to :c:func:`uv_read_start` and - :c:func:`uv_udp_recv_start`. The user must fill the supplied :c:type:`uv_buf_t` - structure with whatever size, as long as it's > 0. A suggested size (65536 at the moment) - is provided, but it doesn't need to be honored. Setting the buffer's length to 0 - will trigger a ``UV_ENOBUFS`` error in the :c:type:`uv_udp_recv_cb` or - :c:type:`uv_read_cb` callback. - -.. c:type:: void (*uv_close_cb)(uv_handle_t* handle) - - Type definition for callback passed to :c:func:`uv_close`. - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: uv_loop_t* uv_handle_t.loop - - Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly. - -.. c:member:: void* uv_handle_t.data - - Space for user-defined arbitrary data. libuv does not use this field. - - -API ---- - -.. c:function:: int uv_is_active(const uv_handle_t* handle) - - Returns non-zero if the handle is active, zero if it's inactive. What - "active" means depends on the type of handle: - - - A uv_async_t handle is always active and cannot be deactivated, except - by closing it with uv_close(). - - - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that - deals with i/o - is active when it is doing something that involves i/o, - like reading, writing, connecting, accepting new connections, etc. - - - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has - been started with a call to uv_check_start(), uv_idle_start(), etc. - - Rule of thumb: if a handle of type `uv_foo_t` has a `uv_foo_start()` - function, then it's active from the moment that function is called. - Likewise, `uv_foo_stop()` deactivates the handle again. - -.. c:function:: int uv_is_closing(const uv_handle_t* handle) - - Returns non-zero if the handle is closing or closed, zero otherwise. - - .. note:: - This function should only be used between the initialization of the handle and the - arrival of the close callback. - -.. c:function:: void uv_close(uv_handle_t* handle, uv_close_cb close_cb) - - Request handle to be closed. `close_cb` will be called asynchronously after - this call. This MUST be called on each handle before memory is released. - - Handles that wrap file descriptors are closed immediately but - `close_cb` will still be deferred to the next iteration of the event loop. - It gives you a chance to free up any resources associated with the handle. - - In-progress requests, like uv_connect_t or uv_write_t, are cancelled and - have their callbacks called asynchronously with status=UV_ECANCELED. - -.. c:function:: void uv_ref(uv_handle_t* handle) - - Reference the given handle. References are idempotent, that is, if a handle - is already referenced calling this function again will have no effect. - - See :ref:`refcount`. - -.. c:function:: void uv_unref(uv_handle_t* handle) - - Un-reference the given handle. References are idempotent, that is, if a handle - is not referenced calling this function again will have no effect. - - See :ref:`refcount`. - -.. c:function:: int uv_has_ref(const uv_handle_t* handle) - - Returns non-zero if the handle referenced, zero otherwise. - - See :ref:`refcount`. - -.. c:function:: size_t uv_handle_size(uv_handle_type type) - - Returns the size of the given handle type. Useful for FFI binding writers - who don't want to know the structure layout. - - -Miscellaneous API functions ---------------------------- - -The following API functions take a :c:type:`uv_handle_t` argument but they work -just for some handle types. - -.. c:function:: int uv_send_buffer_size(uv_handle_t* handle, int* value) - - Gets or sets the size of the send buffer that the operating - system uses for the socket. - - If `*value` == 0, it will return the current send buffer size, - otherwise it will use `*value` to set the new send buffer size. - - This function works for TCP, pipe and UDP handles on Unix and for TCP and - UDP handles on Windows. - - .. note:: - Linux will set double the size and return double the size of the original set value. - -.. c:function:: int uv_recv_buffer_size(uv_handle_t* handle, int* value) - - Gets or sets the size of the receive buffer that the operating - system uses for the socket. - - If `*value` == 0, it will return the current receive buffer size, - otherwise it will use `*value` to set the new receive buffer size. - - This function works for TCP, pipe and UDP handles on Unix and for TCP and - UDP handles on Windows. - - .. note:: - Linux will set double the size and return double the size of the original set value. - -.. c:function:: int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) - - Gets the platform dependent file descriptor equivalent. - - The following handles are supported: TCP, pipes, TTY, UDP and poll. Passing - any other handle type will fail with `UV_EINVAL`. - - If a handle doesn't have an attached file descriptor yet or the handle - itself has been closed, this function will return `UV_EBADF`. - - .. warning:: - Be very careful when using this function. libuv assumes it's in control of the file - descriptor so any change to it may lead to malfunction. - - -.. _refcount: - -Reference counting ------------------- - -The libuv event loop (if run in the default mode) will run until there are no -active `and` referenced handles left. The user can force the loop to exit early -by unreferencing handles which are active, for example by calling :c:func:`uv_unref` -after calling :c:func:`uv_timer_start`. - -A handle can be referenced or unreferenced, the refcounting scheme doesn't use -a counter, so both operations are idempotent. - -All handles are referenced when active by default, see :c:func:`uv_is_active` -for a more detailed explanation on what being `active` involves. diff --git a/outside/libuv-v1.7.5/docs/src/idle.rst b/outside/libuv-v1.7.5/docs/src/idle.rst deleted file mode 100644 index 1f51c4a19e..0000000000 --- a/outside/libuv-v1.7.5/docs/src/idle.rst +++ /dev/null @@ -1,54 +0,0 @@ - -.. _idle: - -:c:type:`uv_idle_t` --- Idle handle -=================================== - -Idle handles will run the given callback once per loop iteration, right -before the :c:type:`uv_prepare_t` handles. - -.. note:: - The notable difference with prepare handles is that when there are active idle handles, - the loop will perform a zero timeout poll instead of blocking for i/o. - -.. warning:: - Despite the name, idle handles will get their callbacks called on every loop iteration, - not when the loop is actually "idle". - - -Data types ----------- - -.. c:type:: uv_idle_t - - Idle handle type. - -.. c:type:: void (*uv_idle_cb)(uv_idle_t* handle) - - Type definition for callback passed to :c:func:`uv_idle_start`. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) - - Initialize the handle. - -.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) - - Start the handle with the given callback. - -.. c:function:: int uv_idle_stop(uv_idle_t* idle) - - Stop the handle, the callback will no longer be called. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/index.rst b/outside/libuv-v1.7.5/docs/src/index.rst deleted file mode 100644 index fa89c4bffe..0000000000 --- a/outside/libuv-v1.7.5/docs/src/index.rst +++ /dev/null @@ -1,95 +0,0 @@ - -Welcome to the libuv API documentation -====================================== - -Overview --------- - -libuv is a multi-platform support library with a focus on asynchronous I/O. It -was primarily developed for use by `Node.js`_, but it's also used by `Luvit`_, -`Julia`_, `pyuv`_, and `others`_. - -.. note:: - In case you find errors in this documentation you can help by sending - `pull requests `_! - -.. _Node.js: http://nodejs.org -.. _Luvit: http://luvit.io -.. _Julia: http://julialang.org -.. _pyuv: https://github.com/saghul/pyuv -.. _others: https://github.com/libuv/libuv/wiki/Projects-that-use-libuv - - -Features --------- - -* Full-featured event loop backed by epoll, kqueue, IOCP, event ports. -* Asynchronous TCP and UDP sockets -* Asynchronous DNS resolution -* Asynchronous file and file system operations -* File system events -* ANSI escape code controlled TTY -* IPC with socket sharing, using Unix domain sockets or named pipes (Windows) -* Child processes -* Thread pool -* Signal handling -* High resolution clock -* Threading and synchronization primitives - - -Downloads ---------- - -libuv can be downloaded from `here `_. - - -Installation ------------- - -Installation instructions can be found on `the README `_. - - -Upgrading ---------- - -Migration guides for different libuv versions, starting with 1.0. - -.. toctree:: - :maxdepth: 1 - - migration_010_100 - - -Documentation -------------- - -.. toctree:: - :maxdepth: 1 - - design - errors - version - loop - handle - request - timer - prepare - check - idle - async - poll - signal - process - stream - tcp - pipe - tty - udp - fs_event - fs_poll - fs - threadpool - dns - dll - threading - misc diff --git a/outside/libuv-v1.7.5/docs/src/loop.rst b/outside/libuv-v1.7.5/docs/src/loop.rst deleted file mode 100644 index 2a01d79637..0000000000 --- a/outside/libuv-v1.7.5/docs/src/loop.rst +++ /dev/null @@ -1,166 +0,0 @@ - -.. _loop: - -:c:type:`uv_loop_t` --- Event loop -================================== - -The event loop is the central part of libuv's functionality. It takes care -of polling for i/o and scheduling callbacks to be run based on different sources -of events. - - -Data types ----------- - -.. c:type:: uv_loop_t - - Loop data type. - -.. c:type:: uv_run_mode - - Mode used to run the loop with :c:func:`uv_run`. - - :: - - typedef enum { - UV_RUN_DEFAULT = 0, - UV_RUN_ONCE, - UV_RUN_NOWAIT - } uv_run_mode; - -.. c:type:: void (*uv_walk_cb)(uv_handle_t* handle, void* arg) - - Type definition for callback passed to :c:func:`uv_walk`. - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: void* uv_loop_t.data - - Space for user-defined arbitrary data. libuv does not use this field. libuv does, however, - initialize it to NULL in :c:func:`uv_loop_init`, and it poisons the value (on debug builds) - on :c:func:`uv_loop_close`. - - -API ---- - -.. c:function:: int uv_loop_init(uv_loop_t* loop) - - Initializes the given `uv_loop_t` structure. - -.. c:function:: int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) - - .. versionadded:: 1.0.2 - - Set additional loop options. You should normally call this before the - first call to :c:func:`uv_run` unless mentioned otherwise. - - Returns 0 on success or a UV_E* error code on failure. Be prepared to - handle UV_ENOSYS; it means the loop option is not supported by the platform. - - Supported options: - - - UV_LOOP_BLOCK_SIGNAL: Block a signal when polling for new events. The - second argument to :c:func:`uv_loop_configure` is the signal number. - - This operation is currently only implemented for SIGPROF signals, - to suppress unnecessary wakeups when using a sampling profiler. - Requesting other signals will fail with UV_EINVAL. - -.. c:function:: int uv_loop_close(uv_loop_t* loop) - - Closes all internal loop resources. This function must only be called once - the loop has finished its execution or it will return UV_EBUSY. After this - function returns the user shall free the memory allocated for the loop. - -.. c:function:: uv_loop_t* uv_default_loop(void) - - Returns the initialized default loop. It may return NULL in case of - allocation failure. - - This function is just a convenient way for having a global loop throughout - an application, the default loop is in no way different than the ones - initialized with :c:func:`uv_loop_init`. As such, the default loop can (and - should) be closed with :c:func:`uv_loop_close` so the resources associated - with it are freed. - -.. c:function:: int uv_run(uv_loop_t* loop, uv_run_mode mode) - - This function runs the event loop. It will act differently depending on the - specified mode: - - - UV_RUN_DEFAULT: Runs the event loop until there are no more active and - referenced handles or requests. Returns non-zero if :c:func:`uv_stop` - was called and there are still active handles or requests. Returns - zero in all other cases. - - UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if - there are no pending callbacks. Returns zero when done (no active handles - or requests left), or non-zero if more callbacks are expected (meaning - you should run the event loop again sometime in the future). - - UV_RUN_NOWAIT: Poll for i/o once but don't block if there are no - pending callbacks. Returns zero if done (no active handles - or requests left), or non-zero if more callbacks are expected (meaning - you should run the event loop again sometime in the future). - -.. c:function:: int uv_loop_alive(const uv_loop_t* loop) - - Returns non-zero if there are active handles or request in the loop. - -.. c:function:: void uv_stop(uv_loop_t* loop) - - Stop the event loop, causing :c:func:`uv_run` to end as soon as - possible. This will happen not sooner than the next loop iteration. - If this function was called before blocking for i/o, the loop won't block - for i/o on this iteration. - -.. c:function:: size_t uv_loop_size(void) - - Returns the size of the `uv_loop_t` structure. Useful for FFI binding - writers who don't want to know the structure layout. - -.. c:function:: int uv_backend_fd(const uv_loop_t* loop) - - Get backend file descriptor. Only kqueue, epoll and event ports are - supported. - - This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to - poll in one thread and run the event loop's callbacks in another see - test/test-embed.c for an example. - - .. note:: - Embedding a kqueue fd in another kqueue pollset doesn't work on all platforms. It's not - an error to add the fd but it never generates events. - -.. c:function:: int uv_backend_timeout(const uv_loop_t* loop) - - Get the poll timeout. The return value is in milliseconds, or -1 for no - timeout. - -.. c:function:: uint64_t uv_now(const uv_loop_t* loop) - - Return the current timestamp in milliseconds. The timestamp is cached at - the start of the event loop tick, see :c:func:`uv_update_time` for details - and rationale. - - The timestamp increases monotonically from some arbitrary point in time. - Don't make assumptions about the starting point, you will only get - disappointed. - - .. note:: - Use :c:func:`uv_hrtime` if you need sub-millisecond granularity. - -.. c:function:: void uv_update_time(uv_loop_t* loop) - - Update the event loop's concept of "now". Libuv caches the current time - at the start of the event loop tick in order to reduce the number of - time-related system calls. - - You won't normally need to call this function unless you have callbacks - that block the event loop for longer periods of time, where "longer" is - somewhat subjective but probably on the order of a millisecond or more. - -.. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) - - Walk the list of handles: `walk_cb` will be executed with the given `arg`. diff --git a/outside/libuv-v1.7.5/docs/src/migration_010_100.rst b/outside/libuv-v1.7.5/docs/src/migration_010_100.rst deleted file mode 100644 index bb6ac1a809..0000000000 --- a/outside/libuv-v1.7.5/docs/src/migration_010_100.rst +++ /dev/null @@ -1,244 +0,0 @@ - -.. _migration_010_100: - -libuv 0.10 -> 1.0.0 migration guide -=================================== - -Some APIs changed quite a bit throughout the 1.0.0 development process. Here -is a migration guide for the most significant changes that happened after 0.10 -was released. - - -Loop initialization and closing -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In libuv 0.10 (and previous versions), loops were created with `uv_loop_new`, which -allocated memory for a new loop and initialized it; and destroyed with `uv_loop_delete`, -which destroyed the loop and freed the memory. Starting with 1.0, those are deprecated -and the user is responsible for allocating the memory and then initializing the loop. - -libuv 0.10 - -:: - - uv_loop_t* loop = uv_loop_new(); - ... - uv_loop_delete(loop); - -libuv 1.0 - -:: - - uv_loop_t* loop = malloc(sizeof *loop); - uv_loop_init(loop); - ... - uv_loop_close(loop); - free(loop); - -.. note:: - Error handling was omitted for brevity. Check the documentation for :c:func:`uv_loop_init` - and :c:func:`uv_loop_close`. - - -Error handling -~~~~~~~~~~~~~~ - -Error handling had a major overhaul in libuv 1.0. In general, functions and status parameters -would get 0 for success and -1 for failure on libuv 0.10, and the user had to use `uv_last_error` -to fetch the error code, which was a positive number. - -In 1.0, functions and status parameters contain the actual error code, which is 0 for success, or -a negative number in case of error. - -libuv 0.10 - -:: - - ... assume 'server' is a TCP server which is already listening - r = uv_listen((uv_stream_t*) server, 511, NULL); - if (r == -1) { - uv_err_t err = uv_last_error(uv_default_loop()); - /* err.code contains UV_EADDRINUSE */ - } - -libuv 1.0 - -:: - - ... assume 'server' is a TCP server which is already listening - r = uv_listen((uv_stream_t*) server, 511, NULL); - if (r < 0) { - /* r contains UV_EADDRINUSE */ - } - - -Threadpool changes -~~~~~~~~~~~~~~~~~~ - -In libuv 0.10 Unix used a threadpool which defaulted to 4 threads, while Windows used the -`QueueUserWorkItem` API, which uses a Windows internal threadpool, which defaults to 512 -threads per process. - -In 1.0, we unified both implementations, so Windows now uses the same implementation Unix -does. The threadpool size can be set by exporting the ``UV_THREADPOOL_SIZE`` environment -variable. See :c:ref:`threadpool`. - - -Allocation callback API change -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In libuv 0.10 the callback had to return a filled :c:type:`uv_buf_t` by value: - -:: - - uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) { - return uv_buf_init(malloc(size), size); - } - -In libuv 1.0 a pointer to a buffer is passed to the callback, which the user -needs to fill: - -:: - - void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf->base = malloc(size); - buf->len = size; - } - - -Unification of IPv4 / IPv6 APIs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -libuv 1.0 unified the IPv4 and IPv6 APIS. There is no longer a `uv_tcp_bind` and `uv_tcp_bind6` -duality, there is only :c:func:`uv_tcp_bind` now. - -IPv4 functions took ``struct sockaddr_in`` structures by value, and IPv6 functions took -``struct sockaddr_in6``. Now functions take a ``struct sockaddr*`` (note it's a pointer). -It can be stack allocated. - -libuv 0.10 - -:: - - struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", 1234); - ... - uv_tcp_bind(&server, addr) - -libuv 1.0 - -:: - - struct sockaddr_in addr; - uv_ip4_addr("0.0.0.0", 1234, &addr) - ... - uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - -The IPv4 and IPv6 struct creating functions (:c:func:`uv_ip4_addr` and :c:func:`uv_ip6_addr`) -have also changed, make sure you check the documentation. - -..note:: - This change applies to all functions that made a distinction between IPv4 and IPv6 - addresses. - - -Streams / UDP data receive callback API change -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The streams and UDP data receive callbacks now get a pointer to a :c:type:`uv_buf_t` buffer, -not a structure by value. - -libuv 0.10 - -:: - - void on_read(uv_stream_t* handle, - ssize_t nread, - uv_buf_t buf) { - ... - } - - void recv_cb(uv_udp_t* handle, - ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, - unsigned flags) { - ... - } - -libuv 1.0 - -:: - - void on_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - ... - } - - void recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - ... - } - - -Receiving handles over pipes API change -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In libuv 0.10 (and earlier versions) the `uv_read2_start` function was used to start reading -data on a pipe, which could also result in the reception of handles over it. The callback -for such function looked like this: - -:: - - void on_read(uv_pipe_t* pipe, - ssize_t nread, - uv_buf_t buf, - uv_handle_type pending) { - ... - } - -In libuv 1.0, `uv_read2_start` was removed, and the user needs to check if there are pending -handles using :c:func:`uv_pipe_pending_count` and :c:func:`uv_pipe_pending_type` while in -the read callback: - -:: - - void on_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - ... - while (uv_pipe_pending_count((uv_pipe_t*) handle) != 0) { - pending = uv_pipe_pending_type((uv_pipe_t*) handle); - ... - } - ... - } - - -Extracting the file descriptor out of a handle -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -While it wasn't supported by the API, users often accessed the libuv internals in -order to get access to the file descriptor of a TCP handle, for example. - -:: - - fd = handle->io_watcher.fd; - -This is now properly exposed through the :c:func:`uv_fileno` function. - - -uv_fs_readdir rename and API change -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -`uv_fs_readdir` returned a list of strings in the `req->ptr` field upon completion in -libuv 0.10. In 1.0, this function got renamed to :c:func:`uv_fs_scandir`, since it's -actually implemented using ``scandir(3)``. - -In addition, instead of allocating a full list strings, the user is able to get one -result at a time by using the :c:func:`uv_fs_scandir_next` function. This function -does not need to make a roundtrip to the threadpool, because libuv will keep the -list of *dents* returned by ``scandir(3)`` around. diff --git a/outside/libuv-v1.7.5/docs/src/misc.rst b/outside/libuv-v1.7.5/docs/src/misc.rst deleted file mode 100644 index e9ddba3db6..0000000000 --- a/outside/libuv-v1.7.5/docs/src/misc.rst +++ /dev/null @@ -1,290 +0,0 @@ - -.. _misc: - -Miscellaneous utilities -======================= - -This section contains miscellaneous functions that don't really belong in any -other section. - - -Data types ----------- - -.. c:type:: uv_buf_t - - Buffer data type. - - .. c:member:: char* uv_buf_t.base - - Pointer to the base of the buffer. Readonly. - - .. c:member:: size_t uv_buf_t.len - - Total bytes in the buffer. Readonly. - - .. note:: - On Windows this field is ULONG. - -.. c:type:: void* (*uv_malloc_func)(size_t size) - - Replacement function for :man:`malloc(3)`. - See :c:func:`uv_replace_allocator`. - -.. c:type:: void* (*uv_realloc_func)(void* ptr, size_t size) - - Replacement function for :man:`realloc(3)`. - See :c:func:`uv_replace_allocator`. - -.. c:type:: void* (*uv_calloc_func)(size_t count, size_t size) - - Replacement function for :man:`calloc(3)`. - See :c:func:`uv_replace_allocator`. - -.. c:type:: void (*uv_free_func)(void* ptr) - - Replacement function for :man:`free(3)`. - See :c:func:`uv_replace_allocator`. - -.. c:type:: uv_file - - Cross platform representation of a file handle. - -.. c:type:: uv_os_sock_t - - Cross platform representation of a socket handle. - -.. c:type:: uv_os_fd_t - - Abstract representation of a file descriptor. On Unix systems this is a - `typedef` of `int` and on Windows a `HANDLE`. - -.. c:type:: uv_rusage_t - - Data type for resource usage results. - - :: - - typedef struct { - uv_timeval_t ru_utime; /* user CPU time used */ - uv_timeval_t ru_stime; /* system CPU time used */ - uint64_t ru_maxrss; /* maximum resident set size */ - uint64_t ru_ixrss; /* integral shared memory size */ - uint64_t ru_idrss; /* integral unshared data size */ - uint64_t ru_isrss; /* integral unshared stack size */ - uint64_t ru_minflt; /* page reclaims (soft page faults) */ - uint64_t ru_majflt; /* page faults (hard page faults) */ - uint64_t ru_nswap; /* swaps */ - uint64_t ru_inblock; /* block input operations */ - uint64_t ru_oublock; /* block output operations */ - uint64_t ru_msgsnd; /* IPC messages sent */ - uint64_t ru_msgrcv; /* IPC messages received */ - uint64_t ru_nsignals; /* signals received */ - uint64_t ru_nvcsw; /* voluntary context switches */ - uint64_t ru_nivcsw; /* involuntary context switches */ - } uv_rusage_t; - -.. c:type:: uv_cpu_info_t - - Data type for CPU information. - - :: - - typedef struct uv_cpu_info_s { - char* model; - int speed; - struct uv_cpu_times_s { - uint64_t user; - uint64_t nice; - uint64_t sys; - uint64_t idle; - uint64_t irq; - } cpu_times; - } uv_cpu_info_t; - -.. c:type:: uv_interface_address_t - - Data type for interface addresses. - - :: - - typedef struct uv_interface_address_s { - char* name; - char phys_addr[6]; - int is_internal; - union { - struct sockaddr_in address4; - struct sockaddr_in6 address6; - } address; - union { - struct sockaddr_in netmask4; - struct sockaddr_in6 netmask6; - } netmask; - } uv_interface_address_t; - - -API ---- - -.. c:function:: uv_handle_type uv_guess_handle(uv_file file) - - Used to detect what type of stream should be used with a given file - descriptor. Usually this will be used during initialization to guess the - type of the stdio streams. - - For :man:`isatty(3)` equivalent functionality use this function and test - for ``UV_TTY``. - -.. c:function:: int uv_replace_allocator(uv_malloc_func malloc_func, uv_realloc_func realloc_func, uv_calloc_func calloc_func, uv_free_func free_func) - - .. versionadded:: 1.6.0 - - Override the use of the standard library's :man:`malloc(3)`, - :man:`calloc(3)`, :man:`realloc(3)`, :man:`free(3)`, memory allocation - functions. - - This function must be called before any other libuv function is called or - after all resources have been freed and thus libuv doesn't reference - any allocated memory chunk. - - On success, it returns 0, if any of the function pointers is NULL it - returns UV_EINVAL. - - .. warning:: There is no protection against changing the allocator multiple - times. If the user changes it they are responsible for making - sure the allocator is changed while no memory was allocated with - the previous allocator, or that they are compatible. - -.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len) - - Constructor for :c:type:`uv_buf_t`. - - Due to platform differences the user cannot rely on the ordering of the - `base` and `len` members of the uv_buf_t struct. The user is responsible for - freeing `base` after the uv_buf_t is done. Return struct passed by value. - -.. c:function:: char** uv_setup_args(int argc, char** argv) - - Store the program arguments. Required for getting / setting the process title. - -.. c:function:: int uv_get_process_title(char* buffer, size_t size) - - Gets the title of the current process. - -.. c:function:: int uv_set_process_title(const char* title) - - Sets the current process title. - -.. c:function:: int uv_resident_set_memory(size_t* rss) - - Gets the resident set size (RSS) for the current process. - -.. c:function:: int uv_uptime(double* uptime) - - Gets the current system uptime. - -.. c:function:: int uv_getrusage(uv_rusage_t* rusage) - - Gets the resource usage measures for the current process. - - .. note:: - On Windows not all fields are set, the unsupported fields are filled with zeroes. - -.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) - - Gets information about the CPUs on the system. The `cpu_infos` array will - have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`. - -.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) - - Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`. - -.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count) - - Gets address information about the network interfaces on the system. An - array of `count` elements is allocated and returned in `addresses`. It must - be freed by the user, calling :c:func:`uv_free_interface_addresses`. - -.. c:function:: void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) - - Free an array of :c:type:`uv_interface_address_t` which was returned by - :c:func:`uv_interface_addresses`. - -.. c:function:: void uv_loadavg(double avg[3]) - - Gets the load average. See: ``_ - - .. note:: - Returns [0,0,0] on Windows (i.e., it's not implemented). - -.. c:function:: int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) - - Convert a string containing an IPv4 addresses to a binary structure. - -.. c:function:: int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) - - Convert a string containing an IPv6 addresses to a binary structure. - -.. c:function:: int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) - - Convert a binary structure containing an IPv4 address to a string. - -.. c:function:: int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) - - Convert a binary structure containing an IPv6 address to a string. - -.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size) -.. c:function:: int uv_inet_pton(int af, const char* src, void* dst) - - Cross-platform IPv6-capable implementation of :man:`inet_ntop(3)` - and :man:`inet_pton(3)`. On success they return 0. In case of error - the target `dst` pointer is unmodified. - -.. c:function:: int uv_exepath(char* buffer, size_t* size) - - Gets the executable path. - -.. c:function:: int uv_cwd(char* buffer, size_t* size) - - Gets the current working directory. - - .. versionchanged:: 1.1.0 - - On Unix the path no longer ends in a slash. - -.. c:function:: int uv_chdir(const char* dir) - - Changes the current working directory. - -.. c:function:: int uv_os_homedir(char* buffer, size_t* size) - - Gets the current user's home directory. On Windows, `uv_os_homedir()` first - checks the `USERPROFILE` environment variable using - `GetEnvironmentVariableW()`. If `USERPROFILE` is not set, - `GetUserProfileDirectoryW()` is called. On all other operating systems, - `uv_os_homedir()` first checks the `HOME` environment variable using - :man:`getenv(3)`. If `HOME` is not set, :man:`getpwuid_r(3)` is called. The - user's home directory is stored in `buffer`. When `uv_os_homedir()` is - called, `size` indicates the maximum size of `buffer`. On success or - `UV_ENOBUFS` failure, `size` is set to the string length of `buffer`. - - .. warning:: - `uv_os_homedir()` is not thread safe. - - .. versionadded:: 1.6.0 - -.. uint64_t uv_get_free_memory(void) -.. c:function:: uint64_t uv_get_total_memory(void) - - Gets memory information (in bytes). - -.. c:function:: uint64_t uv_hrtime(void) - - Returns the current high-resolution real time. This is expressed in - nanoseconds. It is relative to an arbitrary time in the past. It is not - related to the time of day and therefore not subject to clock drift. The - primary use is for measuring performance between intervals. - - .. note:: - Not every platform can support nanosecond resolution; however, this value will always - be in nanoseconds. diff --git a/outside/libuv-v1.7.5/docs/src/pipe.rst b/outside/libuv-v1.7.5/docs/src/pipe.rst deleted file mode 100644 index d33b0f2b97..0000000000 --- a/outside/libuv-v1.7.5/docs/src/pipe.rst +++ /dev/null @@ -1,104 +0,0 @@ - -.. _pipe: - -:c:type:`uv_pipe_t` --- Pipe handle -=================================== - -Pipe handles provide an abstraction over local domain sockets on Unix and named -pipes on Windows. - -:c:type:`uv_pipe_t` is a 'subclass' of :c:type:`uv_stream_t`. - - -Data types ----------- - -.. c:type:: uv_pipe_t - - Pipe handle type. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_stream_t` members also apply. - - -API ---- - -.. c:function:: int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) - - Initialize a pipe handle. The `ipc` argument is a boolean to indicate if - this pipe will be used for handle passing between processes. - -.. c:function:: int uv_pipe_open(uv_pipe_t* handle, uv_file file) - - Open an existing file descriptor or HANDLE as a pipe. - - .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. - - .. note:: - The passed file descriptor or HANDLE is not checked for its type, but - it's required that it represents a valid pipe. - -.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name) - - Bind the pipe to a file path (Unix) or a name (Windows). - - .. note:: - Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between - 92 and 108 bytes. - -.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb) - - Connect to the Unix domain socket or the named pipe. - - .. note:: - Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between - 92 and 108 bytes. - -.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) - - Get the name of the Unix domain socket or the named pipe. - - A preallocated buffer must be provided. The size parameter holds the length - of the buffer and it's set to the number of bytes written to the buffer on - output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and - len will contain the required size. - - .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, - and the buffer is not null terminated. - -.. c:function:: int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) - - Get the name of the Unix domain socket or the named pipe to which the handle - is connected. - - A preallocated buffer must be provided. The size parameter holds the length - of the buffer and it's set to the number of bytes written to the buffer on - output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and - len will contain the required size. - - .. versionadded:: 1.3.0 - -.. c:function:: void uv_pipe_pending_instances(uv_pipe_t* handle, int count) - - Set the number of pending pipe instance handles when the pipe server is - waiting for connections. - - .. note:: - This setting applies to Windows only. - -.. c:function:: int uv_pipe_pending_count(uv_pipe_t* handle) -.. c:function:: uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) - - Used to receive handles over IPC pipes. - - First - call :c:func:`uv_pipe_pending_count`, if it's > 0 then initialize - a handle of the given `type`, returned by :c:func:`uv_pipe_pending_type` - and call ``uv_accept(pipe, handle)``. - -.. seealso:: The :c:type:`uv_stream_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/poll.rst b/outside/libuv-v1.7.5/docs/src/poll.rst deleted file mode 100644 index 6dc41839ac..0000000000 --- a/outside/libuv-v1.7.5/docs/src/poll.rst +++ /dev/null @@ -1,103 +0,0 @@ - -.. _poll: - -:c:type:`uv_poll_t` --- Poll handle -=================================== - -Poll handles are used to watch file descriptors for readability and -writability, similar to the purpose of :man:`poll(2)`. - -The purpose of poll handles is to enable integrating external libraries that -rely on the event loop to signal it about the socket status changes, like -c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended; -:c:type:`uv_tcp_t`, :c:type:`uv_udp_t`, etc. provide an implementation that is faster and -more scalable than what can be achieved with :c:type:`uv_poll_t`, especially on -Windows. - -It is possible that poll handles occasionally signal that a file descriptor is -readable or writable even when it isn't. The user should therefore always -be prepared to handle EAGAIN or equivalent when it attempts to read from or -write to the fd. - -It is not okay to have multiple active poll handles for the same socket, this -can cause libuv to busyloop or otherwise malfunction. - -The user should not close a file descriptor while it is being polled by an -active poll handle. This can cause the handle to report an error, -but it might also start polling another socket. However the fd can be safely -closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`. - -.. note:: - On windows only sockets can be polled with poll handles. On Unix any file - descriptor that would be accepted by :man:`poll(2)` can be used. - - -Data types ----------- - -.. c:type:: uv_poll_t - - Poll handle type. - -.. c:type:: void (*uv_poll_cb)(uv_poll_t* handle, int status, int events) - - Type definition for callback passed to :c:func:`uv_poll_start`. - -.. c:type:: uv_poll_event - - Poll event types - - :: - - enum uv_poll_event { - UV_READABLE = 1, - UV_WRITABLE = 2 - }; - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) - - Initialize the handle using a file descriptor. - - .. versionchanged:: 1.2.2 the file descriptor is set to non-blocking mode. - -.. c:function:: int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket) - - Initialize the handle using a socket descriptor. On Unix this is identical - to :c:func:`uv_poll_init`. On windows it takes a SOCKET handle. - - .. versionchanged:: 1.2.2 the socket is set to non-blocking mode. - -.. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) - - Starts polling the file descriptor. `events` is a bitmask consisting made up - of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback - will be called with `status` set to 0, and the detected events set on the - `events` field. - - If an error happens while polling, `status` will be < 0 and corresponds - with one of the UV_E* error codes (see :ref:`errors`). The user should - not close the socket while the handle is active. If the user does that - anyway, the callback *may* be called reporting an error status, but this - is **not** guaranteed. - - .. note:: - Calling :c:func:`uv_poll_start` on a handle that is already active is fine. Doing so - will update the events mask that is being watched for. - -.. c:function:: int uv_poll_stop(uv_poll_t* poll) - - Stop polling the file descriptor, the callback will no longer be called. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/prepare.rst b/outside/libuv-v1.7.5/docs/src/prepare.rst deleted file mode 100644 index aca5815580..0000000000 --- a/outside/libuv-v1.7.5/docs/src/prepare.rst +++ /dev/null @@ -1,46 +0,0 @@ - -.. _prepare: - -:c:type:`uv_prepare_t` --- Prepare handle -========================================= - -Prepare handles will run the given callback once per loop iteration, right -before polling for i/o. - - -Data types ----------- - -.. c:type:: uv_prepare_t - - Prepare handle type. - -.. c:type:: void (*uv_prepare_cb)(uv_prepare_t* handle) - - Type definition for callback passed to :c:func:`uv_prepare_start`. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) - - Initialize the handle. - -.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) - - Start the handle with the given callback. - -.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare) - - Stop the handle, the callback will no longer be called. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/process.rst b/outside/libuv-v1.7.5/docs/src/process.rst deleted file mode 100644 index b0380ddfb7..0000000000 --- a/outside/libuv-v1.7.5/docs/src/process.rst +++ /dev/null @@ -1,225 +0,0 @@ - -.. _process: - -:c:type:`uv_process_t` --- Process handle -========================================= - -Process handles will spawn a new process and allow the user to control it and -establish communication channels with it using streams. - - -Data types ----------- - -.. c:type:: uv_process_t - - Process handle type. - -.. c:type:: uv_process_options_t - - Options for spawning the process (passed to :c:func:`uv_spawn`. - - :: - - typedef struct uv_process_options_s { - uv_exit_cb exit_cb; - const char* file; - char** args; - char** env; - const char* cwd; - unsigned int flags; - int stdio_count; - uv_stdio_container_t* stdio; - uv_uid_t uid; - uv_gid_t gid; - } uv_process_options_t; - -.. c:type:: void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal) - - Type definition for callback passed in :c:type:`uv_process_options_t` which - will indicate the exit status and the signal that caused the process to - terminate, if any. - -.. c:type:: uv_process_flags - - Flags to be set on the flags field of :c:type:`uv_process_options_t`. - - :: - - enum uv_process_flags { - /* - * Set the child process' user id. - */ - UV_PROCESS_SETUID = (1 << 0), - /* - * Set the child process' group id. - */ - UV_PROCESS_SETGID = (1 << 1), - /* - * Do not wrap any arguments in quotes, or perform any other escaping, when - * converting the argument list into a command line string. This option is - * only meaningful on Windows systems. On Unix it is silently ignored. - */ - UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), - /* - * Spawn the child process in a detached state - this will make it a process - * group leader, and will effectively enable the child to keep running after - * the parent exits. Note that the child process will still keep the - * parent's event loop alive unless the parent process calls uv_unref() on - * the child's process handle. - */ - UV_PROCESS_DETACHED = (1 << 3), - /* - * Hide the subprocess console window that would normally be created. This - * option is only meaningful on Windows systems. On Unix it is silently - * ignored. - */ - UV_PROCESS_WINDOWS_HIDE = (1 << 4) - }; - -.. c:type:: uv_stdio_container_t - - Container for each stdio handle or fd passed to a child process. - - :: - - typedef struct uv_stdio_container_s { - uv_stdio_flags flags; - union { - uv_stream_t* stream; - int fd; - } data; - } uv_stdio_container_t; - -.. c:type:: uv_stdio_flags - - Flags specifying how a stdio should be transmitted to the child process. - - :: - - typedef enum { - UV_IGNORE = 0x00, - UV_CREATE_PIPE = 0x01, - UV_INHERIT_FD = 0x02, - UV_INHERIT_STREAM = 0x04, - /* - * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE - * determine the direction of flow, from the child process' perspective. Both - * flags may be specified to create a duplex data stream. - */ - UV_READABLE_PIPE = 0x10, - UV_WRITABLE_PIPE = 0x20 - } uv_stdio_flags; - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: uv_process_t.pid - - The PID of the spawned process. It's set after calling :c:func:`uv_spawn`. - -.. note:: - The :c:type:`uv_handle_t` members also apply. - -.. c:member:: uv_process_options_t.exit_cb - - Callback called after the process exits. - -.. c:member:: uv_process_options_t.file - - Path pointing to the program to be executed. - -.. c:member:: uv_process_options_t.args - - Command line arguments. args[0] should be the path to the program. On - Windows this uses `CreateProcess` which concatenates the arguments into a - string this can cause some strange errors. See the - ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:type:`uv_process_flags`. - -.. c:member:: uv_process_options_t.env - - Environment for the new process. If NULL the parents environment is used. - -.. c:member:: uv_process_options_t.cwd - - Current working directory for the subprocess. - -.. c:member:: uv_process_options_t.flags - - Various flags that control how :c:func:`uv_spawn` behaves. See - :c:type:`uv_process_flags`. - -.. c:member:: uv_process_options_t.stdio_count -.. c:member:: uv_process_options_t.stdio - - The `stdio` field points to an array of :c:type:`uv_stdio_container_t` - structs that describe the file descriptors that will be made available to - the child process. The convention is that stdio[0] points to stdin, - fd 1 is used for stdout, and fd 2 is stderr. - - .. note:: - On Windows file descriptors greater than 2 are available to the child process only if - the child processes uses the MSVCRT runtime. - -.. c:member:: uv_process_options_t.uid -.. c:member:: uv_process_options_t.gid - - Libuv can change the child process' user/group id. This happens only when - the appropriate bits are set in the flags fields. - - .. note:: - This is not supported on Windows, :c:func:`uv_spawn` will fail and set the error - to ``UV_ENOTSUP``. - -.. c:member:: uv_stdio_container_t.flags - - Flags specifying how the stdio container should be passed to the child. See - :c:type:`uv_stdio_flags`. - -.. c:member:: uv_stdio_container_t.data - - Union containing either the stream or fd to be passed on to the child - process. - - -API ---- - -.. c:function:: void uv_disable_stdio_inheritance(void) - - Disables inheritance for file descriptors / handles that this process - inherited from its parent. The effect is that child processes spawned by - this process don't accidentally inherit these handles. - - It is recommended to call this function as early in your program as possible, - before the inherited file descriptors can be closed or duplicated. - - .. note:: - This function works on a best-effort basis: there is no guarantee that libuv can discover - all file descriptors that were inherited. In general it does a better job on Windows than - it does on Unix. - -.. c:function:: int uv_spawn(uv_loop_t* loop, uv_process_t* handle, const uv_process_options_t* options) - - Initializes the process handle and starts the process. If the process is - successfully spawned, this function will return 0. Otherwise, the - negative error code corresponding to the reason it couldn't spawn is - returned. - - Possible reasons for failing to spawn would include (but not be limited to) - the file to execute not existing, not having permissions to use the setuid or - setgid specified, or not having enough memory to allocate for the new - process. - -.. c:function:: int uv_process_kill(uv_process_t* handle, int signum) - - Sends the specified signal to the given process handle. Check the documentation - on :c:ref:`signal` for signal support, specially on Windows. - -.. c:function:: int uv_kill(int pid, int signum) - - Sends the specified signal to the given PID. Check the documentation - on :c:ref:`signal` for signal support, specially on Windows. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/request.rst b/outside/libuv-v1.7.5/docs/src/request.rst deleted file mode 100644 index 660b80ae95..0000000000 --- a/outside/libuv-v1.7.5/docs/src/request.rst +++ /dev/null @@ -1,82 +0,0 @@ - -.. _request: - -:c:type:`uv_req_t` --- Base request -=================================== - -`uv_req_t` is the base type for all libuv request types. - -Structures are aligned so that any libuv request can be cast to `uv_req_t`. -All API functions defined here work with any request type. - - -Data types ----------- - -.. c:type:: uv_req_t - - The base libuv request structure. - -.. c:type:: uv_any_req - - Union of all request types. - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: void* uv_req_t.data - - Space for user-defined arbitrary data. libuv does not use this field. - -.. c:member:: uv_req_type uv_req_t.type - - Indicated the type of request. Readonly. - - :: - - typedef enum { - UV_UNKNOWN_REQ = 0, - UV_REQ, - UV_CONNECT, - UV_WRITE, - UV_SHUTDOWN, - UV_UDP_SEND, - UV_FS, - UV_WORK, - UV_GETADDRINFO, - UV_GETNAMEINFO, - UV_REQ_TYPE_PRIVATE, - UV_REQ_TYPE_MAX, - } uv_req_type; - - -API ---- - -.. c:function:: int uv_cancel(uv_req_t* req) - - Cancel a pending request. Fails if the request is executing or has finished - executing. - - Returns 0 on success, or an error code < 0 on failure. - - Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`, - :c:type:`uv_getnameinfo_t` and :c:type:`uv_work_t` requests is - currently supported. - - Cancelled requests have their callbacks invoked some time in the future. - It's **not** safe to free the memory associated with the request until the - callback is called. - - Here is how cancellation is reported to the callback: - - * A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`. - - * A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t` or c:type:`uv_getnameinfo_t` - request has its callback invoked with status == `UV_ECANCELED`. - -.. c:function:: size_t uv_req_size(uv_req_type type) - - Returns the size of the given request type. Useful for FFI binding writers - who don't want to know the structure layout. diff --git a/outside/libuv-v1.7.5/docs/src/signal.rst b/outside/libuv-v1.7.5/docs/src/signal.rst deleted file mode 100644 index dc1223b90a..0000000000 --- a/outside/libuv-v1.7.5/docs/src/signal.rst +++ /dev/null @@ -1,77 +0,0 @@ - -.. _signal: - -:c:type:`uv_signal_t` --- Signal handle -======================================= - -Signal handles implement Unix style signal handling on a per-event loop bases. - -Reception of some signals is emulated on Windows: - -* SIGINT is normally delivered when the user presses CTRL+C. However, like - on Unix, it is not generated when terminal raw mode is enabled. - -* SIGBREAK is delivered when the user pressed CTRL + BREAK. - -* SIGHUP is generated when the user closes the console window. On SIGHUP the - program is given approximately 10 seconds to perform cleanup. After that - Windows will unconditionally terminate it. - -* SIGWINCH is raised whenever libuv detects that the console has been - resized. SIGWINCH is emulated by libuv when the program uses a :c:type:`uv_tty_t` - handle to write to the console. SIGWINCH may not always be delivered in a - timely manner; libuv will only detect size changes when the cursor is - being moved. When a readable :c:type:`uv_tty_t` handle is used in raw mode, - resizing the console buffer will also trigger a SIGWINCH signal. - -Watchers for other signals can be successfully created, but these signals -are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`, -`SIGTERM` and `SIGKILL.` - -Calls to raise() or abort() to programmatically raise a signal are -not detected by libuv; these will not trigger a signal watcher. - -.. note:: - On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to - manage threads. Installing watchers for those signals will lead to unpredictable behavior - and is strongly discouraged. Future versions of libuv may simply reject them. - - -Data types ----------- - -.. c:type:: uv_signal_t - - Signal handle type. - -.. c:type:: void (*uv_signal_cb)(uv_signal_t* handle, int signum) - - Type definition for callback passed to :c:func:`uv_signal_start`. - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: int uv_signal_t.signum - - Signal being monitored by this handle. Readonly. - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_signal_init(uv_loop_t* loop, uv_signal_t* signal) - - Initialize the handle. - -.. c:function:: int uv_signal_start(uv_signal_t* signal, uv_signal_cb cb, int signum) - - Start the handle with the given callback, watching for the given signal. - -.. c:function:: int uv_signal_stop(uv_signal_t* signal) - - Stop the handle, the callback will no longer be called. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/sphinx-plugins/manpage.py b/outside/libuv-v1.7.5/docs/src/sphinx-plugins/manpage.py deleted file mode 100644 index 1d1dc379f4..0000000000 --- a/outside/libuv-v1.7.5/docs/src/sphinx-plugins/manpage.py +++ /dev/null @@ -1,46 +0,0 @@ -# encoding: utf-8 - -# -# Copyright (c) 2013 Dariusz Dwornikowski. All rights reserved. -# -# Adapted from https://github.com/tdi/sphinxcontrib-manpage -# License: Apache 2 -# - - -import re - -from docutils import nodes, utils -from docutils.parsers.rst.roles import set_classes -from string import Template - - -def make_link_node(rawtext, app, name, manpage_num, options): - ref = app.config.man_url_regex - if not ref: - ref = "http://linux.die.net/man/%s/%s" % (manpage_num, name) - else: - s = Template(ref) - ref = s.substitute(num=manpage_num, topic=name) - set_classes(options) - node = nodes.reference(rawtext, "%s(%s)" % (name, manpage_num), refuri=ref, **options) - return node - - -def man_role(name, rawtext, text, lineno, inliner, options={}, content=[]): - app = inliner.document.settings.env.app - p = re.compile("([a-zA-Z0-9_\.-_]+)\((\d)\)") - m = p.match(text) - - manpage_num = m.group(2) - name = m.group(1) - node = make_link_node(rawtext, app, name, manpage_num, options) - return [node], [] - - -def setup(app): - app.info('Initializing manpage plugin') - app.add_role('man', man_role) - app.add_config_value('man_url_regex', None, 'env') - return - diff --git a/outside/libuv-v1.7.5/docs/src/static/architecture.png b/outside/libuv-v1.7.5/docs/src/static/architecture.png deleted file mode 100644 index 81e8749f2495741d4b4c2c5dd8a6bca8803d8818..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206767 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

|<0@v3w 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 aM1obxbA2B^pWMfP?%y@PQ+oUP>;DChUmDi{ diff --git a/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Data/st0-311.jpg b/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Data/st0-311.jpg deleted file mode 100644 index 439f58109369c37760ce8f9b4710711c17993d8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19328 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 diff --git a/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Data/st1-475.jpg b/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Data/st1-475.jpg deleted file mode 100644 index ffb21ff22457dac44441fb7e83272c72fbc4d59e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12655 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 N?>yyS+aZMU{|8A0VY&bS diff --git a/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Index.zip b/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Index.zip deleted file mode 100644 index 17aedace14faf8f2990df3232565328901209d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71160 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 - - - - Template: White (2014-02-28 09:41) - M6.2.2-1878-1 - - diff --git a/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/DocumentIdentifier b/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/DocumentIdentifier deleted file mode 100644 index ddb18f01f9..0000000000 --- a/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/DocumentIdentifier +++ /dev/null @@ -1 +0,0 @@ -F69E9CD9-EEF1-4223-9DA4-A1EA7FE112BA \ No newline at end of file diff --git a/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/Properties.plist b/outside/libuv-v1.7.5/docs/src/static/diagrams.key/Metadata/Properties.plist deleted file mode 100644 index 74bc69317de4fc4ae87da8c71d1615385d70d1f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmYc)$jK}&F)+B!$i&RT%Er#Y$;HjX%NJ3UT9#RynV%Pylb@WJlNytfpIn-onpYAU z>gf_)mRbao1G6)WeM@snG6NFRQ{x2$(=u~X-SUfa6HCG%Y9fm>5{ptnD&qyz4Xmup z3`|U&4UCL+jhsv!bxoX{O?55Y%*}M23@scDT}@4m%q)yTQ}g2eeBuRE+{`RpEuCE~ zbzNQE40TP6fZ8lw98GkADjm(;Tn!D4oE(A5h%u8h)KJez&wxln88{fk859`Q8B7=) l75HPbcg8&-~3o|P_8#_BY8yg!t2RA1> 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

2KUY7yz-7_`p(lc`HgEPC5(QDJ#Lr#t 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 Y>c{6t4Sw{%j~@8Z1FJo-=6lco0p?d?5&!@I diff --git a/outside/libuv-v1.7.5/docs/src/static/favicon.ico b/outside/libuv-v1.7.5/docs/src/static/favicon.ico deleted file mode 100644 index 2c40694cd282ff3d0db2c495c23f3beca40c17fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmeI3J!oE47{^bE(6L>dlR?3;f?AMDoTP|gC(+GON^N!X18j$O66~NjsaQd=(xSMC zL)z#dI2x#nOSZwR!m3x7+NM_xVsKV)SFb<|EpaeeASlj(+q}%U2&yoPD*;Lm&Ey_UhK~ z_4og5Xr+DRP_sk!#l?%;Y8ZWV*^pfGuZHnl8XJu9Yiq#y(Ek|pp24Oo_K^744vEX% z&VG-&+OikQSk~Z?A1-gL|EIsK{O26#L%+nJ84qMmd3jchtG#hWC&Nw%vpc1cK(nJjju2B;@Lx= zdb$)`edHiu4|NQ8|RdXF;=Y~_aQds zM-KRv4+sy(@ZfC92gKI6;H2E;6K(qX-UX~%j0>mIj{8FYL$I_j$2@PzKi(Uqj$`zO z#4L5N(?>*Nx>uvT*8k+fg{fl8rQ8qrD`mB~$cC=BvHB2S^BB zo_6@a7e4Xb##oy-YQyg-4(0Y@Zd<>ncpwkI?I z#(nm2&Rk}dLs#8nOwJ%bGaw_^Z@yn{`_@$KJMZd%`rc^{L%16&qPZZ8yy&yXqHe8E zp4v^DL$+J0`R4$#?Y4)|~%PII2w6MbC!=E%c&^QfI|YuvXc=!{*1Y4?qsL2`h* z$o-C7&RrON*x$_I{LppiJ7@Zwgz&bZi%;^2d%G)#^1eckdtnIwS=8R#;7=cfx8p9} zQLZlb%I^mM$iuvbtO1gd?cjn{}^(OGIzMtu55|%vU*fmf#WDj|cBmZ3E&ULE z^DEBxoq?V3_c`Snao@w)J2O5Htv$MtTiLJ8Ps<-ZzF*?kddj;CIdjfw6M5D+I$xWc zhQGY!fnWQebuQ(MwWVLXOObWGTVP`@;#mIJ;fE&YSX18%)QRXmF?Jtf*EjFnSpH>g zJddJ&XMw)QMPI~mOn)r@Xj{7voZk&B*MxEA-}y5>b8-Dk``zH!=QGwGJ^1uJznGg9 z|1$TION}?{8}*_O`a|A9*KPP*J_HMHIpwG&wQL$C-RQE%*QsQ_U2XFL*_t?GB)|p zoTFdrz*D)r%G#KV^AR(r&U;7R5&a!b^kMysGZx8@XQ0nP@+p19c=pHC-WnK_JFI=lYsh%FxQ85$b^U(; zyvsXi2xoM5o45Q$;<>lsOiqr6az+ok?5p#43dY+lgu~eV!XCTR_3p~Qe5cL4mf+UW zmb(1x$@eO7H!864g(1E`#3$lv{^Anj&Bm9F=&$E59)YX*%ShmI{=yP?CV$TeB#Hb_ z`=8LKQ_5!f8%mqFnE#H7@%+D--L>Nu^WRyOxXOI~8?33Y;%}S(z@z1r`L%pA%3o~Y ik^kAsb9poGOsuT~U&vzKIyJc*jGI?B>sZ!zWBd=1T7Db= diff --git a/outside/libuv-v1.7.5/docs/src/static/logo.png b/outside/libuv-v1.7.5/docs/src/static/logo.png deleted file mode 100644 index eaf1eee577b6774c345d5e21be51130a23b16627..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33545 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 W3*P8um*8Y!7&$3rXpMwP!2bZAf*ghb diff --git a/outside/libuv-v1.7.5/docs/src/static/loop_iteration.png b/outside/libuv-v1.7.5/docs/src/static/loop_iteration.png deleted file mode 100644 index e769cf338b4456ea688b0abf888b646a4253e0eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80528 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 diff --git a/outside/libuv-v1.7.5/img/logos.svg b/outside/libuv-v1.7.5/img/logos.svg deleted file mode 100644 index d6185f8b19..0000000000 --- a/outside/libuv-v1.7.5/img/logos.svg +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/outside/libuv-v1.7.5/include/android-ifaddrs.h b/outside/libuv-v1.7.5/include/android-ifaddrs.h deleted file mode 100644 index 9cd19fec12..0000000000 --- a/outside/libuv-v1.7.5/include/android-ifaddrs.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1995, 1999 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp - */ - -#ifndef _IFADDRS_H_ -#define _IFADDRS_H_ - -struct ifaddrs { - struct ifaddrs *ifa_next; - char *ifa_name; - unsigned int ifa_flags; - struct sockaddr *ifa_addr; - struct sockaddr *ifa_netmask; - struct sockaddr *ifa_dstaddr; - void *ifa_data; -}; - -/* - * This may have been defined in . Note that if is - * to be included it must be included before this header file. - */ -#ifndef ifa_broadaddr -#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ -#endif - -#include - -__BEGIN_DECLS -extern int getifaddrs(struct ifaddrs **ifap); -extern void freeifaddrs(struct ifaddrs *ifa); -__END_DECLS - -#endif diff --git a/outside/libuv-v1.7.5/include/pthread-fixes.h b/outside/libuv-v1.7.5/include/pthread-fixes.h deleted file mode 100644 index 88c6b66987..0000000000 --- a/outside/libuv-v1.7.5/include/pthread-fixes.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2013, Sony Mobile Communications AB - * Copyright (c) 2012, Google Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H - -#include - - -/*Android doesn't provide pthread_barrier_t for now.*/ -#ifndef PTHREAD_BARRIER_SERIAL_THREAD - -/* Anything except 0 will do here.*/ -#define PTHREAD_BARRIER_SERIAL_THREAD 0x12345 - -typedef struct { - pthread_mutex_t mutex; - pthread_cond_t cond; - unsigned count; -} pthread_barrier_t; - -int pthread_barrier_init(pthread_barrier_t* barrier, - const void* barrier_attr, - unsigned count); - -int pthread_barrier_wait(pthread_barrier_t* barrier); -int pthread_barrier_destroy(pthread_barrier_t *barrier); -#endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */ - -int pthread_yield(void); - -/* Workaround pthread_sigmask() returning EINVAL on versions < 4.1 by - * replacing all calls to pthread_sigmask with sigprocmask. See: - * https://android.googlesource.com/platform/bionic/+/9bf330b5 - * https://code.google.com/p/android/issues/detail?id=15337 - */ -int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset); - -#ifdef pthread_sigmask -#undef pthread_sigmask -#endif -#define pthread_sigmask(how, set, oldset) uv__pthread_sigmask(how, set, oldset) - -#endif /* GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H */ diff --git a/outside/libuv-v1.7.5/include/stdint-msvc2008.h b/outside/libuv-v1.7.5/include/stdint-msvc2008.h deleted file mode 100644 index d02608a597..0000000000 --- a/outside/libuv-v1.7.5/include/stdint-msvc2008.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/outside/libuv-v1.7.5/include/tree.h b/outside/libuv-v1.7.5/include/tree.h deleted file mode 100644 index f936416e3d..0000000000 --- a/outside/libuv-v1.7.5/include/tree.h +++ /dev/null @@ -1,768 +0,0 @@ -/*- - * Copyright 2002 Niels Provos - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef UV_TREE_H_ -#define UV_TREE_H_ - -#ifndef UV__UNUSED -# if __GNUC__ -# define UV__UNUSED __attribute__((unused)) -# else -# define UV__UNUSED -# endif -#endif - -/* - * This file defines data structures for different types of trees: - * splay trees and red-black trees. - * - * A splay tree is a self-organizing data structure. Every operation - * on the tree causes a splay to happen. The splay moves the requested - * node to the root of the tree and partly rebalances it. - * - * This has the benefit that request locality causes faster lookups as - * the requested nodes move to the top of the tree. On the other hand, - * every lookup causes memory writes. - * - * The Balance Theorem bounds the total access time for m operations - * and n inserts on an initially empty tree as O((m + n)lg n). The - * amortized cost for a sequence of m accesses to a splay tree is O(lg n); - * - * A red-black tree is a binary search tree with the node color as an - * extra attribute. It fulfills a set of conditions: - * - every search path from the root to a leaf consists of the - * same number of black nodes, - * - each red node (except for the root) has a black parent, - * - each leaf node is black. - * - * Every operation on a red-black tree is bounded as O(lg n). - * The maximum height of a red-black tree is 2lg (n+1). - */ - -#define SPLAY_HEAD(name, type) \ -struct name { \ - struct type *sph_root; /* root of the tree */ \ -} - -#define SPLAY_INITIALIZER(root) \ - { NULL } - -#define SPLAY_INIT(root) do { \ - (root)->sph_root = NULL; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ENTRY(type) \ -struct { \ - struct type *spe_left; /* left element */ \ - struct type *spe_right; /* right element */ \ -} - -#define SPLAY_LEFT(elm, field) (elm)->field.spe_left -#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right -#define SPLAY_ROOT(head) (head)->sph_root -#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) - -/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ -#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_LINKLEFT(head, tmp, field) do { \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_LINKRIGHT(head, tmp, field) do { \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ - SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ -} while (/*CONSTCOND*/ 0) - -/* Generates prototypes and inline functions */ - -#define SPLAY_PROTOTYPE(name, type, field, cmp) \ -void name##_SPLAY(struct name *, struct type *); \ -void name##_SPLAY_MINMAX(struct name *, int); \ -struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ -struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ - \ -/* Finds the node with the same key as elm */ \ -static __inline struct type * \ -name##_SPLAY_FIND(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) \ - return(NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) \ - return (head->sph_root); \ - return (NULL); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_NEXT(struct name *head, struct type *elm) \ -{ \ - name##_SPLAY(head, elm); \ - if (SPLAY_RIGHT(elm, field) != NULL) { \ - elm = SPLAY_RIGHT(elm, field); \ - while (SPLAY_LEFT(elm, field) != NULL) { \ - elm = SPLAY_LEFT(elm, field); \ - } \ - } else \ - elm = NULL; \ - return (elm); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_MIN_MAX(struct name *head, int val) \ -{ \ - name##_SPLAY_MINMAX(head, val); \ - return (SPLAY_ROOT(head)); \ -} - -/* Main splay operation. - * Moves node close to the key of elm to top - */ -#define SPLAY_GENERATE(name, type, field, cmp) \ -struct type * \ -name##_SPLAY_INSERT(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) { \ - SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ - } else { \ - int __comp; \ - name##_SPLAY(head, elm); \ - __comp = (cmp)(elm, (head)->sph_root); \ - if(__comp < 0) { \ - SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_RIGHT(elm, field) = (head)->sph_root; \ - SPLAY_LEFT((head)->sph_root, field) = NULL; \ - } else if (__comp > 0) { \ - SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \ - SPLAY_LEFT(elm, field) = (head)->sph_root; \ - SPLAY_RIGHT((head)->sph_root, field) = NULL; \ - } else \ - return ((head)->sph_root); \ - } \ - (head)->sph_root = (elm); \ - return (NULL); \ -} \ - \ -struct type * \ -name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *__tmp; \ - if (SPLAY_EMPTY(head)) \ - return (NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) { \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ - } else { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ - name##_SPLAY(head, elm); \ - SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ - } \ - return (elm); \ - } \ - return (NULL); \ -} \ - \ -void \ -name##_SPLAY(struct name *head, struct type *elm) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ - int __comp; \ - \ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ - __left = __right = &__node; \ - \ - while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) > 0){ \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} \ - \ -/* Splay with either the minimum or the maximum element \ - * Used to find minimum or maximum element in tree. \ - */ \ -void name##_SPLAY_MINMAX(struct name *head, int __comp) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ - \ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ - __left = __right = &__node; \ - \ - while (1) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp > 0) { \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} - -#define SPLAY_NEGINF -1 -#define SPLAY_INF 1 - -#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) -#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) -#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) -#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) -#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) -#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) - -#define SPLAY_FOREACH(x, name, head) \ - for ((x) = SPLAY_MIN(name, head); \ - (x) != NULL; \ - (x) = SPLAY_NEXT(name, head, x)) - -/* Macros that define a red-black tree */ -#define RB_HEAD(name, type) \ -struct name { \ - struct type *rbh_root; /* root of the tree */ \ -} - -#define RB_INITIALIZER(root) \ - { NULL } - -#define RB_INIT(root) do { \ - (root)->rbh_root = NULL; \ -} while (/*CONSTCOND*/ 0) - -#define RB_BLACK 0 -#define RB_RED 1 -#define RB_ENTRY(type) \ -struct { \ - struct type *rbe_left; /* left element */ \ - struct type *rbe_right; /* right element */ \ - struct type *rbe_parent; /* parent element */ \ - int rbe_color; /* node color */ \ -} - -#define RB_LEFT(elm, field) (elm)->field.rbe_left -#define RB_RIGHT(elm, field) (elm)->field.rbe_right -#define RB_PARENT(elm, field) (elm)->field.rbe_parent -#define RB_COLOR(elm, field) (elm)->field.rbe_color -#define RB_ROOT(head) (head)->rbh_root -#define RB_EMPTY(head) (RB_ROOT(head) == NULL) - -#define RB_SET(elm, parent, field) do { \ - RB_PARENT(elm, field) = parent; \ - RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ - RB_COLOR(elm, field) = RB_RED; \ -} while (/*CONSTCOND*/ 0) - -#define RB_SET_BLACKRED(black, red, field) do { \ - RB_COLOR(black, field) = RB_BLACK; \ - RB_COLOR(red, field) = RB_RED; \ -} while (/*CONSTCOND*/ 0) - -#ifndef RB_AUGMENT -#define RB_AUGMENT(x) do {} while (0) -#endif - -#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ - (tmp) = RB_RIGHT(elm, field); \ - if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ - RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_LEFT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp, field))) \ - RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (/*CONSTCOND*/ 0) - -#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ - (tmp) = RB_LEFT(elm, field); \ - if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ - RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_RIGHT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp, field))) \ - RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (/*CONSTCOND*/ 0) - -/* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) -#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static) -#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ -attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ -attr struct type *name##_RB_INSERT(struct name *, struct type *); \ -attr struct type *name##_RB_FIND(struct name *, struct type *); \ -attr struct type *name##_RB_NFIND(struct name *, struct type *); \ -attr struct type *name##_RB_NEXT(struct type *); \ -attr struct type *name##_RB_PREV(struct type *); \ -attr struct type *name##_RB_MINMAX(struct name *, int); \ - \ - -/* Main rb operation. - * Moves node close to the key of elm to top - */ -#define RB_GENERATE(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp,) -#define RB_GENERATE_STATIC(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static) -#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ -attr void \ -name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ -{ \ - struct type *parent, *gparent, *tmp; \ - while ((parent = RB_PARENT(elm, field)) != NULL && \ - RB_COLOR(parent, field) == RB_RED) { \ - gparent = RB_PARENT(parent, field); \ - if (parent == RB_LEFT(gparent, field)) { \ - tmp = RB_RIGHT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field); \ - elm = gparent; \ - continue; \ - } \ - if (RB_RIGHT(parent, field) == elm) { \ - RB_ROTATE_LEFT(head, parent, tmp, field); \ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_RIGHT(head, gparent, tmp, field); \ - } else { \ - tmp = RB_LEFT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field); \ - elm = gparent; \ - continue; \ - } \ - if (RB_LEFT(parent, field) == elm) { \ - RB_ROTATE_RIGHT(head, parent, tmp, field); \ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_LEFT(head, gparent, tmp, field); \ - } \ - } \ - RB_COLOR(head->rbh_root, field) = RB_BLACK; \ -} \ - \ -attr void \ -name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \ - struct type *elm) \ -{ \ - struct type *tmp; \ - while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ - elm != RB_ROOT(head)) { \ - if (RB_LEFT(parent, field) == elm) { \ - tmp = RB_RIGHT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_LEFT(head, parent, tmp, field); \ - tmp = RB_RIGHT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \ - struct type *oleft; \ - if ((oleft = RB_LEFT(tmp, field)) \ - != NULL) \ - RB_COLOR(oleft, field) = RB_BLACK; \ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_RIGHT(head, tmp, oleft, field); \ - tmp = RB_RIGHT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_RIGHT(tmp, field)) \ - RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \ - RB_ROTATE_LEFT(head, parent, tmp, field); \ - elm = RB_ROOT(head); \ - break; \ - } \ - } else { \ - tmp = RB_LEFT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_RIGHT(head, parent, tmp, field); \ - tmp = RB_LEFT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \ - struct type *oright; \ - if ((oright = RB_RIGHT(tmp, field)) \ - != NULL) \ - RB_COLOR(oright, field) = RB_BLACK; \ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_LEFT(head, tmp, oright, field); \ - tmp = RB_LEFT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_LEFT(tmp, field)) \ - RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \ - RB_ROTATE_RIGHT(head, parent, tmp, field); \ - elm = RB_ROOT(head); \ - break; \ - } \ - } \ - } \ - if (elm) \ - RB_COLOR(elm, field) = RB_BLACK; \ -} \ - \ -attr struct type * \ -name##_RB_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *child, *parent, *old = elm; \ - int color; \ - if (RB_LEFT(elm, field) == NULL) \ - child = RB_RIGHT(elm, field); \ - else if (RB_RIGHT(elm, field) == NULL) \ - child = RB_LEFT(elm, field); \ - else { \ - struct type *left; \ - elm = RB_RIGHT(elm, field); \ - while ((left = RB_LEFT(elm, field)) != NULL) \ - elm = left; \ - child = RB_RIGHT(elm, field); \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ - if (RB_PARENT(elm, field) == old) \ - parent = elm; \ - (elm)->field = (old)->field; \ - if (RB_PARENT(old, field)) { \ - if (RB_LEFT(RB_PARENT(old, field), field) == old) \ - RB_LEFT(RB_PARENT(old, field), field) = elm; \ - else \ - RB_RIGHT(RB_PARENT(old, field), field) = elm; \ - RB_AUGMENT(RB_PARENT(old, field)); \ - } else \ - RB_ROOT(head) = elm; \ - RB_PARENT(RB_LEFT(old, field), field) = elm; \ - if (RB_RIGHT(old, field)) \ - RB_PARENT(RB_RIGHT(old, field), field) = elm; \ - if (parent) { \ - left = parent; \ - do { \ - RB_AUGMENT(left); \ - } while ((left = RB_PARENT(left, field)) != NULL); \ - } \ - goto color; \ - } \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ -color: \ - if (color == RB_BLACK) \ - name##_RB_REMOVE_COLOR(head, parent, child); \ - return (old); \ -} \ - \ -/* Inserts a node into the RB tree */ \ -attr struct type * \ -name##_RB_INSERT(struct name *head, struct type *elm) \ -{ \ - struct type *tmp; \ - struct type *parent = NULL; \ - int comp = 0; \ - tmp = RB_ROOT(head); \ - while (tmp) { \ - parent = tmp; \ - comp = (cmp)(elm, parent); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - RB_SET(elm, parent, field); \ - if (parent != NULL) { \ - if (comp < 0) \ - RB_LEFT(parent, field) = elm; \ - else \ - RB_RIGHT(parent, field) = elm; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = elm; \ - name##_RB_INSERT_COLOR(head, elm); \ - return (NULL); \ -} \ - \ -/* Finds the node with the same key as elm */ \ -attr struct type * \ -name##_RB_FIND(struct name *head, struct type *elm) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (NULL); \ -} \ - \ -/* Finds the first node greater than or equal to the search key */ \ -attr struct type * \ -name##_RB_NFIND(struct name *head, struct type *elm) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - struct type *res = NULL; \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) { \ - res = tmp; \ - tmp = RB_LEFT(tmp, field); \ - } \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (res); \ -} \ - \ -/* ARGSUSED */ \ -attr struct type * \ -name##_RB_NEXT(struct type *elm) \ -{ \ - if (RB_RIGHT(elm, field)) { \ - elm = RB_RIGHT(elm, field); \ - while (RB_LEFT(elm, field)) \ - elm = RB_LEFT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ -} \ - \ -/* ARGSUSED */ \ -attr struct type * \ -name##_RB_PREV(struct type *elm) \ -{ \ - if (RB_LEFT(elm, field)) { \ - elm = RB_LEFT(elm, field); \ - while (RB_RIGHT(elm, field)) \ - elm = RB_RIGHT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ -} \ - \ -attr struct type * \ -name##_RB_MINMAX(struct name *head, int val) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - struct type *parent = NULL; \ - while (tmp) { \ - parent = tmp; \ - if (val < 0) \ - tmp = RB_LEFT(tmp, field); \ - else \ - tmp = RB_RIGHT(tmp, field); \ - } \ - return (parent); \ -} - -#define RB_NEGINF -1 -#define RB_INF 1 - -#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) -#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) -#define RB_FIND(name, x, y) name##_RB_FIND(x, y) -#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(y) -#define RB_PREV(name, x, y) name##_RB_PREV(y) -#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) -#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) - -#define RB_FOREACH(x, name, head) \ - for ((x) = RB_MIN(name, head); \ - (x) != NULL; \ - (x) = name##_RB_NEXT(x)) - -#define RB_FOREACH_FROM(x, name, y) \ - for ((x) = (y); \ - ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ - (x) = (y)) - -#define RB_FOREACH_SAFE(x, name, head, y) \ - for ((x) = RB_MIN(name, head); \ - ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ - (x) = (y)) - -#define RB_FOREACH_REVERSE(x, name, head) \ - for ((x) = RB_MAX(name, head); \ - (x) != NULL; \ - (x) = name##_RB_PREV(x)) - -#define RB_FOREACH_REVERSE_FROM(x, name, y) \ - for ((x) = (y); \ - ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ - (x) = (y)) - -#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ - for ((x) = RB_MAX(name, head); \ - ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ - (x) = (y)) - -#endif /* UV_TREE_H_ */ diff --git a/outside/libuv-v1.7.5/include/uv-aix.h b/outside/libuv-v1.7.5/include/uv-aix.h deleted file mode 100644 index 7dc992fa6d..0000000000 --- a/outside/libuv-v1.7.5/include/uv-aix.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_AIX_H -#define UV_AIX_H - -#define UV_PLATFORM_LOOP_FIELDS \ - int fs_fd; \ - -#define UV_PLATFORM_FS_EVENT_FIELDS \ - uv__io_t event_watcher; \ - char *dir_filename; \ - -#endif /* UV_AIX_H */ diff --git a/outside/libuv-v1.7.5/include/uv-bsd.h b/outside/libuv-v1.7.5/include/uv-bsd.h deleted file mode 100644 index 2d72b3d771..0000000000 --- a/outside/libuv-v1.7.5/include/uv-bsd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_BSD_H -#define UV_BSD_H - -#define UV_PLATFORM_FS_EVENT_FIELDS \ - uv__io_t event_watcher; \ - -#define UV_IO_PRIVATE_PLATFORM_FIELDS \ - int rcount; \ - int wcount; \ - -#define UV_HAVE_KQUEUE 1 - -#endif /* UV_BSD_H */ diff --git a/outside/libuv-v1.7.5/include/uv-darwin.h b/outside/libuv-v1.7.5/include/uv-darwin.h deleted file mode 100644 index d226415820..0000000000 --- a/outside/libuv-v1.7.5/include/uv-darwin.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_DARWIN_H -#define UV_DARWIN_H - -#if defined(__APPLE__) && defined(__MACH__) -# include -# include -# include -# include -# define UV_PLATFORM_SEM_T semaphore_t -#endif - -#define UV_IO_PRIVATE_PLATFORM_FIELDS \ - int rcount; \ - int wcount; \ - -#define UV_PLATFORM_LOOP_FIELDS \ - uv_thread_t cf_thread; \ - void* _cf_reserved; \ - void* cf_state; \ - uv_mutex_t cf_mutex; \ - uv_sem_t cf_sem; \ - void* cf_signals[2]; \ - -#define UV_PLATFORM_FS_EVENT_FIELDS \ - uv__io_t event_watcher; \ - char* realpath; \ - int realpath_len; \ - int cf_flags; \ - uv_async_t* cf_cb; \ - void* cf_events[2]; \ - void* cf_member[2]; \ - int cf_error; \ - uv_mutex_t cf_mutex; \ - -#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \ - void* select; \ - -#define UV_HAVE_KQUEUE 1 - -#endif /* UV_DARWIN_H */ diff --git a/outside/libuv-v1.7.5/include/uv-errno.h b/outside/libuv-v1.7.5/include/uv-errno.h deleted file mode 100644 index 53f30296c1..0000000000 --- a/outside/libuv-v1.7.5/include/uv-errno.h +++ /dev/null @@ -1,418 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_ERRNO_H_ -#define UV_ERRNO_H_ - -#include - -#define UV__EOF (-4095) -#define UV__UNKNOWN (-4094) - -#define UV__EAI_ADDRFAMILY (-3000) -#define UV__EAI_AGAIN (-3001) -#define UV__EAI_BADFLAGS (-3002) -#define UV__EAI_CANCELED (-3003) -#define UV__EAI_FAIL (-3004) -#define UV__EAI_FAMILY (-3005) -#define UV__EAI_MEMORY (-3006) -#define UV__EAI_NODATA (-3007) -#define UV__EAI_NONAME (-3008) -#define UV__EAI_OVERFLOW (-3009) -#define UV__EAI_SERVICE (-3010) -#define UV__EAI_SOCKTYPE (-3011) -#define UV__EAI_BADHINTS (-3013) -#define UV__EAI_PROTOCOL (-3014) - -/* Only map to the system errno on non-Windows platforms. It's apparently - * a fairly common practice for Windows programmers to redefine errno codes. - */ -#if defined(E2BIG) && !defined(_WIN32) -# define UV__E2BIG (-E2BIG) -#else -# define UV__E2BIG (-4093) -#endif - -#if defined(EACCES) && !defined(_WIN32) -# define UV__EACCES (-EACCES) -#else -# define UV__EACCES (-4092) -#endif - -#if defined(EADDRINUSE) && !defined(_WIN32) -# define UV__EADDRINUSE (-EADDRINUSE) -#else -# define UV__EADDRINUSE (-4091) -#endif - -#if defined(EADDRNOTAVAIL) && !defined(_WIN32) -# define UV__EADDRNOTAVAIL (-EADDRNOTAVAIL) -#else -# define UV__EADDRNOTAVAIL (-4090) -#endif - -#if defined(EAFNOSUPPORT) && !defined(_WIN32) -# define UV__EAFNOSUPPORT (-EAFNOSUPPORT) -#else -# define UV__EAFNOSUPPORT (-4089) -#endif - -#if defined(EAGAIN) && !defined(_WIN32) -# define UV__EAGAIN (-EAGAIN) -#else -# define UV__EAGAIN (-4088) -#endif - -#if defined(EALREADY) && !defined(_WIN32) -# define UV__EALREADY (-EALREADY) -#else -# define UV__EALREADY (-4084) -#endif - -#if defined(EBADF) && !defined(_WIN32) -# define UV__EBADF (-EBADF) -#else -# define UV__EBADF (-4083) -#endif - -#if defined(EBUSY) && !defined(_WIN32) -# define UV__EBUSY (-EBUSY) -#else -# define UV__EBUSY (-4082) -#endif - -#if defined(ECANCELED) && !defined(_WIN32) -# define UV__ECANCELED (-ECANCELED) -#else -# define UV__ECANCELED (-4081) -#endif - -#if defined(ECHARSET) && !defined(_WIN32) -# define UV__ECHARSET (-ECHARSET) -#else -# define UV__ECHARSET (-4080) -#endif - -#if defined(ECONNABORTED) && !defined(_WIN32) -# define UV__ECONNABORTED (-ECONNABORTED) -#else -# define UV__ECONNABORTED (-4079) -#endif - -#if defined(ECONNREFUSED) && !defined(_WIN32) -# define UV__ECONNREFUSED (-ECONNREFUSED) -#else -# define UV__ECONNREFUSED (-4078) -#endif - -#if defined(ECONNRESET) && !defined(_WIN32) -# define UV__ECONNRESET (-ECONNRESET) -#else -# define UV__ECONNRESET (-4077) -#endif - -#if defined(EDESTADDRREQ) && !defined(_WIN32) -# define UV__EDESTADDRREQ (-EDESTADDRREQ) -#else -# define UV__EDESTADDRREQ (-4076) -#endif - -#if defined(EEXIST) && !defined(_WIN32) -# define UV__EEXIST (-EEXIST) -#else -# define UV__EEXIST (-4075) -#endif - -#if defined(EFAULT) && !defined(_WIN32) -# define UV__EFAULT (-EFAULT) -#else -# define UV__EFAULT (-4074) -#endif - -#if defined(EHOSTUNREACH) && !defined(_WIN32) -# define UV__EHOSTUNREACH (-EHOSTUNREACH) -#else -# define UV__EHOSTUNREACH (-4073) -#endif - -#if defined(EINTR) && !defined(_WIN32) -# define UV__EINTR (-EINTR) -#else -# define UV__EINTR (-4072) -#endif - -#if defined(EINVAL) && !defined(_WIN32) -# define UV__EINVAL (-EINVAL) -#else -# define UV__EINVAL (-4071) -#endif - -#if defined(EIO) && !defined(_WIN32) -# define UV__EIO (-EIO) -#else -# define UV__EIO (-4070) -#endif - -#if defined(EISCONN) && !defined(_WIN32) -# define UV__EISCONN (-EISCONN) -#else -# define UV__EISCONN (-4069) -#endif - -#if defined(EISDIR) && !defined(_WIN32) -# define UV__EISDIR (-EISDIR) -#else -# define UV__EISDIR (-4068) -#endif - -#if defined(ELOOP) && !defined(_WIN32) -# define UV__ELOOP (-ELOOP) -#else -# define UV__ELOOP (-4067) -#endif - -#if defined(EMFILE) && !defined(_WIN32) -# define UV__EMFILE (-EMFILE) -#else -# define UV__EMFILE (-4066) -#endif - -#if defined(EMSGSIZE) && !defined(_WIN32) -# define UV__EMSGSIZE (-EMSGSIZE) -#else -# define UV__EMSGSIZE (-4065) -#endif - -#if defined(ENAMETOOLONG) && !defined(_WIN32) -# define UV__ENAMETOOLONG (-ENAMETOOLONG) -#else -# define UV__ENAMETOOLONG (-4064) -#endif - -#if defined(ENETDOWN) && !defined(_WIN32) -# define UV__ENETDOWN (-ENETDOWN) -#else -# define UV__ENETDOWN (-4063) -#endif - -#if defined(ENETUNREACH) && !defined(_WIN32) -# define UV__ENETUNREACH (-ENETUNREACH) -#else -# define UV__ENETUNREACH (-4062) -#endif - -#if defined(ENFILE) && !defined(_WIN32) -# define UV__ENFILE (-ENFILE) -#else -# define UV__ENFILE (-4061) -#endif - -#if defined(ENOBUFS) && !defined(_WIN32) -# define UV__ENOBUFS (-ENOBUFS) -#else -# define UV__ENOBUFS (-4060) -#endif - -#if defined(ENODEV) && !defined(_WIN32) -# define UV__ENODEV (-ENODEV) -#else -# define UV__ENODEV (-4059) -#endif - -#if defined(ENOENT) && !defined(_WIN32) -# define UV__ENOENT (-ENOENT) -#else -# define UV__ENOENT (-4058) -#endif - -#if defined(ENOMEM) && !defined(_WIN32) -# define UV__ENOMEM (-ENOMEM) -#else -# define UV__ENOMEM (-4057) -#endif - -#if defined(ENONET) && !defined(_WIN32) -# define UV__ENONET (-ENONET) -#else -# define UV__ENONET (-4056) -#endif - -#if defined(ENOSPC) && !defined(_WIN32) -# define UV__ENOSPC (-ENOSPC) -#else -# define UV__ENOSPC (-4055) -#endif - -#if defined(ENOSYS) && !defined(_WIN32) -# define UV__ENOSYS (-ENOSYS) -#else -# define UV__ENOSYS (-4054) -#endif - -#if defined(ENOTCONN) && !defined(_WIN32) -# define UV__ENOTCONN (-ENOTCONN) -#else -# define UV__ENOTCONN (-4053) -#endif - -#if defined(ENOTDIR) && !defined(_WIN32) -# define UV__ENOTDIR (-ENOTDIR) -#else -# define UV__ENOTDIR (-4052) -#endif - -#if defined(ENOTEMPTY) && !defined(_WIN32) -# define UV__ENOTEMPTY (-ENOTEMPTY) -#else -# define UV__ENOTEMPTY (-4051) -#endif - -#if defined(ENOTSOCK) && !defined(_WIN32) -# define UV__ENOTSOCK (-ENOTSOCK) -#else -# define UV__ENOTSOCK (-4050) -#endif - -#if defined(ENOTSUP) && !defined(_WIN32) -# define UV__ENOTSUP (-ENOTSUP) -#else -# define UV__ENOTSUP (-4049) -#endif - -#if defined(EPERM) && !defined(_WIN32) -# define UV__EPERM (-EPERM) -#else -# define UV__EPERM (-4048) -#endif - -#if defined(EPIPE) && !defined(_WIN32) -# define UV__EPIPE (-EPIPE) -#else -# define UV__EPIPE (-4047) -#endif - -#if defined(EPROTO) && !defined(_WIN32) -# define UV__EPROTO (-EPROTO) -#else -# define UV__EPROTO (-4046) -#endif - -#if defined(EPROTONOSUPPORT) && !defined(_WIN32) -# define UV__EPROTONOSUPPORT (-EPROTONOSUPPORT) -#else -# define UV__EPROTONOSUPPORT (-4045) -#endif - -#if defined(EPROTOTYPE) && !defined(_WIN32) -# define UV__EPROTOTYPE (-EPROTOTYPE) -#else -# define UV__EPROTOTYPE (-4044) -#endif - -#if defined(EROFS) && !defined(_WIN32) -# define UV__EROFS (-EROFS) -#else -# define UV__EROFS (-4043) -#endif - -#if defined(ESHUTDOWN) && !defined(_WIN32) -# define UV__ESHUTDOWN (-ESHUTDOWN) -#else -# define UV__ESHUTDOWN (-4042) -#endif - -#if defined(ESPIPE) && !defined(_WIN32) -# define UV__ESPIPE (-ESPIPE) -#else -# define UV__ESPIPE (-4041) -#endif - -#if defined(ESRCH) && !defined(_WIN32) -# define UV__ESRCH (-ESRCH) -#else -# define UV__ESRCH (-4040) -#endif - -#if defined(ETIMEDOUT) && !defined(_WIN32) -# define UV__ETIMEDOUT (-ETIMEDOUT) -#else -# define UV__ETIMEDOUT (-4039) -#endif - -#if defined(ETXTBSY) && !defined(_WIN32) -# define UV__ETXTBSY (-ETXTBSY) -#else -# define UV__ETXTBSY (-4038) -#endif - -#if defined(EXDEV) && !defined(_WIN32) -# define UV__EXDEV (-EXDEV) -#else -# define UV__EXDEV (-4037) -#endif - -#if defined(EFBIG) && !defined(_WIN32) -# define UV__EFBIG (-EFBIG) -#else -# define UV__EFBIG (-4036) -#endif - -#if defined(ENOPROTOOPT) && !defined(_WIN32) -# define UV__ENOPROTOOPT (-ENOPROTOOPT) -#else -# define UV__ENOPROTOOPT (-4035) -#endif - -#if defined(ERANGE) && !defined(_WIN32) -# define UV__ERANGE (-ERANGE) -#else -# define UV__ERANGE (-4034) -#endif - -#if defined(ENXIO) && !defined(_WIN32) -# define UV__ENXIO (-ENXIO) -#else -# define UV__ENXIO (-4033) -#endif - -#if defined(EMLINK) && !defined(_WIN32) -# define UV__EMLINK (-EMLINK) -#else -# define UV__EMLINK (-4032) -#endif - -/* EHOSTDOWN is not visible on BSD-like systems when _POSIX_C_SOURCE is - * defined. Fortunately, its value is always 64 so it's possible albeit - * icky to hard-code it. - */ -#if defined(EHOSTDOWN) && !defined(_WIN32) -# define UV__EHOSTDOWN (-EHOSTDOWN) -#elif defined(__APPLE__) || \ - defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__OpenBSD__) -# define UV__EHOSTDOWN (-64) -#else -# define UV__EHOSTDOWN (-4031) -#endif - -#endif /* UV_ERRNO_H_ */ diff --git a/outside/libuv-v1.7.5/include/uv-linux.h b/outside/libuv-v1.7.5/include/uv-linux.h deleted file mode 100644 index 9b38405a19..0000000000 --- a/outside/libuv-v1.7.5/include/uv-linux.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_LINUX_H -#define UV_LINUX_H - -#define UV_PLATFORM_LOOP_FIELDS \ - uv__io_t inotify_read_watcher; \ - void* inotify_watchers; \ - int inotify_fd; \ - -#define UV_PLATFORM_FS_EVENT_FIELDS \ - void* watchers[2]; \ - int wd; \ - -#endif /* UV_LINUX_H */ diff --git a/outside/libuv-v1.7.5/include/uv-sunos.h b/outside/libuv-v1.7.5/include/uv-sunos.h deleted file mode 100644 index 042166424e..0000000000 --- a/outside/libuv-v1.7.5/include/uv-sunos.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_SUNOS_H -#define UV_SUNOS_H - -#include -#include - -/* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c, - * add the fs_event fields even when this version of SunOS doesn't support - * file watching. - */ -#define UV_PLATFORM_LOOP_FIELDS \ - uv__io_t fs_event_watcher; \ - int fs_fd; \ - -#if defined(PORT_SOURCE_FILE) - -# define UV_PLATFORM_FS_EVENT_FIELDS \ - file_obj_t fo; \ - int fd; \ - -#endif /* defined(PORT_SOURCE_FILE) */ - -#endif /* UV_SUNOS_H */ diff --git a/outside/libuv-v1.7.5/include/uv-threadpool.h b/outside/libuv-v1.7.5/include/uv-threadpool.h deleted file mode 100644 index 9708ebdd53..0000000000 --- a/outside/libuv-v1.7.5/include/uv-threadpool.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* - * This file is private to libuv. It provides common functionality to both - * Windows and Unix backends. - */ - -#ifndef UV_THREADPOOL_H_ -#define UV_THREADPOOL_H_ - -struct uv__work { - void (*work)(struct uv__work *w); - void (*done)(struct uv__work *w, int status); - struct uv_loop_s* loop; - void* wq[2]; -}; - -#endif /* UV_THREADPOOL_H_ */ diff --git a/outside/libuv-v1.7.5/include/uv-unix.h b/outside/libuv-v1.7.5/include/uv-unix.h deleted file mode 100644 index 82d193bdca..0000000000 --- a/outside/libuv-v1.7.5/include/uv-unix.h +++ /dev/null @@ -1,383 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_UNIX_H -#define UV_UNIX_H - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#ifdef __ANDROID__ -#include "pthread-fixes.h" -#endif -#include - -#include "uv-threadpool.h" - -#if defined(__linux__) -# include "uv-linux.h" -#elif defined(_AIX) -# include "uv-aix.h" -#elif defined(__sun) -# include "uv-sunos.h" -#elif defined(__APPLE__) -# include "uv-darwin.h" -#elif defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) -# include "uv-bsd.h" -#endif - -#ifndef NI_MAXHOST -# define NI_MAXHOST 1025 -#endif - -#ifndef NI_MAXSERV -# define NI_MAXSERV 32 -#endif - -#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS -# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */ -#endif - -struct uv__io_s; -struct uv__async; -struct uv_loop_s; - -typedef void (*uv__io_cb)(struct uv_loop_s* loop, - struct uv__io_s* w, - unsigned int events); -typedef struct uv__io_s uv__io_t; - -struct uv__io_s { - uv__io_cb cb; - void* pending_queue[2]; - void* watcher_queue[2]; - unsigned int pevents; /* Pending event mask i.e. mask at next tick. */ - unsigned int events; /* Current event mask. */ - int fd; - UV_IO_PRIVATE_PLATFORM_FIELDS -}; - -typedef void (*uv__async_cb)(struct uv_loop_s* loop, - struct uv__async* w, - unsigned int nevents); - -struct uv__async { - uv__async_cb cb; - uv__io_t io_watcher; - int wfd; -}; - -#ifndef UV_PLATFORM_SEM_T -# define UV_PLATFORM_SEM_T sem_t -#endif - -#ifndef UV_PLATFORM_LOOP_FIELDS -# define UV_PLATFORM_LOOP_FIELDS /* empty */ -#endif - -#ifndef UV_PLATFORM_FS_EVENT_FIELDS -# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */ -#endif - -#ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS -# define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */ -#endif - -/* Note: May be cast to struct iovec. See writev(2). */ -typedef struct uv_buf_t { - char* base; - size_t len; -} uv_buf_t; - -typedef int uv_file; -typedef int uv_os_sock_t; -typedef int uv_os_fd_t; - -#define UV_ONCE_INIT PTHREAD_ONCE_INIT - -typedef pthread_once_t uv_once_t; -typedef pthread_t uv_thread_t; -typedef pthread_mutex_t uv_mutex_t; -typedef pthread_rwlock_t uv_rwlock_t; -typedef UV_PLATFORM_SEM_T uv_sem_t; -typedef pthread_cond_t uv_cond_t; -typedef pthread_key_t uv_key_t; - -#if defined(__APPLE__) && defined(__MACH__) - -typedef struct { - unsigned int n; - unsigned int count; - uv_mutex_t mutex; - uv_sem_t turnstile1; - uv_sem_t turnstile2; -} uv_barrier_t; - -#else /* defined(__APPLE__) && defined(__MACH__) */ - -typedef pthread_barrier_t uv_barrier_t; - -#endif /* defined(__APPLE__) && defined(__MACH__) */ - -/* Platform-specific definitions for uv_spawn support. */ -typedef gid_t uv_gid_t; -typedef uid_t uv_uid_t; - -typedef struct dirent uv__dirent_t; - -#if defined(DT_UNKNOWN) -# define HAVE_DIRENT_TYPES -# if defined(DT_REG) -# define UV__DT_FILE DT_REG -# else -# define UV__DT_FILE -1 -# endif -# if defined(DT_DIR) -# define UV__DT_DIR DT_DIR -# else -# define UV__DT_DIR -2 -# endif -# if defined(DT_LNK) -# define UV__DT_LINK DT_LNK -# else -# define UV__DT_LINK -3 -# endif -# if defined(DT_FIFO) -# define UV__DT_FIFO DT_FIFO -# else -# define UV__DT_FIFO -4 -# endif -# if defined(DT_SOCK) -# define UV__DT_SOCKET DT_SOCK -# else -# define UV__DT_SOCKET -5 -# endif -# if defined(DT_CHR) -# define UV__DT_CHAR DT_CHR -# else -# define UV__DT_CHAR -6 -# endif -# if defined(DT_BLK) -# define UV__DT_BLOCK DT_BLK -# else -# define UV__DT_BLOCK -7 -# endif -#endif - -/* Platform-specific definitions for uv_dlopen support. */ -#define UV_DYNAMIC /* empty */ - -typedef struct { - void* handle; - char* errmsg; -} uv_lib_t; - -#define UV_LOOP_PRIVATE_FIELDS \ - unsigned long flags; \ - int backend_fd; \ - void* pending_queue[2]; \ - void* watcher_queue[2]; \ - uv__io_t** watchers; \ - unsigned int nwatchers; \ - unsigned int nfds; \ - void* wq[2]; \ - uv_mutex_t wq_mutex; \ - uv_async_t wq_async; \ - uv_rwlock_t cloexec_lock; \ - uv_handle_t* closing_handles; \ - void* process_handles[2]; \ - void* prepare_handles[2]; \ - void* check_handles[2]; \ - void* idle_handles[2]; \ - void* async_handles[2]; \ - struct uv__async async_watcher; \ - struct { \ - void* min; \ - unsigned int nelts; \ - } timer_heap; \ - uint64_t timer_counter; \ - uint64_t time; \ - int signal_pipefd[2]; \ - uv__io_t signal_io_watcher; \ - uv_signal_t child_watcher; \ - int emfile_fd; \ - UV_PLATFORM_LOOP_FIELDS \ - -#define UV_REQ_TYPE_PRIVATE /* empty */ - -#define UV_REQ_PRIVATE_FIELDS /* empty */ - -#define UV_PRIVATE_REQ_TYPES /* empty */ - -#define UV_WRITE_PRIVATE_FIELDS \ - void* queue[2]; \ - unsigned int write_index; \ - uv_buf_t* bufs; \ - unsigned int nbufs; \ - int error; \ - uv_buf_t bufsml[4]; \ - -#define UV_CONNECT_PRIVATE_FIELDS \ - void* queue[2]; \ - -#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */ - -#define UV_UDP_SEND_PRIVATE_FIELDS \ - void* queue[2]; \ - struct sockaddr_storage addr; \ - unsigned int nbufs; \ - uv_buf_t* bufs; \ - ssize_t status; \ - uv_udp_send_cb send_cb; \ - uv_buf_t bufsml[4]; \ - -#define UV_HANDLE_PRIVATE_FIELDS \ - uv_handle_t* next_closing; \ - unsigned int flags; \ - -#define UV_STREAM_PRIVATE_FIELDS \ - uv_connect_t *connect_req; \ - uv_shutdown_t *shutdown_req; \ - uv__io_t io_watcher; \ - void* write_queue[2]; \ - void* write_completed_queue[2]; \ - uv_connection_cb connection_cb; \ - int delayed_error; \ - int accepted_fd; \ - void* queued_fds; \ - UV_STREAM_PRIVATE_PLATFORM_FIELDS \ - -#define UV_TCP_PRIVATE_FIELDS /* empty */ - -#define UV_UDP_PRIVATE_FIELDS \ - uv_alloc_cb alloc_cb; \ - uv_udp_recv_cb recv_cb; \ - uv__io_t io_watcher; \ - void* write_queue[2]; \ - void* write_completed_queue[2]; \ - -#define UV_PIPE_PRIVATE_FIELDS \ - const char* pipe_fname; /* strdup'ed */ - -#define UV_POLL_PRIVATE_FIELDS \ - uv__io_t io_watcher; - -#define UV_PREPARE_PRIVATE_FIELDS \ - uv_prepare_cb prepare_cb; \ - void* queue[2]; \ - -#define UV_CHECK_PRIVATE_FIELDS \ - uv_check_cb check_cb; \ - void* queue[2]; \ - -#define UV_IDLE_PRIVATE_FIELDS \ - uv_idle_cb idle_cb; \ - void* queue[2]; \ - -#define UV_ASYNC_PRIVATE_FIELDS \ - uv_async_cb async_cb; \ - void* queue[2]; \ - int pending; \ - -#define UV_TIMER_PRIVATE_FIELDS \ - uv_timer_cb timer_cb; \ - void* heap_node[3]; \ - uint64_t timeout; \ - uint64_t repeat; \ - uint64_t start_id; - -#define UV_GETADDRINFO_PRIVATE_FIELDS \ - struct uv__work work_req; \ - uv_getaddrinfo_cb cb; \ - struct addrinfo* hints; \ - char* hostname; \ - char* service; \ - struct addrinfo* addrinfo; \ - int retcode; - -#define UV_GETNAMEINFO_PRIVATE_FIELDS \ - struct uv__work work_req; \ - uv_getnameinfo_cb getnameinfo_cb; \ - struct sockaddr_storage storage; \ - int flags; \ - char host[NI_MAXHOST]; \ - char service[NI_MAXSERV]; \ - int retcode; - -#define UV_PROCESS_PRIVATE_FIELDS \ - void* queue[2]; \ - int status; \ - -#define UV_FS_PRIVATE_FIELDS \ - const char *new_path; \ - uv_file file; \ - int flags; \ - mode_t mode; \ - unsigned int nbufs; \ - uv_buf_t* bufs; \ - off_t off; \ - uv_uid_t uid; \ - uv_gid_t gid; \ - double atime; \ - double mtime; \ - struct uv__work work_req; \ - uv_buf_t bufsml[4]; \ - -#define UV_WORK_PRIVATE_FIELDS \ - struct uv__work work_req; - -#define UV_TTY_PRIVATE_FIELDS \ - struct termios orig_termios; \ - int mode; - -#define UV_SIGNAL_PRIVATE_FIELDS \ - /* RB_ENTRY(uv_signal_s) tree_entry; */ \ - struct { \ - struct uv_signal_s* rbe_left; \ - struct uv_signal_s* rbe_right; \ - struct uv_signal_s* rbe_parent; \ - int rbe_color; \ - } tree_entry; \ - /* Use two counters here so we don have to fiddle with atomics. */ \ - unsigned int caught_signals; \ - unsigned int dispatched_signals; - -#define UV_FS_EVENT_PRIVATE_FIELDS \ - uv_fs_event_cb cb; \ - UV_PLATFORM_FS_EVENT_FIELDS \ - -#endif /* UV_UNIX_H */ diff --git a/outside/libuv-v1.7.5/include/uv-version.h b/outside/libuv-v1.7.5/include/uv-version.h deleted file mode 100644 index e1f26601a1..0000000000 --- a/outside/libuv-v1.7.5/include/uv-version.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_VERSION_H -#define UV_VERSION_H - - /* - * Versions with the same major number are ABI stable. API is allowed to - * evolve between minor releases, but only in a backwards compatible way. - * Make sure you update the -soname directives in configure.ac - * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but - * not UV_VERSION_PATCH.) - */ - -#define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 7 -#define UV_VERSION_PATCH 5 -#define UV_VERSION_IS_RELEASE 1 -#define UV_VERSION_SUFFIX "" - -#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \ - (UV_VERSION_MINOR << 8) | \ - (UV_VERSION_PATCH)) - -#endif /* UV_VERSION_H */ diff --git a/outside/libuv-v1.7.5/include/uv-win.h b/outside/libuv-v1.7.5/include/uv-win.h deleted file mode 100644 index 300be47620..0000000000 --- a/outside/libuv-v1.7.5/include/uv-win.h +++ /dev/null @@ -1,653 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0502 -#endif - -#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) -typedef intptr_t ssize_t; -# define _SSIZE_T_ -# define _SSIZE_T_DEFINED -#endif - -#include - -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) -typedef struct pollfd { - SOCKET fd; - short events; - short revents; -} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD; -#endif - -#ifndef LOCALE_INVARIANT -# define LOCALE_INVARIANT 0x007f -#endif - -#include -#include -#include - -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include -#endif - -#include "tree.h" -#include "uv-threadpool.h" - -#define MAX_PIPENAME_LEN 256 - -#ifndef S_IFLNK -# define S_IFLNK 0xA000 -#endif - -/* Additional signals supported by uv_signal and or uv_kill. The CRT defines - * the following signals already: - * - * #define SIGINT 2 - * #define SIGILL 4 - * #define SIGABRT_COMPAT 6 - * #define SIGFPE 8 - * #define SIGSEGV 11 - * #define SIGTERM 15 - * #define SIGBREAK 21 - * #define SIGABRT 22 - * - * The additional signals have values that are common on other Unix - * variants (Linux and Darwin) - */ -#define SIGHUP 1 -#define SIGKILL 9 -#define SIGWINCH 28 - -/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many */ -/* unix-like platforms. However MinGW doesn't define it, so we do. */ -#ifndef SIGABRT_COMPAT -# define SIGABRT_COMPAT 6 -#endif - -/* - * Guids and typedefs for winsock extension functions - * Mingw32 doesn't have these :-( - */ -#ifndef WSAID_ACCEPTEX -# define WSAID_ACCEPTEX \ - {0xb5367df1, 0xcbac, 0x11cf, \ - {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} - -# define WSAID_CONNECTEX \ - {0x25a207b9, 0xddf3, 0x4660, \ - {0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}} - -# define WSAID_GETACCEPTEXSOCKADDRS \ - {0xb5367df2, 0xcbac, 0x11cf, \ - {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} - -# define WSAID_DISCONNECTEX \ - {0x7fda2e11, 0x8630, 0x436f, \ - {0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}} - -# define WSAID_TRANSMITFILE \ - {0xb5367df0, 0xcbac, 0x11cf, \ - {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} - - typedef BOOL PASCAL (*LPFN_ACCEPTEX) - (SOCKET sListenSocket, - SOCKET sAcceptSocket, - PVOID lpOutputBuffer, - DWORD dwReceiveDataLength, - DWORD dwLocalAddressLength, - DWORD dwRemoteAddressLength, - LPDWORD lpdwBytesReceived, - LPOVERLAPPED lpOverlapped); - - typedef BOOL PASCAL (*LPFN_CONNECTEX) - (SOCKET s, - const struct sockaddr* name, - int namelen, - PVOID lpSendBuffer, - DWORD dwSendDataLength, - LPDWORD lpdwBytesSent, - LPOVERLAPPED lpOverlapped); - - typedef void PASCAL (*LPFN_GETACCEPTEXSOCKADDRS) - (PVOID lpOutputBuffer, - DWORD dwReceiveDataLength, - DWORD dwLocalAddressLength, - DWORD dwRemoteAddressLength, - LPSOCKADDR* LocalSockaddr, - LPINT LocalSockaddrLength, - LPSOCKADDR* RemoteSockaddr, - LPINT RemoteSockaddrLength); - - typedef BOOL PASCAL (*LPFN_DISCONNECTEX) - (SOCKET hSocket, - LPOVERLAPPED lpOverlapped, - DWORD dwFlags, - DWORD reserved); - - typedef BOOL PASCAL (*LPFN_TRANSMITFILE) - (SOCKET hSocket, - HANDLE hFile, - DWORD nNumberOfBytesToWrite, - DWORD nNumberOfBytesPerSend, - LPOVERLAPPED lpOverlapped, - LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, - DWORD dwFlags); - - typedef PVOID RTL_SRWLOCK; - typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK; -#endif - -typedef int (WSAAPI* LPFN_WSARECV) - (SOCKET socket, - LPWSABUF buffers, - DWORD buffer_count, - LPDWORD bytes, - LPDWORD flags, - LPWSAOVERLAPPED overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); - -typedef int (WSAAPI* LPFN_WSARECVFROM) - (SOCKET socket, - LPWSABUF buffers, - DWORD buffer_count, - LPDWORD bytes, - LPDWORD flags, - struct sockaddr* addr, - LPINT addr_len, - LPWSAOVERLAPPED overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); - -#ifndef _NTDEF_ - typedef LONG NTSTATUS; - typedef NTSTATUS *PNTSTATUS; -#endif - -#ifndef RTL_CONDITION_VARIABLE_INIT - typedef PVOID CONDITION_VARIABLE, *PCONDITION_VARIABLE; -#endif - -typedef struct _AFD_POLL_HANDLE_INFO { - HANDLE Handle; - ULONG Events; - NTSTATUS Status; -} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO; - -typedef struct _AFD_POLL_INFO { - LARGE_INTEGER Timeout; - ULONG NumberOfHandles; - ULONG Exclusive; - AFD_POLL_HANDLE_INFO Handles[1]; -} AFD_POLL_INFO, *PAFD_POLL_INFO; - -#define UV_MSAFD_PROVIDER_COUNT 3 - - -/** - * It should be possible to cast uv_buf_t[] to WSABUF[] - * see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx - */ -typedef struct uv_buf_t { - ULONG len; - char* base; -} uv_buf_t; - -typedef int uv_file; -typedef SOCKET uv_os_sock_t; -typedef HANDLE uv_os_fd_t; - -typedef HANDLE uv_thread_t; - -typedef HANDLE uv_sem_t; - -typedef CRITICAL_SECTION uv_mutex_t; - -/* This condition variable implementation is based on the SetEvent solution - * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html - * We could not use the SignalObjectAndWait solution (section 3.4) because - * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and - * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs. - */ - -typedef union { - CONDITION_VARIABLE cond_var; - struct { - unsigned int waiters_count; - CRITICAL_SECTION waiters_count_lock; - HANDLE signal_event; - HANDLE broadcast_event; - } fallback; -} uv_cond_t; - -typedef union { - struct { - unsigned int num_readers_; - CRITICAL_SECTION num_readers_lock_; - HANDLE write_semaphore_; - } state_; - /* TODO: remove me in v2.x. */ - struct { - SRWLOCK unused_; - } unused1_; - /* TODO: remove me in v2.x. */ - struct { - uv_mutex_t unused1_; - uv_mutex_t unused2_; - } unused2_; -} uv_rwlock_t; - -typedef struct { - unsigned int n; - unsigned int count; - uv_mutex_t mutex; - uv_sem_t turnstile1; - uv_sem_t turnstile2; -} uv_barrier_t; - -typedef struct { - DWORD tls_index; -} uv_key_t; - -#define UV_ONCE_INIT { 0, NULL } - -typedef struct uv_once_s { - unsigned char ran; - HANDLE event; -} uv_once_t; - -/* Platform-specific definitions for uv_spawn support. */ -typedef unsigned char uv_uid_t; -typedef unsigned char uv_gid_t; - -typedef struct uv__dirent_s { - int d_type; - char d_name[1]; -} uv__dirent_t; - -#define HAVE_DIRENT_TYPES -#define UV__DT_DIR UV_DIRENT_DIR -#define UV__DT_FILE UV_DIRENT_FILE -#define UV__DT_LINK UV_DIRENT_LINK -#define UV__DT_FIFO UV_DIRENT_FIFO -#define UV__DT_SOCKET UV_DIRENT_SOCKET -#define UV__DT_CHAR UV_DIRENT_CHAR -#define UV__DT_BLOCK UV_DIRENT_BLOCK - -/* Platform-specific definitions for uv_dlopen support. */ -#define UV_DYNAMIC FAR WINAPI -typedef struct { - HMODULE handle; - char* errmsg; -} uv_lib_t; - -RB_HEAD(uv_timer_tree_s, uv_timer_s); - -#define UV_LOOP_PRIVATE_FIELDS \ - /* The loop's I/O completion port */ \ - HANDLE iocp; \ - /* The current time according to the event loop. in msecs. */ \ - uint64_t time; \ - /* Tail of a single-linked circular queue of pending reqs. If the queue */ \ - /* is empty, tail_ is NULL. If there is only one item, */ \ - /* tail_->next_req == tail_ */ \ - uv_req_t* pending_reqs_tail; \ - /* Head of a single-linked list of closed handles */ \ - uv_handle_t* endgame_handles; \ - /* The head of the timers tree */ \ - struct uv_timer_tree_s timers; \ - /* Lists of active loop (prepare / check / idle) watchers */ \ - uv_prepare_t* prepare_handles; \ - uv_check_t* check_handles; \ - uv_idle_t* idle_handles; \ - /* This pointer will refer to the prepare/check/idle handle whose */ \ - /* callback is scheduled to be called next. This is needed to allow */ \ - /* safe removal from one of the lists above while that list being */ \ - /* iterated over. */ \ - uv_prepare_t* next_prepare_handle; \ - uv_check_t* next_check_handle; \ - uv_idle_t* next_idle_handle; \ - /* This handle holds the peer sockets for the fast variant of uv_poll_t */ \ - SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT]; \ - /* Counter to keep track of active tcp streams */ \ - unsigned int active_tcp_streams; \ - /* Counter to keep track of active udp streams */ \ - unsigned int active_udp_streams; \ - /* Counter to started timer */ \ - uint64_t timer_counter; \ - /* Threadpool */ \ - void* wq[2]; \ - uv_mutex_t wq_mutex; \ - uv_async_t wq_async; - -#define UV_REQ_TYPE_PRIVATE \ - /* TODO: remove the req suffix */ \ - UV_ACCEPT, \ - UV_FS_EVENT_REQ, \ - UV_POLL_REQ, \ - UV_PROCESS_EXIT, \ - UV_READ, \ - UV_UDP_RECV, \ - UV_WAKEUP, \ - UV_SIGNAL_REQ, - -#define UV_REQ_PRIVATE_FIELDS \ - union { \ - /* Used by I/O operations */ \ - struct { \ - OVERLAPPED overlapped; \ - size_t queued_bytes; \ - } io; \ - } u; \ - struct uv_req_s* next_req; - -#define UV_WRITE_PRIVATE_FIELDS \ - int ipc_header; \ - uv_buf_t write_buffer; \ - HANDLE event_handle; \ - HANDLE wait_handle; - -#define UV_CONNECT_PRIVATE_FIELDS \ - /* empty */ - -#define UV_SHUTDOWN_PRIVATE_FIELDS \ - /* empty */ - -#define UV_UDP_SEND_PRIVATE_FIELDS \ - /* empty */ - -#define UV_PRIVATE_REQ_TYPES \ - typedef struct uv_pipe_accept_s { \ - UV_REQ_FIELDS \ - HANDLE pipeHandle; \ - struct uv_pipe_accept_s* next_pending; \ - } uv_pipe_accept_t; \ - \ - typedef struct uv_tcp_accept_s { \ - UV_REQ_FIELDS \ - SOCKET accept_socket; \ - char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \ - HANDLE event_handle; \ - HANDLE wait_handle; \ - struct uv_tcp_accept_s* next_pending; \ - } uv_tcp_accept_t; \ - \ - typedef struct uv_read_s { \ - UV_REQ_FIELDS \ - HANDLE event_handle; \ - HANDLE wait_handle; \ - } uv_read_t; - -#define uv_stream_connection_fields \ - unsigned int write_reqs_pending; \ - uv_shutdown_t* shutdown_req; - -#define uv_stream_server_fields \ - uv_connection_cb connection_cb; - -#define UV_STREAM_PRIVATE_FIELDS \ - unsigned int reqs_pending; \ - int activecnt; \ - uv_read_t read_req; \ - union { \ - struct { uv_stream_connection_fields } conn; \ - struct { uv_stream_server_fields } serv; \ - } stream; - -#define uv_tcp_server_fields \ - uv_tcp_accept_t* accept_reqs; \ - unsigned int processed_accepts; \ - uv_tcp_accept_t* pending_accepts; \ - LPFN_ACCEPTEX func_acceptex; - -#define uv_tcp_connection_fields \ - uv_buf_t read_buffer; \ - LPFN_CONNECTEX func_connectex; - -#define UV_TCP_PRIVATE_FIELDS \ - SOCKET socket; \ - int delayed_error; \ - union { \ - struct { uv_tcp_server_fields } serv; \ - struct { uv_tcp_connection_fields } conn; \ - } tcp; - -#define UV_UDP_PRIVATE_FIELDS \ - SOCKET socket; \ - unsigned int reqs_pending; \ - int activecnt; \ - uv_req_t recv_req; \ - uv_buf_t recv_buffer; \ - struct sockaddr_storage recv_from; \ - int recv_from_len; \ - uv_udp_recv_cb recv_cb; \ - uv_alloc_cb alloc_cb; \ - LPFN_WSARECV func_wsarecv; \ - LPFN_WSARECVFROM func_wsarecvfrom; - -#define uv_pipe_server_fields \ - int pending_instances; \ - uv_pipe_accept_t* accept_reqs; \ - uv_pipe_accept_t* pending_accepts; - -#define uv_pipe_connection_fields \ - uv_timer_t* eof_timer; \ - uv_write_t ipc_header_write_req; \ - int ipc_pid; \ - uint64_t remaining_ipc_rawdata_bytes; \ - struct { \ - void* queue[2]; \ - int queue_len; \ - } pending_ipc_info; \ - uv_write_t* non_overlapped_writes_tail; \ - uv_mutex_t readfile_mutex; \ - volatile HANDLE readfile_thread; - -#define UV_PIPE_PRIVATE_FIELDS \ - HANDLE handle; \ - WCHAR* name; \ - union { \ - struct { uv_pipe_server_fields } serv; \ - struct { uv_pipe_connection_fields } conn; \ - } pipe; - -/* TODO: put the parser states in an union - TTY handles are always */ -/* half-duplex so read-state can safely overlap write-state. */ -#define UV_TTY_PRIVATE_FIELDS \ - HANDLE handle; \ - union { \ - struct { \ - /* Used for readable TTY handles */ \ - HANDLE read_line_handle; \ - uv_buf_t read_line_buffer; \ - HANDLE read_raw_wait; \ - /* Fields used for translating win keystrokes into vt100 characters */ \ - char last_key[8]; \ - unsigned char last_key_offset; \ - unsigned char last_key_len; \ - WCHAR last_utf16_high_surrogate; \ - INPUT_RECORD last_input_record; \ - } rd; \ - struct { \ - /* Used for writable TTY handles */ \ - /* utf8-to-utf16 conversion state */ \ - unsigned int utf8_codepoint; \ - unsigned char utf8_bytes_left; \ - /* eol conversion state */ \ - unsigned char previous_eol; \ - /* ansi parser state */ \ - unsigned char ansi_parser_state; \ - unsigned char ansi_csi_argc; \ - unsigned short ansi_csi_argv[4]; \ - COORD saved_position; \ - WORD saved_attributes; \ - } wr; \ - } tty; - -#define UV_POLL_PRIVATE_FIELDS \ - SOCKET socket; \ - /* Used in fast mode */ \ - SOCKET peer_socket; \ - AFD_POLL_INFO afd_poll_info_1; \ - AFD_POLL_INFO afd_poll_info_2; \ - /* Used in fast and slow mode. */ \ - uv_req_t poll_req_1; \ - uv_req_t poll_req_2; \ - unsigned char submitted_events_1; \ - unsigned char submitted_events_2; \ - unsigned char mask_events_1; \ - unsigned char mask_events_2; \ - unsigned char events; - -#define UV_TIMER_PRIVATE_FIELDS \ - RB_ENTRY(uv_timer_s) tree_entry; \ - uint64_t due; \ - uint64_t repeat; \ - uint64_t start_id; \ - uv_timer_cb timer_cb; - -#define UV_ASYNC_PRIVATE_FIELDS \ - struct uv_req_s async_req; \ - uv_async_cb async_cb; \ - /* char to avoid alignment issues */ \ - char volatile async_sent; - -#define UV_PREPARE_PRIVATE_FIELDS \ - uv_prepare_t* prepare_prev; \ - uv_prepare_t* prepare_next; \ - uv_prepare_cb prepare_cb; - -#define UV_CHECK_PRIVATE_FIELDS \ - uv_check_t* check_prev; \ - uv_check_t* check_next; \ - uv_check_cb check_cb; - -#define UV_IDLE_PRIVATE_FIELDS \ - uv_idle_t* idle_prev; \ - uv_idle_t* idle_next; \ - uv_idle_cb idle_cb; - -#define UV_HANDLE_PRIVATE_FIELDS \ - uv_handle_t* endgame_next; \ - unsigned int flags; - -#define UV_GETADDRINFO_PRIVATE_FIELDS \ - struct uv__work work_req; \ - uv_getaddrinfo_cb getaddrinfo_cb; \ - void* alloc; \ - WCHAR* node; \ - WCHAR* service; \ - /* The addrinfoW field is used to store a pointer to the hints, and */ \ - /* later on to store the result of GetAddrInfoW. The final result will */ \ - /* be converted to struct addrinfo* and stored in the addrinfo field. */ \ - struct addrinfoW* addrinfow; \ - struct addrinfo* addrinfo; \ - int retcode; - -#define UV_GETNAMEINFO_PRIVATE_FIELDS \ - struct uv__work work_req; \ - uv_getnameinfo_cb getnameinfo_cb; \ - struct sockaddr_storage storage; \ - int flags; \ - char host[NI_MAXHOST]; \ - char service[NI_MAXSERV]; \ - int retcode; - -#define UV_PROCESS_PRIVATE_FIELDS \ - struct uv_process_exit_s { \ - UV_REQ_FIELDS \ - } exit_req; \ - BYTE* child_stdio_buffer; \ - int exit_signal; \ - HANDLE wait_handle; \ - HANDLE process_handle; \ - volatile char exit_cb_pending; - -#define UV_FS_PRIVATE_FIELDS \ - struct uv__work work_req; \ - int flags; \ - DWORD sys_errno_; \ - union { \ - /* TODO: remove me in 0.9. */ \ - WCHAR* pathw; \ - int fd; \ - } file; \ - union { \ - struct { \ - int mode; \ - WCHAR* new_pathw; \ - int file_flags; \ - int fd_out; \ - unsigned int nbufs; \ - uv_buf_t* bufs; \ - int64_t offset; \ - uv_buf_t bufsml[4]; \ - } info; \ - struct { \ - double atime; \ - double mtime; \ - } time; \ - } fs; - -#define UV_WORK_PRIVATE_FIELDS \ - struct uv__work work_req; - -#define UV_FS_EVENT_PRIVATE_FIELDS \ - struct uv_fs_event_req_s { \ - UV_REQ_FIELDS \ - } req; \ - HANDLE dir_handle; \ - int req_pending; \ - uv_fs_event_cb cb; \ - WCHAR* filew; \ - WCHAR* short_filew; \ - WCHAR* dirw; \ - char* buffer; - -#define UV_SIGNAL_PRIVATE_FIELDS \ - RB_ENTRY(uv_signal_s) tree_entry; \ - struct uv_req_s signal_req; \ - unsigned long pending_signum; - -int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size, - char* utf8Buffer, size_t utf8Size); -int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer, - size_t utf16Size); - -#ifndef F_OK -#define F_OK 0 -#endif -#ifndef R_OK -#define R_OK 4 -#endif -#ifndef W_OK -#define W_OK 2 -#endif -#ifndef X_OK -#define X_OK 1 -#endif diff --git a/outside/libuv-v1.7.5/include/uv.h b/outside/libuv-v1.7.5/include/uv.h deleted file mode 100644 index f96026b603..0000000000 --- a/outside/libuv-v1.7.5/include/uv.h +++ /dev/null @@ -1,1472 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* See https://github.com/libuv/libuv#documentation for documentation. */ - -#ifndef UV_H -#define UV_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _WIN32 - /* Windows - set up dll import/export decorators. */ -# if defined(BUILDING_UV_SHARED) - /* Building shared library. */ -# define UV_EXTERN __declspec(dllexport) -# elif defined(USING_UV_SHARED) - /* Using shared library. */ -# define UV_EXTERN __declspec(dllimport) -# else - /* Building static library. */ -# define UV_EXTERN /* nothing */ -# endif -#elif __GNUC__ >= 4 -# define UV_EXTERN __attribute__((visibility("default"))) -#else -# define UV_EXTERN /* nothing */ -#endif - -#include "uv-errno.h" -#include "uv-version.h" -#include - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include -#endif - -#if defined(_WIN32) -# include "uv-win.h" -#else -# include "uv-unix.h" -#endif - -/* Expand this list if necessary. */ -#define UV_ERRNO_MAP(XX) \ - XX(E2BIG, "argument list too long") \ - XX(EACCES, "permission denied") \ - XX(EADDRINUSE, "address already in use") \ - XX(EADDRNOTAVAIL, "address not available") \ - XX(EAFNOSUPPORT, "address family not supported") \ - XX(EAGAIN, "resource temporarily unavailable") \ - XX(EAI_ADDRFAMILY, "address family not supported") \ - XX(EAI_AGAIN, "temporary failure") \ - XX(EAI_BADFLAGS, "bad ai_flags value") \ - XX(EAI_BADHINTS, "invalid value for hints") \ - XX(EAI_CANCELED, "request canceled") \ - XX(EAI_FAIL, "permanent failure") \ - XX(EAI_FAMILY, "ai_family not supported") \ - XX(EAI_MEMORY, "out of memory") \ - XX(EAI_NODATA, "no address") \ - XX(EAI_NONAME, "unknown node or service") \ - XX(EAI_OVERFLOW, "argument buffer overflow") \ - XX(EAI_PROTOCOL, "resolved protocol is unknown") \ - XX(EAI_SERVICE, "service not available for socket type") \ - XX(EAI_SOCKTYPE, "socket type not supported") \ - XX(EALREADY, "connection already in progress") \ - XX(EBADF, "bad file descriptor") \ - XX(EBUSY, "resource busy or locked") \ - XX(ECANCELED, "operation canceled") \ - XX(ECHARSET, "invalid Unicode character") \ - XX(ECONNABORTED, "software caused connection abort") \ - XX(ECONNREFUSED, "connection refused") \ - XX(ECONNRESET, "connection reset by peer") \ - XX(EDESTADDRREQ, "destination address required") \ - XX(EEXIST, "file already exists") \ - XX(EFAULT, "bad address in system call argument") \ - XX(EFBIG, "file too large") \ - XX(EHOSTUNREACH, "host is unreachable") \ - XX(EINTR, "interrupted system call") \ - XX(EINVAL, "invalid argument") \ - XX(EIO, "i/o error") \ - XX(EISCONN, "socket is already connected") \ - XX(EISDIR, "illegal operation on a directory") \ - XX(ELOOP, "too many symbolic links encountered") \ - XX(EMFILE, "too many open files") \ - XX(EMSGSIZE, "message too long") \ - XX(ENAMETOOLONG, "name too long") \ - XX(ENETDOWN, "network is down") \ - XX(ENETUNREACH, "network is unreachable") \ - XX(ENFILE, "file table overflow") \ - XX(ENOBUFS, "no buffer space available") \ - XX(ENODEV, "no such device") \ - XX(ENOENT, "no such file or directory") \ - XX(ENOMEM, "not enough memory") \ - XX(ENONET, "machine is not on the network") \ - XX(ENOPROTOOPT, "protocol not available") \ - XX(ENOSPC, "no space left on device") \ - XX(ENOSYS, "function not implemented") \ - XX(ENOTCONN, "socket is not connected") \ - XX(ENOTDIR, "not a directory") \ - XX(ENOTEMPTY, "directory not empty") \ - XX(ENOTSOCK, "socket operation on non-socket") \ - XX(ENOTSUP, "operation not supported on socket") \ - XX(EPERM, "operation not permitted") \ - XX(EPIPE, "broken pipe") \ - XX(EPROTO, "protocol error") \ - XX(EPROTONOSUPPORT, "protocol not supported") \ - XX(EPROTOTYPE, "protocol wrong type for socket") \ - XX(ERANGE, "result too large") \ - XX(EROFS, "read-only file system") \ - XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \ - XX(ESPIPE, "invalid seek") \ - XX(ESRCH, "no such process") \ - XX(ETIMEDOUT, "connection timed out") \ - XX(ETXTBSY, "text file is busy") \ - XX(EXDEV, "cross-device link not permitted") \ - XX(UNKNOWN, "unknown error") \ - XX(EOF, "end of file") \ - XX(ENXIO, "no such device or address") \ - XX(EMLINK, "too many links") \ - XX(EHOSTDOWN, "host is down") \ - -#define UV_HANDLE_TYPE_MAP(XX) \ - XX(ASYNC, async) \ - XX(CHECK, check) \ - XX(FS_EVENT, fs_event) \ - XX(FS_POLL, fs_poll) \ - XX(HANDLE, handle) \ - XX(IDLE, idle) \ - XX(NAMED_PIPE, pipe) \ - XX(POLL, poll) \ - XX(PREPARE, prepare) \ - XX(PROCESS, process) \ - XX(STREAM, stream) \ - XX(TCP, tcp) \ - XX(TIMER, timer) \ - XX(TTY, tty) \ - XX(UDP, udp) \ - XX(SIGNAL, signal) \ - -#define UV_REQ_TYPE_MAP(XX) \ - XX(REQ, req) \ - XX(CONNECT, connect) \ - XX(WRITE, write) \ - XX(SHUTDOWN, shutdown) \ - XX(UDP_SEND, udp_send) \ - XX(FS, fs) \ - XX(WORK, work) \ - XX(GETADDRINFO, getaddrinfo) \ - XX(GETNAMEINFO, getnameinfo) \ - -typedef enum { -#define XX(code, _) UV_ ## code = UV__ ## code, - UV_ERRNO_MAP(XX) -#undef XX - UV_ERRNO_MAX = UV__EOF - 1 -} uv_errno_t; - -typedef enum { - UV_UNKNOWN_HANDLE = 0, -#define XX(uc, lc) UV_##uc, - UV_HANDLE_TYPE_MAP(XX) -#undef XX - UV_FILE, - UV_HANDLE_TYPE_MAX -} uv_handle_type; - -typedef enum { - UV_UNKNOWN_REQ = 0, -#define XX(uc, lc) UV_##uc, - UV_REQ_TYPE_MAP(XX) -#undef XX - UV_REQ_TYPE_PRIVATE - UV_REQ_TYPE_MAX -} uv_req_type; - - -/* Handle types. */ -typedef struct uv_loop_s uv_loop_t; -typedef struct uv_handle_s uv_handle_t; -typedef struct uv_stream_s uv_stream_t; -typedef struct uv_tcp_s uv_tcp_t; -typedef struct uv_udp_s uv_udp_t; -typedef struct uv_pipe_s uv_pipe_t; -typedef struct uv_tty_s uv_tty_t; -typedef struct uv_poll_s uv_poll_t; -typedef struct uv_timer_s uv_timer_t; -typedef struct uv_prepare_s uv_prepare_t; -typedef struct uv_check_s uv_check_t; -typedef struct uv_idle_s uv_idle_t; -typedef struct uv_async_s uv_async_t; -typedef struct uv_process_s uv_process_t; -typedef struct uv_fs_event_s uv_fs_event_t; -typedef struct uv_fs_poll_s uv_fs_poll_t; -typedef struct uv_signal_s uv_signal_t; - -/* Request types. */ -typedef struct uv_req_s uv_req_t; -typedef struct uv_getaddrinfo_s uv_getaddrinfo_t; -typedef struct uv_getnameinfo_s uv_getnameinfo_t; -typedef struct uv_shutdown_s uv_shutdown_t; -typedef struct uv_write_s uv_write_t; -typedef struct uv_connect_s uv_connect_t; -typedef struct uv_udp_send_s uv_udp_send_t; -typedef struct uv_fs_s uv_fs_t; -typedef struct uv_work_s uv_work_t; - -/* None of the above. */ -typedef struct uv_cpu_info_s uv_cpu_info_t; -typedef struct uv_interface_address_s uv_interface_address_t; -typedef struct uv_dirent_s uv_dirent_t; - -typedef enum { - UV_LOOP_BLOCK_SIGNAL -} uv_loop_option; - -typedef enum { - UV_RUN_DEFAULT = 0, - UV_RUN_ONCE, - UV_RUN_NOWAIT -} uv_run_mode; - - -UV_EXTERN unsigned int uv_version(void); -UV_EXTERN const char* uv_version_string(void); - -typedef void* (*uv_malloc_func)(size_t size); -typedef void* (*uv_realloc_func)(void* ptr, size_t size); -typedef void* (*uv_calloc_func)(size_t count, size_t size); -typedef void (*uv_free_func)(void* ptr); - -UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func, - uv_realloc_func realloc_func, - uv_calloc_func calloc_func, - uv_free_func free_func); - -UV_EXTERN uv_loop_t* uv_default_loop(void); -UV_EXTERN int uv_loop_init(uv_loop_t* loop); -UV_EXTERN int uv_loop_close(uv_loop_t* loop); -/* - * NOTE: - * This function is DEPRECATED (to be removed after 0.12), users should - * allocate the loop manually and use uv_loop_init instead. - */ -UV_EXTERN uv_loop_t* uv_loop_new(void); -/* - * NOTE: - * This function is DEPRECATED (to be removed after 0.12). Users should use - * uv_loop_close and free the memory manually instead. - */ -UV_EXTERN void uv_loop_delete(uv_loop_t*); -UV_EXTERN size_t uv_loop_size(void); -UV_EXTERN int uv_loop_alive(const uv_loop_t* loop); -UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...); - -UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); -UV_EXTERN void uv_stop(uv_loop_t*); - -UV_EXTERN void uv_ref(uv_handle_t*); -UV_EXTERN void uv_unref(uv_handle_t*); -UV_EXTERN int uv_has_ref(const uv_handle_t*); - -UV_EXTERN void uv_update_time(uv_loop_t*); -UV_EXTERN uint64_t uv_now(const uv_loop_t*); - -UV_EXTERN int uv_backend_fd(const uv_loop_t*); -UV_EXTERN int uv_backend_timeout(const uv_loop_t*); - -typedef void (*uv_alloc_cb)(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf); -typedef void (*uv_read_cb)(uv_stream_t* stream, - ssize_t nread, - const uv_buf_t* buf); -typedef void (*uv_write_cb)(uv_write_t* req, int status); -typedef void (*uv_connect_cb)(uv_connect_t* req, int status); -typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status); -typedef void (*uv_connection_cb)(uv_stream_t* server, int status); -typedef void (*uv_close_cb)(uv_handle_t* handle); -typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events); -typedef void (*uv_timer_cb)(uv_timer_t* handle); -typedef void (*uv_async_cb)(uv_async_t* handle); -typedef void (*uv_prepare_cb)(uv_prepare_t* handle); -typedef void (*uv_check_cb)(uv_check_t* handle); -typedef void (*uv_idle_cb)(uv_idle_t* handle); -typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal); -typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg); -typedef void (*uv_fs_cb)(uv_fs_t* req); -typedef void (*uv_work_cb)(uv_work_t* req); -typedef void (*uv_after_work_cb)(uv_work_t* req, int status); -typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, - int status, - struct addrinfo* res); -typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, - int status, - const char* hostname, - const char* service); - -typedef struct { - long tv_sec; - long tv_nsec; -} uv_timespec_t; - - -typedef struct { - uint64_t st_dev; - uint64_t st_mode; - uint64_t st_nlink; - uint64_t st_uid; - uint64_t st_gid; - uint64_t st_rdev; - uint64_t st_ino; - uint64_t st_size; - uint64_t st_blksize; - uint64_t st_blocks; - uint64_t st_flags; - uint64_t st_gen; - uv_timespec_t st_atim; - uv_timespec_t st_mtim; - uv_timespec_t st_ctim; - uv_timespec_t st_birthtim; -} uv_stat_t; - - -typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, - const char* filename, - int events, - int status); - -typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, - int status, - const uv_stat_t* prev, - const uv_stat_t* curr); - -typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum); - - -typedef enum { - UV_LEAVE_GROUP = 0, - UV_JOIN_GROUP -} uv_membership; - - -UV_EXTERN const char* uv_strerror(int err); -UV_EXTERN const char* uv_err_name(int err); - - -#define UV_REQ_FIELDS \ - /* public */ \ - void* data; \ - /* read-only */ \ - uv_req_type type; \ - /* private */ \ - void* active_queue[2]; \ - void* reserved[4]; \ - UV_REQ_PRIVATE_FIELDS \ - -/* Abstract base class of all requests. */ -struct uv_req_s { - UV_REQ_FIELDS -}; - - -/* Platform-specific request types. */ -UV_PRIVATE_REQ_TYPES - - -UV_EXTERN int uv_shutdown(uv_shutdown_t* req, - uv_stream_t* handle, - uv_shutdown_cb cb); - -struct uv_shutdown_s { - UV_REQ_FIELDS - uv_stream_t* handle; - uv_shutdown_cb cb; - UV_SHUTDOWN_PRIVATE_FIELDS -}; - - -#define UV_HANDLE_FIELDS \ - /* public */ \ - void* data; \ - /* read-only */ \ - uv_loop_t* loop; \ - uv_handle_type type; \ - /* private */ \ - uv_close_cb close_cb; \ - void* handle_queue[2]; \ - union { \ - int fd; \ - void* reserved[4]; \ - } u; \ - UV_HANDLE_PRIVATE_FIELDS \ - -/* The abstract base class of all handles. */ -struct uv_handle_s { - UV_HANDLE_FIELDS -}; - -UV_EXTERN size_t uv_handle_size(uv_handle_type type); -UV_EXTERN size_t uv_req_size(uv_req_type type); - -UV_EXTERN int uv_is_active(const uv_handle_t* handle); - -UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg); - -UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb); - -UV_EXTERN int uv_send_buffer_size(uv_handle_t* handle, int* value); -UV_EXTERN int uv_recv_buffer_size(uv_handle_t* handle, int* value); - -UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd); - -UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len); - - -#define UV_STREAM_FIELDS \ - /* number of bytes queued for writing */ \ - size_t write_queue_size; \ - uv_alloc_cb alloc_cb; \ - uv_read_cb read_cb; \ - /* private */ \ - UV_STREAM_PRIVATE_FIELDS - -/* - * uv_stream_t is a subclass of uv_handle_t. - * - * uv_stream is an abstract class. - * - * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t. - */ -struct uv_stream_s { - UV_HANDLE_FIELDS - UV_STREAM_FIELDS -}; - -UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb); -UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client); - -UV_EXTERN int uv_read_start(uv_stream_t*, - uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -UV_EXTERN int uv_read_stop(uv_stream_t*); - -UV_EXTERN int uv_write(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb); -UV_EXTERN int uv_write2(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb); -UV_EXTERN int uv_try_write(uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs); - -/* uv_write_t is a subclass of uv_req_t. */ -struct uv_write_s { - UV_REQ_FIELDS - uv_write_cb cb; - uv_stream_t* send_handle; - uv_stream_t* handle; - UV_WRITE_PRIVATE_FIELDS -}; - - -UV_EXTERN int uv_is_readable(const uv_stream_t* handle); -UV_EXTERN int uv_is_writable(const uv_stream_t* handle); - -UV_EXTERN int uv_stream_set_blocking(uv_stream_t* handle, int blocking); - -UV_EXTERN int uv_is_closing(const uv_handle_t* handle); - - -/* - * uv_tcp_t is a subclass of uv_stream_t. - * - * Represents a TCP stream or TCP server. - */ -struct uv_tcp_s { - UV_HANDLE_FIELDS - UV_STREAM_FIELDS - UV_TCP_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle); -UV_EXTERN int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, unsigned int flags); -UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock); -UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable); -UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, - int enable, - unsigned int delay); -UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); - -enum uv_tcp_flags { - /* Used with uv_tcp_bind, when an IPv6 address is used. */ - UV_TCP_IPV6ONLY = 1 -}; - -UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int flags); -UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen); -UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen); -UV_EXTERN int uv_tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - uv_connect_cb cb); - -/* uv_connect_t is a subclass of uv_req_t. */ -struct uv_connect_s { - UV_REQ_FIELDS - uv_connect_cb cb; - uv_stream_t* handle; - UV_CONNECT_PRIVATE_FIELDS -}; - - -/* - * UDP support. - */ - -enum uv_udp_flags { - /* Disables dual stack mode. */ - UV_UDP_IPV6ONLY = 1, - /* - * Indicates message was truncated because read buffer was too small. The - * remainder was discarded by the OS. Used in uv_udp_recv_cb. - */ - UV_UDP_PARTIAL = 2, - /* - * Indicates if SO_REUSEADDR will be set when binding the handle. - * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other - * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that - * multiple threads or processes can bind to the same address without error - * (provided they all set the flag) but only the last one to bind will receive - * any traffic, in effect "stealing" the port from the previous listener. - */ - UV_UDP_REUSEADDR = 4 -}; - -typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status); -typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags); - -/* uv_udp_t is a subclass of uv_handle_t. */ -struct uv_udp_s { - UV_HANDLE_FIELDS - /* read-only */ - /* - * Number of bytes queued for sending. This field strictly shows how much - * information is currently queued. - */ - size_t send_queue_size; - /* - * Number of send requests currently in the queue awaiting to be processed. - */ - size_t send_queue_count; - UV_UDP_PRIVATE_FIELDS -}; - -/* uv_udp_send_t is a subclass of uv_req_t. */ -struct uv_udp_send_s { - UV_REQ_FIELDS - uv_udp_t* handle; - uv_udp_send_cb cb; - UV_UDP_SEND_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle); -UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags); -UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock); -UV_EXTERN int uv_udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int flags); - -UV_EXTERN int uv_udp_getsockname(const uv_udp_t* handle, - struct sockaddr* name, - int* namelen); -UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, - const char* multicast_addr, - const char* interface_addr, - uv_membership membership); -UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on); -UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl); -UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle, - const char* interface_addr); -UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on); -UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl); -UV_EXTERN int uv_udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - uv_udp_send_cb send_cb); -UV_EXTERN int uv_udp_try_send(uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr); -UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, - uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb); -UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle); - - -/* - * uv_tty_t is a subclass of uv_stream_t. - * - * Representing a stream for the console. - */ -struct uv_tty_s { - UV_HANDLE_FIELDS - UV_STREAM_FIELDS - UV_TTY_PRIVATE_FIELDS -}; - -typedef enum { - /* Initial/normal terminal mode */ - UV_TTY_MODE_NORMAL, - /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */ - UV_TTY_MODE_RAW, - /* Binary-safe I/O mode for IPC (Unix-only) */ - UV_TTY_MODE_IO -} uv_tty_mode_t; - -UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); -UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode); -UV_EXTERN int uv_tty_reset_mode(void); -UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); - -#ifdef __cplusplus -extern "C++" { - -inline int uv_tty_set_mode(uv_tty_t* handle, int mode) { - return uv_tty_set_mode(handle, static_cast(mode)); -} - -} -#endif - -UV_EXTERN uv_handle_type uv_guess_handle(uv_file file); - -/* - * uv_pipe_t is a subclass of uv_stream_t. - * - * Representing a pipe stream or pipe server. On Windows this is a Named - * Pipe. On Unix this is a Unix domain socket. - */ -struct uv_pipe_s { - UV_HANDLE_FIELDS - UV_STREAM_FIELDS - int ipc; /* non-zero if this pipe is used for passing handles */ - UV_PIPE_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc); -UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file); -UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name); -UV_EXTERN void uv_pipe_connect(uv_connect_t* req, - uv_pipe_t* handle, - const char* name, - uv_connect_cb cb); -UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle, - char* buffer, - size_t* size); -UV_EXTERN int uv_pipe_getpeername(const uv_pipe_t* handle, - char* buffer, - size_t* size); -UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count); -UV_EXTERN int uv_pipe_pending_count(uv_pipe_t* handle); -UV_EXTERN uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle); - - -struct uv_poll_s { - UV_HANDLE_FIELDS - uv_poll_cb poll_cb; - UV_POLL_PRIVATE_FIELDS -}; - -enum uv_poll_event { - UV_READABLE = 1, - UV_WRITABLE = 2 -}; - -UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd); -UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop, - uv_poll_t* handle, - uv_os_sock_t socket); -UV_EXTERN int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb); -UV_EXTERN int uv_poll_stop(uv_poll_t* handle); - - -struct uv_prepare_s { - UV_HANDLE_FIELDS - UV_PREPARE_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare); -UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb); -UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare); - - -struct uv_check_s { - UV_HANDLE_FIELDS - UV_CHECK_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check); -UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb); -UV_EXTERN int uv_check_stop(uv_check_t* check); - - -struct uv_idle_s { - UV_HANDLE_FIELDS - UV_IDLE_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle); -UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb); -UV_EXTERN int uv_idle_stop(uv_idle_t* idle); - - -struct uv_async_s { - UV_HANDLE_FIELDS - UV_ASYNC_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_async_init(uv_loop_t*, - uv_async_t* async, - uv_async_cb async_cb); -UV_EXTERN int uv_async_send(uv_async_t* async); - - -/* - * uv_timer_t is a subclass of uv_handle_t. - * - * Used to get woken up at a specified time in the future. - */ -struct uv_timer_s { - UV_HANDLE_FIELDS - UV_TIMER_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle); -UV_EXTERN int uv_timer_start(uv_timer_t* handle, - uv_timer_cb cb, - uint64_t timeout, - uint64_t repeat); -UV_EXTERN int uv_timer_stop(uv_timer_t* handle); -UV_EXTERN int uv_timer_again(uv_timer_t* handle); -UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat); -UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle); - - -/* - * uv_getaddrinfo_t is a subclass of uv_req_t. - * - * Request object for uv_getaddrinfo. - */ -struct uv_getaddrinfo_s { - UV_REQ_FIELDS - /* read-only */ - uv_loop_t* loop; - /* struct addrinfo* addrinfo is marked as private, but it really isn't. */ - UV_GETADDRINFO_PRIVATE_FIELDS -}; - - -UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop, - uv_getaddrinfo_t* req, - uv_getaddrinfo_cb getaddrinfo_cb, - const char* node, - const char* service, - const struct addrinfo* hints); -UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai); - - -/* -* uv_getnameinfo_t is a subclass of uv_req_t. -* -* Request object for uv_getnameinfo. -*/ -struct uv_getnameinfo_s { - UV_REQ_FIELDS - /* read-only */ - uv_loop_t* loop; - /* host and service are marked as private, but they really aren't. */ - UV_GETNAMEINFO_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_getnameinfo(uv_loop_t* loop, - uv_getnameinfo_t* req, - uv_getnameinfo_cb getnameinfo_cb, - const struct sockaddr* addr, - int flags); - - -/* uv_spawn() options. */ -typedef enum { - UV_IGNORE = 0x00, - UV_CREATE_PIPE = 0x01, - UV_INHERIT_FD = 0x02, - UV_INHERIT_STREAM = 0x04, - - /* - * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE - * determine the direction of flow, from the child process' perspective. Both - * flags may be specified to create a duplex data stream. - */ - UV_READABLE_PIPE = 0x10, - UV_WRITABLE_PIPE = 0x20 -} uv_stdio_flags; - -typedef struct uv_stdio_container_s { - uv_stdio_flags flags; - - union { - uv_stream_t* stream; - int fd; - } data; -} uv_stdio_container_t; - -typedef struct uv_process_options_s { - uv_exit_cb exit_cb; /* Called after the process exits. */ - const char* file; /* Path to program to execute. */ - /* - * Command line arguments. args[0] should be the path to the program. On - * Windows this uses CreateProcess which concatenates the arguments into a - * string this can cause some strange errors. See the note at - * windows_verbatim_arguments. - */ - char** args; - /* - * This will be set as the environ variable in the subprocess. If this is - * NULL then the parents environ will be used. - */ - char** env; - /* - * If non-null this represents a directory the subprocess should execute - * in. Stands for current working directory. - */ - const char* cwd; - /* - * Various flags that control how uv_spawn() behaves. See the definition of - * `enum uv_process_flags` below. - */ - unsigned int flags; - /* - * The `stdio` field points to an array of uv_stdio_container_t structs that - * describe the file descriptors that will be made available to the child - * process. The convention is that stdio[0] points to stdin, fd 1 is used for - * stdout, and fd 2 is stderr. - * - * Note that on windows file descriptors greater than 2 are available to the - * child process only if the child processes uses the MSVCRT runtime. - */ - int stdio_count; - uv_stdio_container_t* stdio; - /* - * Libuv can change the child process' user/group id. This happens only when - * the appropriate bits are set in the flags fields. This is not supported on - * windows; uv_spawn() will fail and set the error to UV_ENOTSUP. - */ - uv_uid_t uid; - uv_gid_t gid; -} uv_process_options_t; - -/* - * These are the flags that can be used for the uv_process_options.flags field. - */ -enum uv_process_flags { - /* - * Set the child process' user id. The user id is supplied in the `uid` field - * of the options struct. This does not work on windows; setting this flag - * will cause uv_spawn() to fail. - */ - UV_PROCESS_SETUID = (1 << 0), - /* - * Set the child process' group id. The user id is supplied in the `gid` - * field of the options struct. This does not work on windows; setting this - * flag will cause uv_spawn() to fail. - */ - UV_PROCESS_SETGID = (1 << 1), - /* - * Do not wrap any arguments in quotes, or perform any other escaping, when - * converting the argument list into a command line string. This option is - * only meaningful on Windows systems. On Unix it is silently ignored. - */ - UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), - /* - * Spawn the child process in a detached state - this will make it a process - * group leader, and will effectively enable the child to keep running after - * the parent exits. Note that the child process will still keep the - * parent's event loop alive unless the parent process calls uv_unref() on - * the child's process handle. - */ - UV_PROCESS_DETACHED = (1 << 3), - /* - * Hide the subprocess console window that would normally be created. This - * option is only meaningful on Windows systems. On Unix it is silently - * ignored. - */ - UV_PROCESS_WINDOWS_HIDE = (1 << 4) -}; - -/* - * uv_process_t is a subclass of uv_handle_t. - */ -struct uv_process_s { - UV_HANDLE_FIELDS - uv_exit_cb exit_cb; - int pid; - UV_PROCESS_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_spawn(uv_loop_t* loop, - uv_process_t* handle, - const uv_process_options_t* options); -UV_EXTERN int uv_process_kill(uv_process_t*, int signum); -UV_EXTERN int uv_kill(int pid, int signum); - - -/* - * uv_work_t is a subclass of uv_req_t. - */ -struct uv_work_s { - UV_REQ_FIELDS - uv_loop_t* loop; - uv_work_cb work_cb; - uv_after_work_cb after_work_cb; - UV_WORK_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_queue_work(uv_loop_t* loop, - uv_work_t* req, - uv_work_cb work_cb, - uv_after_work_cb after_work_cb); - -UV_EXTERN int uv_cancel(uv_req_t* req); - - -struct uv_cpu_info_s { - char* model; - int speed; - struct uv_cpu_times_s { - uint64_t user; - uint64_t nice; - uint64_t sys; - uint64_t idle; - uint64_t irq; - } cpu_times; -}; - -struct uv_interface_address_s { - char* name; - char phys_addr[6]; - int is_internal; - union { - struct sockaddr_in address4; - struct sockaddr_in6 address6; - } address; - union { - struct sockaddr_in netmask4; - struct sockaddr_in6 netmask6; - } netmask; -}; - -typedef enum { - UV_DIRENT_UNKNOWN, - UV_DIRENT_FILE, - UV_DIRENT_DIR, - UV_DIRENT_LINK, - UV_DIRENT_FIFO, - UV_DIRENT_SOCKET, - UV_DIRENT_CHAR, - UV_DIRENT_BLOCK -} uv_dirent_type_t; - -struct uv_dirent_s { - const char* name; - uv_dirent_type_t type; -}; - -UV_EXTERN char** uv_setup_args(int argc, char** argv); -UV_EXTERN int uv_get_process_title(char* buffer, size_t size); -UV_EXTERN int uv_set_process_title(const char* title); -UV_EXTERN int uv_resident_set_memory(size_t* rss); -UV_EXTERN int uv_uptime(double* uptime); - -typedef struct { - long tv_sec; - long tv_usec; -} uv_timeval_t; - -typedef struct { - uv_timeval_t ru_utime; /* user CPU time used */ - uv_timeval_t ru_stime; /* system CPU time used */ - uint64_t ru_maxrss; /* maximum resident set size */ - uint64_t ru_ixrss; /* integral shared memory size */ - uint64_t ru_idrss; /* integral unshared data size */ - uint64_t ru_isrss; /* integral unshared stack size */ - uint64_t ru_minflt; /* page reclaims (soft page faults) */ - uint64_t ru_majflt; /* page faults (hard page faults) */ - uint64_t ru_nswap; /* swaps */ - uint64_t ru_inblock; /* block input operations */ - uint64_t ru_oublock; /* block output operations */ - uint64_t ru_msgsnd; /* IPC messages sent */ - uint64_t ru_msgrcv; /* IPC messages received */ - uint64_t ru_nsignals; /* signals received */ - uint64_t ru_nvcsw; /* voluntary context switches */ - uint64_t ru_nivcsw; /* involuntary context switches */ -} uv_rusage_t; - -UV_EXTERN int uv_getrusage(uv_rusage_t* rusage); - -UV_EXTERN int uv_os_homedir(char* buffer, size_t* size); - -UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count); -UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count); - -UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses, - int* count); -UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count); - - -typedef enum { - UV_FS_UNKNOWN = -1, - UV_FS_CUSTOM, - UV_FS_OPEN, - UV_FS_CLOSE, - UV_FS_READ, - UV_FS_WRITE, - UV_FS_SENDFILE, - UV_FS_STAT, - UV_FS_LSTAT, - UV_FS_FSTAT, - UV_FS_FTRUNCATE, - UV_FS_UTIME, - UV_FS_FUTIME, - UV_FS_ACCESS, - UV_FS_CHMOD, - UV_FS_FCHMOD, - UV_FS_FSYNC, - UV_FS_FDATASYNC, - UV_FS_UNLINK, - UV_FS_RMDIR, - UV_FS_MKDIR, - UV_FS_MKDTEMP, - UV_FS_RENAME, - UV_FS_SCANDIR, - UV_FS_LINK, - UV_FS_SYMLINK, - UV_FS_READLINK, - UV_FS_CHOWN, - UV_FS_FCHOWN -} uv_fs_type; - -/* uv_fs_t is a subclass of uv_req_t. */ -struct uv_fs_s { - UV_REQ_FIELDS - uv_fs_type fs_type; - uv_loop_t* loop; - uv_fs_cb cb; - ssize_t result; - void* ptr; - const char* path; - uv_stat_t statbuf; /* Stores the result of uv_fs_stat() and uv_fs_fstat(). */ - UV_FS_PRIVATE_FIELDS -}; - -UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req); -UV_EXTERN int uv_fs_close(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - uv_fs_cb cb); -UV_EXTERN int uv_fs_open(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - int mode, - uv_fs_cb cb); -UV_EXTERN int uv_fs_read(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t offset, - uv_fs_cb cb); -UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_fs_cb cb); -UV_EXTERN int uv_fs_write(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t offset, - uv_fs_cb cb); -UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int mode, - uv_fs_cb cb); -UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop, - uv_fs_t* req, - const char* tpl, - uv_fs_cb cb); -UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_fs_cb cb); -UV_EXTERN int uv_fs_scandir(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - uv_fs_cb cb); -UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req, - uv_dirent_t* ent); -UV_EXTERN int uv_fs_stat(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_fs_cb cb); -UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - uv_fs_cb cb); -UV_EXTERN int uv_fs_rename(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - uv_fs_cb cb); -UV_EXTERN int uv_fs_fsync(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - uv_fs_cb cb); -UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - uv_fs_cb cb); -UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - int64_t offset, - uv_fs_cb cb); -UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, - uv_fs_t* req, - uv_file out_fd, - uv_file in_fd, - int64_t in_offset, - size_t length, - uv_fs_cb cb); -UV_EXTERN int uv_fs_access(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int mode, - uv_fs_cb cb); -UV_EXTERN int uv_fs_chmod(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int mode, - uv_fs_cb cb); -UV_EXTERN int uv_fs_utime(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - double atime, - double mtime, - uv_fs_cb cb); -UV_EXTERN int uv_fs_futime(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - double atime, - double mtime, - uv_fs_cb cb); -UV_EXTERN int uv_fs_lstat(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_fs_cb cb); -UV_EXTERN int uv_fs_link(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - uv_fs_cb cb); - -/* - * This flag can be used with uv_fs_symlink() on Windows to specify whether - * path argument points to a directory. - */ -#define UV_FS_SYMLINK_DIR 0x0001 - -/* - * This flag can be used with uv_fs_symlink() on Windows to specify whether - * the symlink is to be created using junction points. - */ -#define UV_FS_SYMLINK_JUNCTION 0x0002 - -UV_EXTERN int uv_fs_symlink(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - int flags, - uv_fs_cb cb); -UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_fs_cb cb); -UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - int mode, - uv_fs_cb cb); -UV_EXTERN int uv_fs_chown(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_uid_t uid, - uv_gid_t gid, - uv_fs_cb cb); -UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - uv_uid_t uid, - uv_gid_t gid, - uv_fs_cb cb); - - -enum uv_fs_event { - UV_RENAME = 1, - UV_CHANGE = 2 -}; - - -struct uv_fs_event_s { - UV_HANDLE_FIELDS - /* private */ - char* path; - UV_FS_EVENT_PRIVATE_FIELDS -}; - - -/* - * uv_fs_stat() based polling file watcher. - */ -struct uv_fs_poll_s { - UV_HANDLE_FIELDS - /* Private, don't touch. */ - void* poll_ctx; -}; - -UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle); -UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle, - uv_fs_poll_cb poll_cb, - const char* path, - unsigned int interval); -UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle); -UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, - char* buffer, - size_t* size); - - -struct uv_signal_s { - UV_HANDLE_FIELDS - uv_signal_cb signal_cb; - int signum; - UV_SIGNAL_PRIVATE_FIELDS -}; - -UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle); -UV_EXTERN int uv_signal_start(uv_signal_t* handle, - uv_signal_cb signal_cb, - int signum); -UV_EXTERN int uv_signal_stop(uv_signal_t* handle); - -UV_EXTERN void uv_loadavg(double avg[3]); - - -/* - * Flags to be passed to uv_fs_event_start(). - */ -enum uv_fs_event_flags { - /* - * By default, if the fs event watcher is given a directory name, we will - * watch for all events in that directory. This flags overrides this behavior - * and makes fs_event report only changes to the directory entry itself. This - * flag does not affect individual files watched. - * This flag is currently not implemented yet on any backend. - */ - UV_FS_EVENT_WATCH_ENTRY = 1, - - /* - * By default uv_fs_event will try to use a kernel interface such as inotify - * or kqueue to detect events. This may not work on remote filesystems such - * as NFS mounts. This flag makes fs_event fall back to calling stat() on a - * regular interval. - * This flag is currently not implemented yet on any backend. - */ - UV_FS_EVENT_STAT = 2, - - /* - * By default, event watcher, when watching directory, is not registering - * (is ignoring) changes in it's subdirectories. - * This flag will override this behaviour on platforms that support it. - */ - UV_FS_EVENT_RECURSIVE = 4 -}; - - -UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle); -UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* path, - unsigned int flags); -UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle); -UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle, - char* buffer, - size_t* size); - -UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr); -UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr); - -UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size); -UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size); - -UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); -UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); - -UV_EXTERN int uv_exepath(char* buffer, size_t* size); - -UV_EXTERN int uv_cwd(char* buffer, size_t* size); - -UV_EXTERN int uv_chdir(const char* dir); - -UV_EXTERN uint64_t uv_get_free_memory(void); -UV_EXTERN uint64_t uv_get_total_memory(void); - -UV_EXTERN extern uint64_t uv_hrtime(void); - -UV_EXTERN void uv_disable_stdio_inheritance(void); - -UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib); -UV_EXTERN void uv_dlclose(uv_lib_t* lib); -UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr); -UV_EXTERN const char* uv_dlerror(const uv_lib_t* lib); - -UV_EXTERN int uv_mutex_init(uv_mutex_t* handle); -UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle); -UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle); -UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle); -UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle); - -UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock); -UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock); -UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock); -UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock); -UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t* rwlock); -UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock); -UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock); -UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock); - -UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value); -UV_EXTERN void uv_sem_destroy(uv_sem_t* sem); -UV_EXTERN void uv_sem_post(uv_sem_t* sem); -UV_EXTERN void uv_sem_wait(uv_sem_t* sem); -UV_EXTERN int uv_sem_trywait(uv_sem_t* sem); - -UV_EXTERN int uv_cond_init(uv_cond_t* cond); -UV_EXTERN void uv_cond_destroy(uv_cond_t* cond); -UV_EXTERN void uv_cond_signal(uv_cond_t* cond); -UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond); - -UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count); -UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier); -UV_EXTERN int uv_barrier_wait(uv_barrier_t* barrier); - -UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex); -UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, - uint64_t timeout); - -UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void)); - -UV_EXTERN int uv_key_create(uv_key_t* key); -UV_EXTERN void uv_key_delete(uv_key_t* key); -UV_EXTERN void* uv_key_get(uv_key_t* key); -UV_EXTERN void uv_key_set(uv_key_t* key, void* value); - -typedef void (*uv_thread_cb)(void* arg); - -UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg); -UV_EXTERN uv_thread_t uv_thread_self(void); -UV_EXTERN int uv_thread_join(uv_thread_t *tid); -UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2); - -/* The presence of these unions force similar struct layout. */ -#define XX(_, name) uv_ ## name ## _t name; -union uv_any_handle { - UV_HANDLE_TYPE_MAP(XX) -}; - -union uv_any_req { - UV_REQ_TYPE_MAP(XX) -}; -#undef XX - - -struct uv_loop_s { - /* User data - use this for whatever. */ - void* data; - /* Loop reference counting. */ - unsigned int active_handles; - void* handle_queue[2]; - void* active_reqs[2]; - /* Internal flag to signal loop stop. */ - unsigned int stop_flag; - UV_LOOP_PRIVATE_FIELDS -}; - - -/* Don't export the private CPP symbols. */ -#undef UV_HANDLE_TYPE_PRIVATE -#undef UV_REQ_TYPE_PRIVATE -#undef UV_REQ_PRIVATE_FIELDS -#undef UV_STREAM_PRIVATE_FIELDS -#undef UV_TCP_PRIVATE_FIELDS -#undef UV_PREPARE_PRIVATE_FIELDS -#undef UV_CHECK_PRIVATE_FIELDS -#undef UV_IDLE_PRIVATE_FIELDS -#undef UV_ASYNC_PRIVATE_FIELDS -#undef UV_TIMER_PRIVATE_FIELDS -#undef UV_GETADDRINFO_PRIVATE_FIELDS -#undef UV_GETNAMEINFO_PRIVATE_FIELDS -#undef UV_FS_REQ_PRIVATE_FIELDS -#undef UV_WORK_PRIVATE_FIELDS -#undef UV_FS_EVENT_PRIVATE_FIELDS -#undef UV_SIGNAL_PRIVATE_FIELDS -#undef UV_LOOP_PRIVATE_FIELDS -#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS - -#ifdef __cplusplus -} -#endif -#endif /* UV_H */ diff --git a/outside/libuv-v1.7.5/libuv.nsi b/outside/libuv-v1.7.5/libuv.nsi deleted file mode 100644 index 159756e196..0000000000 --- a/outside/libuv-v1.7.5/libuv.nsi +++ /dev/null @@ -1,86 +0,0 @@ -; NSIS installer script for libuv - -!include "MUI2.nsh" - -Name "libuv" -OutFile "libuv-${ARCH}-${VERSION}.exe" - -!include "x64.nsh" -# Default install location, for 32-bit files -InstallDir "$PROGRAMFILES\libuv" - -# Override install and registry locations if this is a 64-bit install. -function .onInit - ${If} ${ARCH} == "x64" - SetRegView 64 - StrCpy $INSTDIR "$PROGRAMFILES64\libuv" - ${EndIf} -functionEnd - -;-------------------------------- -; Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH - - -;-------------------------------- -; Uninstaller pages -!insertmacro MUI_UNPAGE_WELCOME -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES -!insertmacro MUI_UNPAGE_FINISH - -;-------------------------------- -; Languages -!insertmacro MUI_LANGUAGE "English" - -;-------------------------------- -; Installer sections - -Section "Files" SecInstall - SectionIn RO - SetOutPath "$INSTDIR" - File "Release\*.dll" - File "Release\*.lib" - File "LICENSE" - File "README.md" - - SetOutPath "$INSTDIR\include" - File "include\uv.h" - File "include\uv-errno.h" - File "include\uv-threadpool.h" - File "include\uv-version.h" - File "include\uv-win.h" - File "include\tree.h" - - WriteUninstaller "$INSTDIR\Uninstall.exe" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "DisplayName" "libuv-${ARCH}-${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "HelpLink" "http://libuv.org/" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "URLInfoAbout" "http://libuv.org/" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "DisplayVersion" "${VERSION}" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "NoModify" "1" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "NoRepair" "1" -SectionEnd - -Section "Uninstall" - Delete "$INSTDIR\libuv.dll" - Delete "$INSTDIR\libuv.lib" - Delete "$INSTDIR\LICENSE" - Delete "$INSTDIR\README.md" - - Delete "$INSTDIR\include\uv.h" - Delete "$INSTDIR\include\uv-errno.h" - Delete "$INSTDIR\include\uv-threadpool.h" - Delete "$INSTDIR\include\uv-version.h" - Delete "$INSTDIR\include\uv-win.h" - Delete "$INSTDIR\include\tree.h" - - Delete "$INSTDIR\Uninstall.exe" - RMDir "$INSTDIR" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" -SectionEnd - diff --git a/outside/libuv-v1.7.5/libuv.pc.in b/outside/libuv-v1.7.5/libuv.pc.in deleted file mode 100644 index 2933ec2252..0000000000 --- a/outside/libuv-v1.7.5/libuv.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: @PACKAGE_NAME@ -Version: @PACKAGE_VERSION@ -Description: multi-platform support library with a focus on asynchronous I/O. - -Libs: -L${libdir} -luv @LIBS@ -Cflags: -I${includedir} diff --git a/outside/libuv-v1.7.5/m4/.gitignore b/outside/libuv-v1.7.5/m4/.gitignore deleted file mode 100644 index c44e4c2929..0000000000 --- a/outside/libuv-v1.7.5/m4/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore libtoolize-generated files. -*.m4 -!as_case.m4 -!libuv-check-flags.m4 diff --git a/outside/libuv-v1.7.5/m4/as_case.m4 b/outside/libuv-v1.7.5/m4/as_case.m4 deleted file mode 100644 index c7ae0f0f5e..0000000000 --- a/outside/libuv-v1.7.5/m4/as_case.m4 +++ /dev/null @@ -1,21 +0,0 @@ -# AS_CASE(WORD, [PATTERN1], [IF-MATCHED1]...[DEFAULT]) -# ---------------------------------------------------- -# Expand into -# | case WORD in -# | PATTERN1) IF-MATCHED1 ;; -# | ... -# | *) DEFAULT ;; -# | esac -m4_define([_AS_CASE], -[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], - [$#], 1, [ *) $1 ;;], - [$#], 2, [ $1) m4_default([$2], [:]) ;;], - [ $1) m4_default([$2], [:]) ;; -$0(m4_shiftn(2, $@))])dnl -]) -m4_defun([AS_CASE], -[m4_ifval([$2$3], -[case $1 in -_AS_CASE(m4_shift($@)) -esac])]) - diff --git a/outside/libuv-v1.7.5/m4/libuv-check-flags.m4 b/outside/libuv-v1.7.5/m4/libuv-check-flags.m4 deleted file mode 100644 index 59c3063557..0000000000 --- a/outside/libuv-v1.7.5/m4/libuv-check-flags.m4 +++ /dev/null @@ -1,319 +0,0 @@ -dnl Macros to check the presence of generic (non-typed) symbols. -dnl Copyright (c) 2006-2008 Diego Pettenà -dnl Copyright (c) 2006-2008 xine project -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -dnl 02110-1301, USA. -dnl -dnl As a special exception, the copyright owners of the -dnl macro gives unlimited permission to copy, distribute and modify the -dnl configure scripts that are the output of Autoconf when processing the -dnl Macro. You need not follow the terms of the GNU General Public -dnl License when using or distributing such scripts, even though portions -dnl of the text of the Macro appear in them. The GNU General Public -dnl License (GPL) does govern all other use of the material that -dnl constitutes the Autoconf Macro. -dnl -dnl This special exception to the GPL applies to versions of the -dnl Autoconf Macro released by this project. When you make and -dnl distribute a modified version of the Autoconf Macro, you may extend -dnl this special exception to the GPL to apply to your modified version as -dnl well. - -dnl Check if the flag is supported by compiler -dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) - -AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ - AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), - [ac_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $1" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])], - [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], - [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) - CFLAGS="$ac_save_CFLAGS" - ]) - - AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], - [$2], [$3]) -]) - -dnl Check if the flag is supported by compiler (cacheable) -dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) - -AC_DEFUN([CC_CHECK_CFLAGS], [ - AC_CACHE_CHECK([if $CC supports $1 flag], - AS_TR_SH([cc_cv_cflags_$1]), - CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! - ) - - AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], - [$2], [$3]) -]) - -dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) -dnl Check for CFLAG and appends them to CFLAGS if supported -AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ - AC_CACHE_CHECK([if $CC supports $1 flag], - AS_TR_SH([cc_cv_cflags_$1]), - CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! - ) - - AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], - [CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3]) -]) - -dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) -AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ - for flag in $1; do - CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) - done -]) - -dnl Check if the flag is supported by linker (cacheable) -dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) - -AC_DEFUN([CC_CHECK_LDFLAGS], [ - AC_CACHE_CHECK([if $CC supports $1 flag], - AS_TR_SH([cc_cv_ldflags_$1]), - [ac_save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $1" - AC_LANG_PUSH([C]) - AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])], - [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], - [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) - AC_LANG_POP([C]) - LDFLAGS="$ac_save_LDFLAGS" - ]) - - AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], - [$2], [$3]) -]) - -dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for -dnl the current linker to avoid undefined references in a shared object. -AC_DEFUN([CC_NOUNDEFINED], [ - dnl We check $host for which systems to enable this for. - AC_REQUIRE([AC_CANONICAL_HOST]) - - case $host in - dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads - dnl are requested, as different implementations are present; to avoid problems - dnl use -Wl,-z,defs only for those platform not behaving this way. - *-freebsd* | *-openbsd*) ;; - *) - dnl First of all check for the --no-undefined variant of GNU ld. This allows - dnl for a much more readable commandline, so that people can understand what - dnl it does without going to look for what the heck -z defs does. - for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do - CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) - break - done - ;; - esac - - AC_SUBST([LDFLAGS_NOUNDEFINED]) -]) - -dnl Check for a -Werror flag or equivalent. -Werror is the GCC -dnl and ICC flag that tells the compiler to treat all the warnings -dnl as fatal. We usually need this option to make sure that some -dnl constructs (like attributes) are not simply ignored. -dnl -dnl Other compilers don't support -Werror per se, but they support -dnl an equivalent flag: -dnl - Sun Studio compiler supports -errwarn=%all -AC_DEFUN([CC_CHECK_WERROR], [ - AC_CACHE_CHECK( - [for $CC way to treat warnings as errors], - [cc_cv_werror], - [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], - [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) - ]) -]) - -AC_DEFUN([CC_CHECK_ATTRIBUTE], [ - AC_REQUIRE([CC_CHECK_WERROR]) - AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], - AS_TR_SH([cc_cv_attribute_$1]), - [ac_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $cc_cv_werror" - AC_LANG_PUSH([C]) - AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], - [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], - [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) - AC_LANG_POP([C]) - CFLAGS="$ac_save_CFLAGS" - ]) - - AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], - [AC_DEFINE( - AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, - [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] - ) - $4], - [$5]) -]) - -AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ - CC_CHECK_ATTRIBUTE( - [constructor],, - [void __attribute__((constructor)) ctor() { int a; }], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ - CC_CHECK_ATTRIBUTE( - [format], [format(printf, n, n)], - [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ - CC_CHECK_ATTRIBUTE( - [format_arg], [format_arg(printf)], - [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ - CC_CHECK_ATTRIBUTE( - [visibility_$1], [visibility("$1")], - [void __attribute__((visibility("$1"))) $1_function() { }], - [$2], [$3]) -]) - -AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ - CC_CHECK_ATTRIBUTE( - [nonnull], [nonnull()], - [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ - CC_CHECK_ATTRIBUTE( - [unused], , - [void some_function(void *foo, __attribute__((unused)) void *bar);], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ - CC_CHECK_ATTRIBUTE( - [sentinel], , - [void some_function(void *foo, ...) __attribute__((sentinel));], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ - CC_CHECK_ATTRIBUTE( - [deprecated], , - [void some_function(void *foo, ...) __attribute__((deprecated));], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ - CC_CHECK_ATTRIBUTE( - [alias], [weak, alias], - [void other_function(void *foo) { } - void some_function(void *foo) __attribute__((weak, alias("other_function")));], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ - CC_CHECK_ATTRIBUTE( - [malloc], , - [void * __attribute__((malloc)) my_alloc(int n);], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_PACKED], [ - CC_CHECK_ATTRIBUTE( - [packed], , - [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], - [$1], [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_CONST], [ - CC_CHECK_ATTRIBUTE( - [const], , - [int __attribute__((const)) twopow(int n) { return 1 << n; } ], - [$1], [$2]) -]) - -AC_DEFUN([CC_FLAG_VISIBILITY], [ - AC_REQUIRE([CC_CHECK_WERROR]) - AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], - [cc_cv_flag_visibility], - [cc_flag_visibility_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $cc_cv_werror" - CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], - cc_cv_flag_visibility='yes', - cc_cv_flag_visibility='no') - CFLAGS="$cc_flag_visibility_save_CFLAGS"]) - - AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], - [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, - [Define this if the compiler supports the -fvisibility flag]) - $1], - [$2]) -]) - -AC_DEFUN([CC_FUNC_EXPECT], [ - AC_REQUIRE([CC_CHECK_WERROR]) - AC_CACHE_CHECK([if compiler has __builtin_expect function], - [cc_cv_func_expect], - [ac_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $cc_cv_werror" - AC_LANG_PUSH([C]) - AC_COMPILE_IFELSE([AC_LANG_SOURCE( - [int some_function() { - int a = 3; - return (int)__builtin_expect(a, 3); - }])], - [cc_cv_func_expect=yes], - [cc_cv_func_expect=no]) - AC_LANG_POP([C]) - CFLAGS="$ac_save_CFLAGS" - ]) - - AS_IF([test "x$cc_cv_func_expect" = "xyes"], - [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, - [Define this if the compiler supports __builtin_expect() function]) - $1], - [$2]) -]) - -AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ - AC_REQUIRE([CC_CHECK_WERROR]) - AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], - [cc_cv_attribute_aligned], - [ac_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $cc_cv_werror" - AC_LANG_PUSH([C]) - for cc_attribute_align_try in 64 32 16 8 4 2; do - AC_COMPILE_IFELSE([AC_LANG_SOURCE([ - int main() { - static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; - return c; - }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) - done - AC_LANG_POP([C]) - CFLAGS="$ac_save_CFLAGS" - ]) - - if test "x$cc_cv_attribute_aligned" != "x"; then - AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], - [Define the highest alignment supported]) - fi -]) \ No newline at end of file diff --git a/outside/libuv-v1.7.5/samples/.gitignore b/outside/libuv-v1.7.5/samples/.gitignore deleted file mode 100644 index f868091ba3..0000000000 --- a/outside/libuv-v1.7.5/samples/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright StrongLoop, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -*.mk -*.Makefile diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/.gitignore b/outside/libuv-v1.7.5/samples/socks5-proxy/.gitignore deleted file mode 100644 index c177f37451..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright StrongLoop, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -/build/ diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/LICENSE b/outside/libuv-v1.7.5/samples/socks5-proxy/LICENSE deleted file mode 100644 index 63c1447fc5..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/LICENSE +++ /dev/null @@ -1,53 +0,0 @@ -Files: * -======== - -Copyright StrongLoop, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. - - -Files: getopt.c -=============== - -Copyright (c) 1987, 1993, 1994 -The Regents of the University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/Makefile b/outside/libuv-v1.7.5/samples/socks5-proxy/Makefile deleted file mode 100644 index ca43985ec8..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright StrongLoop, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -BUILDTYPE ?= Debug -BUILDDIR ?= build -GYP ?= gyp -V ?= - -SOURCES := client.c defs.h getopt.c main.c s5.c s5.h server.c util.c - -.PHONY: all clean - -all: $(BUILDDIR)/$(BUILDTYPE)/s5-proxy - -clean: - $(RM) $(BUILDDIR) - -$(BUILDDIR)/$(BUILDTYPE)/s5-proxy: $(BUILDDIR)/Makefile $(SOURCES) - $(MAKE) -C $(BUILDDIR) V=$(V) - -$(BUILDDIR)/Makefile: ../../common.gypi build.gyp - $(GYP) \ - -Duv_library=static_library \ - -Goutput_dir=. \ - -I../../common.gypi \ - -f make \ - --depth=. \ - --generator-output=$(BUILDDIR) \ - build.gyp diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/build.gyp b/outside/libuv-v1.7.5/samples/socks5-proxy/build.gyp deleted file mode 100644 index 771a1e146d..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/build.gyp +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright StrongLoop, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -{ - 'targets': [ - { - 'dependencies': ['../../uv.gyp:libuv'], - 'target_name': 's5-proxy', - 'type': 'executable', - 'sources': [ - 'client.c', - 'defs.h', - 'main.c', - 's5.c', - 's5.h', - 'server.c', - 'util.c', - ], - 'conditions': [ - ['OS=="win"', { - 'defines': ['HAVE_UNISTD_H=0'], - 'sources': ['getopt.c'] - }, { - 'defines': ['HAVE_UNISTD_H=1'] - }] - ] - } - ] -} diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/client.c b/outside/libuv-v1.7.5/samples/socks5-proxy/client.c deleted file mode 100644 index ae9913a1c6..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/client.c +++ /dev/null @@ -1,737 +0,0 @@ -/* Copyright StrongLoop, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "defs.h" -#include -#include -#include - -/* A connection is modeled as an abstraction on top of two simple state - * machines, one for reading and one for writing. Either state machine - * is, when active, in one of three states: busy, done or stop; the fourth - * and final state, dead, is an end state and only relevant when shutting - * down the connection. A short overview: - * - * busy done stop - * ----------|---------------------------|--------------------|------| - * readable | waiting for incoming data | have incoming data | idle | - * writable | busy writing out data | completed write | idle | - * - * We could remove the done state from the writable state machine. For our - * purposes, it's functionally equivalent to the stop state. - * - * When the connection with upstream has been established, the client_ctx - * moves into a state where incoming data from the client is sent upstream - * and vice versa, incoming data from upstream is sent to the client. In - * other words, we're just piping data back and forth. See conn_cycle() - * for details. - * - * An interesting deviation from libuv's I/O model is that reads are discrete - * rather than continuous events. In layman's terms, when a read operation - * completes, the connection stops reading until further notice. - * - * The rationale for this approach is that we have to wait until the data - * has been sent out again before we can reuse the read buffer. - * - * It also pleasingly unifies with the request model that libuv uses for - * writes and everything else; libuv may switch to a request model for - * reads in the future. - */ -enum conn_state { - c_busy, /* Busy; waiting for incoming data or for a write to complete. */ - c_done, /* Done; read incoming data or write finished. */ - c_stop, /* Stopped. */ - c_dead -}; - -/* Session states. */ -enum sess_state { - s_handshake, /* Wait for client handshake. */ - s_handshake_auth, /* Wait for client authentication data. */ - s_req_start, /* Start waiting for request data. */ - s_req_parse, /* Wait for request data. */ - s_req_lookup, /* Wait for upstream hostname DNS lookup to complete. */ - s_req_connect, /* Wait for uv_tcp_connect() to complete. */ - s_proxy_start, /* Connected. Start piping data. */ - s_proxy, /* Connected. Pipe data back and forth. */ - s_kill, /* Tear down session. */ - s_almost_dead_0, /* Waiting for finalizers to complete. */ - s_almost_dead_1, /* Waiting for finalizers to complete. */ - s_almost_dead_2, /* Waiting for finalizers to complete. */ - s_almost_dead_3, /* Waiting for finalizers to complete. */ - s_almost_dead_4, /* Waiting for finalizers to complete. */ - s_dead /* Dead. Safe to free now. */ -}; - -static void do_next(client_ctx *cx); -static int do_handshake(client_ctx *cx); -static int do_handshake_auth(client_ctx *cx); -static int do_req_start(client_ctx *cx); -static int do_req_parse(client_ctx *cx); -static int do_req_lookup(client_ctx *cx); -static int do_req_connect_start(client_ctx *cx); -static int do_req_connect(client_ctx *cx); -static int do_proxy_start(client_ctx *cx); -static int do_proxy(client_ctx *cx); -static int do_kill(client_ctx *cx); -static int do_almost_dead(client_ctx *cx); -static int conn_cycle(const char *who, conn *a, conn *b); -static void conn_timer_reset(conn *c); -static void conn_timer_expire(uv_timer_t *handle, int status); -static void conn_getaddrinfo(conn *c, const char *hostname); -static void conn_getaddrinfo_done(uv_getaddrinfo_t *req, - int status, - struct addrinfo *ai); -static int conn_connect(conn *c); -static void conn_connect_done(uv_connect_t *req, int status); -static void conn_read(conn *c); -static void conn_read_done(uv_stream_t *handle, - ssize_t nread, - const uv_buf_t *buf); -static void conn_alloc(uv_handle_t *handle, size_t size, uv_buf_t *buf); -static void conn_write(conn *c, const void *data, unsigned int len); -static void conn_write_done(uv_write_t *req, int status); -static void conn_close(conn *c); -static void conn_close_done(uv_handle_t *handle); - -/* |incoming| has been initialized by server.c when this is called. */ -void client_finish_init(server_ctx *sx, client_ctx *cx) { - conn *incoming; - conn *outgoing; - - cx->sx = sx; - cx->state = s_handshake; - s5_init(&cx->parser); - - incoming = &cx->incoming; - incoming->client = cx; - incoming->result = 0; - incoming->rdstate = c_stop; - incoming->wrstate = c_stop; - incoming->idle_timeout = sx->idle_timeout; - CHECK(0 == uv_timer_init(sx->loop, &incoming->timer_handle)); - - outgoing = &cx->outgoing; - outgoing->client = cx; - outgoing->result = 0; - outgoing->rdstate = c_stop; - outgoing->wrstate = c_stop; - outgoing->idle_timeout = sx->idle_timeout; - CHECK(0 == uv_tcp_init(cx->sx->loop, &outgoing->handle.tcp)); - CHECK(0 == uv_timer_init(cx->sx->loop, &outgoing->timer_handle)); - - /* Wait for the initial packet. */ - conn_read(incoming); -} - -/* This is the core state machine that drives the client <-> upstream proxy. - * We move through the initial handshake and authentication steps first and - * end up (if all goes well) in the proxy state where we're just proxying - * data between the client and upstream. - */ -static void do_next(client_ctx *cx) { - int new_state; - - ASSERT(cx->state != s_dead); - switch (cx->state) { - case s_handshake: - new_state = do_handshake(cx); - break; - case s_handshake_auth: - new_state = do_handshake_auth(cx); - break; - case s_req_start: - new_state = do_req_start(cx); - break; - case s_req_parse: - new_state = do_req_parse(cx); - break; - case s_req_lookup: - new_state = do_req_lookup(cx); - break; - case s_req_connect: - new_state = do_req_connect(cx); - break; - case s_proxy_start: - new_state = do_proxy_start(cx); - break; - case s_proxy: - new_state = do_proxy(cx); - break; - case s_kill: - new_state = do_kill(cx); - break; - case s_almost_dead_0: - case s_almost_dead_1: - case s_almost_dead_2: - case s_almost_dead_3: - case s_almost_dead_4: - new_state = do_almost_dead(cx); - break; - default: - UNREACHABLE(); - } - cx->state = new_state; - - if (cx->state == s_dead) { - if (DEBUG_CHECKS) { - memset(cx, -1, sizeof(*cx)); - } - free(cx); - } -} - -static int do_handshake(client_ctx *cx) { - unsigned int methods; - conn *incoming; - s5_ctx *parser; - uint8_t *data; - size_t size; - int err; - - parser = &cx->parser; - incoming = &cx->incoming; - ASSERT(incoming->rdstate == c_done); - ASSERT(incoming->wrstate == c_stop); - incoming->rdstate = c_stop; - - if (incoming->result < 0) { - pr_err("read error: %s", uv_strerror(incoming->result)); - return do_kill(cx); - } - - data = (uint8_t *) incoming->t.buf; - size = (size_t) incoming->result; - err = s5_parse(parser, &data, &size); - if (err == s5_ok) { - conn_read(incoming); - return s_handshake; /* Need more data. */ - } - - if (size != 0) { - /* Could allow a round-trip saving shortcut here if the requested auth - * method is S5_AUTH_NONE (provided unauthenticated traffic is allowed.) - * Requires client support however. - */ - pr_err("junk in handshake"); - return do_kill(cx); - } - - if (err != s5_auth_select) { - pr_err("handshake error: %s", s5_strerror(err)); - return do_kill(cx); - } - - methods = s5_auth_methods(parser); - if ((methods & S5_AUTH_NONE) && can_auth_none(cx->sx, cx)) { - s5_select_auth(parser, S5_AUTH_NONE); - conn_write(incoming, "\5\0", 2); /* No auth required. */ - return s_req_start; - } - - if ((methods & S5_AUTH_PASSWD) && can_auth_passwd(cx->sx, cx)) { - /* TODO(bnoordhuis) Implement username/password auth. */ - } - - conn_write(incoming, "\5\377", 2); /* No acceptable auth. */ - return s_kill; -} - -/* TODO(bnoordhuis) Implement username/password auth. */ -static int do_handshake_auth(client_ctx *cx) { - UNREACHABLE(); - return do_kill(cx); -} - -static int do_req_start(client_ctx *cx) { - conn *incoming; - - incoming = &cx->incoming; - ASSERT(incoming->rdstate == c_stop); - ASSERT(incoming->wrstate == c_done); - incoming->wrstate = c_stop; - - if (incoming->result < 0) { - pr_err("write error: %s", uv_strerror(incoming->result)); - return do_kill(cx); - } - - conn_read(incoming); - return s_req_parse; -} - -static int do_req_parse(client_ctx *cx) { - conn *incoming; - conn *outgoing; - s5_ctx *parser; - uint8_t *data; - size_t size; - int err; - - parser = &cx->parser; - incoming = &cx->incoming; - outgoing = &cx->outgoing; - ASSERT(incoming->rdstate == c_done); - ASSERT(incoming->wrstate == c_stop); - ASSERT(outgoing->rdstate == c_stop); - ASSERT(outgoing->wrstate == c_stop); - incoming->rdstate = c_stop; - - if (incoming->result < 0) { - pr_err("read error: %s", uv_strerror(incoming->result)); - return do_kill(cx); - } - - data = (uint8_t *) incoming->t.buf; - size = (size_t) incoming->result; - err = s5_parse(parser, &data, &size); - if (err == s5_ok) { - conn_read(incoming); - return s_req_parse; /* Need more data. */ - } - - if (size != 0) { - pr_err("junk in request %u", (unsigned) size); - return do_kill(cx); - } - - if (err != s5_exec_cmd) { - pr_err("request error: %s", s5_strerror(err)); - return do_kill(cx); - } - - if (parser->cmd == s5_cmd_tcp_bind) { - /* Not supported but relatively straightforward to implement. */ - pr_warn("BIND requests are not supported."); - return do_kill(cx); - } - - if (parser->cmd == s5_cmd_udp_assoc) { - /* Not supported. Might be hard to implement because libuv has no - * functionality for detecting the MTU size which the RFC mandates. - */ - pr_warn("UDP ASSOC requests are not supported."); - return do_kill(cx); - } - ASSERT(parser->cmd == s5_cmd_tcp_connect); - - if (parser->atyp == s5_atyp_host) { - conn_getaddrinfo(outgoing, (const char *) parser->daddr); - return s_req_lookup; - } - - if (parser->atyp == s5_atyp_ipv4) { - memset(&outgoing->t.addr4, 0, sizeof(outgoing->t.addr4)); - outgoing->t.addr4.sin_family = AF_INET; - outgoing->t.addr4.sin_port = htons(parser->dport); - memcpy(&outgoing->t.addr4.sin_addr, - parser->daddr, - sizeof(outgoing->t.addr4.sin_addr)); - } else if (parser->atyp == s5_atyp_ipv6) { - memset(&outgoing->t.addr6, 0, sizeof(outgoing->t.addr6)); - outgoing->t.addr6.sin6_family = AF_INET6; - outgoing->t.addr6.sin6_port = htons(parser->dport); - memcpy(&outgoing->t.addr6.sin6_addr, - parser->daddr, - sizeof(outgoing->t.addr6.sin6_addr)); - } else { - UNREACHABLE(); - } - - return do_req_connect_start(cx); -} - -static int do_req_lookup(client_ctx *cx) { - s5_ctx *parser; - conn *incoming; - conn *outgoing; - - parser = &cx->parser; - incoming = &cx->incoming; - outgoing = &cx->outgoing; - ASSERT(incoming->rdstate == c_stop); - ASSERT(incoming->wrstate == c_stop); - ASSERT(outgoing->rdstate == c_stop); - ASSERT(outgoing->wrstate == c_stop); - - if (outgoing->result < 0) { - /* TODO(bnoordhuis) Escape control characters in parser->daddr. */ - pr_err("lookup error for \"%s\": %s", - parser->daddr, - uv_strerror(outgoing->result)); - /* Send back a 'Host unreachable' reply. */ - conn_write(incoming, "\5\4\0\1\0\0\0\0\0\0", 10); - return s_kill; - } - - /* Don't make assumptions about the offset of sin_port/sin6_port. */ - switch (outgoing->t.addr.sa_family) { - case AF_INET: - outgoing->t.addr4.sin_port = htons(parser->dport); - break; - case AF_INET6: - outgoing->t.addr6.sin6_port = htons(parser->dport); - break; - default: - UNREACHABLE(); - } - - return do_req_connect_start(cx); -} - -/* Assumes that cx->outgoing.t.sa contains a valid AF_INET/AF_INET6 address. */ -static int do_req_connect_start(client_ctx *cx) { - conn *incoming; - conn *outgoing; - int err; - - incoming = &cx->incoming; - outgoing = &cx->outgoing; - ASSERT(incoming->rdstate == c_stop); - ASSERT(incoming->wrstate == c_stop); - ASSERT(outgoing->rdstate == c_stop); - ASSERT(outgoing->wrstate == c_stop); - - if (!can_access(cx->sx, cx, &outgoing->t.addr)) { - pr_warn("connection not allowed by ruleset"); - /* Send a 'Connection not allowed by ruleset' reply. */ - conn_write(incoming, "\5\2\0\1\0\0\0\0\0\0", 10); - return s_kill; - } - - err = conn_connect(outgoing); - if (err != 0) { - pr_err("connect error: %s\n", uv_strerror(err)); - return do_kill(cx); - } - - return s_req_connect; -} - -static int do_req_connect(client_ctx *cx) { - const struct sockaddr_in6 *in6; - const struct sockaddr_in *in; - char addr_storage[sizeof(*in6)]; - conn *incoming; - conn *outgoing; - uint8_t *buf; - int addrlen; - - incoming = &cx->incoming; - outgoing = &cx->outgoing; - ASSERT(incoming->rdstate == c_stop); - ASSERT(incoming->wrstate == c_stop); - ASSERT(outgoing->rdstate == c_stop); - ASSERT(outgoing->wrstate == c_stop); - - /* Build and send the reply. Not very pretty but gets the job done. */ - buf = (uint8_t *) incoming->t.buf; - if (outgoing->result == 0) { - /* The RFC mandates that the SOCKS server must include the local port - * and address in the reply. So that's what we do. - */ - addrlen = sizeof(addr_storage); - CHECK(0 == uv_tcp_getsockname(&outgoing->handle.tcp, - (struct sockaddr *) addr_storage, - &addrlen)); - buf[0] = 5; /* Version. */ - buf[1] = 0; /* Success. */ - buf[2] = 0; /* Reserved. */ - if (addrlen == sizeof(*in)) { - buf[3] = 1; /* IPv4. */ - in = (const struct sockaddr_in *) &addr_storage; - memcpy(buf + 4, &in->sin_addr, 4); - memcpy(buf + 8, &in->sin_port, 2); - conn_write(incoming, buf, 10); - } else if (addrlen == sizeof(*in6)) { - buf[3] = 4; /* IPv6. */ - in6 = (const struct sockaddr_in6 *) &addr_storage; - memcpy(buf + 4, &in6->sin6_addr, 16); - memcpy(buf + 20, &in6->sin6_port, 2); - conn_write(incoming, buf, 22); - } else { - UNREACHABLE(); - } - return s_proxy_start; - } else { - pr_err("upstream connection error: %s\n", uv_strerror(outgoing->result)); - /* Send a 'Connection refused' reply. */ - conn_write(incoming, "\5\5\0\1\0\0\0\0\0\0", 10); - return s_kill; - } - - UNREACHABLE(); - return s_kill; -} - -static int do_proxy_start(client_ctx *cx) { - conn *incoming; - conn *outgoing; - - incoming = &cx->incoming; - outgoing = &cx->outgoing; - ASSERT(incoming->rdstate == c_stop); - ASSERT(incoming->wrstate == c_done); - ASSERT(outgoing->rdstate == c_stop); - ASSERT(outgoing->wrstate == c_stop); - incoming->wrstate = c_stop; - - if (incoming->result < 0) { - pr_err("write error: %s", uv_strerror(incoming->result)); - return do_kill(cx); - } - - conn_read(incoming); - conn_read(outgoing); - return s_proxy; -} - -/* Proxy incoming data back and forth. */ -static int do_proxy(client_ctx *cx) { - if (conn_cycle("client", &cx->incoming, &cx->outgoing)) { - return do_kill(cx); - } - - if (conn_cycle("upstream", &cx->outgoing, &cx->incoming)) { - return do_kill(cx); - } - - return s_proxy; -} - -static int do_kill(client_ctx *cx) { - int new_state; - - if (cx->state >= s_almost_dead_0) { - return cx->state; - } - - /* Try to cancel the request. The callback still runs but if the - * cancellation succeeded, it gets called with status=UV_ECANCELED. - */ - new_state = s_almost_dead_1; - if (cx->state == s_req_lookup) { - new_state = s_almost_dead_0; - uv_cancel(&cx->outgoing.t.req); - } - - conn_close(&cx->incoming); - conn_close(&cx->outgoing); - return new_state; -} - -static int do_almost_dead(client_ctx *cx) { - ASSERT(cx->state >= s_almost_dead_0); - return cx->state + 1; /* Another finalizer completed. */ -} - -static int conn_cycle(const char *who, conn *a, conn *b) { - if (a->result < 0) { - if (a->result != UV_EOF) { - pr_err("%s error: %s", who, uv_strerror(a->result)); - } - return -1; - } - - if (b->result < 0) { - return -1; - } - - if (a->wrstate == c_done) { - a->wrstate = c_stop; - } - - /* The logic is as follows: read when we don't write and write when we don't - * read. That gives us back-pressure handling for free because if the peer - * sends data faster than we consume it, TCP congestion control kicks in. - */ - if (a->wrstate == c_stop) { - if (b->rdstate == c_stop) { - conn_read(b); - } else if (b->rdstate == c_done) { - conn_write(a, b->t.buf, b->result); - b->rdstate = c_stop; /* Triggers the call to conn_read() above. */ - } - } - - return 0; -} - -static void conn_timer_reset(conn *c) { - CHECK(0 == uv_timer_start(&c->timer_handle, - conn_timer_expire, - c->idle_timeout, - 0)); -} - -static void conn_timer_expire(uv_timer_t *handle, int status) { - conn *c; - - CHECK(0 == status); - c = CONTAINER_OF(handle, conn, timer_handle); - c->result = UV_ETIMEDOUT; - do_next(c->client); -} - -static void conn_getaddrinfo(conn *c, const char *hostname) { - struct addrinfo hints; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - CHECK(0 == uv_getaddrinfo(c->client->sx->loop, - &c->t.addrinfo_req, - conn_getaddrinfo_done, - hostname, - NULL, - &hints)); - conn_timer_reset(c); -} - -static void conn_getaddrinfo_done(uv_getaddrinfo_t *req, - int status, - struct addrinfo *ai) { - conn *c; - - c = CONTAINER_OF(req, conn, t.addrinfo_req); - c->result = status; - - if (status == 0) { - /* FIXME(bnoordhuis) Should try all addresses. */ - if (ai->ai_family == AF_INET) { - c->t.addr4 = *(const struct sockaddr_in *) ai->ai_addr; - } else if (ai->ai_family == AF_INET6) { - c->t.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr; - } else { - UNREACHABLE(); - } - } - - uv_freeaddrinfo(ai); - do_next(c->client); -} - -/* Assumes that c->t.sa contains a valid AF_INET or AF_INET6 address. */ -static int conn_connect(conn *c) { - ASSERT(c->t.addr.sa_family == AF_INET || - c->t.addr.sa_family == AF_INET6); - conn_timer_reset(c); - return uv_tcp_connect(&c->t.connect_req, - &c->handle.tcp, - &c->t.addr, - conn_connect_done); -} - -static void conn_connect_done(uv_connect_t *req, int status) { - conn *c; - - if (status == UV_ECANCELED) { - return; /* Handle has been closed. */ - } - - c = CONTAINER_OF(req, conn, t.connect_req); - c->result = status; - do_next(c->client); -} - -static void conn_read(conn *c) { - ASSERT(c->rdstate == c_stop); - CHECK(0 == uv_read_start(&c->handle.stream, conn_alloc, conn_read_done)); - c->rdstate = c_busy; - conn_timer_reset(c); -} - -static void conn_read_done(uv_stream_t *handle, - ssize_t nread, - const uv_buf_t *buf) { - conn *c; - - c = CONTAINER_OF(handle, conn, handle); - ASSERT(c->t.buf == buf->base); - ASSERT(c->rdstate == c_busy); - c->rdstate = c_done; - c->result = nread; - - uv_read_stop(&c->handle.stream); - do_next(c->client); -} - -static void conn_alloc(uv_handle_t *handle, size_t size, uv_buf_t *buf) { - conn *c; - - c = CONTAINER_OF(handle, conn, handle); - ASSERT(c->rdstate == c_busy); - buf->base = c->t.buf; - buf->len = sizeof(c->t.buf); -} - -static void conn_write(conn *c, const void *data, unsigned int len) { - uv_buf_t buf; - - ASSERT(c->wrstate == c_stop || c->wrstate == c_done); - c->wrstate = c_busy; - - /* It's okay to cast away constness here, uv_write() won't modify the - * memory. - */ - buf.base = (char *) data; - buf.len = len; - - CHECK(0 == uv_write(&c->write_req, - &c->handle.stream, - &buf, - 1, - conn_write_done)); - conn_timer_reset(c); -} - -static void conn_write_done(uv_write_t *req, int status) { - conn *c; - - if (status == UV_ECANCELED) { - return; /* Handle has been closed. */ - } - - c = CONTAINER_OF(req, conn, write_req); - ASSERT(c->wrstate == c_busy); - c->wrstate = c_done; - c->result = status; - do_next(c->client); -} - -static void conn_close(conn *c) { - ASSERT(c->rdstate != c_dead); - ASSERT(c->wrstate != c_dead); - c->rdstate = c_dead; - c->wrstate = c_dead; - c->timer_handle.data = c; - c->handle.handle.data = c; - uv_close(&c->handle.handle, conn_close_done); - uv_close((uv_handle_t *) &c->timer_handle, conn_close_done); -} - -static void conn_close_done(uv_handle_t *handle) { - conn *c; - - c = handle->data; - do_next(c->client); -} diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/defs.h b/outside/libuv-v1.7.5/samples/socks5-proxy/defs.h deleted file mode 100644 index 99ee8160c8..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/defs.h +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright StrongLoop, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef DEFS_H_ -#define DEFS_H_ - -#include "s5.h" -#include "uv.h" - -#include -#include /* sockaddr_in, sockaddr_in6 */ -#include /* size_t, ssize_t */ -#include -#include /* sockaddr */ - -struct client_ctx; - -typedef struct { - const char *bind_host; - unsigned short bind_port; - unsigned int idle_timeout; -} server_config; - -typedef struct { - unsigned int idle_timeout; /* Connection idle timeout in ms. */ - uv_tcp_t tcp_handle; - uv_loop_t *loop; -} server_ctx; - -typedef struct { - unsigned char rdstate; - unsigned char wrstate; - unsigned int idle_timeout; - struct client_ctx *client; /* Backlink to owning client context. */ - ssize_t result; - union { - uv_handle_t handle; - uv_stream_t stream; - uv_tcp_t tcp; - uv_udp_t udp; - } handle; - uv_timer_t timer_handle; /* For detecting timeouts. */ - uv_write_t write_req; - /* We only need one of these at a time so make them share memory. */ - union { - uv_getaddrinfo_t addrinfo_req; - uv_connect_t connect_req; - uv_req_t req; - struct sockaddr_in6 addr6; - struct sockaddr_in addr4; - struct sockaddr addr; - char buf[2048]; /* Scratch space. Used to read data into. */ - } t; -} conn; - -typedef struct client_ctx { - unsigned int state; - server_ctx *sx; /* Backlink to owning server context. */ - s5_ctx parser; /* The SOCKS protocol parser. */ - conn incoming; /* Connection with the SOCKS client. */ - conn outgoing; /* Connection with upstream. */ -} client_ctx; - -/* server.c */ -int server_run(const server_config *cf, uv_loop_t *loop); -int can_auth_none(const server_ctx *sx, const client_ctx *cx); -int can_auth_passwd(const server_ctx *sx, const client_ctx *cx); -int can_access(const server_ctx *sx, - const client_ctx *cx, - const struct sockaddr *addr); - -/* client.c */ -void client_finish_init(server_ctx *sx, client_ctx *cx); - -/* util.c */ -#if defined(__GNUC__) -# define ATTRIBUTE_FORMAT_PRINTF(a, b) __attribute__((format(printf, a, b))) -#else -# define ATTRIBUTE_FORMAT_PRINTF(a, b) -#endif -void pr_info(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2); -void pr_warn(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2); -void pr_err(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2); -void *xmalloc(size_t size); - -/* main.c */ -const char *_getprogname(void); - -/* getopt.c */ -#if !HAVE_UNISTD_H -extern char *optarg; -int getopt(int argc, char **argv, const char *options); -#endif - -/* ASSERT() is for debug checks, CHECK() for run-time sanity checks. - * DEBUG_CHECKS is for expensive debug checks that we only want to - * enable in debug builds but still want type-checked by the compiler - * in release builds. - */ -#if defined(NDEBUG) -# define ASSERT(exp) -# define CHECK(exp) do { if (!(exp)) abort(); } while (0) -# define DEBUG_CHECKS (0) -#else -# define ASSERT(exp) assert(exp) -# define CHECK(exp) assert(exp) -# define DEBUG_CHECKS (1) -#endif - -#define UNREACHABLE() CHECK(!"Unreachable code reached.") - -/* This macro looks complicated but it's not: it calculates the address - * of the embedding struct through the address of the embedded struct. - * In other words, if struct A embeds struct B, then we can obtain - * the address of A by taking the address of B and subtracting the - * field offset of B in A. - */ -#define CONTAINER_OF(ptr, type, field) \ - ((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field))) - -#endif /* DEFS_H_ */ diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/getopt.c b/outside/libuv-v1.7.5/samples/socks5-proxy/getopt.c deleted file mode 100644 index 8481b2264f..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/getopt.c +++ /dev/null @@ -1,131 +0,0 @@ -/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */ - -/* - * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include -#include - -extern const char *_getprogname(void); - -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt, /* character checked for validity */ - optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -getopt(nargc, nargv, ostr) - int nargc; - char * const nargv[]; - const char *ostr; -{ - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - if (optreset || *place == 0) { /* update scanning pointer */ - optreset = 0; - place = nargv[optind]; - if (optind >= nargc || *place++ != '-') { - /* Argument is absent or is not an option */ - place = EMSG; - return (-1); - } - optopt = *place++; - if (optopt == '-' && *place == 0) { - /* "--" => end of options */ - ++optind; - place = EMSG; - return (-1); - } - if (optopt == 0) { - /* Solitary '-', treat as a '-' option - if the program (eg su) is looking for it. */ - place = EMSG; - if (strchr(ostr, '-') == NULL) - return (-1); - optopt = '-'; - } - } else - optopt = *place++; - - /* See if option letter is one the caller wanted... */ - if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) { - if (*place == 0) - ++optind; - if (opterr && *ostr != ':') - (void)fprintf(stderr, - "%s: illegal option -- %c\n", _getprogname(), - optopt); - return (BADCH); - } - - /* Does this option need an argument? */ - if (oli[1] != ':') { - /* don't need argument */ - optarg = NULL; - if (*place == 0) - ++optind; - } else { - /* Option-argument is either the rest of this argument or the - entire next argument. */ - if (*place) - optarg = place; - else if (nargc > ++optind) - optarg = nargv[optind]; - else { - /* option-argument absent */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - _getprogname(), optopt); - return (BADCH); - } - place = EMSG; - ++optind; - } - return (optopt); /* return option letter */ -} diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/main.c b/outside/libuv-v1.7.5/samples/socks5-proxy/main.c deleted file mode 100644 index 04020cbd3a..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/main.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright StrongLoop, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "defs.h" -#include -#include -#include - -#if HAVE_UNISTD_H -#include /* getopt */ -#endif - -#define DEFAULT_BIND_HOST "127.0.0.1" -#define DEFAULT_BIND_PORT 1080 -#define DEFAULT_IDLE_TIMEOUT (60 * 1000) - -static void parse_opts(server_config *cf, int argc, char **argv); -static void usage(void); - -static const char *progname = __FILE__; /* Reset in main(). */ - -int main(int argc, char **argv) { - server_config config; - int err; - - progname = argv[0]; - memset(&config, 0, sizeof(config)); - config.bind_host = DEFAULT_BIND_HOST; - config.bind_port = DEFAULT_BIND_PORT; - config.idle_timeout = DEFAULT_IDLE_TIMEOUT; - parse_opts(&config, argc, argv); - - err = server_run(&config, uv_default_loop()); - if (err) { - exit(1); - } - - return 0; -} - -const char *_getprogname(void) { - return progname; -} - -static void parse_opts(server_config *cf, int argc, char **argv) { - int opt; - - while (-1 != (opt = getopt(argc, argv, "H:hp:"))) { - switch (opt) { - case 'H': - cf->bind_host = optarg; - break; - - case 'p': - if (1 != sscanf(optarg, "%hu", &cf->bind_port)) { - pr_err("bad port number: %s", optarg); - usage(); - } - break; - - default: - usage(); - } - } -} - -static void usage(void) { - printf("Usage:\n" - "\n" - " %s [-b

[-h] [-p ]\n" - "\n" - "Options:\n" - "\n" - " -b Bind to this address or hostname.\n" - " Default: \"127.0.0.1\"\n" - " -h Show this help message.\n" - " -p Bind to this port number. Default: 1080\n" - "", - progname); - exit(1); -} diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/s5.c b/outside/libuv-v1.7.5/samples/socks5-proxy/s5.c deleted file mode 100644 index 4f08e34524..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/s5.c +++ /dev/null @@ -1,271 +0,0 @@ -/* Copyright StrongLoop, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "s5.h" -#include -#include -#include /* abort() */ -#include /* memset() */ - -enum { - s5_version, - s5_nmethods, - s5_methods, - s5_auth_pw_version, - s5_auth_pw_userlen, - s5_auth_pw_username, - s5_auth_pw_passlen, - s5_auth_pw_password, - s5_req_version, - s5_req_cmd, - s5_req_reserved, - s5_req_atyp, - s5_req_atyp_host, - s5_req_daddr, - s5_req_dport0, - s5_req_dport1, - s5_dead -}; - -void s5_init(s5_ctx *cx) { - memset(cx, 0, sizeof(*cx)); - cx->state = s5_version; -} - -s5_err s5_parse(s5_ctx *cx, uint8_t **data, size_t *size) { - s5_err err; - uint8_t *p; - uint8_t c; - size_t i; - size_t n; - - p = *data; - n = *size; - i = 0; - - while (i < n) { - c = p[i]; - i += 1; - switch (cx->state) { - case s5_version: - if (c != 5) { - err = s5_bad_version; - goto out; - } - cx->state = s5_nmethods; - break; - - case s5_nmethods: - cx->arg0 = 0; - cx->arg1 = c; /* Number of bytes to read. */ - cx->state = s5_methods; - break; - - case s5_methods: - if (cx->arg0 < cx->arg1) { - switch (c) { - case 0: - cx->methods |= S5_AUTH_NONE; - break; - case 1: - cx->methods |= S5_AUTH_GSSAPI; - break; - case 2: - cx->methods |= S5_AUTH_PASSWD; - break; - /* Ignore everything we don't understand. */ - } - cx->arg0 += 1; - } - if (cx->arg0 == cx->arg1) { - err = s5_auth_select; - goto out; - } - break; - - case s5_auth_pw_version: - if (c != 1) { - err = s5_bad_version; - goto out; - } - cx->state = s5_auth_pw_userlen; - break; - - case s5_auth_pw_userlen: - cx->arg0 = 0; - cx->userlen = c; - cx->state = s5_auth_pw_username; - break; - - case s5_auth_pw_username: - if (cx->arg0 < cx->userlen) { - cx->username[cx->arg0] = c; - cx->arg0 += 1; - } - if (cx->arg0 == cx->userlen) { - cx->username[cx->userlen] = '\0'; - cx->state = s5_auth_pw_passlen; - } - break; - - case s5_auth_pw_passlen: - cx->arg0 = 0; - cx->passlen = c; - cx->state = s5_auth_pw_password; - break; - - case s5_auth_pw_password: - if (cx->arg0 < cx->passlen) { - cx->password[cx->arg0] = c; - cx->arg0 += 1; - } - if (cx->arg0 == cx->passlen) { - cx->password[cx->passlen] = '\0'; - cx->state = s5_req_version; - err = s5_auth_verify; - goto out; - } - break; - - case s5_req_version: - if (c != 5) { - err = s5_bad_version; - goto out; - } - cx->state = s5_req_cmd; - break; - - case s5_req_cmd: - switch (c) { - case 1: /* TCP connect */ - cx->cmd = s5_cmd_tcp_connect; - break; - case 3: /* UDP associate */ - cx->cmd = s5_cmd_udp_assoc; - break; - default: - err = s5_bad_cmd; - goto out; - } - cx->state = s5_req_reserved; - break; - - case s5_req_reserved: - cx->state = s5_req_atyp; - break; - - case s5_req_atyp: - cx->arg0 = 0; - switch (c) { - case 1: /* IPv4, four octets. */ - cx->state = s5_req_daddr; - cx->atyp = s5_atyp_ipv4; - cx->arg1 = 4; - break; - case 3: /* Hostname. First byte is length. */ - cx->state = s5_req_atyp_host; - cx->atyp = s5_atyp_host; - cx->arg1 = 0; - break; - case 4: /* IPv6, sixteen octets. */ - cx->state = s5_req_daddr; - cx->atyp = s5_atyp_ipv6; - cx->arg1 = 16; - break; - default: - err = s5_bad_atyp; - goto out; - } - break; - - case s5_req_atyp_host: - cx->arg1 = c; - cx->state = s5_req_daddr; - break; - - case s5_req_daddr: - if (cx->arg0 < cx->arg1) { - cx->daddr[cx->arg0] = c; - cx->arg0 += 1; - } - if (cx->arg0 == cx->arg1) { - cx->daddr[cx->arg1] = '\0'; - cx->state = s5_req_dport0; - } - break; - - case s5_req_dport0: - cx->dport = c << 8; - cx->state = s5_req_dport1; - break; - - case s5_req_dport1: - cx->dport |= c; - cx->state = s5_dead; - err = s5_exec_cmd; - goto out; - - case s5_dead: - break; - - default: - abort(); - } - } - err = s5_ok; - -out: - *data = p + i; - *size = n - i; - return err; -} - -unsigned int s5_auth_methods(const s5_ctx *cx) { - return cx->methods; -} - -int s5_select_auth(s5_ctx *cx, s5_auth_method method) { - int err; - - err = 0; - switch (method) { - case S5_AUTH_NONE: - cx->state = s5_req_version; - break; - case S5_AUTH_PASSWD: - cx->state = s5_auth_pw_version; - break; - default: - err = -EINVAL; - } - - return err; -} - -const char *s5_strerror(s5_err err) { -#define S5_ERR_GEN(_, name, errmsg) case s5_ ## name: return errmsg; - switch (err) { - S5_ERR_MAP(S5_ERR_GEN) - default: ; /* Silence s5_max_errors -Wswitch warning. */ - } -#undef S5_ERR_GEN - return "Unknown error."; -} diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/s5.h b/outside/libuv-v1.7.5/samples/socks5-proxy/s5.h deleted file mode 100644 index 715f322287..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/s5.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright StrongLoop, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef S5_H_ -#define S5_H_ - -#include -#include - -#define S5_ERR_MAP(V) \ - V(-1, bad_version, "Bad protocol version.") \ - V(-2, bad_cmd, "Bad protocol command.") \ - V(-3, bad_atyp, "Bad address type.") \ - V(0, ok, "No error.") \ - V(1, auth_select, "Select authentication method.") \ - V(2, auth_verify, "Verify authentication.") \ - V(3, exec_cmd, "Execute command.") \ - -typedef enum { -#define S5_ERR_GEN(code, name, _) s5_ ## name = code, - S5_ERR_MAP(S5_ERR_GEN) -#undef S5_ERR_GEN - s5_max_errors -} s5_err; - -typedef enum { - S5_AUTH_NONE = 1 << 0, - S5_AUTH_GSSAPI = 1 << 1, - S5_AUTH_PASSWD = 1 << 2 -} s5_auth_method; - -typedef enum { - s5_auth_allow, - s5_auth_deny -} s5_auth_result; - -typedef enum { - s5_atyp_ipv4, - s5_atyp_ipv6, - s5_atyp_host -} s5_atyp; - -typedef enum { - s5_cmd_tcp_connect, - s5_cmd_tcp_bind, - s5_cmd_udp_assoc -} s5_cmd; - -typedef struct { - uint32_t arg0; /* Scratch space for the state machine. */ - uint32_t arg1; /* Scratch space for the state machine. */ - uint8_t state; - uint8_t methods; - uint8_t cmd; - uint8_t atyp; - uint8_t userlen; - uint8_t passlen; - uint16_t dport; - uint8_t username[257]; - uint8_t password[257]; - uint8_t daddr[257]; /* TODO(bnoordhuis) Merge with username/password. */ -} s5_ctx; - -void s5_init(s5_ctx *ctx); - -s5_err s5_parse(s5_ctx *cx, uint8_t **data, size_t *size); - -/* Only call after s5_parse() has returned s5_want_auth_method. */ -unsigned int s5_auth_methods(const s5_ctx *cx); - -/* Call after s5_parse() has returned s5_want_auth_method. */ -int s5_select_auth(s5_ctx *cx, s5_auth_method method); - -const char *s5_strerror(s5_err err); - -#endif /* S5_H_ */ diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/server.c b/outside/libuv-v1.7.5/samples/socks5-proxy/server.c deleted file mode 100644 index 3f1ba42c9e..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/server.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright StrongLoop, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "defs.h" -#include /* INET6_ADDRSTRLEN */ -#include -#include - -#ifndef INET6_ADDRSTRLEN -# define INET6_ADDRSTRLEN 63 -#endif - -typedef struct { - uv_getaddrinfo_t getaddrinfo_req; - server_config config; - server_ctx *servers; - uv_loop_t *loop; -} server_state; - -static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *ai); -static void on_connection(uv_stream_t *server, int status); - -int server_run(const server_config *cf, uv_loop_t *loop) { - struct addrinfo hints; - server_state state; - int err; - - memset(&state, 0, sizeof(state)); - state.servers = NULL; - state.config = *cf; - state.loop = loop; - - /* Resolve the address of the interface that we should bind to. - * The getaddrinfo callback starts the server and everything else. - */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - err = uv_getaddrinfo(loop, - &state.getaddrinfo_req, - do_bind, - cf->bind_host, - NULL, - &hints); - if (err != 0) { - pr_err("getaddrinfo: %s", uv_strerror(err)); - return err; - } - - /* Start the event loop. Control continues in do_bind(). */ - if (uv_run(loop, UV_RUN_DEFAULT)) { - abort(); - } - - /* Please Valgrind. */ - uv_loop_delete(loop); - free(state.servers); - return 0; -} - -/* Bind a server to each address that getaddrinfo() reported. */ -static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) { - char addrbuf[INET6_ADDRSTRLEN + 1]; - unsigned int ipv4_naddrs; - unsigned int ipv6_naddrs; - server_state *state; - server_config *cf; - struct addrinfo *ai; - const void *addrv; - const char *what; - uv_loop_t *loop; - server_ctx *sx; - unsigned int n; - int err; - union { - struct sockaddr addr; - struct sockaddr_in addr4; - struct sockaddr_in6 addr6; - } s; - - state = CONTAINER_OF(req, server_state, getaddrinfo_req); - loop = state->loop; - cf = &state->config; - - if (status < 0) { - pr_err("getaddrinfo(\"%s\"): %s", cf->bind_host, uv_strerror(status)); - uv_freeaddrinfo(addrs); - return; - } - - ipv4_naddrs = 0; - ipv6_naddrs = 0; - for (ai = addrs; ai != NULL; ai = ai->ai_next) { - if (ai->ai_family == AF_INET) { - ipv4_naddrs += 1; - } else if (ai->ai_family == AF_INET6) { - ipv6_naddrs += 1; - } - } - - if (ipv4_naddrs == 0 && ipv6_naddrs == 0) { - pr_err("%s has no IPv4/6 addresses", cf->bind_host); - uv_freeaddrinfo(addrs); - return; - } - - state->servers = - xmalloc((ipv4_naddrs + ipv6_naddrs) * sizeof(state->servers[0])); - - n = 0; - for (ai = addrs; ai != NULL; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { - continue; - } - - if (ai->ai_family == AF_INET) { - s.addr4 = *(const struct sockaddr_in *) ai->ai_addr; - s.addr4.sin_port = htons(cf->bind_port); - addrv = &s.addr4.sin_addr; - } else if (ai->ai_family == AF_INET6) { - s.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr; - s.addr6.sin6_port = htons(cf->bind_port); - addrv = &s.addr6.sin6_addr; - } else { - UNREACHABLE(); - } - - if (uv_inet_ntop(s.addr.sa_family, addrv, addrbuf, sizeof(addrbuf))) { - UNREACHABLE(); - } - - sx = state->servers + n; - sx->loop = loop; - sx->idle_timeout = state->config.idle_timeout; - CHECK(0 == uv_tcp_init(loop, &sx->tcp_handle)); - - what = "uv_tcp_bind"; - err = uv_tcp_bind(&sx->tcp_handle, &s.addr, 0); - if (err == 0) { - what = "uv_listen"; - err = uv_listen((uv_stream_t *) &sx->tcp_handle, 128, on_connection); - } - - if (err != 0) { - pr_err("%s(\"%s:%hu\"): %s", - what, - addrbuf, - cf->bind_port, - uv_strerror(err)); - while (n > 0) { - n -= 1; - uv_close((uv_handle_t *) (state->servers + n), NULL); - } - break; - } - - pr_info("listening on %s:%hu", addrbuf, cf->bind_port); - n += 1; - } - - uv_freeaddrinfo(addrs); -} - -static void on_connection(uv_stream_t *server, int status) { - server_ctx *sx; - client_ctx *cx; - - CHECK(status == 0); - sx = CONTAINER_OF(server, server_ctx, tcp_handle); - cx = xmalloc(sizeof(*cx)); - CHECK(0 == uv_tcp_init(sx->loop, &cx->incoming.handle.tcp)); - CHECK(0 == uv_accept(server, &cx->incoming.handle.stream)); - client_finish_init(sx, cx); -} - -int can_auth_none(const server_ctx *sx, const client_ctx *cx) { - return 1; -} - -int can_auth_passwd(const server_ctx *sx, const client_ctx *cx) { - return 0; -} - -int can_access(const server_ctx *sx, - const client_ctx *cx, - const struct sockaddr *addr) { - const struct sockaddr_in6 *addr6; - const struct sockaddr_in *addr4; - const uint32_t *p; - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - - /* TODO(bnoordhuis) Implement proper access checks. For now, just reject - * traffic to localhost. - */ - if (addr->sa_family == AF_INET) { - addr4 = (const struct sockaddr_in *) addr; - d = ntohl(addr4->sin_addr.s_addr); - return (d >> 24) != 0x7F; - } - - if (addr->sa_family == AF_INET6) { - addr6 = (const struct sockaddr_in6 *) addr; - p = (const uint32_t *) &addr6->sin6_addr.s6_addr; - a = ntohl(p[0]); - b = ntohl(p[1]); - c = ntohl(p[2]); - d = ntohl(p[3]); - if (a == 0 && b == 0 && c == 0 && d == 1) { - return 0; /* "::1" style address. */ - } - if (a == 0 && b == 0 && c == 0xFFFF && (d >> 24) == 0x7F) { - return 0; /* "::ffff:127.x.x.x" style address. */ - } - return 1; - } - - return 0; -} diff --git a/outside/libuv-v1.7.5/samples/socks5-proxy/util.c b/outside/libuv-v1.7.5/samples/socks5-proxy/util.c deleted file mode 100644 index af34f05593..0000000000 --- a/outside/libuv-v1.7.5/samples/socks5-proxy/util.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright StrongLoop, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "defs.h" -#include -#include -#include - -static void pr_do(FILE *stream, - const char *label, - const char *fmt, - va_list ap); - -void *xmalloc(size_t size) { - void *ptr; - - ptr = malloc(size); - if (ptr == NULL) { - pr_err("out of memory, need %lu bytes", (unsigned long) size); - exit(1); - } - - return ptr; -} - -void pr_info(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - pr_do(stdout, "info", fmt, ap); - va_end(ap); -} - -void pr_warn(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - pr_do(stderr, "warn", fmt, ap); - va_end(ap); -} - -void pr_err(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - pr_do(stderr, "error", fmt, ap); - va_end(ap); -} - -static void pr_do(FILE *stream, - const char *label, - const char *fmt, - va_list ap) { - char fmtbuf[1024]; - vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap); - fprintf(stream, "%s:%s: %s\n", _getprogname(), label, fmtbuf); -} diff --git a/outside/libuv-v1.7.5/src/fs-poll.c b/outside/libuv-v1.7.5/src/fs-poll.c deleted file mode 100644 index 44d47b88ed..0000000000 --- a/outside/libuv-v1.7.5/src/fs-poll.c +++ /dev/null @@ -1,255 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "uv-common.h" - -#include -#include -#include - -struct poll_ctx { - uv_fs_poll_t* parent_handle; /* NULL if parent has been stopped or closed */ - int busy_polling; - unsigned int interval; - uint64_t start_time; - uv_loop_t* loop; - uv_fs_poll_cb poll_cb; - uv_timer_t timer_handle; - uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */ - uv_stat_t statbuf; - char path[1]; /* variable length */ -}; - -static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b); -static void poll_cb(uv_fs_t* req); -static void timer_cb(uv_timer_t* timer); -static void timer_close_cb(uv_handle_t* handle); - -static uv_stat_t zero_statbuf; - - -int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL); - return 0; -} - - -int uv_fs_poll_start(uv_fs_poll_t* handle, - uv_fs_poll_cb cb, - const char* path, - unsigned int interval) { - struct poll_ctx* ctx; - uv_loop_t* loop; - size_t len; - int err; - - if (uv__is_active(handle)) - return 0; - - loop = handle->loop; - len = strlen(path); - ctx = uv__calloc(1, sizeof(*ctx) + len); - - if (ctx == NULL) - return UV_ENOMEM; - - ctx->loop = loop; - ctx->poll_cb = cb; - ctx->interval = interval ? interval : 1; - ctx->start_time = uv_now(loop); - ctx->parent_handle = handle; - memcpy(ctx->path, path, len + 1); - - err = uv_timer_init(loop, &ctx->timer_handle); - if (err < 0) - goto error; - - ctx->timer_handle.flags |= UV__HANDLE_INTERNAL; - uv__handle_unref(&ctx->timer_handle); - - err = uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb); - if (err < 0) - goto error; - - handle->poll_ctx = ctx; - uv__handle_start(handle); - - return 0; - -error: - uv__free(ctx); - return err; -} - - -int uv_fs_poll_stop(uv_fs_poll_t* handle) { - struct poll_ctx* ctx; - - if (!uv__is_active(handle)) - return 0; - - ctx = handle->poll_ctx; - assert(ctx != NULL); - assert(ctx->parent_handle != NULL); - ctx->parent_handle = NULL; - handle->poll_ctx = NULL; - - /* Close the timer if it's active. If it's inactive, there's a stat request - * in progress and poll_cb will take care of the cleanup. - */ - if (uv__is_active(&ctx->timer_handle)) - uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); - - uv__handle_stop(handle); - - return 0; -} - - -int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) { - struct poll_ctx* ctx; - size_t required_len; - - if (!uv__is_active(handle)) { - *size = 0; - return UV_EINVAL; - } - - ctx = handle->poll_ctx; - assert(ctx != NULL); - - required_len = strlen(ctx->path); - if (required_len > *size) { - *size = required_len; - return UV_ENOBUFS; - } - - memcpy(buffer, ctx->path, required_len); - *size = required_len; - - return 0; -} - - -void uv__fs_poll_close(uv_fs_poll_t* handle) { - uv_fs_poll_stop(handle); -} - - -static void timer_cb(uv_timer_t* timer) { - struct poll_ctx* ctx; - - ctx = container_of(timer, struct poll_ctx, timer_handle); - assert(ctx->parent_handle != NULL); - assert(ctx->parent_handle->poll_ctx == ctx); - ctx->start_time = uv_now(ctx->loop); - - if (uv_fs_stat(ctx->loop, &ctx->fs_req, ctx->path, poll_cb)) - abort(); -} - - -static void poll_cb(uv_fs_t* req) { - uv_stat_t* statbuf; - struct poll_ctx* ctx; - uint64_t interval; - - ctx = container_of(req, struct poll_ctx, fs_req); - - if (ctx->parent_handle == NULL) { /* handle has been stopped or closed */ - uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); - uv_fs_req_cleanup(req); - return; - } - - if (req->result != 0) { - if (ctx->busy_polling != req->result) { - ctx->poll_cb(ctx->parent_handle, - req->result, - &ctx->statbuf, - &zero_statbuf); - ctx->busy_polling = req->result; - } - goto out; - } - - statbuf = &req->statbuf; - - if (ctx->busy_polling != 0) - if (ctx->busy_polling < 0 || !statbuf_eq(&ctx->statbuf, statbuf)) - ctx->poll_cb(ctx->parent_handle, 0, &ctx->statbuf, statbuf); - - ctx->statbuf = *statbuf; - ctx->busy_polling = 1; - -out: - uv_fs_req_cleanup(req); - - if (ctx->parent_handle == NULL) { /* handle has been stopped by callback */ - uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); - return; - } - - /* Reschedule timer, subtract the delay from doing the stat(). */ - interval = ctx->interval; - interval -= (uv_now(ctx->loop) - ctx->start_time) % interval; - - if (uv_timer_start(&ctx->timer_handle, timer_cb, interval, 0)) - abort(); -} - - -static void timer_close_cb(uv_handle_t* handle) { - uv__free(container_of(handle, struct poll_ctx, timer_handle)); -} - - -static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b) { - return a->st_ctim.tv_nsec == b->st_ctim.tv_nsec - && a->st_mtim.tv_nsec == b->st_mtim.tv_nsec - && a->st_birthtim.tv_nsec == b->st_birthtim.tv_nsec - && a->st_ctim.tv_sec == b->st_ctim.tv_sec - && a->st_mtim.tv_sec == b->st_mtim.tv_sec - && a->st_birthtim.tv_sec == b->st_birthtim.tv_sec - && a->st_size == b->st_size - && a->st_mode == b->st_mode - && a->st_uid == b->st_uid - && a->st_gid == b->st_gid - && a->st_ino == b->st_ino - && a->st_dev == b->st_dev - && a->st_flags == b->st_flags - && a->st_gen == b->st_gen; -} - - -#if defined(_WIN32) - -#include "win/internal.h" -#include "win/handle-inl.h" - -void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); -} - -#endif /* _WIN32 */ diff --git a/outside/libuv-v1.7.5/src/heap-inl.h b/outside/libuv-v1.7.5/src/heap-inl.h deleted file mode 100644 index 1e2ed60e09..0000000000 --- a/outside/libuv-v1.7.5/src/heap-inl.h +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright (c) 2013, Ben Noordhuis - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef UV_SRC_HEAP_H_ -#define UV_SRC_HEAP_H_ - -#include /* NULL */ - -#if defined(__GNUC__) -# define HEAP_EXPORT(declaration) __attribute__((unused)) static declaration -#else -# define HEAP_EXPORT(declaration) static declaration -#endif - -struct heap_node { - struct heap_node* left; - struct heap_node* right; - struct heap_node* parent; -}; - -/* A binary min heap. The usual properties hold: the root is the lowest - * element in the set, the height of the tree is at most log2(nodes) and - * it's always a complete binary tree. - * - * The heap function try hard to detect corrupted tree nodes at the cost - * of a minor reduction in performance. Compile with -DNDEBUG to disable. - */ -struct heap { - struct heap_node* min; - unsigned int nelts; -}; - -/* Return non-zero if a < b. */ -typedef int (*heap_compare_fn)(const struct heap_node* a, - const struct heap_node* b); - -/* Public functions. */ -HEAP_EXPORT(void heap_init(struct heap* heap)); -HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap)); -HEAP_EXPORT(void heap_insert(struct heap* heap, - struct heap_node* newnode, - heap_compare_fn less_than)); -HEAP_EXPORT(void heap_remove(struct heap* heap, - struct heap_node* node, - heap_compare_fn less_than)); -HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than)); - -/* Implementation follows. */ - -HEAP_EXPORT(void heap_init(struct heap* heap)) { - heap->min = NULL; - heap->nelts = 0; -} - -HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap)) { - return heap->min; -} - -/* Swap parent with child. Child moves closer to the root, parent moves away. */ -static void heap_node_swap(struct heap* heap, - struct heap_node* parent, - struct heap_node* child) { - struct heap_node* sibling; - struct heap_node t; - - t = *parent; - *parent = *child; - *child = t; - - parent->parent = child; - if (child->left == child) { - child->left = parent; - sibling = child->right; - } else { - child->right = parent; - sibling = child->left; - } - if (sibling != NULL) - sibling->parent = child; - - if (parent->left != NULL) - parent->left->parent = parent; - if (parent->right != NULL) - parent->right->parent = parent; - - if (child->parent == NULL) - heap->min = child; - else if (child->parent->left == parent) - child->parent->left = child; - else - child->parent->right = child; -} - -HEAP_EXPORT(void heap_insert(struct heap* heap, - struct heap_node* newnode, - heap_compare_fn less_than)) { - struct heap_node** parent; - struct heap_node** child; - unsigned int path; - unsigned int n; - unsigned int k; - - newnode->left = NULL; - newnode->right = NULL; - newnode->parent = NULL; - - /* Calculate the path from the root to the insertion point. This is a min - * heap so we always insert at the left-most free node of the bottom row. - */ - path = 0; - for (k = 0, n = 1 + heap->nelts; n >= 2; k += 1, n /= 2) - path = (path << 1) | (n & 1); - - /* Now traverse the heap using the path we calculated in the previous step. */ - parent = child = &heap->min; - while (k > 0) { - parent = child; - if (path & 1) - child = &(*child)->right; - else - child = &(*child)->left; - path >>= 1; - k -= 1; - } - - /* Insert the new node. */ - newnode->parent = *parent; - *child = newnode; - heap->nelts += 1; - - /* Walk up the tree and check at each node if the heap property holds. - * It's a min heap so parent < child must be true. - */ - while (newnode->parent != NULL && less_than(newnode, newnode->parent)) - heap_node_swap(heap, newnode->parent, newnode); -} - -HEAP_EXPORT(void heap_remove(struct heap* heap, - struct heap_node* node, - heap_compare_fn less_than)) { - struct heap_node* smallest; - struct heap_node** max; - struct heap_node* child; - unsigned int path; - unsigned int k; - unsigned int n; - - if (heap->nelts == 0) - return; - - /* Calculate the path from the min (the root) to the max, the left-most node - * of the bottom row. - */ - path = 0; - for (k = 0, n = heap->nelts; n >= 2; k += 1, n /= 2) - path = (path << 1) | (n & 1); - - /* Now traverse the heap using the path we calculated in the previous step. */ - max = &heap->min; - while (k > 0) { - if (path & 1) - max = &(*max)->right; - else - max = &(*max)->left; - path >>= 1; - k -= 1; - } - - heap->nelts -= 1; - - /* Unlink the max node. */ - child = *max; - *max = NULL; - - if (child == node) { - /* We're removing either the max or the last node in the tree. */ - if (child == heap->min) { - heap->min = NULL; - } - return; - } - - /* Replace the to be deleted node with the max node. */ - child->left = node->left; - child->right = node->right; - child->parent = node->parent; - - if (child->left != NULL) { - child->left->parent = child; - } - - if (child->right != NULL) { - child->right->parent = child; - } - - if (node->parent == NULL) { - heap->min = child; - } else if (node->parent->left == node) { - node->parent->left = child; - } else { - node->parent->right = child; - } - - /* Walk down the subtree and check at each node if the heap property holds. - * It's a min heap so parent < child must be true. If the parent is bigger, - * swap it with the smallest child. - */ - for (;;) { - smallest = child; - if (child->left != NULL && less_than(child->left, smallest)) - smallest = child->left; - if (child->right != NULL && less_than(child->right, smallest)) - smallest = child->right; - if (smallest == child) - break; - heap_node_swap(heap, child, smallest); - } - - /* Walk up the subtree and check that each parent is less than the node - * this is required, because `max` node is not guaranteed to be the - * actual maximum in tree - */ - while (child->parent != NULL && less_than(child, child->parent)) - heap_node_swap(heap, child->parent, child); -} - -HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than)) { - heap_remove(heap, heap->min, less_than); -} - -#undef HEAP_EXPORT - -#endif /* UV_SRC_HEAP_H_ */ diff --git a/outside/libuv-v1.7.5/src/inet.c b/outside/libuv-v1.7.5/src/inet.c deleted file mode 100644 index c948b2e7cf..0000000000 --- a/outside/libuv-v1.7.5/src/inet.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include -#endif - -#include "uv.h" -#include "uv-common.h" - -#define UV__INET_ADDRSTRLEN 16 -#define UV__INET6_ADDRSTRLEN 46 - - -static int inet_ntop4(const unsigned char *src, char *dst, size_t size); -static int inet_ntop6(const unsigned char *src, char *dst, size_t size); -static int inet_pton4(const char *src, unsigned char *dst); -static int inet_pton6(const char *src, unsigned char *dst); - - -int uv_inet_ntop(int af, const void* src, char* dst, size_t size) { - switch (af) { - case AF_INET: - return (inet_ntop4(src, dst, size)); - case AF_INET6: - return (inet_ntop6(src, dst, size)); - default: - return UV_EAFNOSUPPORT; - } - /* NOTREACHED */ -} - - -static int inet_ntop4(const unsigned char *src, char *dst, size_t size) { - static const char fmt[] = "%u.%u.%u.%u"; - char tmp[UV__INET_ADDRSTRLEN]; - int l; - -#ifndef _WIN32 - l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); -#else - l = _snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); -#endif - if (l <= 0 || (size_t) l >= size) { - return UV_ENOSPC; - } - strncpy(dst, tmp, size); - dst[size - 1] = '\0'; - return 0; -} - - -static int inet_ntop6(const unsigned char *src, char *dst, size_t size) { - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[UV__INET6_ADDRSTRLEN], *tp; - struct { int base, len; } best, cur; - unsigned int words[sizeof(struct in6_addr) / sizeof(uint16_t)]; - int i; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < (int) sizeof(struct in6_addr); i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - best.len = 0; - cur.base = -1; - cur.len = 0; - for (i = 0; i < (int) ARRAY_SIZE(words); i++) { - if (words[i] == 0) { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (int) ARRAY_SIZE(words); i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) - *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && (best.len == 6 || - (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) { - int err = inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)); - if (err) - return err; - tp += strlen(tp); - break; - } - tp += sprintf(tp, "%x", words[i]); - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words)) - *tp++ = ':'; - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { - return UV_ENOSPC; - } - strcpy(dst, tmp); - return 0; -} - - -int uv_inet_pton(int af, const char* src, void* dst) { - if (src == NULL || dst == NULL) - return UV_EINVAL; - - switch (af) { - case AF_INET: - return (inet_pton4(src, dst)); - case AF_INET6: { - int len; - char tmp[UV__INET6_ADDRSTRLEN], *s, *p; - s = (char*) src; - p = strchr(src, '%'); - if (p != NULL) { - s = tmp; - len = p - src; - if (len > UV__INET6_ADDRSTRLEN-1) - return UV_EINVAL; - memcpy(s, src, len); - s[len] = '\0'; - } - return inet_pton6(s, dst); - } - default: - return UV_EAFNOSUPPORT; - } - /* NOTREACHED */ -} - - -static int inet_pton4(const char *src, unsigned char *dst) { - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[sizeof(struct in_addr)], *tp; - - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr(digits, ch)) != NULL) { - unsigned int nw = *tp * 10 + (pch - digits); - - if (saw_digit && *tp == 0) - return UV_EINVAL; - if (nw > 255) - return UV_EINVAL; - *tp = nw; - if (!saw_digit) { - if (++octets > 4) - return UV_EINVAL; - saw_digit = 1; - } - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return UV_EINVAL; - *++tp = 0; - saw_digit = 0; - } else - return UV_EINVAL; - } - if (octets < 4) - return UV_EINVAL; - memcpy(dst, tmp, sizeof(struct in_addr)); - return 0; -} - - -static int inet_pton6(const char *src, unsigned char *dst) { - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[sizeof(struct in6_addr)], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, seen_xdigits; - unsigned int val; - - memset((tp = tmp), '\0', sizeof tmp); - endp = tp + sizeof tmp; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return UV_EINVAL; - curtok = src; - seen_xdigits = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (++seen_xdigits > 4) - return UV_EINVAL; - continue; - } - if (ch == ':') { - curtok = src; - if (!seen_xdigits) { - if (colonp) - return UV_EINVAL; - colonp = tp; - continue; - } else if (*src == '\0') { - return UV_EINVAL; - } - if (tp + sizeof(uint16_t) > endp) - return UV_EINVAL; - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - seen_xdigits = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) { - int err = inet_pton4(curtok, tp); - if (err == 0) { - tp += sizeof(struct in_addr); - seen_xdigits = 0; - break; /*%< '\\0' was seen by inet_pton4(). */ - } - } - return UV_EINVAL; - } - if (seen_xdigits) { - if (tp + sizeof(uint16_t) > endp) - return UV_EINVAL; - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = tp - colonp; - int i; - - if (tp == endp) - return UV_EINVAL; - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) - return UV_EINVAL; - memcpy(dst, tmp, sizeof tmp); - return 0; -} diff --git a/outside/libuv-v1.7.5/src/queue.h b/outside/libuv-v1.7.5/src/queue.h deleted file mode 100644 index 60c8000038..0000000000 --- a/outside/libuv-v1.7.5/src/queue.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2013, Ben Noordhuis - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef QUEUE_H_ -#define QUEUE_H_ - -#include - -typedef void *QUEUE[2]; - -/* Private macros. */ -#define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0])) -#define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1])) -#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q))) -#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q))) - -/* Public macros. */ -#define QUEUE_DATA(ptr, type, field) \ - ((type *) ((char *) (ptr) - offsetof(type, field))) - -#define QUEUE_FOREACH(q, h) \ - for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q)) - -#define QUEUE_EMPTY(q) \ - ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q)) - -#define QUEUE_HEAD(q) \ - (QUEUE_NEXT(q)) - -#define QUEUE_INIT(q) \ - do { \ - QUEUE_NEXT(q) = (q); \ - QUEUE_PREV(q) = (q); \ - } \ - while (0) - -#define QUEUE_ADD(h, n) \ - do { \ - QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \ - QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \ - QUEUE_PREV(h) = QUEUE_PREV(n); \ - QUEUE_PREV_NEXT(h) = (h); \ - } \ - while (0) - -#define QUEUE_SPLIT(h, q, n) \ - do { \ - QUEUE_PREV(n) = QUEUE_PREV(h); \ - QUEUE_PREV_NEXT(n) = (n); \ - QUEUE_NEXT(n) = (q); \ - QUEUE_PREV(h) = QUEUE_PREV(q); \ - QUEUE_PREV_NEXT(h) = (h); \ - QUEUE_PREV(q) = (n); \ - } \ - while (0) - -#define QUEUE_INSERT_HEAD(h, q) \ - do { \ - QUEUE_NEXT(q) = QUEUE_NEXT(h); \ - QUEUE_PREV(q) = (h); \ - QUEUE_NEXT_PREV(q) = (q); \ - QUEUE_NEXT(h) = (q); \ - } \ - while (0) - -#define QUEUE_INSERT_TAIL(h, q) \ - do { \ - QUEUE_NEXT(q) = (h); \ - QUEUE_PREV(q) = QUEUE_PREV(h); \ - QUEUE_PREV_NEXT(q) = (q); \ - QUEUE_PREV(h) = (q); \ - } \ - while (0) - -#define QUEUE_REMOVE(q) \ - do { \ - QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \ - QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \ - } \ - while (0) - -#endif /* QUEUE_H_ */ diff --git a/outside/libuv-v1.7.5/src/threadpool.c b/outside/libuv-v1.7.5/src/threadpool.c deleted file mode 100644 index 15d719944f..0000000000 --- a/outside/libuv-v1.7.5/src/threadpool.c +++ /dev/null @@ -1,308 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv-common.h" - -#if !defined(_WIN32) -# include "unix/internal.h" -#else -# include "win/req-inl.h" -/* TODO(saghul): unify internal req functions */ -static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type) { - uv_req_init(loop, req); - req->type = type; - uv__req_register(loop, req); -} -# define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) -#endif - -#include - -#define MAX_THREADPOOL_SIZE 128 - -static uv_once_t once = UV_ONCE_INIT; -static uv_cond_t cond; -static uv_mutex_t mutex; -static unsigned int idle_threads; -static unsigned int nthreads; -static uv_thread_t* threads; -static uv_thread_t default_threads[4]; -static QUEUE exit_message; -static QUEUE wq; -static volatile int initialized; - - -static void uv__cancelled(struct uv__work* w) { - abort(); -} - - -/* To avoid deadlock with uv_cancel() it's crucial that the worker - * never holds the global mutex and the loop-local mutex at the same time. - */ -static void worker(void* arg) { - struct uv__work* w; - QUEUE* q; - - (void) arg; - - for (;;) { - uv_mutex_lock(&mutex); - - while (QUEUE_EMPTY(&wq)) { - idle_threads += 1; - uv_cond_wait(&cond, &mutex); - idle_threads -= 1; - } - - q = QUEUE_HEAD(&wq); - - if (q == &exit_message) - uv_cond_signal(&cond); - else { - QUEUE_REMOVE(q); - QUEUE_INIT(q); /* Signal uv_cancel() that the work req is - executing. */ - } - - uv_mutex_unlock(&mutex); - - if (q == &exit_message) - break; - - w = QUEUE_DATA(q, struct uv__work, wq); - w->work(w); - - uv_mutex_lock(&w->loop->wq_mutex); - w->work = NULL; /* Signal uv_cancel() that the work req is done - executing. */ - QUEUE_INSERT_TAIL(&w->loop->wq, &w->wq); - uv_async_send(&w->loop->wq_async); - uv_mutex_unlock(&w->loop->wq_mutex); - } -} - - -static void post(QUEUE* q) { - uv_mutex_lock(&mutex); - QUEUE_INSERT_TAIL(&wq, q); - if (idle_threads > 0) - uv_cond_signal(&cond); - uv_mutex_unlock(&mutex); -} - - -#ifndef _WIN32 -UV_DESTRUCTOR(static void cleanup(void)) { - unsigned int i; - - if (initialized == 0) - return; - - post(&exit_message); - - for (i = 0; i < nthreads; i++) - if (uv_thread_join(threads + i)) - abort(); - - if (threads != default_threads) - uv__free(threads); - - uv_mutex_destroy(&mutex); - uv_cond_destroy(&cond); - - threads = NULL; - nthreads = 0; - initialized = 0; -} -#endif - - -static void init_once(void) { - unsigned int i; - const char* val; - - nthreads = ARRAY_SIZE(default_threads); - val = getenv("UV_THREADPOOL_SIZE"); - if (val != NULL) - nthreads = atoi(val); - if (nthreads == 0) - nthreads = 1; - if (nthreads > MAX_THREADPOOL_SIZE) - nthreads = MAX_THREADPOOL_SIZE; - - threads = default_threads; - if (nthreads > ARRAY_SIZE(default_threads)) { - threads = uv__malloc(nthreads * sizeof(threads[0])); - if (threads == NULL) { - nthreads = ARRAY_SIZE(default_threads); - threads = default_threads; - } - } - - if (uv_cond_init(&cond)) - abort(); - - if (uv_mutex_init(&mutex)) - abort(); - - QUEUE_INIT(&wq); - - for (i = 0; i < nthreads; i++) - if (uv_thread_create(threads + i, worker, NULL)) - abort(); - - initialized = 1; -} - - -void uv__work_submit(uv_loop_t* loop, - struct uv__work* w, - void (*work)(struct uv__work* w), - void (*done)(struct uv__work* w, int status)) { - uv_once(&once, init_once); - w->loop = loop; - w->work = work; - w->done = done; - post(&w->wq); -} - - -static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) { - int cancelled; - - uv_mutex_lock(&mutex); - uv_mutex_lock(&w->loop->wq_mutex); - - cancelled = !QUEUE_EMPTY(&w->wq) && w->work != NULL; - if (cancelled) - QUEUE_REMOVE(&w->wq); - - uv_mutex_unlock(&w->loop->wq_mutex); - uv_mutex_unlock(&mutex); - - if (!cancelled) - return UV_EBUSY; - - w->work = uv__cancelled; - uv_mutex_lock(&loop->wq_mutex); - QUEUE_INSERT_TAIL(&loop->wq, &w->wq); - uv_async_send(&loop->wq_async); - uv_mutex_unlock(&loop->wq_mutex); - - return 0; -} - - -void uv__work_done(uv_async_t* handle) { - struct uv__work* w; - uv_loop_t* loop; - QUEUE* q; - QUEUE wq; - int err; - - loop = container_of(handle, uv_loop_t, wq_async); - QUEUE_INIT(&wq); - - uv_mutex_lock(&loop->wq_mutex); - if (!QUEUE_EMPTY(&loop->wq)) { - q = QUEUE_HEAD(&loop->wq); - QUEUE_SPLIT(&loop->wq, q, &wq); - } - uv_mutex_unlock(&loop->wq_mutex); - - while (!QUEUE_EMPTY(&wq)) { - q = QUEUE_HEAD(&wq); - QUEUE_REMOVE(q); - - w = container_of(q, struct uv__work, wq); - err = (w->work == uv__cancelled) ? UV_ECANCELED : 0; - w->done(w, err); - } -} - - -static void uv__queue_work(struct uv__work* w) { - uv_work_t* req = container_of(w, uv_work_t, work_req); - - req->work_cb(req); -} - - -static void uv__queue_done(struct uv__work* w, int err) { - uv_work_t* req; - - req = container_of(w, uv_work_t, work_req); - uv__req_unregister(req->loop, req); - - if (req->after_work_cb == NULL) - return; - - req->after_work_cb(req, err); -} - - -int uv_queue_work(uv_loop_t* loop, - uv_work_t* req, - uv_work_cb work_cb, - uv_after_work_cb after_work_cb) { - if (work_cb == NULL) - return UV_EINVAL; - - uv__req_init(loop, req, UV_WORK); - req->loop = loop; - req->work_cb = work_cb; - req->after_work_cb = after_work_cb; - uv__work_submit(loop, &req->work_req, uv__queue_work, uv__queue_done); - return 0; -} - - -int uv_cancel(uv_req_t* req) { - struct uv__work* wreq; - uv_loop_t* loop; - - switch (req->type) { - case UV_FS: - loop = ((uv_fs_t*) req)->loop; - wreq = &((uv_fs_t*) req)->work_req; - break; - case UV_GETADDRINFO: - loop = ((uv_getaddrinfo_t*) req)->loop; - wreq = &((uv_getaddrinfo_t*) req)->work_req; - break; - case UV_GETNAMEINFO: - loop = ((uv_getnameinfo_t*) req)->loop; - wreq = &((uv_getnameinfo_t*) req)->work_req; - break; - case UV_WORK: - loop = ((uv_work_t*) req)->loop; - wreq = &((uv_work_t*) req)->work_req; - break; - default: - return UV_EINVAL; - } - - return uv__work_cancel(loop, req, wreq); -} diff --git a/outside/libuv-v1.7.5/src/unix/aix.c b/outside/libuv-v1.7.5/src/unix/aix.c deleted file mode 100644 index c90b7e5cb9..0000000000 --- a/outside/libuv-v1.7.5/src/unix/aix.c +++ /dev/null @@ -1,1158 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#ifdef HAVE_SYS_AHAFS_EVPRODS_H -#include -#endif - -#include -#include -#include -#include -#include - -#define RDWR_BUF_SIZE 4096 -#define EQ(a,b) (strcmp(a,b) == 0) - -int uv__platform_loop_init(uv_loop_t* loop) { - loop->fs_fd = -1; - - /* Passing maxfd of -1 should mean the limit is determined - * by the user's ulimit or the global limit as per the doc */ - loop->backend_fd = pollset_create(-1); - - if (loop->backend_fd == -1) - return -1; - - return 0; -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { - if (loop->fs_fd != -1) { - uv__close(loop->fs_fd); - loop->fs_fd = -1; - } - - if (loop->backend_fd != -1) { - pollset_destroy(loop->backend_fd); - loop->backend_fd = -1; - } -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - struct pollfd events[1024]; - struct pollfd pqry; - struct pollfd* pe; - struct poll_ctl pc; - QUEUE* q; - uv__io_t* w; - uint64_t base; - uint64_t diff; - int nevents; - int count; - int nfds; - int i; - int rc; - int add_failed; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - assert(w->fd >= 0); - assert(w->fd < (int) loop->nwatchers); - - pc.events = w->pevents; - pc.fd = w->fd; - - add_failed = 0; - if (w->events == 0) { - pc.cmd = PS_ADD; - if (pollset_ctl(loop->backend_fd, &pc, 1)) { - if (errno != EINVAL) { - assert(0 && "Failed to add file descriptor (pc.fd) to pollset"); - abort(); - } - /* Check if the fd is already in the pollset */ - pqry.fd = pc.fd; - rc = pollset_query(loop->backend_fd, &pqry); - switch (rc) { - case -1: - assert(0 && "Failed to query pollset for file descriptor"); - abort(); - case 0: - assert(0 && "Pollset does not contain file descriptor"); - abort(); - } - /* If we got here then the pollset already contained the file descriptor even though - * we didn't think it should. This probably shouldn't happen, but we can continue. */ - add_failed = 1; - } - } - if (w->events != 0 || add_failed) { - /* Modify, potentially removing events -- need to delete then add. - * Could maybe mod if we knew for sure no events are removed, but - * content of w->events is handled above as not reliable (falls back) - * so may require a pollset_query() which would have to be pretty cheap - * compared to a PS_DELETE to be worth optimizing. Alternatively, could - * lazily remove events, squelching them in the mean time. */ - pc.cmd = PS_DELETE; - if (pollset_ctl(loop->backend_fd, &pc, 1)) { - assert(0 && "Failed to delete file descriptor (pc.fd) from pollset"); - abort(); - } - pc.cmd = PS_ADD; - if (pollset_ctl(loop->backend_fd, &pc, 1)) { - assert(0 && "Failed to add file descriptor (pc.fd) to pollset"); - abort(); - } - } - - w->events = w->pevents; - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - - for (;;) { - nfds = pollset_poll(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout); - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (nfds == 0) { - assert(timeout != -1); - return; - } - - if (nfds == -1) { - if (errno != EINTR) { - abort(); - } - - if (timeout == -1) - continue; - - if (timeout == 0) - return; - - /* Interrupted by a signal. Update timeout and poll again. */ - goto update_timeout; - } - - nevents = 0; - - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = (void*) events; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - - for (i = 0; i < nfds; i++) { - pe = events + i; - pc.cmd = PS_DELETE; - pc.fd = pe->fd; - - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (pc.fd == -1) - continue; - - assert(pc.fd >= 0); - assert((unsigned) pc.fd < loop->nwatchers); - - w = loop->watchers[pc.fd]; - - if (w == NULL) { - /* File descriptor that we've stopped watching, disarm it. - * - * Ignore all errors because we may be racing with another thread - * when the file descriptor is closed. - */ - pollset_ctl(loop->backend_fd, &pc, 1); - continue; - } - - w->cb(loop, w, pe->revents); - nevents++; - } - - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - diff = loop->time - base; - if (diff >= (uint64_t) timeout) - return; - - timeout -= diff; - } -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - uint64_t G = 1000000000; - timebasestruct_t t; - read_wall_time(&t, TIMEBASE_SZ); - time_base_to_time(&t, TIMEBASE_SZ); - return (uint64_t) t.tb_high * G + t.tb_low; -} - - -/* - * We could use a static buffer for the path manipulations that we need outside - * of the function, but this function could be called by multiple consumers and - * we don't want to potentially create a race condition in the use of snprintf. - * There is no direct way of getting the exe path in AIX - either through /procfs - * or through some libc APIs. The below approach is to parse the argv[0]'s pattern - * and use it in conjunction with PATH environment variable to craft one. - */ -int uv_exepath(char* buffer, size_t* size) { - int res; - char args[PATH_MAX]; - char abspath[PATH_MAX]; - size_t abspath_size; - struct procsinfo pi; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - pi.pi_pid = getpid(); - res = getargs(&pi, sizeof(pi), args, sizeof(args)); - if (res < 0) - return -EINVAL; - - /* - * Possibilities for args: - * i) an absolute path such as: /home/user/myprojects/nodejs/node - * ii) a relative path such as: ./node or ../myprojects/nodejs/node - * iii) a bare filename such as "node", after exporting PATH variable - * to its location. - */ - - /* Case i) and ii) absolute or relative paths */ - if (strchr(args, '/') != NULL) { - if (realpath(args, abspath) != abspath) - return -errno; - - abspath_size = strlen(abspath); - - *size -= 1; - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - return 0; - } else { - /* Case iii). Search PATH environment variable */ - char trypath[PATH_MAX]; - char *clonedpath = NULL; - char *token = NULL; - char *path = getenv("PATH"); - - if (path == NULL) - return -EINVAL; - - clonedpath = uv__strdup(path); - if (clonedpath == NULL) - return -ENOMEM; - - token = strtok(clonedpath, ":"); - while (token != NULL) { - snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args); - if (realpath(trypath, abspath) == abspath) { - /* Check the match is executable */ - if (access(abspath, X_OK) == 0) { - abspath_size = strlen(abspath); - - *size -= 1; - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - uv__free(clonedpath); - return 0; - } - } - token = strtok(NULL, ":"); - } - uv__free(clonedpath); - - /* Out of tokens (path entries), and no match found */ - return -EINVAL; - } -} - - -uint64_t uv_get_free_memory(void) { - perfstat_memory_total_t mem_total; - int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1); - if (result == -1) { - return 0; - } - return mem_total.real_free * 4096; -} - - -uint64_t uv_get_total_memory(void) { - perfstat_memory_total_t mem_total; - int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1); - if (result == -1) { - return 0; - } - return mem_total.real_total * 4096; -} - - -void uv_loadavg(double avg[3]) { - perfstat_cpu_total_t ps_total; - int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); - if (result == -1) { - avg[0] = 0.; avg[1] = 0.; avg[2] = 0.; - return; - } - avg[0] = ps_total.loadavg[0] / (double)(1 << SBITS); - avg[1] = ps_total.loadavg[1] / (double)(1 << SBITS); - avg[2] = ps_total.loadavg[2] / (double)(1 << SBITS); -} - - -#ifdef HAVE_SYS_AHAFS_EVPRODS_H -static char *uv__rawname(char *cp) { - static char rawbuf[FILENAME_MAX+1]; - char *dp = rindex(cp, '/'); - - if (dp == 0) - return 0; - - *dp = 0; - strcpy(rawbuf, cp); - *dp = '/'; - strcat(rawbuf, "/r"); - strcat(rawbuf, dp+1); - return rawbuf; -} - - -/* - * Determine whether given pathname is a directory - * Returns 0 if the path is a directory, -1 if not - * - * Note: Opportunity here for more detailed error information but - * that requires changing callers of this function as well - */ -static int uv__path_is_a_directory(char* filename) { - struct stat statbuf; - - if (stat(filename, &statbuf) < 0) - return -1; /* failed: not a directory, assume it is a file */ - - if (statbuf.st_type == VDIR) - return 0; - - return -1; -} - - -/* - * Check whether AHAFS is mounted. - * Returns 0 if AHAFS is mounted, or an error code < 0 on failure - */ -static int uv__is_ahafs_mounted(void){ - int rv, i = 2; - struct vmount *p; - int size_multiplier = 10; - size_t siz = sizeof(struct vmount)*size_multiplier; - struct vmount *vmt; - const char *dev = "/aha"; - char *obj, *stub; - - p = uv__malloc(siz); - if (p == NULL) - return -errno; - - /* Retrieve all mounted filesystems */ - rv = mntctl(MCTL_QUERY, siz, (char*)p); - if (rv < 0) - return -errno; - if (rv == 0) { - /* buffer was not large enough, reallocate to correct size */ - siz = *(int*)p; - uv__free(p); - p = uv__malloc(siz); - if (p == NULL) - return -errno; - rv = mntctl(MCTL_QUERY, siz, (char*)p); - if (rv < 0) - return -errno; - } - - /* Look for dev in filesystems mount info */ - for(vmt = p, i = 0; i < rv; i++) { - obj = vmt2dataptr(vmt, VMT_OBJECT); /* device */ - stub = vmt2dataptr(vmt, VMT_STUB); /* mount point */ - - if (EQ(obj, dev) || EQ(uv__rawname(obj), dev) || EQ(stub, dev)) { - uv__free(p); /* Found a match */ - return 0; - } - vmt = (struct vmount *) ((char *) vmt + vmt->vmt_length); - } - - /* /aha is required for monitoring filesystem changes */ - return -1; -} - -/* - * Recursive call to mkdir() to create intermediate folders, if any - * Returns code from mkdir call - */ -static int uv__makedir_p(const char *dir) { - char tmp[256]; - char *p = NULL; - size_t len; - int err; - - snprintf(tmp, sizeof(tmp),"%s",dir); - len = strlen(tmp); - if (tmp[len - 1] == '/') - tmp[len - 1] = 0; - for (p = tmp + 1; *p; p++) { - if (*p == '/') { - *p = 0; - err = mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if(err != 0) - return err; - *p = '/'; - } - } - return mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); -} - -/* - * Creates necessary subdirectories in the AIX Event Infrastructure - * file system for monitoring the object specified. - * Returns code from mkdir call - */ -static int uv__make_subdirs_p(const char *filename) { - char cmd[2048]; - char *p; - int rc = 0; - - /* Strip off the monitor file name */ - p = strrchr(filename, '/'); - - if (p == NULL) - return 0; - - if (uv__path_is_a_directory((char*)filename) == 0) { - sprintf(cmd, "/aha/fs/modDir.monFactory"); - } else { - sprintf(cmd, "/aha/fs/modFile.monFactory"); - } - - strncat(cmd, filename, (p - filename)); - rc = uv__makedir_p(cmd); - - if (rc == -1 && errno != EEXIST){ - return -errno; - } - - return rc; -} - - -/* - * Checks if /aha is mounted, then proceeds to set up the monitoring - * objects for the specified file. - * Returns 0 on success, or an error code < 0 on failure - */ -static int uv__setup_ahafs(const char* filename, int *fd) { - int rc = 0; - char mon_file_write_string[RDWR_BUF_SIZE]; - char mon_file[PATH_MAX]; - int file_is_directory = 0; /* -1 == NO, 0 == YES */ - - /* Create monitor file name for object */ - file_is_directory = uv__path_is_a_directory((char*)filename); - - if (file_is_directory == 0) - sprintf(mon_file, "/aha/fs/modDir.monFactory"); - else - sprintf(mon_file, "/aha/fs/modFile.monFactory"); - - if ((strlen(mon_file) + strlen(filename) + 5) > PATH_MAX) - return -ENAMETOOLONG; - - /* Make the necessary subdirectories for the monitor file */ - rc = uv__make_subdirs_p(filename); - if (rc == -1 && errno != EEXIST) - return rc; - - strcat(mon_file, filename); - strcat(mon_file, ".mon"); - - *fd = 0; errno = 0; - - /* Open the monitor file, creating it if necessary */ - *fd = open(mon_file, O_CREAT|O_RDWR); - if (*fd < 0) - return -errno; - - /* Write out the monitoring specifications. - * In this case, we are monitoring for a state change event type - * CHANGED=YES - * We will be waiting in select call, rather than a read: - * WAIT_TYPE=WAIT_IN_SELECT - * We only want minimal information for files: - * INFO_LVL=1 - * For directories, we want more information to track what file - * caused the change - * INFO_LVL=2 - */ - - if (file_is_directory == 0) - sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=2"); - else - sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1"); - - rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1); - if (rc < 0) - return -errno; - - return 0; -} - -/* - * Skips a specified number of lines in the buffer passed in. - * Walks the buffer pointed to by p and attempts to skip n lines. - * Returns the total number of lines skipped - */ -static int uv__skip_lines(char **p, int n) { - int lines = 0; - - while(n > 0) { - *p = strchr(*p, '\n'); - if (!p) - return lines; - - (*p)++; - n--; - lines++; - } - return lines; -} - - -/* - * Parse the event occurrence data to figure out what event just occurred - * and take proper action. - * - * The buf is a pointer to the buffer containing the event occurrence data - * Returns 0 on success, -1 if unrecoverable error in parsing - * - */ -static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) { - int evp_rc, i; - char *p; - char filename[PATH_MAX]; /* To be used when handling directories */ - - p = buf; - *events = 0; - - /* Clean the filename buffer*/ - for(i = 0; i < PATH_MAX; i++) { - filename[i] = 0; - } - i = 0; - - /* Check for BUF_WRAP */ - if (strncmp(buf, "BUF_WRAP", strlen("BUF_WRAP")) == 0) { - assert(0 && "Buffer wrap detected, Some event occurrences lost!"); - return 0; - } - - /* Since we are using the default buffer size (4K), and have specified - * INFO_LVL=1, we won't see any EVENT_OVERFLOW conditions. Applications - * should check for this keyword if they are using an INFO_LVL of 2 or - * higher, and have a buffer size of <= 4K - */ - - /* Skip to RC_FROM_EVPROD */ - if (uv__skip_lines(&p, 9) != 9) - return -1; - - if (sscanf(p, "RC_FROM_EVPROD=%d\nEND_EVENT_DATA", &evp_rc) == 1) { - if (uv__path_is_a_directory(handle->path) == 0) { /* Directory */ - if (evp_rc == AHAFS_MODDIR_UNMOUNT || evp_rc == AHAFS_MODDIR_REMOVE_SELF) { - /* The directory is no longer available for monitoring */ - *events = UV_RENAME; - handle->dir_filename = NULL; - } else { - /* A file was added/removed inside the directory */ - *events = UV_CHANGE; - - /* Get the EVPROD_INFO */ - if (uv__skip_lines(&p, 1) != 1) - return -1; - - /* Scan out the name of the file that triggered the event*/ - if (sscanf(p, "BEGIN_EVPROD_INFO\n%sEND_EVPROD_INFO", filename) == 1) { - handle->dir_filename = uv__strdup((const char*)&filename); - } else - return -1; - } - } else { /* Regular File */ - if (evp_rc == AHAFS_MODFILE_RENAME) - *events = UV_RENAME; - else - *events = UV_CHANGE; - } - } - else - return -1; - - return 0; -} - - -/* This is the internal callback */ -static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) { - char result_data[RDWR_BUF_SIZE]; - int bytes, rc = 0; - uv_fs_event_t* handle; - int events = 0; - int i = 0; - char fname[PATH_MAX]; - char *p; - - handle = container_of(event_watch, uv_fs_event_t, event_watcher); - - /* Clean all the buffers*/ - for(i = 0; i < PATH_MAX; i++) { - fname[i] = 0; - } - i = 0; - - /* At this point, we assume that polling has been done on the - * file descriptor, so we can just read the AHAFS event occurrence - * data and parse its results without having to block anything - */ - bytes = pread(event_watch->fd, result_data, RDWR_BUF_SIZE, 0); - - assert((bytes <= 0) && "uv__ahafs_event - Error reading monitor file"); - - /* Parse the data */ - if(bytes > 0) - rc = uv__parse_data(result_data, &events, handle); - - /* For directory changes, the name of the files that triggered the change - * are never absolute pathnames - */ - if (uv__path_is_a_directory(handle->path) == 0) { - p = handle->dir_filename; - while(*p != NULL){ - fname[i]= *p; - i++; - p++; - } - } else { - /* For file changes, figure out whether filename is absolute or not */ - if (handle->path[0] == '/') { - p = strrchr(handle->path, '/'); - p++; - - while(*p != NULL) { - fname[i]= *p; - i++; - p++; - } - } - } - - /* Unrecoverable error */ - if (rc == -1) - return; - else /* Call the actual JavaScript callback function */ - handle->cb(handle, (const char*)&fname, events, 0); -} -#endif - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { -#ifdef HAVE_SYS_AHAFS_EVPRODS_H - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); - return 0; -#else - return -ENOSYS; -#endif -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* filename, - unsigned int flags) { -#ifdef HAVE_SYS_AHAFS_EVPRODS_H - int fd, rc, i = 0, res = 0; - char cwd[PATH_MAX]; - char absolute_path[PATH_MAX]; - char fname[PATH_MAX]; - char *p; - - /* Clean all the buffers*/ - for(i = 0; i < PATH_MAX; i++) { - cwd[i] = 0; - absolute_path[i] = 0; - fname[i] = 0; - } - i = 0; - - /* Figure out whether filename is absolute or not */ - if (filename[0] == '/') { - /* We have absolute pathname, create the relative pathname*/ - sprintf(absolute_path, filename); - p = strrchr(filename, '/'); - p++; - } else { - if (filename[0] == '.' && filename[1] == '/') { - /* We have a relative pathname, compose the absolute pathname */ - sprintf(fname, filename); - snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid()); - res = readlink(cwd, absolute_path, sizeof(absolute_path) - 1); - if (res < 0) - return res; - p = strrchr(absolute_path, '/'); - p++; - p++; - } else { - /* We have a relative pathname, compose the absolute pathname */ - sprintf(fname, filename); - snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid()); - res = readlink(cwd, absolute_path, sizeof(absolute_path) - 1); - if (res < 0) - return res; - p = strrchr(absolute_path, '/'); - p++; - } - /* Copy to filename buffer */ - while(filename[i] != NULL) { - *p = filename[i]; - i++; - p++; - } - } - - if (uv__is_ahafs_mounted() < 0) /* /aha checks failed */ - return UV_ENOSYS; - - /* Setup ahafs */ - rc = uv__setup_ahafs((const char *)absolute_path, &fd); - if (rc != 0) - return rc; - - /* Setup/Initialize all the libuv routines */ - uv__handle_start(handle); - uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); - handle->path = uv__strdup((const char*)&absolute_path); - handle->cb = cb; - - uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN); - - return 0; -#else - return -ENOSYS; -#endif -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { -#ifdef HAVE_SYS_AHAFS_EVPRODS_H - if (!uv__is_active(handle)) - return 0; - - uv__io_close(handle->loop, &handle->event_watcher); - uv__handle_stop(handle); - - if (uv__path_is_a_directory(handle->path) == 0) { - uv__free(handle->dir_filename); - handle->dir_filename = NULL; - } - - uv__free(handle->path); - handle->path = NULL; - uv__close(handle->event_watcher.fd); - handle->event_watcher.fd = -1; - - return 0; -#else - return -ENOSYS; -#endif -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { -#ifdef HAVE_SYS_AHAFS_EVPRODS_H - uv_fs_event_stop(handle); -#else - UNREACHABLE(); -#endif -} - - -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (size > 0) { - buffer[0] = '\0'; - } - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - char pp[64]; - psinfo_t psinfo; - int err; - int fd; - - snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid()); - - fd = open(pp, O_RDONLY); - if (fd == -1) - return -errno; - - /* FIXME(bnoordhuis) Handle EINTR. */ - err = -EINVAL; - if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) { - *rss = (size_t)psinfo.pr_rssize * 1024; - err = 0; - } - uv__close(fd); - - return err; -} - - -int uv_uptime(double* uptime) { - struct utmp *utmp_buf; - size_t entries = 0; - time_t boot_time; - - utmpname(UTMP_FILE); - - setutent(); - - while ((utmp_buf = getutent()) != NULL) { - if (utmp_buf->ut_user[0] && utmp_buf->ut_type == USER_PROCESS) - ++entries; - if (utmp_buf->ut_type == BOOT_TIME) - boot_time = utmp_buf->ut_time; - } - - endutent(); - - if (boot_time == 0) - return -ENOSYS; - - *uptime = time(NULL) - boot_time; - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - uv_cpu_info_t* cpu_info; - perfstat_cpu_total_t ps_total; - perfstat_cpu_t* ps_cpus; - perfstat_id_t cpu_id; - int result, ncpus, idx = 0; - - result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); - if (result == -1) { - return -ENOSYS; - } - - ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); - if (result == -1) { - return -ENOSYS; - } - - ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t)); - if (!ps_cpus) { - return -ENOMEM; - } - - strcpy(cpu_id.name, FIRST_CPU); - result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); - if (result == -1) { - uv__free(ps_cpus); - return -ENOSYS; - } - - *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t)); - if (!*cpu_infos) { - uv__free(ps_cpus); - return -ENOMEM; - } - - *count = ncpus; - - cpu_info = *cpu_infos; - while (idx < ncpus) { - cpu_info->speed = (int)(ps_total.processorHZ / 1000000); - cpu_info->model = uv__strdup(ps_total.description); - cpu_info->cpu_times.user = ps_cpus[idx].user; - cpu_info->cpu_times.sys = ps_cpus[idx].sys; - cpu_info->cpu_times.idle = ps_cpus[idx].idle; - cpu_info->cpu_times.irq = ps_cpus[idx].wait; - cpu_info->cpu_times.nice = 0; - cpu_info++; - idx++; - } - - uv__free(ps_cpus); - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; ++i) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - uv_interface_address_t* address; - int sockfd, size = 1; - struct ifconf ifc; - struct ifreq *ifr, *p, flg; - - *count = 0; - - if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) { - return -errno; - } - - if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) { - SAVE_ERRNO(uv__close(sockfd)); - return -errno; - } - - ifc.ifc_req = (struct ifreq*)uv__malloc(size); - ifc.ifc_len = size; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { - SAVE_ERRNO(uv__close(sockfd)); - return -errno; - } - -#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) - - /* Count all up and running ipv4/ipv6 addresses */ - ifr = ifc.ifc_req; - while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { - p = ifr; - ifr = (struct ifreq*) - ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); - - if (!(p->ifr_addr.sa_family == AF_INET6 || - p->ifr_addr.sa_family == AF_INET)) - continue; - - memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { - SAVE_ERRNO(uv__close(sockfd)); - return -errno; - } - - if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) - continue; - - (*count)++; - } - - /* Alloc the return interface structs */ - *addresses = (uv_interface_address_t*) - uv__malloc(*count * sizeof(uv_interface_address_t)); - if (!(*addresses)) { - uv__close(sockfd); - return -ENOMEM; - } - address = *addresses; - - ifr = ifc.ifc_req; - while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { - p = ifr; - ifr = (struct ifreq*) - ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); - - if (!(p->ifr_addr.sa_family == AF_INET6 || - p->ifr_addr.sa_family == AF_INET)) - continue; - - memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { - uv__close(sockfd); - return -ENOSYS; - } - - if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) - continue; - - /* All conditions above must match count loop */ - - address->name = uv__strdup(p->ifr_name); - - if (p->ifr_addr.sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); - } - - /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */ - - address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; - - address++; - } - -#undef ADDR_SIZE - - uv__close(sockfd); - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; ++i) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} - -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct pollfd* events; - uintptr_t i; - uintptr_t nfds; - struct poll_ctl pc; - - assert(loop->watchers != NULL); - - events = (struct pollfd*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - - if (events != NULL) - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if ((int) events[i].fd == fd) - events[i].fd = -1; - - /* Remove the file descriptor from the poll set */ - pc.events = 0; - pc.cmd = PS_DELETE; - pc.fd = fd; - if(loop->backend_fd >= 0) - pollset_ctl(loop->backend_fd, &pc, 1); -} diff --git a/outside/libuv-v1.7.5/src/unix/android-ifaddrs.c b/outside/libuv-v1.7.5/src/unix/android-ifaddrs.c deleted file mode 100644 index 71f7290b32..0000000000 --- a/outside/libuv-v1.7.5/src/unix/android-ifaddrs.c +++ /dev/null @@ -1,703 +0,0 @@ -/* -Copyright (c) 2013, Kenneth MacKay -Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement n° 289016) -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "android-ifaddrs.h" -#include "uv-common.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct NetlinkList -{ - struct NetlinkList *m_next; - struct nlmsghdr *m_data; - unsigned int m_size; -} NetlinkList; - -static int netlink_socket(void) -{ - struct sockaddr_nl l_addr; - - int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if(l_socket < 0) - { - return -1; - } - - memset(&l_addr, 0, sizeof(l_addr)); - l_addr.nl_family = AF_NETLINK; - if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0) - { - close(l_socket); - return -1; - } - - return l_socket; -} - -static int netlink_send(int p_socket, int p_request) -{ - char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))]; - - struct nlmsghdr *l_hdr; - struct rtgenmsg *l_msg; - struct sockaddr_nl l_addr; - - memset(l_buffer, 0, sizeof(l_buffer)); - - l_hdr = (struct nlmsghdr *)l_buffer; - l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr); - - l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg)); - l_hdr->nlmsg_type = p_request; - l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; - l_hdr->nlmsg_pid = 0; - l_hdr->nlmsg_seq = p_socket; - l_msg->rtgen_family = AF_UNSPEC; - - memset(&l_addr, 0, sizeof(l_addr)); - l_addr.nl_family = AF_NETLINK; - return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr))); -} - -static int netlink_recv(int p_socket, void *p_buffer, size_t p_len) -{ - struct sockaddr_nl l_addr; - struct msghdr l_msg; - - struct iovec l_iov; - l_iov.iov_base = p_buffer; - l_iov.iov_len = p_len; - - for(;;) - { - int l_result; - l_msg.msg_name = (void *)&l_addr; - l_msg.msg_namelen = sizeof(l_addr); - l_msg.msg_iov = &l_iov; - l_msg.msg_iovlen = 1; - l_msg.msg_control = NULL; - l_msg.msg_controllen = 0; - l_msg.msg_flags = 0; - l_result = recvmsg(p_socket, &l_msg, 0); - - if(l_result < 0) - { - if(errno == EINTR) - { - continue; - } - return -2; - } - - /* Buffer was too small */ - if(l_msg.msg_flags & MSG_TRUNC) - { - return -1; - } - return l_result; - } -} - -static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done) -{ - size_t l_size = 4096; - void *l_buffer = NULL; - - for(;;) - { - int l_read; - - uv__free(l_buffer); - l_buffer = uv__malloc(l_size); - if (l_buffer == NULL) - { - return NULL; - } - - l_read = netlink_recv(p_socket, l_buffer, l_size); - *p_size = l_read; - if(l_read == -2) - { - uv__free(l_buffer); - return NULL; - } - if(l_read >= 0) - { - pid_t l_pid = getpid(); - struct nlmsghdr *l_hdr; - for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) - { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - *p_done = 1; - break; - } - - if(l_hdr->nlmsg_type == NLMSG_ERROR) - { - uv__free(l_buffer); - return NULL; - } - } - return l_buffer; - } - - l_size *= 2; - } -} - -static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size) -{ - NetlinkList *l_item = uv__malloc(sizeof(NetlinkList)); - if (l_item == NULL) - { - return NULL; - } - - l_item->m_next = NULL; - l_item->m_data = p_data; - l_item->m_size = p_size; - return l_item; -} - -static void freeResultList(NetlinkList *p_list) -{ - NetlinkList *l_cur; - while(p_list) - { - l_cur = p_list; - p_list = p_list->m_next; - uv__free(l_cur->m_data); - uv__free(l_cur); - } -} - -static NetlinkList *getResultList(int p_socket, int p_request) -{ - int l_size; - int l_done; - NetlinkList *l_list; - NetlinkList *l_end; - - if(netlink_send(p_socket, p_request) < 0) - { - return NULL; - } - - l_list = NULL; - l_end = NULL; - - l_done = 0; - while(!l_done) - { - NetlinkList *l_item; - - struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done); - /* Error */ - if(!l_hdr) - { - freeResultList(l_list); - return NULL; - } - - l_item = newListItem(l_hdr, l_size); - if (!l_item) - { - freeResultList(l_list); - return NULL; - } - if(!l_list) - { - l_list = l_item; - } - else - { - l_end->m_next = l_item; - } - l_end = l_item; - } - return l_list; -} - -static size_t maxSize(size_t a, size_t b) -{ - return (a > b ? a : b); -} - -static size_t calcAddrLen(sa_family_t p_family, int p_dataSize) -{ - switch(p_family) - { - case AF_INET: - return sizeof(struct sockaddr_in); - case AF_INET6: - return sizeof(struct sockaddr_in6); - case AF_PACKET: - return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize); - default: - return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize); - } -} - -static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size) -{ - switch(p_family) - { - case AF_INET: - memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size); - break; - case AF_INET6: - memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size); - break; - case AF_PACKET: - memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size); - ((struct sockaddr_ll*)p_dest)->sll_halen = p_size; - break; - default: - memcpy(p_dest->sa_data, p_data, p_size); - break; - } - p_dest->sa_family = p_family; -} - -static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry) -{ - if(!*p_resultList) - { - *p_resultList = p_entry; - } - else - { - struct ifaddrs *l_cur = *p_resultList; - while(l_cur->ifa_next) - { - l_cur = l_cur->ifa_next; - } - l_cur->ifa_next = p_entry; - } -} - -static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList) -{ - struct ifaddrs *l_entry; - - char *l_index; - char *l_name; - char *l_addr; - char *l_data; - - struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr); - - size_t l_nameSize = 0; - size_t l_addrSize = 0; - size_t l_dataSize = 0; - - size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); - struct rtattr *l_rta; - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFLA_ADDRESS: - case IFLA_BROADCAST: - l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize)); - break; - case IFLA_IFNAME: - l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); - break; - case IFLA_STATS: - l_dataSize += NLMSG_ALIGN(l_rtaSize); - break; - default: - break; - } - } - - l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize); - if (l_entry == NULL) - { - return -1; - } - memset(l_entry, 0, sizeof(struct ifaddrs)); - l_entry->ifa_name = ""; - - l_index = ((char *)l_entry) + sizeof(struct ifaddrs); - l_name = l_index + sizeof(int); - l_addr = l_name + l_nameSize; - l_data = l_addr + l_addrSize; - - /* Save the interface index so we can look it up when handling the - * addresses. - */ - memcpy(l_index, &l_info->ifi_index, sizeof(int)); - - l_entry->ifa_flags = l_info->ifi_flags; - - l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFLA_ADDRESS: - case IFLA_BROADCAST: - { - size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize); - makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); - ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index; - ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type; - if(l_rta->rta_type == IFLA_ADDRESS) - { - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; - } - l_addr += NLMSG_ALIGN(l_addrLen); - break; - } - case IFLA_IFNAME: - strncpy(l_name, l_rtaData, l_rtaDataSize); - l_name[l_rtaDataSize] = '\0'; - l_entry->ifa_name = l_name; - break; - case IFLA_STATS: - memcpy(l_data, l_rtaData, l_rtaDataSize); - l_entry->ifa_data = l_data; - break; - default: - break; - } - } - - addToEnd(p_resultList, l_entry); - return 0; -} - -static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks) -{ - int l_num = 0; - struct ifaddrs *l_cur = *p_links; - while(l_cur && l_num < p_numLinks) - { - char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs); - int l_index; - memcpy(&l_index, l_indexPtr, sizeof(int)); - if(l_index == p_index) - { - return l_cur; - } - - l_cur = l_cur->ifa_next; - ++l_num; - } - return NULL; -} - -static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks) -{ - struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr); - struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks); - - size_t l_nameSize = 0; - size_t l_addrSize = 0; - - int l_addedNetmask = 0; - - size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); - struct rtattr *l_rta; - struct ifaddrs *l_entry; - - char *l_name; - char *l_addr; - - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - if(l_info->ifa_family == AF_PACKET) - { - continue; - } - - switch(l_rta->rta_type) - { - case IFA_ADDRESS: - case IFA_LOCAL: - if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask) - { - /* Make room for netmask */ - l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); - l_addedNetmask = 1; - } - case IFA_BROADCAST: - l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); - break; - case IFA_LABEL: - l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); - break; - default: - break; - } - } - - l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); - if (l_entry == NULL) - { - return -1; - } - memset(l_entry, 0, sizeof(struct ifaddrs)); - l_entry->ifa_name = (l_interface ? l_interface->ifa_name : ""); - - l_name = ((char *)l_entry) + sizeof(struct ifaddrs); - l_addr = l_name + l_nameSize; - - l_entry->ifa_flags = l_info->ifa_flags; - if(l_interface) - { - l_entry->ifa_flags |= l_interface->ifa_flags; - } - - l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFA_ADDRESS: - case IFA_BROADCAST: - case IFA_LOCAL: - { - size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize); - makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); - if(l_info->ifa_family == AF_INET6) - { - if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData)) - { - ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index; - } - } - - /* Apparently in a point-to-point network IFA_ADDRESS contains - * the dest address and IFA_LOCAL contains the local address - */ - if(l_rta->rta_type == IFA_ADDRESS) - { - if(l_entry->ifa_addr) - { - l_entry->ifa_dstaddr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - } - else if(l_rta->rta_type == IFA_LOCAL) - { - if(l_entry->ifa_addr) - { - l_entry->ifa_dstaddr = l_entry->ifa_addr; - } - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; - } - l_addr += NLMSG_ALIGN(l_addrLen); - break; - } - case IFA_LABEL: - strncpy(l_name, l_rtaData, l_rtaDataSize); - l_name[l_rtaDataSize] = '\0'; - l_entry->ifa_name = l_name; - break; - default: - break; - } - } - - if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6)) - { - unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128); - unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen); - char l_mask[16] = {0}; - unsigned i; - for(i=0; i<(l_prefix/8); ++i) - { - l_mask[i] = 0xff; - } - if(l_prefix % 8) - { - l_mask[i] = 0xff << (8 - (l_prefix % 8)); - } - - makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8); - l_entry->ifa_netmask = (struct sockaddr *)l_addr; - } - - addToEnd(p_resultList, l_entry); - return 0; -} - -static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList) -{ - - int l_numLinks = 0; - pid_t l_pid = getpid(); - for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) - { - unsigned int l_nlsize = p_netlinkList->m_size; - struct nlmsghdr *l_hdr; - for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) - { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - break; - } - - if(l_hdr->nlmsg_type == RTM_NEWLINK) - { - if(interpretLink(l_hdr, p_resultList) == -1) - { - return -1; - } - ++l_numLinks; - } - } - } - return l_numLinks; -} - -static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks) -{ - pid_t l_pid = getpid(); - for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) - { - unsigned int l_nlsize = p_netlinkList->m_size; - struct nlmsghdr *l_hdr; - for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) - { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - break; - } - - if(l_hdr->nlmsg_type == RTM_NEWADDR) - { - if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1) - { - return -1; - } - } - } - } - return 0; -} - -int getifaddrs(struct ifaddrs **ifap) -{ - int l_socket; - int l_result; - int l_numLinks; - NetlinkList *l_linkResults; - NetlinkList *l_addrResults; - - if(!ifap) - { - return -1; - } - *ifap = NULL; - - l_socket = netlink_socket(); - if(l_socket < 0) - { - return -1; - } - - l_linkResults = getResultList(l_socket, RTM_GETLINK); - if(!l_linkResults) - { - close(l_socket); - return -1; - } - - l_addrResults = getResultList(l_socket, RTM_GETADDR); - if(!l_addrResults) - { - close(l_socket); - freeResultList(l_linkResults); - return -1; - } - - l_result = 0; - l_numLinks = interpretLinks(l_socket, l_linkResults, ifap); - if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1) - { - l_result = -1; - } - - freeResultList(l_linkResults); - freeResultList(l_addrResults); - close(l_socket); - return l_result; -} - -void freeifaddrs(struct ifaddrs *ifa) -{ - struct ifaddrs *l_cur; - while(ifa) - { - l_cur = ifa; - ifa = ifa->ifa_next; - uv__free(l_cur); - } -} diff --git a/outside/libuv-v1.7.5/src/unix/async.c b/outside/libuv-v1.7.5/src/unix/async.c deleted file mode 100644 index 9ff24aeb3d..0000000000 --- a/outside/libuv-v1.7.5/src/unix/async.c +++ /dev/null @@ -1,284 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* This file contains both the uv__async internal infrastructure and the - * user-facing uv_async_t functions. - */ - -#include "uv.h" -#include "internal.h" -#include "atomic-ops.h" - -#include -#include /* snprintf() */ -#include -#include -#include -#include - -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents); -static int uv__async_eventfd(void); - - -int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { - int err; - - err = uv__async_start(loop, &loop->async_watcher, uv__async_event); - if (err) - return err; - - uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC); - handle->async_cb = async_cb; - handle->pending = 0; - - QUEUE_INSERT_TAIL(&loop->async_handles, &handle->queue); - uv__handle_start(handle); - - return 0; -} - - -int uv_async_send(uv_async_t* handle) { - /* Do a cheap read first. */ - if (ACCESS_ONCE(int, handle->pending) != 0) - return 0; - - if (cmpxchgi(&handle->pending, 0, 1) == 0) - uv__async_send(&handle->loop->async_watcher); - - return 0; -} - - -void uv__async_close(uv_async_t* handle) { - QUEUE_REMOVE(&handle->queue); - uv__handle_stop(handle); -} - - -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents) { - QUEUE* q; - uv_async_t* h; - - QUEUE_FOREACH(q, &loop->async_handles) { - h = QUEUE_DATA(q, uv_async_t, queue); - - if (cmpxchgi(&h->pending, 1, 0) == 0) - continue; - - if (h->async_cb == NULL) - continue; - h->async_cb(h); - } -} - - -static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - struct uv__async* wa; - char buf[1024]; - unsigned n; - ssize_t r; - - n = 0; - for (;;) { - r = read(w->fd, buf, sizeof(buf)); - - if (r > 0) - n += r; - - if (r == sizeof(buf)) - continue; - - if (r != -1) - break; - - if (errno == EAGAIN || errno == EWOULDBLOCK) - break; - - if (errno == EINTR) - continue; - - abort(); - } - - wa = container_of(w, struct uv__async, io_watcher); - -#if defined(__linux__) - if (wa->wfd == -1) { - uint64_t val; - assert(n == sizeof(val)); - memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */ - wa->cb(loop, wa, val); - return; - } -#endif - - wa->cb(loop, wa, n); -} - - -void uv__async_send(struct uv__async* wa) { - const void* buf; - ssize_t len; - int fd; - int r; - - buf = ""; - len = 1; - fd = wa->wfd; - -#if defined(__linux__) - if (fd == -1) { - static const uint64_t val = 1; - buf = &val; - len = sizeof(val); - fd = wa->io_watcher.fd; /* eventfd */ - } -#endif - - do - r = write(fd, buf, len); - while (r == -1 && errno == EINTR); - - if (r == len) - return; - - if (r == -1) - if (errno == EAGAIN || errno == EWOULDBLOCK) - return; - - abort(); -} - - -void uv__async_init(struct uv__async* wa) { - wa->io_watcher.fd = -1; - wa->wfd = -1; -} - - -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { - int pipefd[2]; - int err; - - if (wa->io_watcher.fd != -1) - return 0; - - err = uv__async_eventfd(); - if (err >= 0) { - pipefd[0] = err; - pipefd[1] = -1; - } - else if (err == -ENOSYS) { - err = uv__make_pipe(pipefd, UV__F_NONBLOCK); -#if defined(__linux__) - /* Save a file descriptor by opening one of the pipe descriptors as - * read/write through the procfs. That file descriptor can then - * function as both ends of the pipe. - */ - if (err == 0) { - char buf[32]; - int fd; - - snprintf(buf, sizeof(buf), "/proc/self/fd/%d", pipefd[0]); - fd = uv__open_cloexec(buf, O_RDWR); - if (fd >= 0) { - uv__close(pipefd[0]); - uv__close(pipefd[1]); - pipefd[0] = fd; - pipefd[1] = fd; - } - } -#endif - } - - if (err < 0) - return err; - - uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]); - uv__io_start(loop, &wa->io_watcher, UV__POLLIN); - wa->wfd = pipefd[1]; - wa->cb = cb; - - return 0; -} - - -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) { - if (wa->io_watcher.fd == -1) - return; - - if (wa->wfd != -1) { - if (wa->wfd != wa->io_watcher.fd) - uv__close(wa->wfd); - wa->wfd = -1; - } - - uv__io_stop(loop, &wa->io_watcher, UV__POLLIN); - uv__close(wa->io_watcher.fd); - wa->io_watcher.fd = -1; -} - - -static int uv__async_eventfd() { -#if defined(__linux__) - static int no_eventfd2; - static int no_eventfd; - int fd; - - if (no_eventfd2) - goto skip_eventfd2; - - fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK); - if (fd != -1) - return fd; - - if (errno != ENOSYS) - return -errno; - - no_eventfd2 = 1; - -skip_eventfd2: - - if (no_eventfd) - goto skip_eventfd; - - fd = uv__eventfd(0); - if (fd != -1) { - uv__cloexec(fd, 1); - uv__nonblock(fd, 1); - return fd; - } - - if (errno != ENOSYS) - return -errno; - - no_eventfd = 1; - -skip_eventfd: - -#endif - - return -ENOSYS; -} diff --git a/outside/libuv-v1.7.5/src/unix/atomic-ops.h b/outside/libuv-v1.7.5/src/unix/atomic-ops.h deleted file mode 100644 index 8fb157dcc6..0000000000 --- a/outside/libuv-v1.7.5/src/unix/atomic-ops.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2013, Ben Noordhuis - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef UV_ATOMIC_OPS_H_ -#define UV_ATOMIC_OPS_H_ - -#include "internal.h" /* UV_UNUSED */ - -UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)); -UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)); -UV_UNUSED(static void cpu_relax(void)); - -/* Prefer hand-rolled assembly over the gcc builtins because the latter also - * issue full memory barriers. - */ -UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { -#if defined(__i386__) || defined(__x86_64__) - int out; - __asm__ __volatile__ ("lock; cmpxchg %2, %1;" - : "=a" (out), "+m" (*(volatile int*) ptr) - : "r" (newval), "0" (oldval) - : "memory"); - return out; -#elif defined(_AIX) && defined(__xlC__) - const int out = (*(volatile int*) ptr); - __compare_and_swap(ptr, &oldval, newval); - return out; -#else - return __sync_val_compare_and_swap(ptr, oldval, newval); -#endif -} - -UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) { -#if defined(__i386__) || defined(__x86_64__) - long out; - __asm__ __volatile__ ("lock; cmpxchg %2, %1;" - : "=a" (out), "+m" (*(volatile long*) ptr) - : "r" (newval), "0" (oldval) - : "memory"); - return out; -#elif defined(_AIX) && defined(__xlC__) - const long out = (*(volatile int*) ptr); -# if defined(__64BIT__) - __compare_and_swaplp(ptr, &oldval, newval); -# else - __compare_and_swap(ptr, &oldval, newval); -# endif /* if defined(__64BIT__) */ - return out; -#else - return __sync_val_compare_and_swap(ptr, oldval, newval); -#endif -} - -UV_UNUSED(static void cpu_relax(void)) { -#if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */ -#endif -} - -#endif /* UV_ATOMIC_OPS_H_ */ diff --git a/outside/libuv-v1.7.5/src/unix/core.c b/outside/libuv-v1.7.5/src/unix/core.c deleted file mode 100644 index e149357e07..0000000000 --- a/outside/libuv-v1.7.5/src/unix/core.c +++ /dev/null @@ -1,1091 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include /* NULL */ -#include /* printf */ -#include -#include /* strerror */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* INT_MAX, PATH_MAX, IOV_MAX */ -#include /* writev */ -#include /* getrusage */ -#include - -#ifdef __linux__ -# include -#endif - -#ifdef __sun -# include -# include -#endif - -#ifdef __APPLE__ -# include /* _NSGetExecutablePath */ -# include -# include -#endif - -#if defined(__FreeBSD__) || defined(__DragonFly__) -# include -# include -# include -# include -# define UV__O_CLOEXEC O_CLOEXEC -# if defined(__FreeBSD__) && __FreeBSD__ >= 10 -# define uv__accept4 accept4 -# define UV__SOCK_NONBLOCK SOCK_NONBLOCK -# define UV__SOCK_CLOEXEC SOCK_CLOEXEC -# endif -# if !defined(F_DUP2FD_CLOEXEC) && defined(_F_DUP2FD_CLOEXEC) -# define F_DUP2FD_CLOEXEC _F_DUP2FD_CLOEXEC -# endif -#endif - -#ifdef _AIX -#include -#endif - -static int uv__run_pending(uv_loop_t* loop); - -/* Verify that uv_buf_t is ABI-compatible with struct iovec. */ -STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec)); -STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) == - sizeof(((struct iovec*) 0)->iov_base)); -STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) == - sizeof(((struct iovec*) 0)->iov_len)); -STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base)); -STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len)); - - -uint64_t uv_hrtime(void) { - return uv__hrtime(UV_CLOCK_PRECISE); -} - - -void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - - handle->flags |= UV_CLOSING; - handle->close_cb = close_cb; - - switch (handle->type) { - case UV_NAMED_PIPE: - uv__pipe_close((uv_pipe_t*)handle); - break; - - case UV_TTY: - uv__stream_close((uv_stream_t*)handle); - break; - - case UV_TCP: - uv__tcp_close((uv_tcp_t*)handle); - break; - - case UV_UDP: - uv__udp_close((uv_udp_t*)handle); - break; - - case UV_PREPARE: - uv__prepare_close((uv_prepare_t*)handle); - break; - - case UV_CHECK: - uv__check_close((uv_check_t*)handle); - break; - - case UV_IDLE: - uv__idle_close((uv_idle_t*)handle); - break; - - case UV_ASYNC: - uv__async_close((uv_async_t*)handle); - break; - - case UV_TIMER: - uv__timer_close((uv_timer_t*)handle); - break; - - case UV_PROCESS: - uv__process_close((uv_process_t*)handle); - break; - - case UV_FS_EVENT: - uv__fs_event_close((uv_fs_event_t*)handle); - break; - - case UV_POLL: - uv__poll_close((uv_poll_t*)handle); - break; - - case UV_FS_POLL: - uv__fs_poll_close((uv_fs_poll_t*)handle); - break; - - case UV_SIGNAL: - uv__signal_close((uv_signal_t*) handle); - /* Signal handles may not be closed immediately. The signal code will */ - /* itself close uv__make_close_pending whenever appropriate. */ - return; - - default: - assert(0); - } - - uv__make_close_pending(handle); -} - -int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) { - int r; - int fd; - socklen_t len; - - if (handle == NULL || value == NULL) - return -EINVAL; - - if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE) - fd = uv__stream_fd((uv_stream_t*) handle); - else if (handle->type == UV_UDP) - fd = ((uv_udp_t *) handle)->io_watcher.fd; - else - return -ENOTSUP; - - len = sizeof(*value); - - if (*value == 0) - r = getsockopt(fd, SOL_SOCKET, optname, value, &len); - else - r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len); - - if (r < 0) - return -errno; - - return 0; -} - -void uv__make_close_pending(uv_handle_t* handle) { - assert(handle->flags & UV_CLOSING); - assert(!(handle->flags & UV_CLOSED)); - handle->next_closing = handle->loop->closing_handles; - handle->loop->closing_handles = handle; -} - -int uv__getiovmax(void) { -#if defined(IOV_MAX) - return IOV_MAX; -#elif defined(_SC_IOV_MAX) - static int iovmax = -1; - if (iovmax == -1) - iovmax = sysconf(_SC_IOV_MAX); - return iovmax; -#else - return 1024; -#endif -} - - -static void uv__finish_close(uv_handle_t* handle) { - /* Note: while the handle is in the UV_CLOSING state now, it's still possible - * for it to be active in the sense that uv__is_active() returns true. - * A good example is when the user calls uv_shutdown(), immediately followed - * by uv_close(). The handle is considered active at this point because the - * completion of the shutdown req is still pending. - */ - assert(handle->flags & UV_CLOSING); - assert(!(handle->flags & UV_CLOSED)); - handle->flags |= UV_CLOSED; - - switch (handle->type) { - case UV_PREPARE: - case UV_CHECK: - case UV_IDLE: - case UV_ASYNC: - case UV_TIMER: - case UV_PROCESS: - case UV_FS_EVENT: - case UV_FS_POLL: - case UV_POLL: - case UV_SIGNAL: - break; - - case UV_NAMED_PIPE: - case UV_TCP: - case UV_TTY: - uv__stream_destroy((uv_stream_t*)handle); - break; - - case UV_UDP: - uv__udp_finish_close((uv_udp_t*)handle); - break; - - default: - assert(0); - break; - } - - uv__handle_unref(handle); - QUEUE_REMOVE(&handle->handle_queue); - - if (handle->close_cb) { - handle->close_cb(handle); - } -} - - -static void uv__run_closing_handles(uv_loop_t* loop) { - uv_handle_t* p; - uv_handle_t* q; - - p = loop->closing_handles; - loop->closing_handles = NULL; - - while (p) { - q = p->next_closing; - uv__finish_close(p); - p = q; - } -} - - -int uv_is_closing(const uv_handle_t* handle) { - return uv__is_closing(handle); -} - - -int uv_backend_fd(const uv_loop_t* loop) { - return loop->backend_fd; -} - - -int uv_backend_timeout(const uv_loop_t* loop) { - if (loop->stop_flag != 0) - return 0; - - if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) - return 0; - - if (!QUEUE_EMPTY(&loop->idle_handles)) - return 0; - - if (!QUEUE_EMPTY(&loop->pending_queue)) - return 0; - - if (loop->closing_handles) - return 0; - - return uv__next_timeout(loop); -} - - -static int uv__loop_alive(const uv_loop_t* loop) { - return uv__has_active_handles(loop) || - uv__has_active_reqs(loop) || - loop->closing_handles != NULL; -} - - -int uv_loop_alive(const uv_loop_t* loop) { - return uv__loop_alive(loop); -} - - -int uv_run(uv_loop_t* loop, uv_run_mode mode) { - int timeout; - int r; - int ran_pending; - - r = uv__loop_alive(loop); - if (!r) - uv__update_time(loop); - - while (r != 0 && loop->stop_flag == 0) { - uv__update_time(loop); - uv__run_timers(loop); - ran_pending = uv__run_pending(loop); - uv__run_idle(loop); - uv__run_prepare(loop); - - timeout = 0; - if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) - timeout = uv_backend_timeout(loop); - - uv__io_poll(loop, timeout); - uv__run_check(loop); - uv__run_closing_handles(loop); - - if (mode == UV_RUN_ONCE) { - /* UV_RUN_ONCE implies forward progress: at least one callback must have - * been invoked when it returns. uv__io_poll() can return without doing - * I/O (meaning: no callbacks) when its timeout expires - which means we - * have pending timers that satisfy the forward progress constraint. - * - * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from - * the check. - */ - uv__update_time(loop); - uv__run_timers(loop); - } - - r = uv__loop_alive(loop); - if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT) - break; - } - - /* The if statement lets gcc compile it to a conditional store. Avoids - * dirtying a cache line. - */ - if (loop->stop_flag != 0) - loop->stop_flag = 0; - - return r; -} - - -void uv_update_time(uv_loop_t* loop) { - uv__update_time(loop); -} - - -int uv_is_active(const uv_handle_t* handle) { - return uv__is_active(handle); -} - - -/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */ -int uv__socket(int domain, int type, int protocol) { - int sockfd; - int err; - -#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) - sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol); - if (sockfd != -1) - return sockfd; - - if (errno != EINVAL) - return -errno; -#endif - - sockfd = socket(domain, type, protocol); - if (sockfd == -1) - return -errno; - - err = uv__nonblock(sockfd, 1); - if (err == 0) - err = uv__cloexec(sockfd, 1); - - if (err) { - uv__close(sockfd); - return err; - } - -#if defined(SO_NOSIGPIPE) - { - int on = 1; - setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); - } -#endif - - return sockfd; -} - - -int uv__accept(int sockfd) { - int peerfd; - int err; - - assert(sockfd >= 0); - - while (1) { -#if defined(__linux__) || __FreeBSD__ >= 10 - static int no_accept4; - - if (no_accept4) - goto skip; - - peerfd = uv__accept4(sockfd, - NULL, - NULL, - UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC); - if (peerfd != -1) - return peerfd; - - if (errno == EINTR) - continue; - - if (errno != ENOSYS) - return -errno; - - no_accept4 = 1; -skip: -#endif - - peerfd = accept(sockfd, NULL, NULL); - if (peerfd == -1) { - if (errno == EINTR) - continue; - return -errno; - } - - err = uv__cloexec(peerfd, 1); - if (err == 0) - err = uv__nonblock(peerfd, 1); - - if (err) { - uv__close(peerfd); - return err; - } - - return peerfd; - } -} - - -int uv__close(int fd) { - int saved_errno; - int rc; - - assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */ - assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ - - saved_errno = errno; - rc = close(fd); - if (rc == -1) { - rc = -errno; - if (rc == -EINTR) - rc = -EINPROGRESS; /* For platform/libc consistency. */ - errno = saved_errno; - } - - return rc; -} - - -#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \ - defined(_AIX) || defined(__DragonFly__) - -int uv__nonblock(int fd, int set) { - int r; - - do - r = ioctl(fd, FIONBIO, &set); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - - -int uv__cloexec(int fd, int set) { - int r; - - do - r = ioctl(fd, set ? FIOCLEX : FIONCLEX); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - -#else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \ - defined(_AIX) || defined(__DragonFly__)) */ - -int uv__nonblock(int fd, int set) { - int flags; - int r; - - do - r = fcntl(fd, F_GETFL); - while (r == -1 && errno == EINTR); - - if (r == -1) - return -errno; - - /* Bail out now if already set/clear. */ - if (!!(r & O_NONBLOCK) == !!set) - return 0; - - if (set) - flags = r | O_NONBLOCK; - else - flags = r & ~O_NONBLOCK; - - do - r = fcntl(fd, F_SETFL, flags); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - - -int uv__cloexec(int fd, int set) { - int flags; - int r; - - do - r = fcntl(fd, F_GETFD); - while (r == -1 && errno == EINTR); - - if (r == -1) - return -errno; - - /* Bail out now if already set/clear. */ - if (!!(r & FD_CLOEXEC) == !!set) - return 0; - - if (set) - flags = r | FD_CLOEXEC; - else - flags = r & ~FD_CLOEXEC; - - do - r = fcntl(fd, F_SETFD, flags); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - -#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \ - defined(_AIX) || defined(__DragonFly__) */ - - -/* This function is not execve-safe, there is a race window - * between the call to dup() and fcntl(FD_CLOEXEC). - */ -int uv__dup(int fd) { - int err; - - fd = dup(fd); - - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err) { - uv__close(fd); - return err; - } - - return fd; -} - - -ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) { - struct cmsghdr* cmsg; - ssize_t rc; - int* pfd; - int* end; -#if defined(__linux__) - static int no_msg_cmsg_cloexec; - if (no_msg_cmsg_cloexec == 0) { - rc = recvmsg(fd, msg, flags | 0x40000000); /* MSG_CMSG_CLOEXEC */ - if (rc != -1) - return rc; - if (errno != EINVAL) - return -errno; - rc = recvmsg(fd, msg, flags); - if (rc == -1) - return -errno; - no_msg_cmsg_cloexec = 1; - } else { - rc = recvmsg(fd, msg, flags); - } -#else - rc = recvmsg(fd, msg, flags); -#endif - if (rc == -1) - return -errno; - if (msg->msg_controllen == 0) - return rc; - for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) - if (cmsg->cmsg_type == SCM_RIGHTS) - for (pfd = (int*) CMSG_DATA(cmsg), - end = (int*) ((char*) cmsg + cmsg->cmsg_len); - pfd < end; - pfd += 1) - uv__cloexec(*pfd, 1); - return rc; -} - - -int uv_cwd(char* buffer, size_t* size) { - if (buffer == NULL || size == NULL) - return -EINVAL; - - if (getcwd(buffer, *size) == NULL) - return -errno; - - *size = strlen(buffer); - if (*size > 1 && buffer[*size - 1] == '/') { - buffer[*size-1] = '\0'; - (*size)--; - } - - return 0; -} - - -int uv_chdir(const char* dir) { - if (chdir(dir)) - return -errno; - - return 0; -} - - -void uv_disable_stdio_inheritance(void) { - int fd; - - /* Set the CLOEXEC flag on all open descriptors. Unconditionally try the - * first 16 file descriptors. After that, bail out after the first error. - */ - for (fd = 0; ; fd++) - if (uv__cloexec(fd, 1) && fd > 15) - break; -} - - -int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { - int fd_out; - - switch (handle->type) { - case UV_TCP: - case UV_NAMED_PIPE: - case UV_TTY: - fd_out = uv__stream_fd((uv_stream_t*) handle); - break; - - case UV_UDP: - fd_out = ((uv_udp_t *) handle)->io_watcher.fd; - break; - - case UV_POLL: - fd_out = ((uv_poll_t *) handle)->io_watcher.fd; - break; - - default: - return -EINVAL; - } - - if (uv__is_closing(handle) || fd_out == -1) - return -EBADF; - - *fd = fd_out; - return 0; -} - - -static int uv__run_pending(uv_loop_t* loop) { - QUEUE* q; - QUEUE pq; - uv__io_t* w; - - if (QUEUE_EMPTY(&loop->pending_queue)) - return 0; - - QUEUE_INIT(&pq); - q = QUEUE_HEAD(&loop->pending_queue); - QUEUE_SPLIT(&loop->pending_queue, q, &pq); - - while (!QUEUE_EMPTY(&pq)) { - q = QUEUE_HEAD(&pq); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - w = QUEUE_DATA(q, uv__io_t, pending_queue); - w->cb(loop, w, UV__POLLOUT); - } - - return 1; -} - - -static unsigned int next_power_of_two(unsigned int val) { - val -= 1; - val |= val >> 1; - val |= val >> 2; - val |= val >> 4; - val |= val >> 8; - val |= val >> 16; - val += 1; - return val; -} - -static void maybe_resize(uv_loop_t* loop, unsigned int len) { - uv__io_t** watchers; - void* fake_watcher_list; - void* fake_watcher_count; - unsigned int nwatchers; - unsigned int i; - - if (len <= loop->nwatchers) - return; - - /* Preserve fake watcher list and count at the end of the watchers */ - if (loop->watchers != NULL) { - fake_watcher_list = loop->watchers[loop->nwatchers]; - fake_watcher_count = loop->watchers[loop->nwatchers + 1]; - } else { - fake_watcher_list = NULL; - fake_watcher_count = NULL; - } - - nwatchers = next_power_of_two(len + 2) - 2; - watchers = uv__realloc(loop->watchers, - (nwatchers + 2) * sizeof(loop->watchers[0])); - - if (watchers == NULL) - abort(); - for (i = loop->nwatchers; i < nwatchers; i++) - watchers[i] = NULL; - watchers[nwatchers] = fake_watcher_list; - watchers[nwatchers + 1] = fake_watcher_count; - - loop->watchers = watchers; - loop->nwatchers = nwatchers; -} - - -void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) { - assert(cb != NULL); - assert(fd >= -1); - QUEUE_INIT(&w->pending_queue); - QUEUE_INIT(&w->watcher_queue); - w->cb = cb; - w->fd = fd; - w->events = 0; - w->pevents = 0; - -#if defined(UV_HAVE_KQUEUE) - w->rcount = 0; - w->wcount = 0; -#endif /* defined(UV_HAVE_KQUEUE) */ -} - - -void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT))); - assert(0 != events); - assert(w->fd >= 0); - assert(w->fd < INT_MAX); - - w->pevents |= events; - maybe_resize(loop, w->fd + 1); - -#if !defined(__sun) - /* The event ports backend needs to rearm all file descriptors on each and - * every tick of the event loop but the other backends allow us to - * short-circuit here if the event mask is unchanged. - */ - if (w->events == w->pevents) { - if (w->events == 0 && !QUEUE_EMPTY(&w->watcher_queue)) { - QUEUE_REMOVE(&w->watcher_queue); - QUEUE_INIT(&w->watcher_queue); - } - return; - } -#endif - - if (QUEUE_EMPTY(&w->watcher_queue)) - QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); - - if (loop->watchers[w->fd] == NULL) { - loop->watchers[w->fd] = w; - loop->nfds++; - } -} - - -void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT))); - assert(0 != events); - - if (w->fd == -1) - return; - - assert(w->fd >= 0); - - /* Happens when uv__io_stop() is called on a handle that was never started. */ - if ((unsigned) w->fd >= loop->nwatchers) - return; - - w->pevents &= ~events; - - if (w->pevents == 0) { - QUEUE_REMOVE(&w->watcher_queue); - QUEUE_INIT(&w->watcher_queue); - - if (loop->watchers[w->fd] != NULL) { - assert(loop->watchers[w->fd] == w); - assert(loop->nfds > 0); - loop->watchers[w->fd] = NULL; - loop->nfds--; - w->events = 0; - } - } - else if (QUEUE_EMPTY(&w->watcher_queue)) - QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); -} - - -void uv__io_close(uv_loop_t* loop, uv__io_t* w) { - uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT); - QUEUE_REMOVE(&w->pending_queue); - - /* Remove stale events for this file descriptor */ - uv__platform_invalidate_fd(loop, w->fd); -} - - -void uv__io_feed(uv_loop_t* loop, uv__io_t* w) { - if (QUEUE_EMPTY(&w->pending_queue)) - QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue); -} - - -int uv__io_active(const uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT))); - assert(0 != events); - return 0 != (w->pevents & events); -} - - -int uv_getrusage(uv_rusage_t* rusage) { - struct rusage usage; - - if (getrusage(RUSAGE_SELF, &usage)) - return -errno; - - rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec; - rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec; - - rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec; - rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec; - - rusage->ru_maxrss = usage.ru_maxrss; - rusage->ru_ixrss = usage.ru_ixrss; - rusage->ru_idrss = usage.ru_idrss; - rusage->ru_isrss = usage.ru_isrss; - rusage->ru_minflt = usage.ru_minflt; - rusage->ru_majflt = usage.ru_majflt; - rusage->ru_nswap = usage.ru_nswap; - rusage->ru_inblock = usage.ru_inblock; - rusage->ru_oublock = usage.ru_oublock; - rusage->ru_msgsnd = usage.ru_msgsnd; - rusage->ru_msgrcv = usage.ru_msgrcv; - rusage->ru_nsignals = usage.ru_nsignals; - rusage->ru_nvcsw = usage.ru_nvcsw; - rusage->ru_nivcsw = usage.ru_nivcsw; - - return 0; -} - - -int uv__open_cloexec(const char* path, int flags) { - int err; - int fd; - -#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 9) || \ - defined(__DragonFly__) - static int no_cloexec; - - if (!no_cloexec) { - fd = open(path, flags | UV__O_CLOEXEC); - if (fd != -1) - return fd; - - if (errno != EINVAL) - return -errno; - - /* O_CLOEXEC not supported. */ - no_cloexec = 1; - } -#endif - - fd = open(path, flags); - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err) { - uv__close(fd); - return err; - } - - return fd; -} - - -int uv__dup2_cloexec(int oldfd, int newfd) { - int r; -#if defined(__FreeBSD__) && __FreeBSD__ >= 10 - do - r = dup3(oldfd, newfd, O_CLOEXEC); - while (r == -1 && errno == EINTR); - if (r == -1) - return -errno; - return r; -#elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC) - do - r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd); - while (r == -1 && errno == EINTR); - if (r != -1) - return r; - if (errno != EINVAL) - return -errno; - /* Fall through. */ -#elif defined(__linux__) - static int no_dup3; - if (!no_dup3) { - do - r = uv__dup3(oldfd, newfd, UV__O_CLOEXEC); - while (r == -1 && (errno == EINTR || errno == EBUSY)); - if (r != -1) - return r; - if (errno != ENOSYS) - return -errno; - /* Fall through. */ - no_dup3 = 1; - } -#endif - { - int err; - do - r = dup2(oldfd, newfd); -#if defined(__linux__) - while (r == -1 && (errno == EINTR || errno == EBUSY)); -#else - while (r == -1 && errno == EINTR); -#endif - - if (r == -1) - return -errno; - - err = uv__cloexec(newfd, 1); - if (err) { - uv__close(newfd); - return err; - } - - return r; - } -} - - -int uv_os_homedir(char* buffer, size_t* size) { - struct passwd pw; - struct passwd* result; - char* buf; - uid_t uid; - size_t bufsize; - size_t len; - long initsize; - int r; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - /* Check if the HOME environment variable is set first */ - buf = getenv("HOME"); - - if (buf != NULL) { - len = strlen(buf); - - if (len >= *size) { - *size = len; - return -ENOBUFS; - } - - memcpy(buffer, buf, len + 1); - *size = len; - - return 0; - } - - /* HOME is not set, so call getpwuid() */ - initsize = sysconf(_SC_GETPW_R_SIZE_MAX); - - if (initsize <= 0) - bufsize = 4096; - else - bufsize = (size_t) initsize; - - uid = getuid(); - buf = NULL; - - for (;;) { - uv__free(buf); - buf = uv__malloc(bufsize); - - if (buf == NULL) - return -ENOMEM; - - r = getpwuid_r(uid, &pw, buf, bufsize, &result); - - if (r != ERANGE) - break; - - bufsize *= 2; - } - - if (r != 0) { - uv__free(buf); - return -r; - } - - if (result == NULL) { - uv__free(buf); - return -ENOENT; - } - - len = strlen(pw.pw_dir); - - if (len >= *size) { - *size = len; - uv__free(buf); - return -ENOBUFS; - } - - memcpy(buffer, pw.pw_dir, len + 1); - *size = len; - uv__free(buf); - - return 0; -} diff --git a/outside/libuv-v1.7.5/src/unix/darwin-proctitle.c b/outside/libuv-v1.7.5/src/unix/darwin-proctitle.c deleted file mode 100644 index 1142311609..0000000000 --- a/outside/libuv-v1.7.5/src/unix/darwin-proctitle.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include - -#include - -#if !TARGET_OS_IPHONE -# include -# include -#endif - - -static int uv__pthread_setname_np(const char* name) { - int (*dynamic_pthread_setname_np)(const char* name); - char namebuf[64]; /* MAXTHREADNAMESIZE */ - int err; - - /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */ - *(void **)(&dynamic_pthread_setname_np) = - dlsym(RTLD_DEFAULT, "pthread_setname_np"); - - if (dynamic_pthread_setname_np == NULL) - return -ENOSYS; - - strncpy(namebuf, name, sizeof(namebuf) - 1); - namebuf[sizeof(namebuf) - 1] = '\0'; - - err = dynamic_pthread_setname_np(namebuf); - if (err) - return -err; - - return 0; -} - - -int uv__set_process_title(const char* title) { -#if TARGET_OS_IPHONE - return uv__pthread_setname_np(title); -#else - CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, - const char*, - CFStringEncoding); - CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef); - void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef); - void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef); - CFTypeRef (*pLSGetCurrentApplicationASN)(void); - OSStatus (*pLSSetApplicationInformationItem)(int, - CFTypeRef, - CFStringRef, - CFStringRef, - CFDictionaryRef*); - void* application_services_handle; - void* core_foundation_handle; - CFBundleRef launch_services_bundle; - CFStringRef* display_name_key; - CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef); - CFBundleRef (*pCFBundleGetMainBundle)(void); - CFBundleRef hi_services_bundle; - OSStatus (*pSetApplicationIsDaemon)(int); - CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef); - void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t, - void*); - CFTypeRef asn; - int err; - - err = -ENOENT; - application_services_handle = dlopen("/System/Library/Frameworks/" - "ApplicationServices.framework/" - "Versions/A/ApplicationServices", - RTLD_LAZY | RTLD_LOCAL); - core_foundation_handle = dlopen("/System/Library/Frameworks/" - "CoreFoundation.framework/" - "Versions/A/CoreFoundation", - RTLD_LAZY | RTLD_LOCAL); - - if (application_services_handle == NULL || core_foundation_handle == NULL) - goto out; - - *(void **)(&pCFStringCreateWithCString) = - dlsym(core_foundation_handle, "CFStringCreateWithCString"); - *(void **)(&pCFBundleGetBundleWithIdentifier) = - dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier"); - *(void **)(&pCFBundleGetDataPointerForName) = - dlsym(core_foundation_handle, "CFBundleGetDataPointerForName"); - *(void **)(&pCFBundleGetFunctionPointerForName) = - dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName"); - - if (pCFStringCreateWithCString == NULL || - pCFBundleGetBundleWithIdentifier == NULL || - pCFBundleGetDataPointerForName == NULL || - pCFBundleGetFunctionPointerForName == NULL) { - goto out; - } - -#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) - - launch_services_bundle = - pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices")); - - if (launch_services_bundle == NULL) - goto out; - - *(void **)(&pLSGetCurrentApplicationASN) = - pCFBundleGetFunctionPointerForName(launch_services_bundle, - S("_LSGetCurrentApplicationASN")); - - if (pLSGetCurrentApplicationASN == NULL) - goto out; - - *(void **)(&pLSSetApplicationInformationItem) = - pCFBundleGetFunctionPointerForName(launch_services_bundle, - S("_LSSetApplicationInformationItem")); - - if (pLSSetApplicationInformationItem == NULL) - goto out; - - display_name_key = pCFBundleGetDataPointerForName(launch_services_bundle, - S("_kLSDisplayNameKey")); - - if (display_name_key == NULL || *display_name_key == NULL) - goto out; - - *(void **)(&pCFBundleGetInfoDictionary) = dlsym(core_foundation_handle, - "CFBundleGetInfoDictionary"); - *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle, - "CFBundleGetMainBundle"); - if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL) - goto out; - - /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */ - hi_services_bundle = - pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices")); - err = -ENOENT; - if (hi_services_bundle == NULL) - goto out; - - *(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName( - hi_services_bundle, - S("SetApplicationIsDaemon")); - *(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName( - launch_services_bundle, - S("_LSApplicationCheckIn")); - *(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) = - pCFBundleGetFunctionPointerForName( - launch_services_bundle, - S("_LSSetApplicationLaunchServicesServerConnectionStatus")); - if (pSetApplicationIsDaemon == NULL || - pLSApplicationCheckIn == NULL || - pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) { - goto out; - } - - if (pSetApplicationIsDaemon(1) != noErr) - goto out; - - pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL); - - /* Check into process manager?! */ - pLSApplicationCheckIn(-2, - pCFBundleGetInfoDictionary(pCFBundleGetMainBundle())); - - asn = pLSGetCurrentApplicationASN(); - - err = -EINVAL; - if (pLSSetApplicationInformationItem(-2, /* Magic value. */ - asn, - *display_name_key, - S(title), - NULL) != noErr) { - goto out; - } - - uv__pthread_setname_np(title); /* Don't care if it fails. */ - err = 0; - -out: - if (core_foundation_handle != NULL) - dlclose(core_foundation_handle); - - if (application_services_handle != NULL) - dlclose(application_services_handle); - - return err; -#endif /* !TARGET_OS_IPHONE */ -} diff --git a/outside/libuv-v1.7.5/src/unix/darwin.c b/outside/libuv-v1.7.5/src/unix/darwin.c deleted file mode 100644 index dab6ca999d..0000000000 --- a/outside/libuv-v1.7.5/src/unix/darwin.c +++ /dev/null @@ -1,333 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include /* _NSGetExecutablePath */ -#include -#include -#include /* sysconf */ - - -int uv__platform_loop_init(uv_loop_t* loop) { - loop->cf_state = NULL; - - if (uv__kqueue_init(loop)) - return -errno; - - return 0; -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { - uv__fsevents_loop_delete(loop); -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - static mach_timebase_info_data_t info; - - if ((ACCESS_ONCE(uint32_t, info.numer) == 0 || - ACCESS_ONCE(uint32_t, info.denom) == 0) && - mach_timebase_info(&info) != KERN_SUCCESS) - abort(); - - return mach_absolute_time() * info.numer / info.denom; -} - - -int uv_exepath(char* buffer, size_t* size) { - /* realpath(exepath) may be > PATH_MAX so double it to be on the safe side. */ - char abspath[PATH_MAX * 2 + 1]; - char exepath[PATH_MAX + 1]; - uint32_t exepath_size; - size_t abspath_size; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - exepath_size = sizeof(exepath); - if (_NSGetExecutablePath(exepath, &exepath_size)) - return -EIO; - - if (realpath(exepath, abspath) != abspath) - return -errno; - - abspath_size = strlen(abspath); - if (abspath_size == 0) - return -EIO; - - *size -= 1; - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - vm_statistics_data_t info; - mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t); - - if (host_statistics(mach_host_self(), HOST_VM_INFO, - (host_info_t)&info, &count) != KERN_SUCCESS) { - return -EINVAL; /* FIXME(bnoordhuis) Translate error. */ - } - - return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE); -} - - -uint64_t uv_get_total_memory(void) { - uint64_t info; - int which[] = {CTL_HW, HW_MEMSIZE}; - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -int uv_resident_set_memory(size_t* rss) { - mach_msg_type_number_t count; - task_basic_info_data_t info; - kern_return_t err; - - count = TASK_BASIC_INFO_COUNT; - err = task_info(mach_task_self(), - TASK_BASIC_INFO, - (task_info_t) &info, - &count); - (void) &err; - /* task_info(TASK_BASIC_INFO) cannot really fail. Anything other than - * KERN_SUCCESS implies a libuv bug. - */ - assert(err == KERN_SUCCESS); - *rss = info.resident_size; - - return 0; -} - - -int uv_uptime(double* uptime) { - time_t now; - struct timeval info; - size_t size = sizeof(info); - static int which[] = {CTL_KERN, KERN_BOOTTIME}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - now = time(NULL); - *uptime = now - info.tv_sec; - - return 0; -} - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), - multiplier = ((uint64_t)1000L / ticks); - char model[512]; - uint64_t cpuspeed; - size_t size; - unsigned int i; - natural_t numcpus; - mach_msg_type_number_t msg_type; - processor_cpu_load_info_data_t *info; - uv_cpu_info_t* cpu_info; - - size = sizeof(model); - if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) && - sysctlbyname("hw.model", &model, &size, NULL, 0)) { - return -errno; - } - - size = sizeof(cpuspeed); - if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0)) - return -errno; - - if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, - (processor_info_array_t*)&info, - &msg_type) != KERN_SUCCESS) { - return -EINVAL; /* FIXME(bnoordhuis) Translate error. */ - } - - *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) { - vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); - return -ENOMEM; - } - - *count = numcpus; - - for (i = 0; i < numcpus; i++) { - cpu_info = &(*cpu_infos)[i]; - - cpu_info->cpu_times.user = (uint64_t)(info[i].cpu_ticks[0]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(info[i].cpu_ticks[3]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(info[i].cpu_ticks[1]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier; - cpu_info->cpu_times.irq = 0; - - cpu_info->model = uv__strdup(model); - cpu_info->speed = cpuspeed/1000000; - } - vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); - - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Mac OS X getifaddrs returns information related to Mac Addresses for - * various devices, such as firewire, etc. These are not relevant here. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/outside/libuv-v1.7.5/src/unix/dl.c b/outside/libuv-v1.7.5/src/unix/dl.c deleted file mode 100644 index 7c6d41c969..0000000000 --- a/outside/libuv-v1.7.5/src/unix/dl.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include - -static int uv__dlerror(uv_lib_t* lib); - - -int uv_dlopen(const char* filename, uv_lib_t* lib) { - dlerror(); /* Reset error status. */ - lib->errmsg = NULL; - lib->handle = dlopen(filename, RTLD_LAZY); - return lib->handle ? 0 : uv__dlerror(lib); -} - - -void uv_dlclose(uv_lib_t* lib) { - if (lib->errmsg) { - uv__free(lib->errmsg); - lib->errmsg = NULL; - } - - if (lib->handle) { - /* Ignore errors. No good way to signal them without leaking memory. */ - dlclose(lib->handle); - lib->handle = NULL; - } -} - - -int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { - dlerror(); /* Reset error status. */ - *ptr = dlsym(lib->handle, name); - return uv__dlerror(lib); -} - - -const char* uv_dlerror(const uv_lib_t* lib) { - return lib->errmsg ? lib->errmsg : "no error"; -} - - -static int uv__dlerror(uv_lib_t* lib) { - const char* errmsg; - - if (lib->errmsg) - uv__free(lib->errmsg); - - errmsg = dlerror(); - - if (errmsg) { - lib->errmsg = uv__strdup(errmsg); - return -1; - } - else { - lib->errmsg = NULL; - return 0; - } -} diff --git a/outside/libuv-v1.7.5/src/unix/freebsd.c b/outside/libuv-v1.7.5/src/unix/freebsd.c deleted file mode 100644 index c69608b139..0000000000 --- a/outside/libuv-v1.7.5/src/unix/freebsd.c +++ /dev/null @@ -1,448 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include /* VM_LOADAVG */ -#include -#include -#include /* sysconf */ -#include - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - -#ifndef CPUSTATES -# define CPUSTATES 5U -#endif -#ifndef CP_USER -# define CP_USER 0 -# define CP_NICE 1 -# define CP_SYS 2 -# define CP_IDLE 3 -# define CP_INTR 4 -#endif - -static char *process_title; - - -int uv__platform_loop_init(uv_loop_t* loop) { - return uv__kqueue_init(loop); -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - -#ifdef __DragonFly__ -int uv_exepath(char* buffer, size_t* size) { - char abspath[PATH_MAX * 2 + 1]; - ssize_t abspath_size; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - abspath_size = readlink("/proc/curproc/file", abspath, sizeof(abspath)); - if (abspath_size < 0) - return -errno; - - assert(abspath_size > 0); - *size -= 1; - - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - return 0; -} -#else -int uv_exepath(char* buffer, size_t* size) { - char abspath[PATH_MAX * 2 + 1]; - int mib[4]; - size_t abspath_size; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - - abspath_size = sizeof abspath; - if (sysctl(mib, 4, abspath, &abspath_size, NULL, 0)) - return -errno; - - assert(abspath_size > 0); - abspath_size -= 1; - *size -= 1; - - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - return 0; -} -#endif - -uint64_t uv_get_free_memory(void) { - int freecount; - size_t size = sizeof(freecount); - - if (sysctlbyname("vm.stats.vm.v_free_count", &freecount, &size, NULL, 0)) - return -errno; - - return (uint64_t) freecount * sysconf(_SC_PAGESIZE); - -} - - -uint64_t uv_get_total_memory(void) { - unsigned long info; - int which[] = {CTL_HW, HW_PHYSMEM}; - - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -char** uv_setup_args(int argc, char** argv) { - process_title = argc ? uv__strdup(argv[0]) : NULL; - return argv; -} - - -int uv_set_process_title(const char* title) { - int oid[4]; - - if (process_title) uv__free(process_title); - process_title = uv__strdup(title); - - oid[0] = CTL_KERN; - oid[1] = KERN_PROC; - oid[2] = KERN_PROC_ARGS; - oid[3] = getpid(); - - sysctl(oid, - ARRAY_SIZE(oid), - NULL, - NULL, - process_title, - strlen(process_title) + 1); - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title) { - strncpy(buffer, process_title, size); - } else { - if (size > 0) { - buffer[0] = '\0'; - } - } - - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - kvm_t *kd = NULL; - struct kinfo_proc *kinfo = NULL; - pid_t pid; - int nprocs; - size_t page_size = getpagesize(); - - pid = getpid(); - - kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); - if (kd == NULL) goto error; - - kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs); - if (kinfo == NULL) goto error; - -#ifdef __DragonFly__ - *rss = kinfo->kp_vm_rssize * page_size; -#else - *rss = kinfo->ki_rssize * page_size; -#endif - - kvm_close(kd); - - return 0; - -error: - if (kd) kvm_close(kd); - return -EPERM; -} - - -int uv_uptime(double* uptime) { - int r; - struct timespec sp; - r = clock_gettime(CLOCK_MONOTONIC, &sp); - if (r) - return -errno; - - *uptime = sp.tv_sec; - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), - multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus, - cur = 0; - uv_cpu_info_t* cpu_info; - const char* maxcpus_key; - const char* cptimes_key; - char model[512]; - long* cp_times; - int numcpus; - size_t size; - int i; - -#if defined(__DragonFly__) - /* This is not quite correct but DragonFlyBSD doesn't seem to have anything - * comparable to kern.smp.maxcpus or kern.cp_times (kern.cp_time is a total, - * not per CPU). At least this stops uv_cpu_info() from failing completely. - */ - maxcpus_key = "hw.ncpu"; - cptimes_key = "kern.cp_time"; -#else - maxcpus_key = "kern.smp.maxcpus"; - cptimes_key = "kern.cp_times"; -#endif - - size = sizeof(model); - if (sysctlbyname("hw.model", &model, &size, NULL, 0)) - return -errno; - - size = sizeof(numcpus); - if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) - return -errno; - - *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) - return -ENOMEM; - - *count = numcpus; - - size = sizeof(cpuspeed); - if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) { - SAVE_ERRNO(uv__free(*cpu_infos)); - return -errno; - } - - /* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of - * ncpu. - */ - size = sizeof(maxcpus); - if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) { - SAVE_ERRNO(uv__free(*cpu_infos)); - return -errno; - } - - size = maxcpus * CPUSTATES * sizeof(long); - - cp_times = uv__malloc(size); - if (cp_times == NULL) { - uv__free(*cpu_infos); - return -ENOMEM; - } - - if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) { - SAVE_ERRNO(uv__free(cp_times)); - SAVE_ERRNO(uv__free(*cpu_infos)); - return -errno; - } - - for (i = 0; i < numcpus; i++) { - cpu_info = &(*cpu_infos)[i]; - - cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; - cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; - - cpu_info->model = uv__strdup(model); - cpu_info->speed = cpuspeed; - - cur+=CPUSTATES; - } - - uv__free(cp_times); - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On FreeBSD getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/outside/libuv-v1.7.5/src/unix/fs.c b/outside/libuv-v1.7.5/src/unix/fs.c deleted file mode 100644 index d739c28258..0000000000 --- a/outside/libuv-v1.7.5/src/unix/fs.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* Caveat emptor: this file deviates from the libuv convention of returning - * negated errno codes. Most uv_fs_*() functions map directly to the system - * call of the same name. For more complex wrappers, it's easier to just - * return -1 with errno set. The dispatcher in uv__fs_work() takes care of - * getting the errno to the right place (req->result or as the return value.) - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) -# define HAVE_PREADV 1 -#else -# define HAVE_PREADV 0 -#endif - -#if defined(__linux__) || defined(__sun) -# include -#endif - -#define INIT(subtype) \ - do { \ - req->type = UV_FS; \ - if (cb != NULL) \ - uv__req_init(loop, req, UV_FS); \ - req->fs_type = UV_FS_ ## subtype; \ - req->result = 0; \ - req->ptr = NULL; \ - req->loop = loop; \ - req->path = NULL; \ - req->new_path = NULL; \ - req->cb = cb; \ - } \ - while (0) - -#define PATH \ - do { \ - assert(path != NULL); \ - if (cb == NULL) { \ - req->path = path; \ - } else { \ - req->path = uv__strdup(path); \ - if (req->path == NULL) \ - return -ENOMEM; \ - } \ - } \ - while (0) - -#define PATH2 \ - do { \ - if (cb == NULL) { \ - req->path = path; \ - req->new_path = new_path; \ - } else { \ - size_t path_len; \ - size_t new_path_len; \ - path_len = strlen(path) + 1; \ - new_path_len = strlen(new_path) + 1; \ - req->path = uv__malloc(path_len + new_path_len); \ - if (req->path == NULL) \ - return -ENOMEM; \ - req->new_path = req->path + path_len; \ - memcpy((void*) req->path, path, path_len); \ - memcpy((void*) req->new_path, new_path, new_path_len); \ - } \ - } \ - while (0) - -#define POST \ - do { \ - if (cb != NULL) { \ - uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \ - return 0; \ - } \ - else { \ - uv__fs_work(&req->work_req); \ - return req->result; \ - } \ - } \ - while (0) - - -static ssize_t uv__fs_fdatasync(uv_fs_t* req) { -#if defined(__linux__) || defined(__sun) || defined(__NetBSD__) - return fdatasync(req->file); -#elif defined(__APPLE__) && defined(F_FULLFSYNC) - return fcntl(req->file, F_FULLFSYNC); -#else - return fsync(req->file); -#endif -} - - -static ssize_t uv__fs_futime(uv_fs_t* req) { -#if defined(__linux__) - /* utimesat() has nanosecond resolution but we stick to microseconds - * for the sake of consistency with other platforms. - */ - static int no_utimesat; - struct timespec ts[2]; - struct timeval tv[2]; - char path[sizeof("/proc/self/fd/") + 3 * sizeof(int)]; - int r; - - if (no_utimesat) - goto skip; - - ts[0].tv_sec = req->atime; - ts[0].tv_nsec = (unsigned long)(req->atime * 1000000) % 1000000 * 1000; - ts[1].tv_sec = req->mtime; - ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000; - - r = uv__utimesat(req->file, NULL, ts, 0); - if (r == 0) - return r; - - if (errno != ENOSYS) - return r; - - no_utimesat = 1; - -skip: - - tv[0].tv_sec = req->atime; - tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000; - tv[1].tv_sec = req->mtime; - tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000; - snprintf(path, sizeof(path), "/proc/self/fd/%d", (int) req->file); - - r = utimes(path, tv); - if (r == 0) - return r; - - switch (errno) { - case ENOENT: - if (fcntl(req->file, F_GETFL) == -1 && errno == EBADF) - break; - /* Fall through. */ - - case EACCES: - case ENOTDIR: - errno = ENOSYS; - break; - } - - return r; - -#elif defined(__APPLE__) \ - || defined(__DragonFly__) \ - || defined(__FreeBSD__) \ - || defined(__NetBSD__) \ - || defined(__OpenBSD__) \ - || defined(__sun) - struct timeval tv[2]; - tv[0].tv_sec = req->atime; - tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000; - tv[1].tv_sec = req->mtime; - tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000; -# if defined(__sun) - return futimesat(req->file, NULL, tv); -# else - return futimes(req->file, tv); -# endif -#else - errno = ENOSYS; - return -1; -#endif -} - - -static ssize_t uv__fs_mkdtemp(uv_fs_t* req) { - return mkdtemp((char*) req->path) ? 0 : -1; -} - - -static ssize_t uv__fs_open(uv_fs_t* req) { - static int no_cloexec_support; - int r; - - /* Try O_CLOEXEC before entering locks */ - if (no_cloexec_support == 0) { -#ifdef O_CLOEXEC - r = open(req->path, req->flags | O_CLOEXEC, req->mode); - if (r >= 0) - return r; - if (errno != EINVAL) - return r; - no_cloexec_support = 1; -#endif /* O_CLOEXEC */ - } - - if (req->cb != NULL) - uv_rwlock_rdlock(&req->loop->cloexec_lock); - - r = open(req->path, req->flags, req->mode); - - /* In case of failure `uv__cloexec` will leave error in `errno`, - * so it is enough to just set `r` to `-1`. - */ - if (r >= 0 && uv__cloexec(r, 1) != 0) { - r = uv__close(r); - if (r != 0 && r != -EINPROGRESS) - abort(); - r = -1; - } - - if (req->cb != NULL) - uv_rwlock_rdunlock(&req->loop->cloexec_lock); - - return r; -} - - -static ssize_t uv__fs_read(uv_fs_t* req) { -#if defined(__linux__) - static int no_preadv; -#endif - ssize_t result; - -#if defined(_AIX) - struct stat buf; - if(fstat(req->file, &buf)) - return -1; - if(S_ISDIR(buf.st_mode)) { - errno = EISDIR; - return -1; - } -#endif /* defined(_AIX) */ - 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); - } 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 defined(__linux__) - if (no_preadv) retry: -# endif - { - off_t nread; - size_t index; - - nread = 0; - index = 0; - result = 1; - do { - if (req->bufs[index].len > 0) { - result = pread(req->file, - req->bufs[index].base, - req->bufs[index].len, - req->off + nread); - if (result > 0) - nread += result; - } - index++; - } while (index < req->nbufs && result > 0); - if (nread > 0) - result = nread; - } -# if defined(__linux__) - else { - result = uv__preadv(req->file, - (struct iovec*)req->bufs, - req->nbufs, - req->off); - if (result == -1 && errno == ENOSYS) { - no_preadv = 1; - goto retry; - } - } -# endif -#endif - } - -done: - return result; -} - - -#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8)) -static int uv__fs_scandir_filter(uv__dirent_t* dent) { -#else -static int uv__fs_scandir_filter(const uv__dirent_t* dent) { -#endif - return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0; -} - - -static ssize_t uv__fs_scandir(uv_fs_t* req) { - uv__dirent_t **dents; - int saved_errno; - int n; - - dents = NULL; - n = scandir(req->path, &dents, uv__fs_scandir_filter, alphasort); - - /* NOTE: We will use nbufs as an index field */ - req->nbufs = 0; - - if (n == 0) - goto out; /* osx still needs to deallocate some memory */ - else if (n == -1) - return n; - - req->ptr = dents; - - return n; - -out: - saved_errno = errno; - if (dents != NULL) { - int i; - - for (i = 0; i < n; i++) - uv__free(dents[i]); - uv__free(dents); - } - errno = saved_errno; - - req->ptr = NULL; - - return n; -} - - -static ssize_t uv__fs_readlink(uv_fs_t* req) { - ssize_t len; - char* buf; - - len = pathconf(req->path, _PC_PATH_MAX); - - if (len == -1) { -#if defined(PATH_MAX) - len = PATH_MAX; -#else - len = 4096; -#endif - } - - buf = uv__malloc(len + 1); - - if (buf == NULL) { - errno = ENOMEM; - return -1; - } - - len = readlink(req->path, buf, len); - - if (len == -1) { - uv__free(buf); - return -1; - } - - buf[len] = '\0'; - req->ptr = buf; - - return 0; -} - - -static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) { - struct pollfd pfd; - int use_pread; - off_t offset; - ssize_t nsent; - ssize_t nread; - ssize_t nwritten; - size_t buflen; - size_t len; - ssize_t n; - int in_fd; - int out_fd; - char buf[8192]; - - len = req->bufsml[0].len; - in_fd = req->flags; - out_fd = req->file; - offset = req->off; - use_pread = 1; - - /* Here are the rules regarding errors: - * - * 1. Read errors are reported only if nsent==0, otherwise we return nsent. - * The user needs to know that some data has already been sent, to stop - * them from sending it twice. - * - * 2. Write errors are always reported. Write errors are bad because they - * mean data loss: we've read data but now we can't write it out. - * - * We try to use pread() and fall back to regular read() if the source fd - * doesn't support positional reads, for example when it's a pipe fd. - * - * If we get EAGAIN when writing to the target fd, we poll() on it until - * it becomes writable again. - * - * FIXME: If we get a write error when use_pread==1, it should be safe to - * return the number of sent bytes instead of an error because pread() - * is, in theory, idempotent. However, special files in /dev or /proc - * may support pread() but not necessarily return the same data on - * successive reads. - * - * FIXME: There is no way now to signal that we managed to send *some* data - * before a write error. - */ - for (nsent = 0; (size_t) nsent < len; ) { - buflen = len - nsent; - - if (buflen > sizeof(buf)) - buflen = sizeof(buf); - - do - if (use_pread) - nread = pread(in_fd, buf, buflen, offset); - else - nread = read(in_fd, buf, buflen); - while (nread == -1 && errno == EINTR); - - if (nread == 0) - goto out; - - if (nread == -1) { - if (use_pread && nsent == 0 && (errno == EIO || errno == ESPIPE)) { - use_pread = 0; - continue; - } - - if (nsent == 0) - nsent = -1; - - goto out; - } - - for (nwritten = 0; nwritten < nread; ) { - do - n = write(out_fd, buf + nwritten, nread - nwritten); - while (n == -1 && errno == EINTR); - - if (n != -1) { - nwritten += n; - continue; - } - - if (errno != EAGAIN && errno != EWOULDBLOCK) { - nsent = -1; - goto out; - } - - pfd.fd = out_fd; - pfd.events = POLLOUT; - pfd.revents = 0; - - do - n = poll(&pfd, 1, -1); - while (n == -1 && errno == EINTR); - - if (n == -1 || (pfd.revents & ~POLLOUT) != 0) { - errno = EIO; - nsent = -1; - goto out; - } - } - - offset += nread; - nsent += nread; - } - -out: - if (nsent != -1) - req->off = offset; - - return nsent; -} - - -static ssize_t uv__fs_sendfile(uv_fs_t* req) { - int in_fd; - int out_fd; - - in_fd = req->flags; - out_fd = req->file; - -#if defined(__linux__) || defined(__sun) - { - off_t off; - ssize_t r; - - off = req->off; - r = sendfile(out_fd, in_fd, &off, req->bufsml[0].len); - - /* sendfile() on SunOS returns EINVAL if the target fd is not a socket but - * it still writes out data. Fortunately, we can detect it by checking if - * the offset has been updated. - */ - if (r != -1 || off > req->off) { - r = off - req->off; - req->off = off; - return r; - } - - if (errno == EINVAL || - errno == EIO || - errno == ENOTSOCK || - errno == EXDEV) { - errno = 0; - return uv__fs_sendfile_emul(req); - } - - return -1; - } -#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__) - { - off_t len; - ssize_t r; - - /* sendfile() on FreeBSD and Darwin returns EAGAIN if the target fd is in - * non-blocking mode and not all data could be written. If a non-zero - * number of bytes have been sent, we don't consider it an error. - */ - -#if defined(__FreeBSD__) || defined(__DragonFly__) - len = 0; - r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0); -#else - /* The darwin sendfile takes len as an input for the length to send, - * so make sure to initialize it with the caller's value. */ - len = req->bufsml[0].len; - r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0); -#endif - - /* - * The man page for sendfile(2) on DragonFly states that `len` contains - * a meaningful value ONLY in case of EAGAIN and EINTR. - * Nothing is said about it's value in case of other errors, so better - * not depend on the potential wrong assumption that is was not modified - * by the syscall. - */ - if (r == 0 || ((errno == EAGAIN || errno == EINTR) && len != 0)) { - req->off += len; - return (ssize_t) len; - } - - if (errno == EINVAL || - errno == EIO || - errno == ENOTSOCK || - errno == EXDEV) { - errno = 0; - return uv__fs_sendfile_emul(req); - } - - return -1; - } -#else - /* Squelch compiler warnings. */ - (void) &in_fd; - (void) &out_fd; - - return uv__fs_sendfile_emul(req); -#endif -} - - -static ssize_t uv__fs_utime(uv_fs_t* req) { - struct utimbuf buf; - buf.actime = req->atime; - buf.modtime = req->mtime; - return utime(req->path, &buf); /* TODO use utimes() where available */ -} - - -static ssize_t uv__fs_write(uv_fs_t* req) { -#if defined(__linux__) - static int no_pwritev; -#endif - ssize_t r; - - /* 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; - pthread_mutex_lock(&lock); -#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); - } 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 defined(__linux__) - if (no_pwritev) retry: -# endif - { - off_t written; - size_t index; - - written = 0; - index = 0; - r = 0; - do { - if (req->bufs[index].len > 0) { - r = pwrite(req->file, - req->bufs[index].base, - req->bufs[index].len, - req->off + written); - if (r > 0) - written += r; - } - index++; - } while (index < req->nbufs && r >= 0); - if (written > 0) - r = written; - } -# if defined(__linux__) - else { - r = uv__pwritev(req->file, - (struct iovec*) req->bufs, - req->nbufs, - req->off); - if (r == -1 && errno == ENOSYS) { - no_pwritev = 1; - goto retry; - } - } -# endif -#endif - } - -done: -#if defined(__APPLE__) - pthread_mutex_unlock(&lock); -#endif - - return r; -} - -static void uv__to_stat(struct stat* src, uv_stat_t* dst) { - dst->st_dev = src->st_dev; - dst->st_mode = src->st_mode; - dst->st_nlink = src->st_nlink; - dst->st_uid = src->st_uid; - dst->st_gid = src->st_gid; - dst->st_rdev = src->st_rdev; - dst->st_ino = src->st_ino; - dst->st_size = src->st_size; - dst->st_blksize = src->st_blksize; - dst->st_blocks = src->st_blocks; - -#if defined(__APPLE__) - dst->st_atim.tv_sec = src->st_atimespec.tv_sec; - dst->st_atim.tv_nsec = src->st_atimespec.tv_nsec; - dst->st_mtim.tv_sec = src->st_mtimespec.tv_sec; - dst->st_mtim.tv_nsec = src->st_mtimespec.tv_nsec; - dst->st_ctim.tv_sec = src->st_ctimespec.tv_sec; - dst->st_ctim.tv_nsec = src->st_ctimespec.tv_nsec; - dst->st_birthtim.tv_sec = src->st_birthtimespec.tv_sec; - dst->st_birthtim.tv_nsec = src->st_birthtimespec.tv_nsec; - dst->st_flags = src->st_flags; - dst->st_gen = src->st_gen; -#elif defined(__ANDROID__) - dst->st_atim.tv_sec = src->st_atime; - dst->st_atim.tv_nsec = src->st_atime_nsec; - dst->st_mtim.tv_sec = src->st_mtime; - dst->st_mtim.tv_nsec = src->st_mtime_nsec; - dst->st_ctim.tv_sec = src->st_ctime; - dst->st_ctim.tv_nsec = src->st_ctime_nsec; - dst->st_birthtim.tv_sec = src->st_ctime; - dst->st_birthtim.tv_nsec = src->st_ctime_nsec; - dst->st_flags = 0; - dst->st_gen = 0; -#elif !defined(_AIX) && ( \ - defined(_BSD_SOURCE) || \ - defined(_SVID_SOURCE) || \ - defined(_XOPEN_SOURCE) || \ - defined(_DEFAULT_SOURCE)) - dst->st_atim.tv_sec = src->st_atim.tv_sec; - dst->st_atim.tv_nsec = src->st_atim.tv_nsec; - dst->st_mtim.tv_sec = src->st_mtim.tv_sec; - dst->st_mtim.tv_nsec = src->st_mtim.tv_nsec; - dst->st_ctim.tv_sec = src->st_ctim.tv_sec; - dst->st_ctim.tv_nsec = src->st_ctim.tv_nsec; -# if defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) - dst->st_birthtim.tv_sec = src->st_birthtim.tv_sec; - dst->st_birthtim.tv_nsec = src->st_birthtim.tv_nsec; - dst->st_flags = src->st_flags; - dst->st_gen = src->st_gen; -# else - dst->st_birthtim.tv_sec = src->st_ctim.tv_sec; - dst->st_birthtim.tv_nsec = src->st_ctim.tv_nsec; - dst->st_flags = 0; - dst->st_gen = 0; -# endif -#else - dst->st_atim.tv_sec = src->st_atime; - dst->st_atim.tv_nsec = 0; - dst->st_mtim.tv_sec = src->st_mtime; - dst->st_mtim.tv_nsec = 0; - dst->st_ctim.tv_sec = src->st_ctime; - dst->st_ctim.tv_nsec = 0; - dst->st_birthtim.tv_sec = src->st_ctime; - dst->st_birthtim.tv_nsec = 0; - dst->st_flags = 0; - dst->st_gen = 0; -#endif -} - - -static int uv__fs_stat(const char *path, uv_stat_t *buf) { - struct stat pbuf; - int ret; - ret = stat(path, &pbuf); - uv__to_stat(&pbuf, buf); - return ret; -} - - -static int uv__fs_lstat(const char *path, uv_stat_t *buf) { - struct stat pbuf; - int ret; - ret = lstat(path, &pbuf); - uv__to_stat(&pbuf, buf); - return ret; -} - - -static int uv__fs_fstat(int fd, uv_stat_t *buf) { - struct stat pbuf; - int ret; - ret = fstat(fd, &pbuf); - uv__to_stat(&pbuf, buf); - return ret; -} - - -typedef ssize_t (*uv__fs_buf_iter_processor)(uv_fs_t* req); -static ssize_t uv__fs_buf_iter(uv_fs_t* req, uv__fs_buf_iter_processor process) { - unsigned int iovmax; - unsigned int nbufs; - uv_buf_t* bufs; - ssize_t total; - ssize_t result; - - iovmax = uv__getiovmax(); - nbufs = req->nbufs; - bufs = req->bufs; - total = 0; - - while (nbufs > 0) { - req->nbufs = nbufs; - if (req->nbufs > iovmax) - req->nbufs = iovmax; - - result = process(req); - if (result <= 0) { - if (total == 0) - total = result; - break; - } - - if (req->off >= 0) - req->off += result; - - req->bufs += req->nbufs; - nbufs -= req->nbufs; - total += result; - } - - if (bufs != req->bufsml) - uv__free(bufs); - req->bufs = NULL; - - return total; -} - - -static void uv__fs_work(struct uv__work* w) { - int retry_on_eintr; - uv_fs_t* req; - ssize_t r; - - req = container_of(w, uv_fs_t, work_req); - retry_on_eintr = !(req->fs_type == UV_FS_CLOSE); - - do { - errno = 0; - -#define X(type, action) \ - case UV_FS_ ## type: \ - r = action; \ - break; - - switch (req->fs_type) { - X(ACCESS, access(req->path, req->flags)); - X(CHMOD, chmod(req->path, req->mode)); - X(CHOWN, chown(req->path, req->uid, req->gid)); - X(CLOSE, close(req->file)); - X(FCHMOD, fchmod(req->file, req->mode)); - X(FCHOWN, fchown(req->file, req->uid, req->gid)); - X(FDATASYNC, uv__fs_fdatasync(req)); - X(FSTAT, uv__fs_fstat(req->file, &req->statbuf)); - X(FSYNC, fsync(req->file)); - X(FTRUNCATE, ftruncate(req->file, req->off)); - X(FUTIME, uv__fs_futime(req)); - X(LSTAT, uv__fs_lstat(req->path, &req->statbuf)); - X(LINK, link(req->path, req->new_path)); - X(MKDIR, mkdir(req->path, req->mode)); - X(MKDTEMP, uv__fs_mkdtemp(req)); - X(OPEN, uv__fs_open(req)); - X(READ, uv__fs_buf_iter(req, uv__fs_read)); - X(SCANDIR, uv__fs_scandir(req)); - X(READLINK, uv__fs_readlink(req)); - X(RENAME, rename(req->path, req->new_path)); - X(RMDIR, rmdir(req->path)); - X(SENDFILE, uv__fs_sendfile(req)); - X(STAT, uv__fs_stat(req->path, &req->statbuf)); - X(SYMLINK, symlink(req->path, req->new_path)); - X(UNLINK, unlink(req->path)); - X(UTIME, uv__fs_utime(req)); - X(WRITE, uv__fs_buf_iter(req, uv__fs_write)); - default: abort(); - } -#undef X - } while (r == -1 && errno == EINTR && retry_on_eintr); - - if (r == -1) - req->result = -errno; - else - req->result = r; - - if (r == 0 && (req->fs_type == UV_FS_STAT || - req->fs_type == UV_FS_FSTAT || - req->fs_type == UV_FS_LSTAT)) { - req->ptr = &req->statbuf; - } -} - - -static void uv__fs_done(struct uv__work* w, int status) { - uv_fs_t* req; - - req = container_of(w, uv_fs_t, work_req); - uv__req_unregister(req->loop, req); - - if (status == -ECANCELED) { - assert(req->result == 0); - req->result = -ECANCELED; - } - - req->cb(req); -} - - -int uv_fs_access(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - uv_fs_cb cb) { - INIT(ACCESS); - PATH; - req->flags = flags; - POST; -} - - -int uv_fs_chmod(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int mode, - uv_fs_cb cb) { - INIT(CHMOD); - PATH; - req->mode = mode; - POST; -} - - -int uv_fs_chown(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_uid_t uid, - uv_gid_t gid, - uv_fs_cb cb) { - INIT(CHOWN); - PATH; - req->uid = uid; - req->gid = gid; - POST; -} - - -int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(CLOSE); - req->file = file; - POST; -} - - -int uv_fs_fchmod(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - int mode, - uv_fs_cb cb) { - INIT(FCHMOD); - req->file = file; - req->mode = mode; - POST; -} - - -int uv_fs_fchown(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - uv_uid_t uid, - uv_gid_t gid, - uv_fs_cb cb) { - INIT(FCHOWN); - req->file = file; - req->uid = uid; - req->gid = gid; - POST; -} - - -int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(FDATASYNC); - req->file = file; - POST; -} - - -int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(FSTAT); - req->file = file; - POST; -} - - -int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(FSYNC); - req->file = file; - POST; -} - - -int uv_fs_ftruncate(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - int64_t off, - uv_fs_cb cb) { - INIT(FTRUNCATE); - req->file = file; - req->off = off; - POST; -} - - -int uv_fs_futime(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - double atime, - double mtime, - uv_fs_cb cb) { - INIT(FUTIME); - req->file = file; - req->atime = atime; - req->mtime = mtime; - POST; -} - - -int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(LSTAT); - PATH; - POST; -} - - -int uv_fs_link(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - uv_fs_cb cb) { - INIT(LINK); - PATH2; - POST; -} - - -int uv_fs_mkdir(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int mode, - uv_fs_cb cb) { - INIT(MKDIR); - PATH; - req->mode = mode; - POST; -} - - -int uv_fs_mkdtemp(uv_loop_t* loop, - uv_fs_t* req, - const char* tpl, - uv_fs_cb cb) { - INIT(MKDTEMP); - req->path = uv__strdup(tpl); - if (req->path == NULL) - return -ENOMEM; - POST; -} - - -int uv_fs_open(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - int mode, - uv_fs_cb cb) { - INIT(OPEN); - PATH; - req->flags = flags; - req->mode = mode; - POST; -} - - -int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, - uv_file file, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t off, - uv_fs_cb cb) { - if (bufs == NULL || nbufs == 0) - return -EINVAL; - - INIT(READ); - req->file = file; - - req->nbufs = nbufs; - req->bufs = req->bufsml; - if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = uv__malloc(nbufs * sizeof(*bufs)); - - if (req->bufs == NULL) - return -ENOMEM; - - memcpy(req->bufs, bufs, nbufs * sizeof(*bufs)); - - req->off = off; - POST; -} - - -int uv_fs_scandir(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - uv_fs_cb cb) { - INIT(SCANDIR); - PATH; - req->flags = flags; - POST; -} - - -int uv_fs_readlink(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_fs_cb cb) { - INIT(READLINK); - PATH; - POST; -} - - -int uv_fs_rename(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - uv_fs_cb cb) { - INIT(RENAME); - PATH2; - POST; -} - - -int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(RMDIR); - PATH; - POST; -} - - -int uv_fs_sendfile(uv_loop_t* loop, - uv_fs_t* req, - uv_file out_fd, - uv_file in_fd, - int64_t off, - size_t len, - uv_fs_cb cb) { - INIT(SENDFILE); - req->flags = in_fd; /* hack */ - req->file = out_fd; - req->off = off; - req->bufsml[0].len = len; - POST; -} - - -int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(STAT); - PATH; - POST; -} - - -int uv_fs_symlink(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - int flags, - uv_fs_cb cb) { - INIT(SYMLINK); - PATH2; - req->flags = flags; - POST; -} - - -int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(UNLINK); - PATH; - POST; -} - - -int uv_fs_utime(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - double atime, - double mtime, - uv_fs_cb cb) { - INIT(UTIME); - PATH; - req->atime = atime; - req->mtime = mtime; - POST; -} - - -int uv_fs_write(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t off, - uv_fs_cb cb) { - if (bufs == NULL || nbufs == 0) - return -EINVAL; - - INIT(WRITE); - req->file = file; - - req->nbufs = nbufs; - req->bufs = req->bufsml; - if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = uv__malloc(nbufs * sizeof(*bufs)); - - if (req->bufs == NULL) - return -ENOMEM; - - memcpy(req->bufs, bufs, nbufs * sizeof(*bufs)); - - req->off = off; - POST; -} - - -void uv_fs_req_cleanup(uv_fs_t* req) { - /* Only necessary for asychronous requests, i.e., requests with a callback. - * Synchronous ones don't copy their arguments and have req->path and - * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the - * exception to the rule, it always allocates memory. - */ - if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP)) - uv__free((void*) req->path); /* Memory is shared with req->new_path. */ - - req->path = NULL; - req->new_path = NULL; - - if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL) - uv__fs_scandir_cleanup(req); - - if (req->ptr != &req->statbuf) - uv__free(req->ptr); - req->ptr = NULL; -} diff --git a/outside/libuv-v1.7.5/src/unix/fsevents.c b/outside/libuv-v1.7.5/src/unix/fsevents.c deleted file mode 100644 index 8143f7c1f0..0000000000 --- a/outside/libuv-v1.7.5/src/unix/fsevents.c +++ /dev/null @@ -1,899 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#if TARGET_OS_IPHONE - -/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */ - -int uv__fsevents_init(uv_fs_event_t* handle) { - return 0; -} - - -int uv__fsevents_close(uv_fs_event_t* handle) { - return 0; -} - - -void uv__fsevents_loop_delete(uv_loop_t* loop) { -} - -#else /* TARGET_OS_IPHONE */ - -#include -#include -#include -#include - -#include -#include - -/* These are macros to avoid "initializer element is not constant" errors - * with old versions of gcc. - */ -#define kFSEventsModified (kFSEventStreamEventFlagItemFinderInfoMod | \ - kFSEventStreamEventFlagItemModified | \ - kFSEventStreamEventFlagItemInodeMetaMod | \ - kFSEventStreamEventFlagItemChangeOwner | \ - kFSEventStreamEventFlagItemXattrMod) - -#define kFSEventsRenamed (kFSEventStreamEventFlagItemCreated | \ - kFSEventStreamEventFlagItemRemoved | \ - kFSEventStreamEventFlagItemRenamed) - -#define kFSEventsSystem (kFSEventStreamEventFlagUserDropped | \ - kFSEventStreamEventFlagKernelDropped | \ - kFSEventStreamEventFlagEventIdsWrapped | \ - kFSEventStreamEventFlagHistoryDone | \ - kFSEventStreamEventFlagMount | \ - kFSEventStreamEventFlagUnmount | \ - kFSEventStreamEventFlagRootChanged) - -typedef struct uv__fsevents_event_s uv__fsevents_event_t; -typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t; -typedef struct uv__cf_loop_state_s uv__cf_loop_state_t; - -struct uv__cf_loop_signal_s { - QUEUE member; - uv_fs_event_t* handle; -}; - -struct uv__fsevents_event_s { - QUEUE member; - int events; - char path[1]; -}; - -struct uv__cf_loop_state_s { - CFRunLoopRef loop; - CFRunLoopSourceRef signal_source; - int fsevent_need_reschedule; - FSEventStreamRef fsevent_stream; - uv_sem_t fsevent_sem; - uv_mutex_t fsevent_mutex; - void* fsevent_handles[2]; - unsigned int fsevent_handle_count; -}; - -/* Forward declarations */ -static void uv__cf_loop_cb(void* arg); -static void* uv__cf_loop_runner(void* arg); -static int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle); - -/* Lazy-loaded by uv__fsevents_global_init(). */ -static CFArrayRef (*pCFArrayCreate)(CFAllocatorRef, - const void**, - CFIndex, - const CFArrayCallBacks*); -static void (*pCFRelease)(CFTypeRef); -static void (*pCFRunLoopAddSource)(CFRunLoopRef, - CFRunLoopSourceRef, - CFStringRef); -static CFRunLoopRef (*pCFRunLoopGetCurrent)(void); -static void (*pCFRunLoopRemoveSource)(CFRunLoopRef, - CFRunLoopSourceRef, - CFStringRef); -static void (*pCFRunLoopRun)(void); -static CFRunLoopSourceRef (*pCFRunLoopSourceCreate)(CFAllocatorRef, - CFIndex, - CFRunLoopSourceContext*); -static void (*pCFRunLoopSourceSignal)(CFRunLoopSourceRef); -static void (*pCFRunLoopStop)(CFRunLoopRef); -static void (*pCFRunLoopWakeUp)(CFRunLoopRef); -static CFStringRef (*pCFStringCreateWithFileSystemRepresentation)( - CFAllocatorRef, - const char*); -static CFStringEncoding (*pCFStringGetSystemEncoding)(void); -static CFStringRef (*pkCFRunLoopDefaultMode); -static FSEventStreamRef (*pFSEventStreamCreate)(CFAllocatorRef, - FSEventStreamCallback, - FSEventStreamContext*, - CFArrayRef, - FSEventStreamEventId, - CFTimeInterval, - FSEventStreamCreateFlags); -static void (*pFSEventStreamFlushSync)(FSEventStreamRef); -static void (*pFSEventStreamInvalidate)(FSEventStreamRef); -static void (*pFSEventStreamRelease)(FSEventStreamRef); -static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef, - CFRunLoopRef, - CFStringRef); -static Boolean (*pFSEventStreamStart)(FSEventStreamRef); -static void (*pFSEventStreamStop)(FSEventStreamRef); - -#define UV__FSEVENTS_PROCESS(handle, block) \ - do { \ - QUEUE events; \ - QUEUE* q; \ - uv__fsevents_event_t* event; \ - int err; \ - uv_mutex_lock(&(handle)->cf_mutex); \ - /* Split-off all events and empty original queue */ \ - QUEUE_INIT(&events); \ - if (!QUEUE_EMPTY(&(handle)->cf_events)) { \ - q = QUEUE_HEAD(&(handle)->cf_events); \ - QUEUE_SPLIT(&(handle)->cf_events, q, &events); \ - } \ - /* Get error (if any) and zero original one */ \ - err = (handle)->cf_error; \ - (handle)->cf_error = 0; \ - uv_mutex_unlock(&(handle)->cf_mutex); \ - /* Loop through events, deallocating each after processing */ \ - while (!QUEUE_EMPTY(&events)) { \ - q = QUEUE_HEAD(&events); \ - event = QUEUE_DATA(q, uv__fsevents_event_t, member); \ - QUEUE_REMOVE(q); \ - /* NOTE: Checking uv__is_active() is required here, because handle \ - * callback may close handle and invoking it after it will lead to \ - * incorrect behaviour */ \ - if (!uv__is_closing((handle)) && uv__is_active((handle))) \ - block \ - /* Free allocated data */ \ - uv__free(event); \ - } \ - if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle))) \ - (handle)->cb((handle), NULL, 0, err); \ - } while (0) - - -/* Runs in UV loop's thread, when there're events to report to handle */ -static void uv__fsevents_cb(uv_async_t* cb) { - uv_fs_event_t* handle; - - handle = cb->data; - - UV__FSEVENTS_PROCESS(handle, { - handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0); - }); -} - - -/* Runs in CF thread, pushed event into handle's event list */ -static void uv__fsevents_push_event(uv_fs_event_t* handle, - QUEUE* events, - int err) { - assert(events != NULL || err != 0); - uv_mutex_lock(&handle->cf_mutex); - - /* Concatenate two queues */ - if (events != NULL) - QUEUE_ADD(&handle->cf_events, events); - - /* Propagate error */ - if (err != 0) - handle->cf_error = err; - uv_mutex_unlock(&handle->cf_mutex); - - uv_async_send(handle->cf_cb); -} - - -/* Runs in CF thread, when there're events in FSEventStream */ -static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef, - void* info, - size_t numEvents, - void* eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[]) { - size_t i; - int len; - char** paths; - char* path; - char* pos; - uv_fs_event_t* handle; - QUEUE* q; - uv_loop_t* loop; - uv__cf_loop_state_t* state; - uv__fsevents_event_t* event; - QUEUE head; - - loop = info; - state = loop->cf_state; - assert(state != NULL); - paths = eventPaths; - - /* For each handle */ - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_FOREACH(q, &state->fsevent_handles) { - handle = QUEUE_DATA(q, uv_fs_event_t, cf_member); - QUEUE_INIT(&head); - - /* Process and filter out events */ - for (i = 0; i < numEvents; i++) { - /* Ignore system events */ - if (eventFlags[i] & kFSEventsSystem) - continue; - - path = paths[i]; - len = strlen(path); - - /* Filter out paths that are outside handle's request */ - if (strncmp(path, handle->realpath, handle->realpath_len) != 0) - continue; - - if (handle->realpath_len > 1 || *handle->realpath != '/') { - path += handle->realpath_len; - len -= handle->realpath_len; - - /* Skip forward slash */ - if (*path != '\0') { - path++; - len--; - } - } - -#ifdef MAC_OS_X_VERSION_10_7 - /* Ignore events with path equal to directory itself */ - if (len == 0) - continue; -#endif /* MAC_OS_X_VERSION_10_7 */ - - /* Do not emit events from subdirectories (without option set) */ - if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) { - pos = strchr(path + 1, '/'); - if (pos != NULL) - continue; - } - -#ifndef MAC_OS_X_VERSION_10_7 - path = ""; - len = 0; -#endif /* MAC_OS_X_VERSION_10_7 */ - - event = uv__malloc(sizeof(*event) + len); - if (event == NULL) - break; - - memset(event, 0, sizeof(*event)); - memcpy(event->path, path, len + 1); - - if ((eventFlags[i] & kFSEventsModified) != 0 && - (eventFlags[i] & kFSEventsRenamed) == 0) - event->events = UV_CHANGE; - else - event->events = UV_RENAME; - - QUEUE_INSERT_TAIL(&head, &event->member); - } - - if (!QUEUE_EMPTY(&head)) - uv__fsevents_push_event(handle, &head, 0); - } - uv_mutex_unlock(&state->fsevent_mutex); -} - - -/* Runs in CF thread */ -static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) { - uv__cf_loop_state_t* state; - FSEventStreamContext ctx; - FSEventStreamRef ref; - CFAbsoluteTime latency; - FSEventStreamCreateFlags flags; - - /* Initialize context */ - ctx.version = 0; - ctx.info = loop; - ctx.retain = NULL; - ctx.release = NULL; - ctx.copyDescription = NULL; - - latency = 0.05; - - /* Explanation of selected flags: - * 1. NoDefer - without this flag, events that are happening continuously - * (i.e. each event is happening after time interval less than `latency`, - * counted from previous event), will be deferred and passed to callback - * once they'll either fill whole OS buffer, or when this continuous stream - * will stop (i.e. there'll be delay between events, bigger than - * `latency`). - * Specifying this flag will invoke callback after `latency` time passed - * since event. - * 2. FileEvents - fire callback for file changes too (by default it is firing - * it only for directory changes). - */ - flags = kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents; - - /* - * NOTE: It might sound like a good idea to remember last seen StreamEventId, - * but in reality one dir might have last StreamEventId less than, the other, - * that is being watched now. Which will cause FSEventStream API to report - * changes to files from the past. - */ - ref = pFSEventStreamCreate(NULL, - &uv__fsevents_event_cb, - &ctx, - paths, - kFSEventStreamEventIdSinceNow, - latency, - flags); - assert(ref != NULL); - - state = loop->cf_state; - pFSEventStreamScheduleWithRunLoop(ref, - state->loop, - *pkCFRunLoopDefaultMode); - if (!pFSEventStreamStart(ref)) { - pFSEventStreamInvalidate(ref); - pFSEventStreamRelease(ref); - return -EMFILE; - } - - state->fsevent_stream = ref; - return 0; -} - - -/* Runs in CF thread */ -static void uv__fsevents_destroy_stream(uv_loop_t* loop) { - uv__cf_loop_state_t* state; - - state = loop->cf_state; - - if (state->fsevent_stream == NULL) - return; - - /* Flush all accumulated events */ - pFSEventStreamFlushSync(state->fsevent_stream); - - /* Stop emitting events */ - pFSEventStreamStop(state->fsevent_stream); - - /* Release stream */ - pFSEventStreamInvalidate(state->fsevent_stream); - pFSEventStreamRelease(state->fsevent_stream); - state->fsevent_stream = NULL; -} - - -/* Runs in CF thread, when there're new fsevent handles to add to stream */ -static void uv__fsevents_reschedule(uv_fs_event_t* handle) { - uv__cf_loop_state_t* state; - QUEUE* q; - uv_fs_event_t* curr; - CFArrayRef cf_paths; - CFStringRef* paths; - unsigned int i; - int err; - unsigned int path_count; - - state = handle->loop->cf_state; - paths = NULL; - cf_paths = NULL; - err = 0; - /* NOTE: `i` is used in deallocation loop below */ - i = 0; - - /* Optimization to prevent O(n^2) time spent when starting to watch - * many files simultaneously - */ - uv_mutex_lock(&state->fsevent_mutex); - if (state->fsevent_need_reschedule == 0) { - uv_mutex_unlock(&state->fsevent_mutex); - goto final; - } - state->fsevent_need_reschedule = 0; - uv_mutex_unlock(&state->fsevent_mutex); - - /* Destroy previous FSEventStream */ - uv__fsevents_destroy_stream(handle->loop); - - /* Any failure below will be a memory failure */ - err = -ENOMEM; - - /* Create list of all watched paths */ - uv_mutex_lock(&state->fsevent_mutex); - path_count = state->fsevent_handle_count; - if (path_count != 0) { - paths = uv__malloc(sizeof(*paths) * path_count); - if (paths == NULL) { - uv_mutex_unlock(&state->fsevent_mutex); - goto final; - } - - q = &state->fsevent_handles; - for (; i < path_count; i++) { - q = QUEUE_NEXT(q); - assert(q != &state->fsevent_handles); - curr = QUEUE_DATA(q, uv_fs_event_t, cf_member); - - assert(curr->realpath != NULL); - paths[i] = - pCFStringCreateWithFileSystemRepresentation(NULL, curr->realpath); - if (paths[i] == NULL) { - uv_mutex_unlock(&state->fsevent_mutex); - goto final; - } - } - } - uv_mutex_unlock(&state->fsevent_mutex); - err = 0; - - if (path_count != 0) { - /* Create new FSEventStream */ - cf_paths = pCFArrayCreate(NULL, (const void**) paths, path_count, NULL); - if (cf_paths == NULL) { - err = -ENOMEM; - goto final; - } - err = uv__fsevents_create_stream(handle->loop, cf_paths); - } - -final: - /* Deallocate all paths in case of failure */ - if (err != 0) { - if (cf_paths == NULL) { - while (i != 0) - pCFRelease(paths[--i]); - uv__free(paths); - } else { - /* CFArray takes ownership of both strings and original C-array */ - pCFRelease(cf_paths); - } - - /* Broadcast error to all handles */ - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_FOREACH(q, &state->fsevent_handles) { - curr = QUEUE_DATA(q, uv_fs_event_t, cf_member); - uv__fsevents_push_event(curr, NULL, err); - } - uv_mutex_unlock(&state->fsevent_mutex); - } - - /* - * Main thread will block until the removal of handle from the list, - * we must tell it when we're ready. - * - * NOTE: This is coupled with `uv_sem_wait()` in `uv__fsevents_close` - */ - if (!uv__is_active(handle)) - uv_sem_post(&state->fsevent_sem); -} - - -static int uv__fsevents_global_init(void) { - static pthread_mutex_t global_init_mutex = PTHREAD_MUTEX_INITIALIZER; - static void* core_foundation_handle; - static void* core_services_handle; - int err; - - err = 0; - pthread_mutex_lock(&global_init_mutex); - if (core_foundation_handle != NULL) - goto out; - - /* The libraries are never unloaded because we currently don't have a good - * mechanism for keeping a reference count. It's unlikely to be an issue - * but if it ever becomes one, we can turn the dynamic library handles into - * per-event loop properties and have the dynamic linker keep track for us. - */ - err = -ENOSYS; - core_foundation_handle = dlopen("/System/Library/Frameworks/" - "CoreFoundation.framework/" - "Versions/A/CoreFoundation", - RTLD_LAZY | RTLD_LOCAL); - if (core_foundation_handle == NULL) - goto out; - - core_services_handle = dlopen("/System/Library/Frameworks/" - "CoreServices.framework/" - "Versions/A/CoreServices", - RTLD_LAZY | RTLD_LOCAL); - if (core_services_handle == NULL) - goto out; - - err = -ENOENT; -#define V(handle, symbol) \ - do { \ - *(void **)(&p ## symbol) = dlsym((handle), #symbol); \ - if (p ## symbol == NULL) \ - goto out; \ - } \ - while (0) - V(core_foundation_handle, CFArrayCreate); - V(core_foundation_handle, CFRelease); - V(core_foundation_handle, CFRunLoopAddSource); - V(core_foundation_handle, CFRunLoopGetCurrent); - V(core_foundation_handle, CFRunLoopRemoveSource); - V(core_foundation_handle, CFRunLoopRun); - V(core_foundation_handle, CFRunLoopSourceCreate); - V(core_foundation_handle, CFRunLoopSourceSignal); - V(core_foundation_handle, CFRunLoopStop); - V(core_foundation_handle, CFRunLoopWakeUp); - V(core_foundation_handle, CFStringCreateWithFileSystemRepresentation); - V(core_foundation_handle, CFStringGetSystemEncoding); - V(core_foundation_handle, kCFRunLoopDefaultMode); - V(core_services_handle, FSEventStreamCreate); - V(core_services_handle, FSEventStreamFlushSync); - V(core_services_handle, FSEventStreamInvalidate); - V(core_services_handle, FSEventStreamRelease); - V(core_services_handle, FSEventStreamScheduleWithRunLoop); - V(core_services_handle, FSEventStreamStart); - V(core_services_handle, FSEventStreamStop); -#undef V - err = 0; - -out: - if (err && core_services_handle != NULL) { - dlclose(core_services_handle); - core_services_handle = NULL; - } - - if (err && core_foundation_handle != NULL) { - dlclose(core_foundation_handle); - core_foundation_handle = NULL; - } - - pthread_mutex_unlock(&global_init_mutex); - return err; -} - - -/* Runs in UV loop */ -static int uv__fsevents_loop_init(uv_loop_t* loop) { - CFRunLoopSourceContext ctx; - uv__cf_loop_state_t* state; - pthread_attr_t attr_storage; - pthread_attr_t* attr; - int err; - - if (loop->cf_state != NULL) - return 0; - - err = uv__fsevents_global_init(); - if (err) - return err; - - state = uv__calloc(1, sizeof(*state)); - if (state == NULL) - return -ENOMEM; - - err = uv_mutex_init(&loop->cf_mutex); - if (err) - goto fail_mutex_init; - - err = uv_sem_init(&loop->cf_sem, 0); - if (err) - goto fail_sem_init; - - QUEUE_INIT(&loop->cf_signals); - - err = uv_sem_init(&state->fsevent_sem, 0); - if (err) - goto fail_fsevent_sem_init; - - err = uv_mutex_init(&state->fsevent_mutex); - if (err) - goto fail_fsevent_mutex_init; - - QUEUE_INIT(&state->fsevent_handles); - state->fsevent_need_reschedule = 0; - state->fsevent_handle_count = 0; - - memset(&ctx, 0, sizeof(ctx)); - ctx.info = loop; - ctx.perform = uv__cf_loop_cb; - state->signal_source = pCFRunLoopSourceCreate(NULL, 0, &ctx); - if (state->signal_source == NULL) { - err = -ENOMEM; - goto fail_signal_source_create; - } - - /* In the unlikely event that pthread_attr_init() fails, create the thread - * with the default stack size. We'll use a little more address space but - * that in itself is not a fatal error. - */ - attr = &attr_storage; - if (pthread_attr_init(attr)) - attr = NULL; - - if (attr != NULL) - if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN)) - abort(); - - loop->cf_state = state; - - /* uv_thread_t is an alias for pthread_t. */ - err = -pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop); - - if (attr != NULL) - pthread_attr_destroy(attr); - - if (err) - goto fail_thread_create; - - /* Synchronize threads */ - uv_sem_wait(&loop->cf_sem); - return 0; - -fail_thread_create: - loop->cf_state = NULL; - -fail_signal_source_create: - uv_mutex_destroy(&state->fsevent_mutex); - -fail_fsevent_mutex_init: - uv_sem_destroy(&state->fsevent_sem); - -fail_fsevent_sem_init: - uv_sem_destroy(&loop->cf_sem); - -fail_sem_init: - uv_mutex_destroy(&loop->cf_mutex); - -fail_mutex_init: - uv__free(state); - return err; -} - - -/* Runs in UV loop */ -void uv__fsevents_loop_delete(uv_loop_t* loop) { - uv__cf_loop_signal_t* s; - uv__cf_loop_state_t* state; - QUEUE* q; - - if (loop->cf_state == NULL) - return; - - if (uv__cf_loop_signal(loop, NULL) != 0) - abort(); - - uv_thread_join(&loop->cf_thread); - uv_sem_destroy(&loop->cf_sem); - uv_mutex_destroy(&loop->cf_mutex); - - /* Free any remaining data */ - while (!QUEUE_EMPTY(&loop->cf_signals)) { - q = QUEUE_HEAD(&loop->cf_signals); - s = QUEUE_DATA(q, uv__cf_loop_signal_t, member); - QUEUE_REMOVE(q); - uv__free(s); - } - - /* Destroy state */ - state = loop->cf_state; - uv_sem_destroy(&state->fsevent_sem); - uv_mutex_destroy(&state->fsevent_mutex); - pCFRelease(state->signal_source); - uv__free(state); - loop->cf_state = NULL; -} - - -/* Runs in CF thread. This is the CF loop's body */ -static void* uv__cf_loop_runner(void* arg) { - uv_loop_t* loop; - uv__cf_loop_state_t* state; - - loop = arg; - state = loop->cf_state; - state->loop = pCFRunLoopGetCurrent(); - - pCFRunLoopAddSource(state->loop, - state->signal_source, - *pkCFRunLoopDefaultMode); - - uv_sem_post(&loop->cf_sem); - - pCFRunLoopRun(); - pCFRunLoopRemoveSource(state->loop, - state->signal_source, - *pkCFRunLoopDefaultMode); - - return NULL; -} - - -/* Runs in CF thread, executed after `uv__cf_loop_signal()` */ -static void uv__cf_loop_cb(void* arg) { - uv_loop_t* loop; - uv__cf_loop_state_t* state; - QUEUE* item; - QUEUE split_head; - uv__cf_loop_signal_t* s; - - loop = arg; - state = loop->cf_state; - QUEUE_INIT(&split_head); - - uv_mutex_lock(&loop->cf_mutex); - if (!QUEUE_EMPTY(&loop->cf_signals)) { - QUEUE* split_pos = QUEUE_HEAD(&loop->cf_signals); - QUEUE_SPLIT(&loop->cf_signals, split_pos, &split_head); - } - uv_mutex_unlock(&loop->cf_mutex); - - while (!QUEUE_EMPTY(&split_head)) { - item = QUEUE_HEAD(&split_head); - - s = QUEUE_DATA(item, uv__cf_loop_signal_t, member); - - /* This was a termination signal */ - if (s->handle == NULL) - pCFRunLoopStop(state->loop); - else - uv__fsevents_reschedule(s->handle); - - QUEUE_REMOVE(item); - uv__free(s); - } -} - - -/* Runs in UV loop to notify CF thread */ -int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__cf_loop_signal_t* item; - uv__cf_loop_state_t* state; - - item = uv__malloc(sizeof(*item)); - if (item == NULL) - return -ENOMEM; - - item->handle = handle; - - uv_mutex_lock(&loop->cf_mutex); - QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member); - uv_mutex_unlock(&loop->cf_mutex); - - state = loop->cf_state; - assert(state != NULL); - pCFRunLoopSourceSignal(state->signal_source); - pCFRunLoopWakeUp(state->loop); - - return 0; -} - - -/* Runs in UV loop to initialize handle */ -int uv__fsevents_init(uv_fs_event_t* handle) { - int err; - uv__cf_loop_state_t* state; - - err = uv__fsevents_loop_init(handle->loop); - if (err) - return err; - - /* Get absolute path to file */ - handle->realpath = realpath(handle->path, NULL); - if (handle->realpath == NULL) - return -errno; - handle->realpath_len = strlen(handle->realpath); - - /* Initialize event queue */ - QUEUE_INIT(&handle->cf_events); - handle->cf_error = 0; - - /* - * Events will occur in other thread. - * Initialize callback for getting them back into event loop's thread - */ - handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb)); - if (handle->cf_cb == NULL) { - err = -ENOMEM; - goto fail_cf_cb_malloc; - } - - handle->cf_cb->data = handle; - uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb); - handle->cf_cb->flags |= UV__HANDLE_INTERNAL; - uv_unref((uv_handle_t*) handle->cf_cb); - - err = uv_mutex_init(&handle->cf_mutex); - if (err) - goto fail_cf_mutex_init; - - /* Insert handle into the list */ - state = handle->loop->cf_state; - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_INSERT_TAIL(&state->fsevent_handles, &handle->cf_member); - state->fsevent_handle_count++; - state->fsevent_need_reschedule = 1; - uv_mutex_unlock(&state->fsevent_mutex); - - /* Reschedule FSEventStream */ - assert(handle != NULL); - err = uv__cf_loop_signal(handle->loop, handle); - if (err) - goto fail_loop_signal; - - return 0; - -fail_loop_signal: - uv_mutex_destroy(&handle->cf_mutex); - -fail_cf_mutex_init: - uv__free(handle->cf_cb); - handle->cf_cb = NULL; - -fail_cf_cb_malloc: - uv__free(handle->realpath); - handle->realpath = NULL; - handle->realpath_len = 0; - - return err; -} - - -/* Runs in UV loop to de-initialize handle */ -int uv__fsevents_close(uv_fs_event_t* handle) { - int err; - uv__cf_loop_state_t* state; - - if (handle->cf_cb == NULL) - return -EINVAL; - - /* Remove handle from the list */ - state = handle->loop->cf_state; - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_REMOVE(&handle->cf_member); - state->fsevent_handle_count--; - state->fsevent_need_reschedule = 1; - uv_mutex_unlock(&state->fsevent_mutex); - - /* Reschedule FSEventStream */ - assert(handle != NULL); - err = uv__cf_loop_signal(handle->loop, handle); - if (err) - return -err; - - /* Wait for deinitialization */ - uv_sem_wait(&state->fsevent_sem); - - uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) uv__free); - handle->cf_cb = NULL; - - /* Free data in queue */ - UV__FSEVENTS_PROCESS(handle, { - /* NOP */ - }); - - uv_mutex_destroy(&handle->cf_mutex); - uv__free(handle->realpath); - handle->realpath = NULL; - handle->realpath_len = 0; - - return 0; -} - -#endif /* TARGET_OS_IPHONE */ diff --git a/outside/libuv-v1.7.5/src/unix/getaddrinfo.c b/outside/libuv-v1.7.5/src/unix/getaddrinfo.c deleted file mode 100644 index 2049aea2f3..0000000000 --- a/outside/libuv-v1.7.5/src/unix/getaddrinfo.c +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* Expose glibc-specific EAI_* error codes. Needs to be defined before we - * include any headers. - */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include "uv.h" -#include "internal.h" - -#include -#include /* NULL */ -#include -#include - -/* EAI_* constants. */ -#include - - -int uv__getaddrinfo_translate_error(int sys_err) { - switch (sys_err) { - case 0: return 0; -#if defined(EAI_ADDRFAMILY) - case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY; -#endif -#if defined(EAI_AGAIN) - case EAI_AGAIN: return UV_EAI_AGAIN; -#endif -#if defined(EAI_BADFLAGS) - case EAI_BADFLAGS: return UV_EAI_BADFLAGS; -#endif -#if defined(EAI_BADHINTS) - case EAI_BADHINTS: return UV_EAI_BADHINTS; -#endif -#if defined(EAI_CANCELED) - case EAI_CANCELED: return UV_EAI_CANCELED; -#endif -#if defined(EAI_FAIL) - case EAI_FAIL: return UV_EAI_FAIL; -#endif -#if defined(EAI_FAMILY) - case EAI_FAMILY: return UV_EAI_FAMILY; -#endif -#if defined(EAI_MEMORY) - case EAI_MEMORY: return UV_EAI_MEMORY; -#endif -#if defined(EAI_NODATA) - case EAI_NODATA: return UV_EAI_NODATA; -#endif -#if defined(EAI_NONAME) -# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME - case EAI_NONAME: return UV_EAI_NONAME; -# endif -#endif -#if defined(EAI_OVERFLOW) - case EAI_OVERFLOW: return UV_EAI_OVERFLOW; -#endif -#if defined(EAI_PROTOCOL) - case EAI_PROTOCOL: return UV_EAI_PROTOCOL; -#endif -#if defined(EAI_SERVICE) - case EAI_SERVICE: return UV_EAI_SERVICE; -#endif -#if defined(EAI_SOCKTYPE) - case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE; -#endif -#if defined(EAI_SYSTEM) - case EAI_SYSTEM: return -errno; -#endif - } - assert(!"unknown EAI_* error code"); - abort(); - return 0; /* Pacify compiler. */ -} - - -static void uv__getaddrinfo_work(struct uv__work* w) { - uv_getaddrinfo_t* req; - int err; - - req = container_of(w, uv_getaddrinfo_t, work_req); - err = getaddrinfo(req->hostname, req->service, req->hints, &req->addrinfo); - req->retcode = uv__getaddrinfo_translate_error(err); -} - - -static void uv__getaddrinfo_done(struct uv__work* w, int status) { - uv_getaddrinfo_t* req; - - req = container_of(w, uv_getaddrinfo_t, work_req); - uv__req_unregister(req->loop, req); - - /* See initialization in uv_getaddrinfo(). */ - if (req->hints) - uv__free(req->hints); - else if (req->service) - uv__free(req->service); - else if (req->hostname) - uv__free(req->hostname); - else - assert(0); - - req->hints = NULL; - req->service = NULL; - req->hostname = NULL; - - if (status == -ECANCELED) { - assert(req->retcode == 0); - req->retcode = UV_EAI_CANCELED; - } - - if (req->cb) - req->cb(req, req->retcode, req->addrinfo); -} - - -int uv_getaddrinfo(uv_loop_t* loop, - uv_getaddrinfo_t* req, - uv_getaddrinfo_cb cb, - const char* hostname, - const char* service, - const struct addrinfo* hints) { - size_t hostname_len; - size_t service_len; - size_t hints_len; - size_t len; - char* buf; - - if (req == NULL || (hostname == NULL && service == NULL)) - return -EINVAL; - - hostname_len = hostname ? strlen(hostname) + 1 : 0; - service_len = service ? strlen(service) + 1 : 0; - hints_len = hints ? sizeof(*hints) : 0; - buf = uv__malloc(hostname_len + service_len + hints_len); - - if (buf == NULL) - return -ENOMEM; - - uv__req_init(loop, req, UV_GETADDRINFO); - req->loop = loop; - req->cb = cb; - req->addrinfo = NULL; - req->hints = NULL; - req->service = NULL; - req->hostname = NULL; - req->retcode = 0; - - /* order matters, see uv_getaddrinfo_done() */ - len = 0; - - if (hints) { - req->hints = memcpy(buf + len, hints, sizeof(*hints)); - len += sizeof(*hints); - } - - if (service) { - req->service = memcpy(buf + len, service, service_len); - len += service_len; - } - - if (hostname) - req->hostname = memcpy(buf + len, hostname, hostname_len); - - if (cb) { - uv__work_submit(loop, - &req->work_req, - uv__getaddrinfo_work, - uv__getaddrinfo_done); - return 0; - } else { - uv__getaddrinfo_work(&req->work_req); - uv__getaddrinfo_done(&req->work_req, 0); - return req->retcode; - } -} - - -void uv_freeaddrinfo(struct addrinfo* ai) { - if (ai) - freeaddrinfo(ai); -} diff --git a/outside/libuv-v1.7.5/src/unix/getnameinfo.c b/outside/libuv-v1.7.5/src/unix/getnameinfo.c deleted file mode 100644 index daa798a450..0000000000 --- a/outside/libuv-v1.7.5/src/unix/getnameinfo.c +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to -* deal in the Software without restriction, including without limitation the -* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -* sell copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -* IN THE SOFTWARE. -*/ - -#include -#include -#include -#include - -#include "uv.h" -#include "internal.h" - - -static void uv__getnameinfo_work(struct uv__work* w) { - uv_getnameinfo_t* req; - int err; - socklen_t salen; - - req = container_of(w, uv_getnameinfo_t, work_req); - - if (req->storage.ss_family == AF_INET) - salen = sizeof(struct sockaddr_in); - else if (req->storage.ss_family == AF_INET6) - salen = sizeof(struct sockaddr_in6); - else - abort(); - - err = getnameinfo((struct sockaddr*) &req->storage, - salen, - req->host, - sizeof(req->host), - req->service, - sizeof(req->service), - req->flags); - req->retcode = uv__getaddrinfo_translate_error(err); -} - -static void uv__getnameinfo_done(struct uv__work* w, int status) { - uv_getnameinfo_t* req; - char* host; - char* service; - - req = container_of(w, uv_getnameinfo_t, work_req); - uv__req_unregister(req->loop, req); - host = service = NULL; - - if (status == -ECANCELED) { - assert(req->retcode == 0); - req->retcode = UV_EAI_CANCELED; - } else if (req->retcode == 0) { - host = req->host; - service = req->service; - } - - if (req->getnameinfo_cb) - req->getnameinfo_cb(req, req->retcode, host, service); -} - -/* -* Entry point for getnameinfo -* return 0 if a callback will be made -* return error code if validation fails -*/ -int uv_getnameinfo(uv_loop_t* loop, - uv_getnameinfo_t* req, - uv_getnameinfo_cb getnameinfo_cb, - const struct sockaddr* addr, - int flags) { - if (req == NULL || addr == NULL) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) { - memcpy(&req->storage, - addr, - sizeof(struct sockaddr_in)); - } else if (addr->sa_family == AF_INET6) { - memcpy(&req->storage, - addr, - sizeof(struct sockaddr_in6)); - } else { - return UV_EINVAL; - } - - uv__req_init(loop, (uv_req_t*)req, UV_GETNAMEINFO); - - req->getnameinfo_cb = getnameinfo_cb; - req->flags = flags; - req->type = UV_GETNAMEINFO; - req->loop = loop; - req->retcode = 0; - - if (getnameinfo_cb) { - uv__work_submit(loop, - &req->work_req, - uv__getnameinfo_work, - uv__getnameinfo_done); - return 0; - } else { - uv__getnameinfo_work(&req->work_req); - uv__getnameinfo_done(&req->work_req, 0); - return req->retcode; - } -} diff --git a/outside/libuv-v1.7.5/src/unix/internal.h b/outside/libuv-v1.7.5/src/unix/internal.h deleted file mode 100644 index 741fa57d69..0000000000 --- a/outside/libuv-v1.7.5/src/unix/internal.h +++ /dev/null @@ -1,316 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_UNIX_INTERNAL_H_ -#define UV_UNIX_INTERNAL_H_ - -#include "uv-common.h" - -#include -#include /* abort */ -#include /* strrchr */ -#include /* O_CLOEXEC, may be */ - -#if defined(__STRICT_ANSI__) -# define inline __inline -#endif - -#if defined(__linux__) -# include "linux-syscalls.h" -#endif /* __linux__ */ - -#if defined(__sun) -# include -# include -#endif /* __sun */ - -#if defined(_AIX) -#define reqevents events -#define rtnevents revents -#include -#endif /* _AIX */ - -#if defined(__APPLE__) && !TARGET_OS_IPHONE -# include -#endif - -#define ACCESS_ONCE(type, var) \ - (*(volatile type*) &(var)) - -#define ROUND_UP(a, b) \ - ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a)) - -#define UNREACHABLE() \ - do { \ - assert(0 && "unreachable code"); \ - abort(); \ - } \ - while (0) - -#define SAVE_ERRNO(block) \ - do { \ - int _saved_errno = errno; \ - do { block; } while (0); \ - errno = _saved_errno; \ - } \ - while (0) - -/* The __clang__ and __INTEL_COMPILER checks are superfluous because they - * define __GNUC__. They are here to convey to you, dear reader, that these - * macros are enabled when compiling with clang or icc. - */ -#if defined(__clang__) || \ - defined(__GNUC__) || \ - defined(__INTEL_COMPILER) || \ - defined(__SUNPRO_C) -# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration -# define UV_UNUSED(declaration) __attribute__((unused)) declaration -#else -# define UV_DESTRUCTOR(declaration) declaration -# define UV_UNUSED(declaration) declaration -#endif - -#if defined(__linux__) -# define UV__POLLIN UV__EPOLLIN -# define UV__POLLOUT UV__EPOLLOUT -# define UV__POLLERR UV__EPOLLERR -# define UV__POLLHUP UV__EPOLLHUP -#endif - -#if defined(__sun) || defined(_AIX) -# define UV__POLLIN POLLIN -# define UV__POLLOUT POLLOUT -# define UV__POLLERR POLLERR -# define UV__POLLHUP POLLHUP -#endif - -#ifndef UV__POLLIN -# define UV__POLLIN 1 -#endif - -#ifndef UV__POLLOUT -# define UV__POLLOUT 2 -#endif - -#ifndef UV__POLLERR -# define UV__POLLERR 4 -#endif - -#ifndef UV__POLLHUP -# define UV__POLLHUP 8 -#endif - -#if !defined(O_CLOEXEC) && defined(__FreeBSD__) -/* - * It may be that we are just missing `__POSIX_VISIBLE >= 200809`. - * Try using fixed value const and give up, if it doesn't work - */ -# define O_CLOEXEC 0x00100000 -#endif - -typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t; - -/* handle flags */ -enum { - UV_CLOSING = 0x01, /* uv_close() called but not finished. */ - UV_CLOSED = 0x02, /* close(2) finished. */ - UV_STREAM_READING = 0x04, /* uv_read_start() called. */ - UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */ - UV_STREAM_SHUT = 0x10, /* Write side closed. */ - UV_STREAM_READABLE = 0x20, /* The stream is readable */ - UV_STREAM_WRITABLE = 0x40, /* The stream is writable */ - UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */ - UV_STREAM_READ_PARTIAL = 0x100, /* read(2) read less than requested. */ - UV_STREAM_READ_EOF = 0x200, /* read(2) read EOF. */ - UV_TCP_NODELAY = 0x400, /* Disable Nagle. */ - UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */ - UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */ - UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */ - UV_UDP_PROCESSING = 0x20000 /* Handle is running the send callback queue. */ -}; - -/* loop flags */ -enum { - UV_LOOP_BLOCK_SIGPROF = 1 -}; - -typedef enum { - UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */ - UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */ -} uv_clocktype_t; - -struct uv__stream_queued_fds_s { - unsigned int size; - unsigned int offset; - int fds[1]; -}; - - -/* core */ -int uv__nonblock(int fd, int set); -int uv__close(int fd); -int uv__cloexec(int fd, int set); -int uv__socket(int domain, int type, int protocol); -int uv__dup(int fd); -ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags); -void uv__make_close_pending(uv_handle_t* handle); -int uv__getiovmax(void); - -void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd); -void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events); -void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events); -void uv__io_close(uv_loop_t* loop, uv__io_t* w); -void uv__io_feed(uv_loop_t* loop, uv__io_t* w); -int uv__io_active(const uv__io_t* w, unsigned int events); -void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ - -/* async */ -void uv__async_send(struct uv__async* wa); -void uv__async_init(struct uv__async* wa); -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb); -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa); - -/* loop */ -void uv__run_idle(uv_loop_t* loop); -void uv__run_check(uv_loop_t* loop); -void uv__run_prepare(uv_loop_t* loop); - -/* stream */ -void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream, - uv_handle_type type); -int uv__stream_open(uv_stream_t*, int fd, int flags); -void uv__stream_destroy(uv_stream_t* stream); -#if defined(__APPLE__) -int uv__stream_try_select(uv_stream_t* stream, int* fd); -#endif /* defined(__APPLE__) */ -void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); -int uv__accept(int sockfd); -int uv__dup2_cloexec(int oldfd, int newfd); -int uv__open_cloexec(const char* path, int flags); - -/* tcp */ -int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); -int uv__tcp_nodelay(int fd, int on); -int uv__tcp_keepalive(int fd, int on, unsigned int delay); - -/* pipe */ -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); - -/* timer */ -void uv__run_timers(uv_loop_t* loop); -int uv__next_timeout(const uv_loop_t* loop); - -/* signal */ -void uv__signal_close(uv_signal_t* handle); -void uv__signal_global_once_init(void); -void uv__signal_loop_cleanup(uv_loop_t* loop); - -/* platform specific */ -uint64_t uv__hrtime(uv_clocktype_t type); -int uv__kqueue_init(uv_loop_t* loop); -int uv__platform_loop_init(uv_loop_t* loop); -void uv__platform_loop_delete(uv_loop_t* loop); -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd); - -/* various */ -void uv__async_close(uv_async_t* handle); -void uv__check_close(uv_check_t* handle); -void uv__fs_event_close(uv_fs_event_t* handle); -void uv__idle_close(uv_idle_t* handle); -void uv__pipe_close(uv_pipe_t* handle); -void uv__poll_close(uv_poll_t* handle); -void uv__prepare_close(uv_prepare_t* handle); -void uv__process_close(uv_process_t* handle); -void uv__stream_close(uv_stream_t* handle); -void uv__tcp_close(uv_tcp_t* handle); -void uv__timer_close(uv_timer_t* handle); -void uv__udp_close(uv_udp_t* handle); -void uv__udp_finish_close(uv_udp_t* handle); -uv_handle_type uv__handle_type(int fd); - -#if defined(__APPLE__) -int uv___stream_fd(const uv_stream_t* handle); -#define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle))) -#else -#define uv__stream_fd(handle) ((handle)->io_watcher.fd) -#endif /* defined(__APPLE__) */ - -#ifdef UV__O_NONBLOCK -# define UV__F_NONBLOCK UV__O_NONBLOCK -#else -# define UV__F_NONBLOCK 1 -#endif - -int uv__make_socketpair(int fds[2], int flags); -int uv__make_pipe(int fds[2], int flags); - -#if defined(__APPLE__) - -int uv__fsevents_init(uv_fs_event_t* handle); -int uv__fsevents_close(uv_fs_event_t* handle); -void uv__fsevents_loop_delete(uv_loop_t* loop); - -/* OSX < 10.7 has no file events, polyfill them */ -#ifndef MAC_OS_X_VERSION_10_7 - -static const int kFSEventStreamCreateFlagFileEvents = 0x00000010; -static const int kFSEventStreamEventFlagItemCreated = 0x00000100; -static const int kFSEventStreamEventFlagItemRemoved = 0x00000200; -static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400; -static const int kFSEventStreamEventFlagItemRenamed = 0x00000800; -static const int kFSEventStreamEventFlagItemModified = 0x00001000; -static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000; -static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000; -static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000; -static const int kFSEventStreamEventFlagItemIsFile = 0x00010000; -static const int kFSEventStreamEventFlagItemIsDir = 0x00020000; -static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000; - -#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */ - -#endif /* defined(__APPLE__) */ - -UV_UNUSED(static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type)) { - req->type = type; - uv__req_register(loop, req); -} -#define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) - -UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { - /* Use a fast time source if available. We only need millisecond precision. - */ - loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000; -} - -UV_UNUSED(static char* uv__basename_r(const char* path)) { - char* s; - - s = strrchr(path, '/'); - if (s == NULL) - return (char*) path; - - return s + 1; -} - -#endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/outside/libuv-v1.7.5/src/unix/kqueue.c b/outside/libuv-v1.7.5/src/unix/kqueue.c deleted file mode 100644 index 495f20d285..0000000000 --- a/outside/libuv-v1.7.5/src/unix/kqueue.c +++ /dev/null @@ -1,426 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags); - - -int uv__kqueue_init(uv_loop_t* loop) { - loop->backend_fd = kqueue(); - if (loop->backend_fd == -1) - return -errno; - - uv__cloexec(loop->backend_fd, 1); - - return 0; -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - struct kevent events[1024]; - struct kevent* ev; - struct timespec spec; - unsigned int nevents; - unsigned int revents; - QUEUE* q; - uv__io_t* w; - sigset_t* pset; - sigset_t set; - uint64_t base; - uint64_t diff; - int filter; - int fflags; - int count; - int nfds; - int fd; - int op; - int i; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - nevents = 0; - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - assert(w->fd >= 0); - assert(w->fd < (int) loop->nwatchers); - - if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) { - filter = EVFILT_READ; - fflags = 0; - op = EV_ADD; - - if (w->cb == uv__fs_event) { - filter = EVFILT_VNODE; - fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME - | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE; - op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */ - } - - EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0); - - if (++nevents == ARRAY_SIZE(events)) { - if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) - abort(); - nevents = 0; - } - } - - if ((w->events & UV__POLLOUT) == 0 && (w->pevents & UV__POLLOUT) != 0) { - EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); - - if (++nevents == ARRAY_SIZE(events)) { - if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) - abort(); - nevents = 0; - } - } - - w->events = w->pevents; - } - - pset = NULL; - if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { - pset = &set; - sigemptyset(pset); - sigaddset(pset, SIGPROF); - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - - for (;; nevents = 0) { - if (timeout != -1) { - spec.tv_sec = timeout / 1000; - spec.tv_nsec = (timeout % 1000) * 1000000; - } - - if (pset != NULL) - pthread_sigmask(SIG_BLOCK, pset, NULL); - - nfds = kevent(loop->backend_fd, - events, - nevents, - events, - ARRAY_SIZE(events), - timeout == -1 ? NULL : &spec); - - if (pset != NULL) - pthread_sigmask(SIG_UNBLOCK, pset, NULL); - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (nfds == 0) { - assert(timeout != -1); - return; - } - - if (nfds == -1) { - if (errno != EINTR) - abort(); - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - - /* Interrupted by a signal. Update timeout and poll again. */ - goto update_timeout; - } - - nevents = 0; - - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = (void*) events; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - for (i = 0; i < nfds; i++) { - ev = events + i; - fd = ev->ident; - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (fd == -1) - continue; - w = loop->watchers[fd]; - - if (w == NULL) { - /* File descriptor that we've stopped watching, disarm it. */ - /* TODO batch up */ - struct kevent events[1]; - - EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) - if (errno != EBADF && errno != ENOENT) - abort(); - - continue; - } - - if (ev->filter == EVFILT_VNODE) { - assert(w->events == UV__POLLIN); - assert(w->pevents == UV__POLLIN); - w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */ - nevents++; - continue; - } - - revents = 0; - - if (ev->filter == EVFILT_READ) { - if (w->pevents & UV__POLLIN) { - revents |= UV__POLLIN; - w->rcount = ev->data; - } else { - /* TODO batch up */ - struct kevent events[1]; - EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) - if (errno != ENOENT) - abort(); - } - } - - if (ev->filter == EVFILT_WRITE) { - if (w->pevents & UV__POLLOUT) { - revents |= UV__POLLOUT; - w->wcount = ev->data; - } else { - /* TODO batch up */ - struct kevent events[1]; - EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) - if (errno != ENOENT) - abort(); - } - } - - if (ev->flags & EV_ERROR) - revents |= UV__POLLERR; - - if (revents == 0) - continue; - - w->cb(loop, w, revents); - nevents++; - } - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - diff = loop->time - base; - if (diff >= (uint64_t) timeout) - return; - - timeout -= diff; - } -} - - -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct kevent* events; - uintptr_t i; - uintptr_t nfds; - - assert(loop->watchers != NULL); - - events = (struct kevent*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - if (events == NULL) - return; - - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if ((int) events[i].ident == fd) - events[i].ident = -1; -} - - -static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) { - uv_fs_event_t* handle; - struct kevent ev; - int events; - const char* path; -#if defined(F_GETPATH) - /* MAXPATHLEN == PATH_MAX but the former is what XNU calls it internally. */ - char pathbuf[MAXPATHLEN]; -#endif - - handle = container_of(w, uv_fs_event_t, event_watcher); - - if (fflags & (NOTE_ATTRIB | NOTE_EXTEND)) - events = UV_CHANGE; - else - events = UV_RENAME; - - path = NULL; -#if defined(F_GETPATH) - /* Also works when the file has been unlinked from the file system. Passing - * in the path when the file has been deleted is arguably a little strange - * but it's consistent with what the inotify backend does. - */ - if (fcntl(handle->event_watcher.fd, F_GETPATH, pathbuf) == 0) - path = uv__basename_r(pathbuf); -#endif - handle->cb(handle, path, events, 0); - - if (handle->event_watcher.fd == -1) - return; - - /* Watcher operates in one-shot mode, re-arm it. */ - fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME - | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE; - - EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0); - - if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL)) - abort(); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* path, - unsigned int flags) { -#if defined(__APPLE__) - struct stat statbuf; -#endif /* defined(__APPLE__) */ - int fd; - - if (uv__is_active(handle)) - return -EINVAL; - - /* TODO open asynchronously - but how do we report back errors? */ - fd = open(path, O_RDONLY); - if (fd == -1) - return -errno; - - uv__handle_start(handle); - uv__io_init(&handle->event_watcher, uv__fs_event, fd); - handle->path = uv__strdup(path); - handle->cb = cb; - -#if defined(__APPLE__) - /* Nullify field to perform checks later */ - handle->cf_cb = NULL; - handle->realpath = NULL; - handle->realpath_len = 0; - handle->cf_flags = flags; - - if (fstat(fd, &statbuf)) - goto fallback; - /* FSEvents works only with directories */ - if (!(statbuf.st_mode & S_IFDIR)) - goto fallback; - - /* The fallback fd is no longer needed */ - uv__close(fd); - handle->event_watcher.fd = -1; - - return uv__fsevents_init(handle); - -fallback: -#endif /* defined(__APPLE__) */ - - uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN); - - return 0; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - if (!uv__is_active(handle)) - return 0; - - uv__handle_stop(handle); - -#if defined(__APPLE__) - if (uv__fsevents_close(handle)) -#endif /* defined(__APPLE__) */ - { - uv__io_close(handle->loop, &handle->event_watcher); - } - - uv__free(handle->path); - handle->path = NULL; - - if (handle->event_watcher.fd != -1) { - /* When FSEvents is used, we don't use the event_watcher's fd under certain - * confitions. (see uv_fs_event_start) */ - uv__close(handle->event_watcher.fd); - handle->event_watcher.fd = -1; - } - - return 0; -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { - uv_fs_event_stop(handle); -} diff --git a/outside/libuv-v1.7.5/src/unix/linux-core.c b/outside/libuv-v1.7.5/src/unix/linux-core.c deleted file mode 100644 index e6e68283d5..0000000000 --- a/outside/libuv-v1.7.5/src/unix/linux-core.c +++ /dev/null @@ -1,897 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define HAVE_IFADDRS_H 1 - -#ifdef __UCLIBC__ -# if __UCLIBC_MAJOR__ < 0 || __UCLIBC_MINOR__ < 9 || __UCLIBC_SUBLEVEL__ < 32 -# undef HAVE_IFADDRS_H -# endif -#endif - -#ifdef HAVE_IFADDRS_H -# if defined(__ANDROID__) -# include "android-ifaddrs.h" -# else -# include -# endif -# include -# include -# include -#endif /* HAVE_IFADDRS_H */ - -/* Available from 2.6.32 onwards. */ -#ifndef CLOCK_MONOTONIC_COARSE -# define CLOCK_MONOTONIC_COARSE 6 -#endif - -/* This is rather annoying: CLOCK_BOOTTIME lives in but we can't - * include that file because it conflicts with . We'll just have to - * define it ourselves. - */ -#ifndef CLOCK_BOOTTIME -# define CLOCK_BOOTTIME 7 -#endif - -static int read_models(unsigned int numcpus, uv_cpu_info_t* ci); -static int read_times(unsigned int numcpus, uv_cpu_info_t* ci); -static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci); -static unsigned long read_cpufreq(unsigned int cpunum); - - -int uv__platform_loop_init(uv_loop_t* loop) { - int fd; - - fd = uv__epoll_create1(UV__EPOLL_CLOEXEC); - - /* epoll_create1() can fail either because it's not implemented (old kernel) - * or because it doesn't understand the EPOLL_CLOEXEC flag. - */ - if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) { - fd = uv__epoll_create(256); - - if (fd != -1) - uv__cloexec(fd, 1); - } - - loop->backend_fd = fd; - loop->inotify_fd = -1; - loop->inotify_watchers = NULL; - - if (fd == -1) - return -errno; - - return 0; -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { - if (loop->inotify_fd == -1) return; - uv__io_stop(loop, &loop->inotify_read_watcher, UV__POLLIN); - uv__close(loop->inotify_fd); - loop->inotify_fd = -1; -} - - -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct uv__epoll_event* events; - struct uv__epoll_event dummy; - uintptr_t i; - uintptr_t nfds; - - assert(loop->watchers != NULL); - - events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - if (events != NULL) - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if ((int) events[i].data == fd) - events[i].data = -1; - - /* Remove the file descriptor from the epoll. - * This avoids a problem where the same file description remains open - * in another process, causing repeated junk epoll events. - * - * We pass in a dummy epoll_event, to work around a bug in old kernels. - */ - if (loop->backend_fd >= 0) { - /* Work around a bug in kernels 3.10 to 3.19 where passing a struct that - * has the EPOLLWAKEUP flag set generates spurious audit syslog warnings. - */ - memset(&dummy, 0, sizeof(dummy)); - uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &dummy); - } -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes - * effectively infinite on 32 bits architectures. To avoid blocking - * indefinitely, we cap the timeout and poll again if necessary. - * - * Note that "30 minutes" is a simplification because it depends on - * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200, - * that being the largest value I have seen in the wild (and only once.) - */ - static const int max_safe_timeout = 1789569; - static int no_epoll_pwait; - static int no_epoll_wait; - struct uv__epoll_event events[1024]; - struct uv__epoll_event* pe; - struct uv__epoll_event e; - int real_timeout; - QUEUE* q; - uv__io_t* w; - sigset_t sigset; - uint64_t sigmask; - uint64_t base; - int nevents; - int count; - int nfds; - int fd; - int op; - int i; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - assert(w->fd >= 0); - assert(w->fd < (int) loop->nwatchers); - - e.events = w->pevents; - e.data = w->fd; - - if (w->events == 0) - op = UV__EPOLL_CTL_ADD; - else - op = UV__EPOLL_CTL_MOD; - - /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching - * events, skip the syscall and squelch the events after epoll_wait(). - */ - if (uv__epoll_ctl(loop->backend_fd, op, w->fd, &e)) { - if (errno != EEXIST) - abort(); - - assert(op == UV__EPOLL_CTL_ADD); - - /* We've reactivated a file descriptor that's been watched before. */ - if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_MOD, w->fd, &e)) - abort(); - } - - w->events = w->pevents; - } - - sigmask = 0; - if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { - sigemptyset(&sigset); - sigaddset(&sigset, SIGPROF); - sigmask |= 1 << (SIGPROF - 1); - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - real_timeout = timeout; - - for (;;) { - /* See the comment for max_safe_timeout for an explanation of why - * this is necessary. Executive summary: kernel bug workaround. - */ - if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) - timeout = max_safe_timeout; - - if (sigmask != 0 && no_epoll_pwait != 0) - if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) - abort(); - - if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) { - nfds = uv__epoll_pwait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout, - sigmask); - if (nfds == -1 && errno == ENOSYS) - no_epoll_pwait = 1; - } else { - nfds = uv__epoll_wait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout); - if (nfds == -1 && errno == ENOSYS) - no_epoll_wait = 1; - } - - if (sigmask != 0 && no_epoll_pwait != 0) - if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) - abort(); - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (nfds == 0) { - assert(timeout != -1); - - timeout = real_timeout - timeout; - if (timeout > 0) - continue; - - return; - } - - if (nfds == -1) { - if (errno == ENOSYS) { - /* epoll_wait() or epoll_pwait() failed, try the other system call. */ - assert(no_epoll_wait == 0 || no_epoll_pwait == 0); - continue; - } - - if (errno != EINTR) - abort(); - - if (timeout == -1) - continue; - - if (timeout == 0) - return; - - /* Interrupted by a signal. Update timeout and poll again. */ - goto update_timeout; - } - - nevents = 0; - - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = (void*) events; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - for (i = 0; i < nfds; i++) { - pe = events + i; - fd = pe->data; - - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (fd == -1) - continue; - - assert(fd >= 0); - assert((unsigned) fd < loop->nwatchers); - - w = loop->watchers[fd]; - - if (w == NULL) { - /* File descriptor that we've stopped watching, disarm it. - * - * Ignore all errors because we may be racing with another thread - * when the file descriptor is closed. - */ - uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe); - continue; - } - - /* Give users only events they're interested in. Prevents spurious - * callbacks when previous callback invocation in this loop has stopped - * the current watcher. Also, filters out events that users has not - * requested us to watch. - */ - pe->events &= w->pevents | UV__POLLERR | UV__POLLHUP; - - /* Work around an epoll quirk where it sometimes reports just the - * EPOLLERR or EPOLLHUP event. In order to force the event loop to - * move forward, we merge in the read/write events that the watcher - * is interested in; uv__read() and uv__write() will then deal with - * the error or hangup in the usual fashion. - * - * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user - * reads the available data, calls uv_read_stop(), then sometime later - * calls uv_read_start() again. By then, libuv has forgotten about the - * hangup and the kernel won't report EPOLLIN again because there's - * nothing left to read. If anything, libuv is to blame here. The - * current hack is just a quick bandaid; to properly fix it, libuv - * needs to remember the error/hangup event. We should get that for - * free when we switch over to edge-triggered I/O. - */ - if (pe->events == UV__EPOLLERR || pe->events == UV__EPOLLHUP) - pe->events |= w->pevents & (UV__EPOLLIN | UV__EPOLLOUT); - - if (pe->events != 0) { - w->cb(loop, w, pe->events); - nevents++; - } - } - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - real_timeout -= (loop->time - base); - if (real_timeout <= 0) - return; - - timeout = real_timeout; - } -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - static clock_t fast_clock_id = -1; - struct timespec t; - clock_t clock_id; - - /* Prefer CLOCK_MONOTONIC_COARSE if available but only when it has - * millisecond granularity or better. CLOCK_MONOTONIC_COARSE is - * serviced entirely from the vDSO, whereas CLOCK_MONOTONIC may - * decide to make a costly system call. - */ - /* TODO(bnoordhuis) Use CLOCK_MONOTONIC_COARSE for UV_CLOCK_PRECISE - * when it has microsecond granularity or better (unlikely). - */ - if (type == UV_CLOCK_FAST && fast_clock_id == -1) { - if (clock_getres(CLOCK_MONOTONIC_COARSE, &t) == 0 && - t.tv_nsec <= 1 * 1000 * 1000) { - fast_clock_id = CLOCK_MONOTONIC_COARSE; - } else { - fast_clock_id = CLOCK_MONOTONIC; - } - } - - clock_id = CLOCK_MONOTONIC; - if (type == UV_CLOCK_FAST) - clock_id = fast_clock_id; - - if (clock_gettime(clock_id, &t)) - return 0; /* Not really possible. */ - - return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec; -} - - -void uv_loadavg(double avg[3]) { - struct sysinfo info; - - if (sysinfo(&info) < 0) return; - - avg[0] = (double) info.loads[0] / 65536.0; - avg[1] = (double) info.loads[1] / 65536.0; - avg[2] = (double) info.loads[2] / 65536.0; -} - - -int uv_exepath(char* buffer, size_t* size) { - ssize_t n; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - n = *size - 1; - if (n > 0) - n = readlink("/proc/self/exe", buffer, n); - - if (n == -1) - return -errno; - - buffer[n] = '\0'; - *size = n; - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES); -} - - -uint64_t uv_get_total_memory(void) { - return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES); -} - - -int uv_resident_set_memory(size_t* rss) { - char buf[1024]; - const char* s; - ssize_t n; - long val; - int fd; - int i; - - do - fd = open("/proc/self/stat", O_RDONLY); - while (fd == -1 && errno == EINTR); - - if (fd == -1) - return -errno; - - do - n = read(fd, buf, sizeof(buf) - 1); - while (n == -1 && errno == EINTR); - - uv__close(fd); - if (n == -1) - return -errno; - buf[n] = '\0'; - - s = strchr(buf, ' '); - if (s == NULL) - goto err; - - s += 1; - if (*s != '(') - goto err; - - s = strchr(s, ')'); - if (s == NULL) - goto err; - - for (i = 1; i <= 22; i++) { - s = strchr(s + 1, ' '); - if (s == NULL) - goto err; - } - - errno = 0; - val = strtol(s, NULL, 10); - if (errno != 0) - goto err; - if (val < 0) - goto err; - - *rss = val * getpagesize(); - return 0; - -err: - return -EINVAL; -} - - -int uv_uptime(double* uptime) { - static volatile int no_clock_boottime; - struct timespec now; - int r; - - /* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available - * (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system - * is suspended. - */ - if (no_clock_boottime) { - retry: r = clock_gettime(CLOCK_MONOTONIC, &now); - } - else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) { - no_clock_boottime = 1; - goto retry; - } - - if (r) - return -errno; - - *uptime = now.tv_sec; - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int numcpus; - uv_cpu_info_t* ci; - int err; - - *cpu_infos = NULL; - *count = 0; - - numcpus = sysconf(_SC_NPROCESSORS_ONLN); - assert(numcpus != (unsigned int) -1); - assert(numcpus != 0); - - ci = uv__calloc(numcpus, sizeof(*ci)); - if (ci == NULL) - return -ENOMEM; - - err = read_models(numcpus, ci); - if (err == 0) - err = read_times(numcpus, ci); - - if (err) { - uv_free_cpu_info(ci, numcpus); - return err; - } - - /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo. - * We don't check for errors here. Worst case, the field is left zero. - */ - if (ci[0].speed == 0) - read_speeds(numcpus, ci); - - *cpu_infos = ci; - *count = numcpus; - - return 0; -} - - -static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) { - unsigned int num; - - for (num = 0; num < numcpus; num++) - ci[num].speed = read_cpufreq(num) / 1000; -} - - -/* Also reads the CPU frequency on x86. The other architectures only have - * a BogoMIPS field, which may not be very accurate. - * - * Note: Simply returns on error, uv_cpu_info() takes care of the cleanup. - */ -static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { - static const char model_marker[] = "model name\t: "; - static const char speed_marker[] = "cpu MHz\t\t: "; - const char* inferred_model; - unsigned int model_idx; - unsigned int speed_idx; - char buf[1024]; - char* model; - FILE* fp; - - /* Most are unused on non-ARM, non-MIPS and non-x86 architectures. */ - (void) &model_marker; - (void) &speed_marker; - (void) &speed_idx; - (void) &model; - (void) &buf; - (void) &fp; - - model_idx = 0; - speed_idx = 0; - -#if defined(__arm__) || \ - defined(__i386__) || \ - defined(__mips__) || \ - defined(__x86_64__) - fp = fopen("/proc/cpuinfo", "r"); - if (fp == NULL) - return -errno; - - while (fgets(buf, sizeof(buf), fp)) { - if (model_idx < numcpus) { - if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) { - model = buf + sizeof(model_marker) - 1; - model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */ - if (model == NULL) { - fclose(fp); - return -ENOMEM; - } - ci[model_idx++].model = model; - continue; - } - } -#if defined(__arm__) || defined(__mips__) - if (model_idx < numcpus) { -#if defined(__arm__) - /* Fallback for pre-3.8 kernels. */ - static const char model_marker[] = "Processor\t: "; -#else /* defined(__mips__) */ - static const char model_marker[] = "cpu model\t\t: "; -#endif - if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) { - model = buf + sizeof(model_marker) - 1; - model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */ - if (model == NULL) { - fclose(fp); - return -ENOMEM; - } - ci[model_idx++].model = model; - continue; - } - } -#else /* !__arm__ && !__mips__ */ - if (speed_idx < numcpus) { - if (strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0) { - ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1); - continue; - } - } -#endif /* __arm__ || __mips__ */ - } - - fclose(fp); -#endif /* __arm__ || __i386__ || __mips__ || __x86_64__ */ - - /* Now we want to make sure that all the models contain *something* because - * it's not safe to leave them as null. Copy the last entry unless there - * isn't one, in that case we simply put "unknown" into everything. - */ - inferred_model = "unknown"; - if (model_idx > 0) - inferred_model = ci[model_idx - 1].model; - - while (model_idx < numcpus) { - model = uv__strndup(inferred_model, strlen(inferred_model)); - if (model == NULL) - return -ENOMEM; - ci[model_idx++].model = model; - } - - return 0; -} - - -static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) { - unsigned long clock_ticks; - struct uv_cpu_times_s ts; - unsigned long user; - unsigned long nice; - unsigned long sys; - unsigned long idle; - unsigned long dummy; - unsigned long irq; - unsigned int num; - unsigned int len; - char buf[1024]; - FILE* fp; - - clock_ticks = sysconf(_SC_CLK_TCK); - assert(clock_ticks != (unsigned long) -1); - assert(clock_ticks != 0); - - fp = fopen("/proc/stat", "r"); - if (fp == NULL) - return -errno; - - if (!fgets(buf, sizeof(buf), fp)) - abort(); - - num = 0; - - while (fgets(buf, sizeof(buf), fp)) { - if (num >= numcpus) - break; - - if (strncmp(buf, "cpu", 3)) - break; - - /* skip "cpu " marker */ - { - unsigned int n; - int r = sscanf(buf, "cpu%u ", &n); - assert(r == 1); - (void) r; /* silence build warning */ - for (len = sizeof("cpu0"); n /= 10; len++); - } - - /* Line contains user, nice, system, idle, iowait, irq, softirq, steal, - * guest, guest_nice but we're only interested in the first four + irq. - * - * Don't use %*s to skip fields or %ll to read straight into the uint64_t - * fields, they're not allowed in C89 mode. - */ - if (6 != sscanf(buf + len, - "%lu %lu %lu %lu %lu %lu", - &user, - &nice, - &sys, - &idle, - &dummy, - &irq)) - abort(); - - ts.user = clock_ticks * user; - ts.nice = clock_ticks * nice; - ts.sys = clock_ticks * sys; - ts.idle = clock_ticks * idle; - ts.irq = clock_ticks * irq; - ci[num++].cpu_times = ts; - } - fclose(fp); - assert(num == numcpus); - - return 0; -} - - -static unsigned long read_cpufreq(unsigned int cpunum) { - unsigned long val; - char buf[1024]; - FILE* fp; - - snprintf(buf, - sizeof(buf), - "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", - cpunum); - - fp = fopen(buf, "r"); - if (fp == NULL) - return 0; - - if (fscanf(fp, "%lu", &val) != 1) - val = 0; - - fclose(fp); - - return val; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { -#ifndef HAVE_IFADDRS_H - return -ENOSYS; -#else - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_ll *sll; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - *addresses = NULL; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { - continue; - } - - (*count)++; - } - - if (*count == 0) - return 0; - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Linux getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == PF_PACKET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_PACKET)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sll = (struct sockaddr_ll*)ent->ifa_addr; - memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -#endif -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} - - -void uv__set_process_title(const char* title) { -#if defined(PR_SET_NAME) - prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */ -#endif -} diff --git a/outside/libuv-v1.7.5/src/unix/linux-inotify.c b/outside/libuv-v1.7.5/src/unix/linux-inotify.c deleted file mode 100644 index d9ed9f4b24..0000000000 --- a/outside/libuv-v1.7.5/src/unix/linux-inotify.c +++ /dev/null @@ -1,257 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "tree.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -struct watcher_list { - RB_ENTRY(watcher_list) entry; - QUEUE watchers; - char* path; - int wd; -}; - -struct watcher_root { - struct watcher_list* rbh_root; -}; -#define CAST(p) ((struct watcher_root*)(p)) - - -static int compare_watchers(const struct watcher_list* a, - const struct watcher_list* b) { - if (a->wd < b->wd) return -1; - if (a->wd > b->wd) return 1; - return 0; -} - - -RB_GENERATE_STATIC(watcher_root, watcher_list, entry, compare_watchers) - - -static void uv__inotify_read(uv_loop_t* loop, - uv__io_t* w, - unsigned int revents); - - -static int new_inotify_fd(void) { - int err; - int fd; - - fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC); - if (fd != -1) - return fd; - - if (errno != ENOSYS) - return -errno; - - fd = uv__inotify_init(); - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err == 0) - err = uv__nonblock(fd, 1); - - if (err) { - uv__close(fd); - return err; - } - - return fd; -} - - -static int init_inotify(uv_loop_t* loop) { - int err; - - if (loop->inotify_fd != -1) - return 0; - - err = new_inotify_fd(); - if (err < 0) - return err; - - loop->inotify_fd = err; - uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd); - uv__io_start(loop, &loop->inotify_read_watcher, UV__POLLIN); - - return 0; -} - - -static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) { - struct watcher_list w; - w.wd = wd; - return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w); -} - - -static void uv__inotify_read(uv_loop_t* loop, - uv__io_t* dummy, - unsigned int events) { - const struct uv__inotify_event* e; - struct watcher_list* w; - uv_fs_event_t* h; - QUEUE* q; - const char* path; - ssize_t size; - const char *p; - /* needs to be large enough for sizeof(inotify_event) + strlen(path) */ - char buf[4096]; - - while (1) { - do - size = read(loop->inotify_fd, buf, sizeof(buf)); - while (size == -1 && errno == EINTR); - - if (size == -1) { - assert(errno == EAGAIN || errno == EWOULDBLOCK); - break; - } - - assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */ - - /* Now we have one or more inotify_event structs. */ - for (p = buf; p < buf + size; p += sizeof(*e) + e->len) { - e = (const struct uv__inotify_event*)p; - - events = 0; - if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY)) - events |= UV_CHANGE; - if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY)) - events |= UV_RENAME; - - w = find_watcher(loop, e->wd); - if (w == NULL) - continue; /* Stale event, no watchers left. */ - - /* inotify does not return the filename when monitoring a single file - * for modifications. Repurpose the filename for API compatibility. - * I'm not convinced this is a good thing, maybe it should go. - */ - path = e->len ? (const char*) (e + 1) : uv__basename_r(w->path); - - QUEUE_FOREACH(q, &w->watchers) { - h = QUEUE_DATA(q, uv_fs_event_t, watchers); - h->cb(h, path, events, 0); - } - } - } -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* path, - unsigned int flags) { - struct watcher_list* w; - int events; - int err; - int wd; - - if (uv__is_active(handle)) - return -EINVAL; - - err = init_inotify(handle->loop); - if (err) - return err; - - events = UV__IN_ATTRIB - | UV__IN_CREATE - | UV__IN_MODIFY - | UV__IN_DELETE - | UV__IN_DELETE_SELF - | UV__IN_MOVE_SELF - | UV__IN_MOVED_FROM - | UV__IN_MOVED_TO; - - wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events); - if (wd == -1) - return -errno; - - w = find_watcher(handle->loop, wd); - if (w) - goto no_insert; - - w = uv__malloc(sizeof(*w) + strlen(path) + 1); - if (w == NULL) - return -ENOMEM; - - w->wd = wd; - w->path = strcpy((char*)(w + 1), path); - QUEUE_INIT(&w->watchers); - RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w); - -no_insert: - uv__handle_start(handle); - QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers); - handle->path = w->path; - handle->cb = cb; - handle->wd = wd; - - return 0; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - struct watcher_list* w; - - if (!uv__is_active(handle)) - return 0; - - w = find_watcher(handle->loop, handle->wd); - assert(w != NULL); - - handle->wd = -1; - handle->path = NULL; - uv__handle_stop(handle); - QUEUE_REMOVE(&handle->watchers); - - if (QUEUE_EMPTY(&w->watchers)) { - /* No watchers left for this path. Clean up. */ - RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w); - uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd); - uv__free(w); - } - - return 0; -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { - uv_fs_event_stop(handle); -} diff --git a/outside/libuv-v1.7.5/src/unix/linux-syscalls.c b/outside/libuv-v1.7.5/src/unix/linux-syscalls.c deleted file mode 100644 index 566e1f37cf..0000000000 --- a/outside/libuv-v1.7.5/src/unix/linux-syscalls.c +++ /dev/null @@ -1,471 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "linux-syscalls.h" -#include -#include -#include -#include -#include - -#if defined(__has_feature) -# if __has_feature(memory_sanitizer) -# define MSAN_ACTIVE 1 -# include -# endif -#endif - -#if defined(__i386__) -# ifndef __NR_socketcall -# define __NR_socketcall 102 -# endif -#endif - -#if defined(__arm__) -# if defined(__thumb__) || defined(__ARM_EABI__) -# define UV_SYSCALL_BASE 0 -# else -# define UV_SYSCALL_BASE 0x900000 -# endif -#endif /* __arm__ */ - -#ifndef __NR_accept4 -# if defined(__x86_64__) -# define __NR_accept4 288 -# elif defined(__i386__) - /* Nothing. Handled through socketcall(). */ -# elif defined(__arm__) -# define __NR_accept4 (UV_SYSCALL_BASE + 366) -# endif -#endif /* __NR_accept4 */ - -#ifndef __NR_eventfd -# if defined(__x86_64__) -# define __NR_eventfd 284 -# elif defined(__i386__) -# define __NR_eventfd 323 -# elif defined(__arm__) -# define __NR_eventfd (UV_SYSCALL_BASE + 351) -# endif -#endif /* __NR_eventfd */ - -#ifndef __NR_eventfd2 -# if defined(__x86_64__) -# define __NR_eventfd2 290 -# elif defined(__i386__) -# define __NR_eventfd2 328 -# elif defined(__arm__) -# define __NR_eventfd2 (UV_SYSCALL_BASE + 356) -# endif -#endif /* __NR_eventfd2 */ - -#ifndef __NR_epoll_create -# if defined(__x86_64__) -# define __NR_epoll_create 213 -# elif defined(__i386__) -# define __NR_epoll_create 254 -# elif defined(__arm__) -# define __NR_epoll_create (UV_SYSCALL_BASE + 250) -# endif -#endif /* __NR_epoll_create */ - -#ifndef __NR_epoll_create1 -# if defined(__x86_64__) -# define __NR_epoll_create1 291 -# elif defined(__i386__) -# define __NR_epoll_create1 329 -# elif defined(__arm__) -# define __NR_epoll_create1 (UV_SYSCALL_BASE + 357) -# endif -#endif /* __NR_epoll_create1 */ - -#ifndef __NR_epoll_ctl -# if defined(__x86_64__) -# define __NR_epoll_ctl 233 /* used to be 214 */ -# elif defined(__i386__) -# define __NR_epoll_ctl 255 -# elif defined(__arm__) -# define __NR_epoll_ctl (UV_SYSCALL_BASE + 251) -# endif -#endif /* __NR_epoll_ctl */ - -#ifndef __NR_epoll_wait -# if defined(__x86_64__) -# define __NR_epoll_wait 232 /* used to be 215 */ -# elif defined(__i386__) -# define __NR_epoll_wait 256 -# elif defined(__arm__) -# define __NR_epoll_wait (UV_SYSCALL_BASE + 252) -# endif -#endif /* __NR_epoll_wait */ - -#ifndef __NR_epoll_pwait -# if defined(__x86_64__) -# define __NR_epoll_pwait 281 -# elif defined(__i386__) -# define __NR_epoll_pwait 319 -# elif defined(__arm__) -# define __NR_epoll_pwait (UV_SYSCALL_BASE + 346) -# endif -#endif /* __NR_epoll_pwait */ - -#ifndef __NR_inotify_init -# if defined(__x86_64__) -# define __NR_inotify_init 253 -# elif defined(__i386__) -# define __NR_inotify_init 291 -# elif defined(__arm__) -# define __NR_inotify_init (UV_SYSCALL_BASE + 316) -# endif -#endif /* __NR_inotify_init */ - -#ifndef __NR_inotify_init1 -# if defined(__x86_64__) -# define __NR_inotify_init1 294 -# elif defined(__i386__) -# define __NR_inotify_init1 332 -# elif defined(__arm__) -# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360) -# endif -#endif /* __NR_inotify_init1 */ - -#ifndef __NR_inotify_add_watch -# if defined(__x86_64__) -# define __NR_inotify_add_watch 254 -# elif defined(__i386__) -# define __NR_inotify_add_watch 292 -# elif defined(__arm__) -# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317) -# endif -#endif /* __NR_inotify_add_watch */ - -#ifndef __NR_inotify_rm_watch -# if defined(__x86_64__) -# define __NR_inotify_rm_watch 255 -# elif defined(__i386__) -# define __NR_inotify_rm_watch 293 -# elif defined(__arm__) -# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318) -# endif -#endif /* __NR_inotify_rm_watch */ - -#ifndef __NR_pipe2 -# if defined(__x86_64__) -# define __NR_pipe2 293 -# elif defined(__i386__) -# define __NR_pipe2 331 -# elif defined(__arm__) -# define __NR_pipe2 (UV_SYSCALL_BASE + 359) -# endif -#endif /* __NR_pipe2 */ - -#ifndef __NR_recvmmsg -# if defined(__x86_64__) -# define __NR_recvmmsg 299 -# elif defined(__i386__) -# define __NR_recvmmsg 337 -# elif defined(__arm__) -# define __NR_recvmmsg (UV_SYSCALL_BASE + 365) -# endif -#endif /* __NR_recvmsg */ - -#ifndef __NR_sendmmsg -# if defined(__x86_64__) -# define __NR_sendmmsg 307 -# elif defined(__i386__) -# define __NR_sendmmsg 345 -# elif defined(__arm__) -# define __NR_sendmmsg (UV_SYSCALL_BASE + 374) -# endif -#endif /* __NR_sendmmsg */ - -#ifndef __NR_utimensat -# if defined(__x86_64__) -# define __NR_utimensat 280 -# elif defined(__i386__) -# define __NR_utimensat 320 -# elif defined(__arm__) -# define __NR_utimensat (UV_SYSCALL_BASE + 348) -# endif -#endif /* __NR_utimensat */ - -#ifndef __NR_preadv -# if defined(__x86_64__) -# define __NR_preadv 295 -# elif defined(__i386__) -# define __NR_preadv 333 -# elif defined(__arm__) -# define __NR_preadv (UV_SYSCALL_BASE + 361) -# endif -#endif /* __NR_preadv */ - -#ifndef __NR_pwritev -# if defined(__x86_64__) -# define __NR_pwritev 296 -# elif defined(__i386__) -# define __NR_pwritev 334 -# elif defined(__arm__) -# define __NR_pwritev (UV_SYSCALL_BASE + 362) -# endif -#endif /* __NR_pwritev */ - -#ifndef __NR_dup3 -# if defined(__x86_64__) -# define __NR_dup3 292 -# elif defined(__i386__) -# define __NR_dup3 330 -# elif defined(__arm__) -# define __NR_dup3 (UV_SYSCALL_BASE + 358) -# endif -#endif /* __NR_pwritev */ - - -int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) { -#if defined(__i386__) - unsigned long args[4]; - int r; - - args[0] = (unsigned long) fd; - args[1] = (unsigned long) addr; - args[2] = (unsigned long) addrlen; - args[3] = (unsigned long) flags; - - r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args); - - /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does - * a bad flags argument. Try to distinguish between the two cases. - */ - if (r == -1) - if (errno == EINVAL) - if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0) - errno = ENOSYS; - - return r; -#elif defined(__NR_accept4) - return syscall(__NR_accept4, fd, addr, addrlen, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__eventfd(unsigned int count) { -#if defined(__NR_eventfd) - return syscall(__NR_eventfd, count); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__eventfd2(unsigned int count, int flags) { -#if defined(__NR_eventfd2) - return syscall(__NR_eventfd2, count, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_create(int size) { -#if defined(__NR_epoll_create) - return syscall(__NR_epoll_create, size); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_create1(int flags) { -#if defined(__NR_epoll_create1) - return syscall(__NR_epoll_create1, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event* events) { -#if defined(__NR_epoll_ctl) - return syscall(__NR_epoll_ctl, epfd, op, fd, events); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_wait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout) { -#if defined(__NR_epoll_wait) - int result; - result = syscall(__NR_epoll_wait, epfd, events, nevents, timeout); -#if MSAN_ACTIVE - if (result > 0) - __msan_unpoison(events, sizeof(events[0]) * result); -#endif - return result; -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_pwait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout, - uint64_t sigmask) { -#if defined(__NR_epoll_pwait) - int result; - result = syscall(__NR_epoll_pwait, - epfd, - events, - nevents, - timeout, - &sigmask, - sizeof(sigmask)); -#if MSAN_ACTIVE - if (result > 0) - __msan_unpoison(events, sizeof(events[0]) * result); -#endif - return result; -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_init(void) { -#if defined(__NR_inotify_init) - return syscall(__NR_inotify_init); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_init1(int flags) { -#if defined(__NR_inotify_init1) - return syscall(__NR_inotify_init1, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) { -#if defined(__NR_inotify_add_watch) - return syscall(__NR_inotify_add_watch, fd, path, mask); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_rm_watch(int fd, int32_t wd) { -#if defined(__NR_inotify_rm_watch) - return syscall(__NR_inotify_rm_watch, fd, wd); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__pipe2(int pipefd[2], int flags) { -#if defined(__NR_pipe2) - int result; - result = syscall(__NR_pipe2, pipefd, flags); -#if MSAN_ACTIVE - if (!result) - __msan_unpoison(pipefd, sizeof(int[2])); -#endif - return result; -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__sendmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags) { -#if defined(__NR_sendmmsg) - return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__recvmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags, - struct timespec* timeout) { -#if defined(__NR_recvmmsg) - return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__utimesat(int dirfd, - const char* path, - const struct timespec times[2], - int flags) -{ -#if defined(__NR_utimensat) - return syscall(__NR_utimensat, dirfd, path, times, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) { -#if defined(__NR_preadv) - return syscall(__NR_preadv, fd, iov, iovcnt, offset); -#else - return errno = ENOSYS, -1; -#endif -} - - -ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) { -#if defined(__NR_pwritev) - return syscall(__NR_pwritev, fd, iov, iovcnt, offset); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__dup3(int oldfd, int newfd, int flags) { -#if defined(__NR_dup3) - return syscall(__NR_dup3, oldfd, newfd, flags); -#else - return errno = ENOSYS, -1; -#endif -} diff --git a/outside/libuv-v1.7.5/src/unix/linux-syscalls.h b/outside/libuv-v1.7.5/src/unix/linux-syscalls.h deleted file mode 100644 index 6f249b7245..0000000000 --- a/outside/libuv-v1.7.5/src/unix/linux-syscalls.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_LINUX_SYSCALL_H_ -#define UV_LINUX_SYSCALL_H_ - -#undef _GNU_SOURCE -#define _GNU_SOURCE - -#include -#include -#include -#include -#include - -#if defined(__alpha__) -# define UV__O_CLOEXEC 0x200000 -#elif defined(__hppa__) -# define UV__O_CLOEXEC 0x200000 -#elif defined(__sparc__) -# define UV__O_CLOEXEC 0x400000 -#else -# define UV__O_CLOEXEC 0x80000 -#endif - -#if defined(__alpha__) -# define UV__O_NONBLOCK 0x4 -#elif defined(__hppa__) -# define UV__O_NONBLOCK O_NONBLOCK -#elif defined(__mips__) -# define UV__O_NONBLOCK 0x80 -#elif defined(__sparc__) -# define UV__O_NONBLOCK 0x4000 -#else -# define UV__O_NONBLOCK 0x800 -#endif - -#define UV__EFD_CLOEXEC UV__O_CLOEXEC -#define UV__EFD_NONBLOCK UV__O_NONBLOCK - -#define UV__IN_CLOEXEC UV__O_CLOEXEC -#define UV__IN_NONBLOCK UV__O_NONBLOCK - -#define UV__SOCK_CLOEXEC UV__O_CLOEXEC -#if defined(SOCK_NONBLOCK) -# define UV__SOCK_NONBLOCK SOCK_NONBLOCK -#else -# define UV__SOCK_NONBLOCK UV__O_NONBLOCK -#endif - -/* epoll flags */ -#define UV__EPOLL_CLOEXEC UV__O_CLOEXEC -#define UV__EPOLL_CTL_ADD 1 -#define UV__EPOLL_CTL_DEL 2 -#define UV__EPOLL_CTL_MOD 3 - -#define UV__EPOLLIN 1 -#define UV__EPOLLOUT 4 -#define UV__EPOLLERR 8 -#define UV__EPOLLHUP 16 -#define UV__EPOLLONESHOT 0x40000000 -#define UV__EPOLLET 0x80000000 - -/* inotify flags */ -#define UV__IN_ACCESS 0x001 -#define UV__IN_MODIFY 0x002 -#define UV__IN_ATTRIB 0x004 -#define UV__IN_CLOSE_WRITE 0x008 -#define UV__IN_CLOSE_NOWRITE 0x010 -#define UV__IN_OPEN 0x020 -#define UV__IN_MOVED_FROM 0x040 -#define UV__IN_MOVED_TO 0x080 -#define UV__IN_CREATE 0x100 -#define UV__IN_DELETE 0x200 -#define UV__IN_DELETE_SELF 0x400 -#define UV__IN_MOVE_SELF 0x800 - -#if defined(__x86_64__) -struct uv__epoll_event { - uint32_t events; - uint64_t data; -} __attribute__((packed)); -#else -struct uv__epoll_event { - uint32_t events; - uint64_t data; -}; -#endif - -struct uv__inotify_event { - int32_t wd; - uint32_t mask; - uint32_t cookie; - uint32_t len; - /* char name[0]; */ -}; - -struct uv__mmsghdr { - struct msghdr msg_hdr; - unsigned int msg_len; -}; - -int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags); -int uv__eventfd(unsigned int count); -int uv__epoll_create(int size); -int uv__epoll_create1(int flags); -int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event *ev); -int uv__epoll_wait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout); -int uv__epoll_pwait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout, - uint64_t sigmask); -int uv__eventfd2(unsigned int count, int flags); -int uv__inotify_init(void); -int uv__inotify_init1(int flags); -int uv__inotify_add_watch(int fd, const char* path, uint32_t mask); -int uv__inotify_rm_watch(int fd, int32_t wd); -int uv__pipe2(int pipefd[2], int flags); -int uv__recvmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags, - struct timespec* timeout); -int uv__sendmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags); -int uv__utimesat(int dirfd, - const char* path, - const struct timespec times[2], - int flags); -ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); -ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); -int uv__dup3(int oldfd, int newfd, int flags); - -#endif /* UV_LINUX_SYSCALL_H_ */ diff --git a/outside/libuv-v1.7.5/src/unix/loop-watcher.c b/outside/libuv-v1.7.5/src/unix/loop-watcher.c deleted file mode 100644 index dc25760bd5..0000000000 --- a/outside/libuv-v1.7.5/src/unix/loop-watcher.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#define UV_LOOP_WATCHER_DEFINE(name, type) \ - int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ - uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \ - handle->name##_cb = NULL; \ - return 0; \ - } \ - \ - int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ - if (uv__is_active(handle)) return 0; \ - if (cb == NULL) return -EINVAL; \ - QUEUE_INSERT_HEAD(&handle->loop->name##_handles, &handle->queue); \ - handle->name##_cb = cb; \ - uv__handle_start(handle); \ - return 0; \ - } \ - \ - int uv_##name##_stop(uv_##name##_t* handle) { \ - if (!uv__is_active(handle)) return 0; \ - QUEUE_REMOVE(&handle->queue); \ - uv__handle_stop(handle); \ - return 0; \ - } \ - \ - void uv__run_##name(uv_loop_t* loop) { \ - uv_##name##_t* h; \ - QUEUE* q; \ - QUEUE_FOREACH(q, &loop->name##_handles) { \ - h = QUEUE_DATA(q, uv_##name##_t, queue); \ - h->name##_cb(h); \ - } \ - } \ - \ - void uv__##name##_close(uv_##name##_t* handle) { \ - uv_##name##_stop(handle); \ - } - -UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) -UV_LOOP_WATCHER_DEFINE(check, CHECK) -UV_LOOP_WATCHER_DEFINE(idle, IDLE) diff --git a/outside/libuv-v1.7.5/src/unix/loop.c b/outside/libuv-v1.7.5/src/unix/loop.c deleted file mode 100644 index 92e96f09ed..0000000000 --- a/outside/libuv-v1.7.5/src/unix/loop.c +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "tree.h" -#include "internal.h" -#include "heap-inl.h" -#include -#include -#include - -int uv_loop_init(uv_loop_t* loop) { - int err; - - uv__signal_global_once_init(); - - memset(loop, 0, sizeof(*loop)); - heap_init((struct heap*) &loop->timer_heap); - QUEUE_INIT(&loop->wq); - QUEUE_INIT(&loop->active_reqs); - QUEUE_INIT(&loop->idle_handles); - QUEUE_INIT(&loop->async_handles); - QUEUE_INIT(&loop->check_handles); - QUEUE_INIT(&loop->prepare_handles); - QUEUE_INIT(&loop->handle_queue); - - loop->nfds = 0; - loop->watchers = NULL; - loop->nwatchers = 0; - QUEUE_INIT(&loop->pending_queue); - QUEUE_INIT(&loop->watcher_queue); - - loop->closing_handles = NULL; - uv__update_time(loop); - uv__async_init(&loop->async_watcher); - loop->signal_pipefd[0] = -1; - loop->signal_pipefd[1] = -1; - loop->backend_fd = -1; - loop->emfile_fd = -1; - - loop->timer_counter = 0; - loop->stop_flag = 0; - - err = uv__platform_loop_init(loop); - if (err) - return err; - - err = uv_signal_init(loop, &loop->child_watcher); - if (err) - goto fail_signal_init; - - uv__handle_unref(&loop->child_watcher); - loop->child_watcher.flags |= UV__HANDLE_INTERNAL; - QUEUE_INIT(&loop->process_handles); - - err = uv_rwlock_init(&loop->cloexec_lock); - if (err) - goto fail_rwlock_init; - - err = uv_mutex_init(&loop->wq_mutex); - if (err) - goto fail_mutex_init; - - err = uv_async_init(loop, &loop->wq_async, uv__work_done); - if (err) - goto fail_async_init; - - uv__handle_unref(&loop->wq_async); - loop->wq_async.flags |= UV__HANDLE_INTERNAL; - - return 0; - -fail_async_init: - uv_mutex_destroy(&loop->wq_mutex); - -fail_mutex_init: - uv_rwlock_destroy(&loop->cloexec_lock); - -fail_rwlock_init: - uv__signal_loop_cleanup(loop); - -fail_signal_init: - uv__platform_loop_delete(loop); - - return err; -} - - -void uv__loop_close(uv_loop_t* loop) { - uv__signal_loop_cleanup(loop); - uv__platform_loop_delete(loop); - uv__async_stop(loop, &loop->async_watcher); - - if (loop->emfile_fd != -1) { - uv__close(loop->emfile_fd); - loop->emfile_fd = -1; - } - - if (loop->backend_fd != -1) { - uv__close(loop->backend_fd); - loop->backend_fd = -1; - } - - uv_mutex_lock(&loop->wq_mutex); - assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!"); - assert(!uv__has_active_reqs(loop)); - uv_mutex_unlock(&loop->wq_mutex); - uv_mutex_destroy(&loop->wq_mutex); - - /* - * Note that all thread pool stuff is finished at this point and - * it is safe to just destroy rw lock - */ - uv_rwlock_destroy(&loop->cloexec_lock); - -#if 0 - assert(QUEUE_EMPTY(&loop->pending_queue)); - assert(QUEUE_EMPTY(&loop->watcher_queue)); - assert(loop->nfds == 0); -#endif - - uv__free(loop->watchers); - loop->watchers = NULL; - loop->nwatchers = 0; -} - - -int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { - if (option != UV_LOOP_BLOCK_SIGNAL) - return UV_ENOSYS; - - if (va_arg(ap, int) != SIGPROF) - return UV_EINVAL; - - loop->flags |= UV_LOOP_BLOCK_SIGPROF; - return 0; -} diff --git a/outside/libuv-v1.7.5/src/unix/netbsd.c b/outside/libuv-v1.7.5/src/unix/netbsd.c deleted file mode 100644 index 29f2a4dec6..0000000000 --- a/outside/libuv-v1.7.5/src/unix/netbsd.c +++ /dev/null @@ -1,368 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - -static char *process_title; - - -int uv__platform_loop_init(uv_loop_t* loop) { - return uv__kqueue_init(loop); -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -int uv_exepath(char* buffer, size_t* size) { - int mib[4]; - size_t cb; - pid_t mypid; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - mypid = getpid(); - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = mypid; - mib[3] = KERN_PROC_ARGV; - - cb = *size; - if (sysctl(mib, 4, buffer, &cb, NULL, 0)) - return -errno; - *size = strlen(buffer); - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - struct uvmexp info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_UVMEXP}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info.free * sysconf(_SC_PAGESIZE); -} - - -uint64_t uv_get_total_memory(void) { -#if defined(HW_PHYSMEM64) - uint64_t info; - int which[] = {CTL_HW, HW_PHYSMEM64}; -#else - unsigned int info; - int which[] = {CTL_HW, HW_PHYSMEM}; -#endif - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -char** uv_setup_args(int argc, char** argv) { - process_title = argc ? uv__strdup(argv[0]) : NULL; - return argv; -} - - -int uv_set_process_title(const char* title) { - if (process_title) uv__free(process_title); - - process_title = uv__strdup(title); - setproctitle("%s", title); - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title) { - strncpy(buffer, process_title, size); - } else { - if (size > 0) { - buffer[0] = '\0'; - } - } - - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - kvm_t *kd = NULL; - struct kinfo_proc2 *kinfo = NULL; - pid_t pid; - int nprocs; - int max_size = sizeof(struct kinfo_proc2); - int page_size; - - page_size = getpagesize(); - pid = getpid(); - - kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open"); - - if (kd == NULL) goto error; - - kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs); - if (kinfo == NULL) goto error; - - *rss = kinfo->p_vm_rssize * page_size; - - kvm_close(kd); - - return 0; - -error: - if (kd) kvm_close(kd); - return -EPERM; -} - - -int uv_uptime(double* uptime) { - time_t now; - struct timeval info; - size_t size = sizeof(info); - static int which[] = {CTL_KERN, KERN_BOOTTIME}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - now = time(NULL); - - *uptime = (double)(now - info.tv_sec); - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK); - unsigned int multiplier = ((uint64_t)1000L / ticks); - unsigned int cur = 0; - uv_cpu_info_t* cpu_info; - u_int64_t* cp_times; - char model[512]; - u_int64_t cpuspeed; - int numcpus; - size_t size; - int i; - - size = sizeof(model); - if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) && - sysctlbyname("hw.model", &model, &size, NULL, 0)) { - return -errno; - } - - size = sizeof(numcpus); - if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) - return -errno; - *count = numcpus; - - /* Only i386 and amd64 have machdep.tsc_freq */ - size = sizeof(cpuspeed); - if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0)) - cpuspeed = 0; - - size = numcpus * CPUSTATES * sizeof(*cp_times); - cp_times = uv__malloc(size); - if (cp_times == NULL) - return -ENOMEM; - - if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0)) - return -errno; - - *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) { - uv__free(cp_times); - uv__free(*cpu_infos); - return -ENOMEM; - } - - for (i = 0; i < numcpus; i++) { - cpu_info = &(*cpu_infos)[i]; - cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; - cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; - cpu_info->model = uv__strdup(model); - cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6); - cur += CPUSTATES; - } - uv__free(cp_times); - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/outside/libuv-v1.7.5/src/unix/openbsd.c b/outside/libuv-v1.7.5/src/unix/openbsd.c deleted file mode 100644 index c8d5459938..0000000000 --- a/outside/libuv-v1.7.5/src/unix/openbsd.c +++ /dev/null @@ -1,384 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - - -static char *process_title; - - -int uv__platform_loop_init(uv_loop_t* loop) { - return uv__kqueue_init(loop); -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -int uv_exepath(char* buffer, size_t* size) { - int mib[4]; - char **argsbuf = NULL; - char **argsbuf_tmp; - size_t argsbuf_size = 100U; - size_t exepath_size; - pid_t mypid; - int err; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - mypid = getpid(); - for (;;) { - err = -ENOMEM; - argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size); - if (argsbuf_tmp == NULL) - goto out; - argsbuf = argsbuf_tmp; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = mypid; - mib[3] = KERN_PROC_ARGV; - if (sysctl(mib, 4, argsbuf, &argsbuf_size, NULL, 0) == 0) { - break; - } - if (errno != ENOMEM) { - err = -errno; - goto out; - } - argsbuf_size *= 2U; - } - - if (argsbuf[0] == NULL) { - err = -EINVAL; /* FIXME(bnoordhuis) More appropriate error. */ - goto out; - } - - *size -= 1; - exepath_size = strlen(argsbuf[0]); - if (*size > exepath_size) - *size = exepath_size; - - memcpy(buffer, argsbuf[0], *size); - buffer[*size] = '\0'; - err = 0; - -out: - uv__free(argsbuf); - - return err; -} - - -uint64_t uv_get_free_memory(void) { - struct uvmexp info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_UVMEXP}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info.free * sysconf(_SC_PAGESIZE); -} - - -uint64_t uv_get_total_memory(void) { - uint64_t info; - int which[] = {CTL_HW, HW_PHYSMEM64}; - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -char** uv_setup_args(int argc, char** argv) { - process_title = argc ? uv__strdup(argv[0]) : NULL; - return argv; -} - - -int uv_set_process_title(const char* title) { - if (process_title) uv__free(process_title); - process_title = uv__strdup(title); - setproctitle(title); - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title) { - strncpy(buffer, process_title, size); - } else { - if (size > 0) { - buffer[0] = '\0'; - } - } - - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - struct kinfo_proc kinfo; - size_t page_size = getpagesize(); - size_t size = sizeof(struct kinfo_proc); - int mib[6]; - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - mib[4] = sizeof(struct kinfo_proc); - mib[5] = 1; - - if (sysctl(mib, 6, &kinfo, &size, NULL, 0) < 0) - return -errno; - - *rss = kinfo.p_vm_rssize * page_size; - return 0; -} - - -int uv_uptime(double* uptime) { - time_t now; - struct timeval info; - size_t size = sizeof(info); - static int which[] = {CTL_KERN, KERN_BOOTTIME}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - now = time(NULL); - - *uptime = (double)(now - info.tv_sec); - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), - multiplier = ((uint64_t)1000L / ticks), cpuspeed; - uint64_t info[CPUSTATES]; - char model[512]; - int numcpus = 1; - int which[] = {CTL_HW,HW_MODEL,0}; - size_t size; - int i; - uv_cpu_info_t* cpu_info; - - size = sizeof(model); - if (sysctl(which, 2, &model, &size, NULL, 0)) - return -errno; - - which[1] = HW_NCPU; - size = sizeof(numcpus); - if (sysctl(which, 2, &numcpus, &size, NULL, 0)) - return -errno; - - *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) - return -ENOMEM; - - *count = numcpus; - - which[1] = HW_CPUSPEED; - size = sizeof(cpuspeed); - if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) { - SAVE_ERRNO(uv__free(*cpu_infos)); - return -errno; - } - - size = sizeof(info); - which[0] = CTL_KERN; - which[1] = KERN_CPTIME2; - for (i = 0; i < numcpus; i++) { - which[2] = i; - size = sizeof(info); - if (sysctl(which, 3, &info, &size, NULL, 0)) { - SAVE_ERRNO(uv__free(*cpu_infos)); - return -errno; - } - - cpu_info = &(*cpu_infos)[i]; - - cpu_info->cpu_times.user = (uint64_t)(info[CP_USER]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(info[CP_NICE]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(info[CP_SYS]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier; - cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier; - - cpu_info->model = uv__strdup(model); - cpu_info->speed = cpuspeed; - } - - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs) != 0) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/outside/libuv-v1.7.5/src/unix/pipe.c b/outside/libuv-v1.7.5/src/unix/pipe.c deleted file mode 100644 index 7f87a713bf..0000000000 --- a/outside/libuv-v1.7.5/src/unix/pipe.c +++ /dev/null @@ -1,288 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include - - -int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { - uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); - handle->shutdown_req = NULL; - handle->connect_req = NULL; - handle->pipe_fname = NULL; - handle->ipc = ipc; - return 0; -} - - -int uv_pipe_bind(uv_pipe_t* handle, const char* name) { - struct sockaddr_un saddr; - const char* pipe_fname; - int sockfd; - int err; - - pipe_fname = NULL; - sockfd = -1; - - /* Already bound? */ - if (uv__stream_fd(handle) >= 0) - return -EINVAL; - - /* Make a copy of the file name, it outlives this function's scope. */ - pipe_fname = uv__strdup(name); - if (pipe_fname == NULL) - return -ENOMEM; - - /* We've got a copy, don't touch the original any more. */ - name = NULL; - - err = uv__socket(AF_UNIX, SOCK_STREAM, 0); - if (err < 0) - goto err_socket; - sockfd = err; - - memset(&saddr, 0, sizeof saddr); - strncpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path) - 1); - saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; - saddr.sun_family = AF_UNIX; - - if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { - err = -errno; - /* Convert ENOENT to EACCES for compatibility with Windows. */ - if (err == -ENOENT) - err = -EACCES; - goto err_bind; - } - - /* Success. */ - handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */ - handle->io_watcher.fd = sockfd; - return 0; - -err_bind: - uv__close(sockfd); - -err_socket: - uv__free((void*)pipe_fname); - return err; -} - - -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { - if (uv__stream_fd(handle) == -1) - return -EINVAL; - - if (listen(uv__stream_fd(handle), backlog)) - return -errno; - - handle->connection_cb = cb; - handle->io_watcher.cb = uv__server_io; - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN); - return 0; -} - - -void uv__pipe_close(uv_pipe_t* handle) { - if (handle->pipe_fname) { - /* - * Unlink the file system entity before closing the file descriptor. - * Doing it the other way around introduces a race where our process - * unlinks a socket with the same name that's just been created by - * another thread or process. - */ - unlink(handle->pipe_fname); - uv__free((void*)handle->pipe_fname); - handle->pipe_fname = NULL; - } - - uv__stream_close((uv_stream_t*)handle); -} - - -int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { - int err; - - err = uv__nonblock(fd, 1); - if (err) - return err; - -#if defined(__APPLE__) - err = uv__stream_try_select((uv_stream_t*) handle, &fd); - if (err) - return err; -#endif /* defined(__APPLE__) */ - - return uv__stream_open((uv_stream_t*)handle, - fd, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); -} - - -void uv_pipe_connect(uv_connect_t* req, - uv_pipe_t* handle, - const char* name, - uv_connect_cb cb) { - struct sockaddr_un saddr; - int new_sock; - int err; - int r; - - new_sock = (uv__stream_fd(handle) == -1); - - if (new_sock) { - err = uv__socket(AF_UNIX, SOCK_STREAM, 0); - if (err < 0) - goto out; - handle->io_watcher.fd = err; - } - - memset(&saddr, 0, sizeof saddr); - strncpy(saddr.sun_path, name, sizeof(saddr.sun_path) - 1); - saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; - saddr.sun_family = AF_UNIX; - - do { - r = connect(uv__stream_fd(handle), - (struct sockaddr*)&saddr, sizeof saddr); - } - while (r == -1 && errno == EINTR); - - if (r == -1 && errno != EINPROGRESS) { - err = -errno; - goto out; - } - - err = 0; - if (new_sock) { - err = uv__stream_open((uv_stream_t*)handle, - uv__stream_fd(handle), - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - } - - if (err == 0) - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT); - -out: - handle->delayed_error = err; - handle->connect_req = req; - - uv__req_init(handle->loop, req, UV_CONNECT); - req->handle = (uv_stream_t*)handle; - req->cb = cb; - QUEUE_INIT(&req->queue); - - /* Force callback to run on next tick in case of error. */ - if (err) - uv__io_feed(handle->loop, &handle->io_watcher); - - /* Mimic the Windows pipe implementation, always - * return 0 and let the callback handle errors. - */ -} - - -typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*); - - -static int uv__pipe_getsockpeername(const uv_pipe_t* handle, - uv__peersockfunc func, - char* buffer, - size_t* size) { - struct sockaddr_un sa; - socklen_t addrlen; - int err; - - addrlen = sizeof(sa); - memset(&sa, 0, addrlen); - err = func(uv__stream_fd(handle), (struct sockaddr*) &sa, &addrlen); - if (err < 0) { - *size = 0; - return -errno; - } - -#if defined(__linux__) - if (sa.sun_path[0] == 0) - /* Linux abstract namespace */ - addrlen -= offsetof(struct sockaddr_un, sun_path); - else -#endif - addrlen = strlen(sa.sun_path); - - - if (addrlen > *size) { - *size = addrlen; - return UV_ENOBUFS; - } - - memcpy(buffer, sa.sun_path, addrlen); - *size = addrlen; - - return 0; -} - - -int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) { - return uv__pipe_getsockpeername(handle, getsockname, buffer, size); -} - - -int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) { - return uv__pipe_getsockpeername(handle, getpeername, buffer, size); -} - - -void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { -} - - -int uv_pipe_pending_count(uv_pipe_t* handle) { - uv__stream_queued_fds_t* queued_fds; - - if (!handle->ipc) - return 0; - - if (handle->accepted_fd == -1) - return 0; - - if (handle->queued_fds == NULL) - return 1; - - queued_fds = handle->queued_fds; - return queued_fds->offset + 1; -} - - -uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { - if (!handle->ipc) - return UV_UNKNOWN_HANDLE; - - if (handle->accepted_fd == -1) - return UV_UNKNOWN_HANDLE; - else - return uv__handle_type(handle->accepted_fd); -} diff --git a/outside/libuv-v1.7.5/src/unix/poll.c b/outside/libuv-v1.7.5/src/unix/poll.c deleted file mode 100644 index 37da3b9585..0000000000 --- a/outside/libuv-v1.7.5/src/unix/poll.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include - - -static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - uv_poll_t* handle; - int pevents; - - handle = container_of(w, uv_poll_t, io_watcher); - - if (events & UV__POLLERR) { - uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT); - uv__handle_stop(handle); - handle->poll_cb(handle, -EBADF, 0); - return; - } - - pevents = 0; - if (events & UV__POLLIN) - pevents |= UV_READABLE; - if (events & UV__POLLOUT) - pevents |= UV_WRITABLE; - - handle->poll_cb(handle, 0, pevents); -} - - -int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { - int err; - - err = uv__nonblock(fd, 1); - if (err) - return err; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); - uv__io_init(&handle->io_watcher, uv__poll_io, fd); - handle->poll_cb = NULL; - return 0; -} - - -int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, - uv_os_sock_t socket) { - return uv_poll_init(loop, handle, socket); -} - - -static void uv__poll_stop(uv_poll_t* handle) { - uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT); - uv__handle_stop(handle); -} - - -int uv_poll_stop(uv_poll_t* handle) { - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - uv__poll_stop(handle); - return 0; -} - - -int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { - int events; - - assert((pevents & ~(UV_READABLE | UV_WRITABLE)) == 0); - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - - uv__poll_stop(handle); - - if (pevents == 0) - return 0; - - events = 0; - if (pevents & UV_READABLE) - events |= UV__POLLIN; - if (pevents & UV_WRITABLE) - events |= UV__POLLOUT; - - uv__io_start(handle->loop, &handle->io_watcher, events); - uv__handle_start(handle); - handle->poll_cb = poll_cb; - - return 0; -} - - -void uv__poll_close(uv_poll_t* handle) { - uv__poll_stop(handle); -} diff --git a/outside/libuv-v1.7.5/src/unix/process.c b/outside/libuv-v1.7.5/src/unix/process.c deleted file mode 100644 index 9fa061e6bc..0000000000 --- a/outside/libuv-v1.7.5/src/unix/process.c +++ /dev/null @@ -1,552 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#if defined(__APPLE__) && !TARGET_OS_IPHONE -# include -# define environ (*_NSGetEnviron()) -#else -extern char **environ; -#endif - -#ifdef __linux__ -# include -#endif - - -static void uv__chld(uv_signal_t* handle, int signum) { - uv_process_t* process; - uv_loop_t* loop; - int exit_status; - int term_signal; - int status; - pid_t pid; - QUEUE pending; - QUEUE* q; - QUEUE* h; - - assert(signum == SIGCHLD); - - QUEUE_INIT(&pending); - loop = handle->loop; - - h = &loop->process_handles; - q = QUEUE_HEAD(h); - while (q != h) { - process = QUEUE_DATA(q, uv_process_t, queue); - q = QUEUE_NEXT(q); - - do - pid = waitpid(process->pid, &status, WNOHANG); - while (pid == -1 && errno == EINTR); - - if (pid == 0) - continue; - - if (pid == -1) { - if (errno != ECHILD) - abort(); - continue; - } - - process->status = status; - QUEUE_REMOVE(&process->queue); - QUEUE_INSERT_TAIL(&pending, &process->queue); - } - - h = &pending; - q = QUEUE_HEAD(h); - while (q != h) { - process = QUEUE_DATA(q, uv_process_t, queue); - q = QUEUE_NEXT(q); - - QUEUE_REMOVE(&process->queue); - QUEUE_INIT(&process->queue); - uv__handle_stop(process); - - if (process->exit_cb == NULL) - continue; - - exit_status = 0; - if (WIFEXITED(process->status)) - exit_status = WEXITSTATUS(process->status); - - term_signal = 0; - if (WIFSIGNALED(process->status)) - term_signal = WTERMSIG(process->status); - - process->exit_cb(process, exit_status, term_signal); - } - assert(QUEUE_EMPTY(&pending)); -} - - -int uv__make_socketpair(int fds[2], int flags) { -#if defined(__linux__) - static int no_cloexec; - - if (no_cloexec) - goto skip; - - if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0) - return 0; - - /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported. - * Anything else is a genuine error. - */ - if (errno != EINVAL) - return -errno; - - no_cloexec = 1; - -skip: -#endif - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) - return -errno; - - uv__cloexec(fds[0], 1); - uv__cloexec(fds[1], 1); - - if (flags & UV__F_NONBLOCK) { - uv__nonblock(fds[0], 1); - uv__nonblock(fds[1], 1); - } - - return 0; -} - - -int uv__make_pipe(int fds[2], int flags) { -#if defined(__linux__) - static int no_pipe2; - - if (no_pipe2) - goto skip; - - if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0) - return 0; - - if (errno != ENOSYS) - return -errno; - - no_pipe2 = 1; - -skip: -#endif - - if (pipe(fds)) - return -errno; - - uv__cloexec(fds[0], 1); - uv__cloexec(fds[1], 1); - - if (flags & UV__F_NONBLOCK) { - uv__nonblock(fds[0], 1); - uv__nonblock(fds[1], 1); - } - - return 0; -} - - -/* - * Used for initializing stdio streams like options.stdin_stream. Returns - * zero on success. See also the cleanup section in uv_spawn(). - */ -static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { - int mask; - int fd; - - mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM; - - switch (container->flags & mask) { - case UV_IGNORE: - return 0; - - case UV_CREATE_PIPE: - assert(container->data.stream != NULL); - if (container->data.stream->type != UV_NAMED_PIPE) - return -EINVAL; - else - return uv__make_socketpair(fds, 0); - - case UV_INHERIT_FD: - case UV_INHERIT_STREAM: - if (container->flags & UV_INHERIT_FD) - fd = container->data.fd; - else - fd = uv__stream_fd(container->data.stream); - - if (fd == -1) - return -EINVAL; - - fds[1] = fd; - return 0; - - default: - assert(0 && "Unexpected flags"); - return -EINVAL; - } -} - - -static int uv__process_open_stream(uv_stdio_container_t* container, - int pipefds[2], - int writable) { - int flags; - int err; - - if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0) - return 0; - - err = uv__close(pipefds[1]); - if (err != 0 && err != -EINPROGRESS) - abort(); - - pipefds[1] = -1; - uv__nonblock(pipefds[0], 1); - - if (container->data.stream->type == UV_NAMED_PIPE && - ((uv_pipe_t*)container->data.stream)->ipc) - flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE; - else if (writable) - flags = UV_STREAM_WRITABLE; - else - flags = UV_STREAM_READABLE; - - return uv__stream_open(container->data.stream, pipefds[0], flags); -} - - -static void uv__process_close_stream(uv_stdio_container_t* container) { - if (!(container->flags & UV_CREATE_PIPE)) return; - uv__stream_close((uv_stream_t*)container->data.stream); -} - - -static void uv__write_int(int fd, int val) { - ssize_t n; - - do - n = write(fd, &val, sizeof(val)); - while (n == -1 && errno == EINTR); - - if (n == -1 && errno == EPIPE) - return; /* parent process has quit */ - - assert(n == sizeof(val)); -} - - -static void uv__process_child_init(const uv_process_options_t* options, - int stdio_count, - int (*pipes)[2], - int error_fd) { - int close_fd; - int use_fd; - int fd; - - if (options->flags & UV_PROCESS_DETACHED) - setsid(); - - /* First duplicate low numbered fds, since it's not safe to duplicate them, - * they could get replaced. Example: swapping stdout and stderr; without - * this fd 2 (stderr) would be duplicated into fd 1, thus making both - * stdout and stderr go to the same fd, which was not the intention. */ - for (fd = 0; fd < stdio_count; fd++) { - use_fd = pipes[fd][1]; - if (use_fd < 0 || use_fd >= fd) - continue; - pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count); - if (pipes[fd][1] == -1) { - uv__write_int(error_fd, -errno); - _exit(127); - } - } - - for (fd = 0; fd < stdio_count; fd++) { - close_fd = pipes[fd][0]; - use_fd = pipes[fd][1]; - - if (use_fd < 0) { - if (fd >= 3) - continue; - else { - /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is - * set - */ - use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR); - close_fd = use_fd; - - if (use_fd == -1) { - uv__write_int(error_fd, -errno); - _exit(127); - } - } - } - - if (fd == use_fd) - uv__cloexec(use_fd, 0); - else - fd = dup2(use_fd, fd); - - if (fd == -1) { - uv__write_int(error_fd, -errno); - _exit(127); - } - - if (fd <= 2) - uv__nonblock(fd, 0); - - if (close_fd >= stdio_count) - uv__close(close_fd); - } - - for (fd = 0; fd < stdio_count; fd++) { - use_fd = pipes[fd][1]; - - if (use_fd >= stdio_count) - uv__close(use_fd); - } - - if (options->cwd != NULL && chdir(options->cwd)) { - uv__write_int(error_fd, -errno); - _exit(127); - } - - if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) { - /* When dropping privileges from root, the `setgroups` call will - * remove any extraneous groups. If we don't call this, then - * even though our uid has dropped, we may still have groups - * that enable us to do super-user things. This will fail if we - * aren't root, so don't bother checking the return value, this - * is just done as an optimistic privilege dropping function. - */ - SAVE_ERRNO(setgroups(0, NULL)); - } - - if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) { - uv__write_int(error_fd, -errno); - _exit(127); - } - - if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) { - uv__write_int(error_fd, -errno); - _exit(127); - } - - if (options->env != NULL) { - environ = options->env; - } - - execvp(options->file, options->args); - uv__write_int(error_fd, -errno); - _exit(127); -} - - -int uv_spawn(uv_loop_t* loop, - uv_process_t* process, - const uv_process_options_t* options) { - int signal_pipe[2] = { -1, -1 }; - int (*pipes)[2]; - int stdio_count; - ssize_t r; - pid_t pid; - int err; - int exec_errorno; - int i; - int status; - - assert(options->file != NULL); - assert(!(options->flags & ~(UV_PROCESS_DETACHED | - UV_PROCESS_SETGID | - UV_PROCESS_SETUID | - UV_PROCESS_WINDOWS_HIDE | - UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); - - uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS); - QUEUE_INIT(&process->queue); - - stdio_count = options->stdio_count; - if (stdio_count < 3) - stdio_count = 3; - - err = -ENOMEM; - pipes = uv__malloc(stdio_count * sizeof(*pipes)); - if (pipes == NULL) - goto error; - - for (i = 0; i < stdio_count; i++) { - pipes[i][0] = -1; - pipes[i][1] = -1; - } - - for (i = 0; i < options->stdio_count; i++) { - err = uv__process_init_stdio(options->stdio + i, pipes[i]); - if (err) - goto error; - } - - /* This pipe is used by the parent to wait until - * the child has called `execve()`. We need this - * to avoid the following race condition: - * - * if ((pid = fork()) > 0) { - * kill(pid, SIGTERM); - * } - * else if (pid == 0) { - * execve("/bin/cat", argp, envp); - * } - * - * The parent sends a signal immediately after forking. - * Since the child may not have called `execve()` yet, - * there is no telling what process receives the signal, - * our fork or /bin/cat. - * - * To avoid ambiguity, we create a pipe with both ends - * marked close-on-exec. Then, after the call to `fork()`, - * the parent polls the read end until it EOFs or errors with EPIPE. - */ - err = uv__make_pipe(signal_pipe, 0); - if (err) - goto error; - - uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD); - - /* Acquire write lock to prevent opening new fds in worker threads */ - uv_rwlock_wrlock(&loop->cloexec_lock); - pid = fork(); - - if (pid == -1) { - err = -errno; - uv_rwlock_wrunlock(&loop->cloexec_lock); - uv__close(signal_pipe[0]); - uv__close(signal_pipe[1]); - goto error; - } - - if (pid == 0) { - uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]); - abort(); - } - - /* Release lock in parent process */ - uv_rwlock_wrunlock(&loop->cloexec_lock); - uv__close(signal_pipe[1]); - - process->status = 0; - exec_errorno = 0; - do - r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno)); - while (r == -1 && errno == EINTR); - - if (r == 0) - ; /* okay, EOF */ - else if (r == sizeof(exec_errorno)) { - do - err = waitpid(pid, &status, 0); /* okay, read errorno */ - while (err == -1 && errno == EINTR); - assert(err == pid); - } else if (r == -1 && errno == EPIPE) { - do - err = waitpid(pid, &status, 0); /* okay, got EPIPE */ - while (err == -1 && errno == EINTR); - assert(err == pid); - } else - abort(); - - uv__close(signal_pipe[0]); - - for (i = 0; i < options->stdio_count; i++) { - err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0); - if (err == 0) - continue; - - while (i--) - uv__process_close_stream(options->stdio + i); - - goto error; - } - - /* Only activate this handle if exec() happened successfully */ - if (exec_errorno == 0) { - QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue); - uv__handle_start(process); - } - - process->pid = pid; - process->exit_cb = options->exit_cb; - - uv__free(pipes); - return exec_errorno; - -error: - if (pipes != NULL) { - for (i = 0; i < stdio_count; i++) { - if (i < options->stdio_count) - if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM)) - continue; - if (pipes[i][0] != -1) - close(pipes[i][0]); - if (pipes[i][1] != -1) - close(pipes[i][1]); - } - uv__free(pipes); - } - - return err; -} - - -int uv_process_kill(uv_process_t* process, int signum) { - return uv_kill(process->pid, signum); -} - - -int uv_kill(int pid, int signum) { - if (kill(pid, signum)) - return -errno; - else - return 0; -} - - -void uv__process_close(uv_process_t* handle) { - QUEUE_REMOVE(&handle->queue); - uv__handle_stop(handle); - if (QUEUE_EMPTY(&handle->loop->process_handles)) - uv_signal_stop(&handle->loop->child_watcher); -} diff --git a/outside/libuv-v1.7.5/src/unix/proctitle.c b/outside/libuv-v1.7.5/src/unix/proctitle.c deleted file mode 100644 index 19214e5ec9..0000000000 --- a/outside/libuv-v1.7.5/src/unix/proctitle.c +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include - -extern void uv__set_process_title(const char* title); - -static void* args_mem; - -static struct { - char* str; - size_t len; -} process_title; - - -char** uv_setup_args(int argc, char** argv) { - char** new_argv; - size_t size; - char* s; - int i; - - if (argc <= 0) - return argv; - - /* Calculate how much memory we need for the argv strings. */ - size = 0; - for (i = 0; i < argc; i++) - size += strlen(argv[i]) + 1; - - process_title.str = argv[0]; - process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0]; - assert(process_title.len + 1 == size); /* argv memory should be adjacent. */ - - /* Add space for the argv pointers. */ - size += (argc + 1) * sizeof(char*); - - new_argv = uv__malloc(size); - if (new_argv == NULL) - return argv; - args_mem = new_argv; - - /* Copy over the strings and set up the pointer table. */ - s = (char*) &new_argv[argc + 1]; - for (i = 0; i < argc; i++) { - size = strlen(argv[i]) + 1; - memcpy(s, argv[i], size); - new_argv[i] = s; - s += size; - } - new_argv[i] = NULL; - - return new_argv; -} - - -int uv_set_process_title(const char* title) { - if (process_title.len == 0) - return 0; - - /* No need to terminate, byte after is always '\0'. */ - strncpy(process_title.str, title, process_title.len); - uv__set_process_title(title); - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title.len > 0) - strncpy(buffer, process_title.str, size); - else if (size > 0) - buffer[0] = '\0'; - - return 0; -} - - -UV_DESTRUCTOR(static void free_args_mem(void)) { - uv__free(args_mem); /* Keep valgrind happy. */ - args_mem = NULL; -} diff --git a/outside/libuv-v1.7.5/src/unix/pthread-fixes.c b/outside/libuv-v1.7.5/src/unix/pthread-fixes.c deleted file mode 100644 index 3a71eb5aae..0000000000 --- a/outside/libuv-v1.7.5/src/unix/pthread-fixes.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (c) 2013, Sony Mobile Communications AB - * Copyright (c) 2012, Google Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Android versions < 4.1 have a broken pthread_sigmask. - * Note that this block of code must come before any inclusion of - * pthread-fixes.h so that the real pthread_sigmask can be referenced. - * */ -#include -#include -#include - -int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) { - static int workaround; - - if (workaround) { - return sigprocmask(how, set, oset); - } else if (pthread_sigmask(how, set, oset)) { - if (errno == EINVAL && sigprocmask(how, set, oset) == 0) { - workaround = 1; - return 0; - } else { - return -1; - } - } else { - return 0; - } -} - -/*Android doesn't provide pthread_barrier_t for now.*/ -#ifndef PTHREAD_BARRIER_SERIAL_THREAD - -#include "pthread-fixes.h" - -int pthread_barrier_init(pthread_barrier_t* barrier, - const void* barrier_attr, - unsigned count) { - barrier->count = count; - pthread_mutex_init(&barrier->mutex, NULL); - pthread_cond_init(&barrier->cond, NULL); - return 0; -} - -int pthread_barrier_wait(pthread_barrier_t* barrier) { - /* Lock the mutex*/ - pthread_mutex_lock(&barrier->mutex); - /* Decrement the count. If this is the first thread to reach 0, wake up - waiters, unlock the mutex, then return PTHREAD_BARRIER_SERIAL_THREAD.*/ - if (--barrier->count == 0) { - /* First thread to reach the barrier */ - pthread_cond_broadcast(&barrier->cond); - pthread_mutex_unlock(&barrier->mutex); - return PTHREAD_BARRIER_SERIAL_THREAD; - } - /* Otherwise, wait for other threads until the count reaches 0, then - return 0 to indicate this is not the first thread.*/ - do { - pthread_cond_wait(&barrier->cond, &barrier->mutex); - } while (barrier->count > 0); - - pthread_mutex_unlock(&barrier->mutex); - return 0; -} - -int pthread_barrier_destroy(pthread_barrier_t *barrier) { - barrier->count = 0; - pthread_cond_destroy(&barrier->cond); - pthread_mutex_destroy(&barrier->mutex); - return 0; -} - -#endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */ - -int pthread_yield(void) { - sched_yield(); - return 0; -} diff --git a/outside/libuv-v1.7.5/src/unix/signal.c b/outside/libuv-v1.7.5/src/unix/signal.c deleted file mode 100644 index 0b7a405c15..0000000000 --- a/outside/libuv-v1.7.5/src/unix/signal.c +++ /dev/null @@ -1,465 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include - - -typedef struct { - uv_signal_t* handle; - int signum; -} uv__signal_msg_t; - -RB_HEAD(uv__signal_tree_s, uv_signal_s); - - -static int uv__signal_unlock(void); -static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events); -static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); -static void uv__signal_stop(uv_signal_t* handle); - - -static pthread_once_t uv__signal_global_init_guard = PTHREAD_ONCE_INIT; -static struct uv__signal_tree_s uv__signal_tree = - RB_INITIALIZER(uv__signal_tree); -static int uv__signal_lock_pipefd[2]; - - -RB_GENERATE_STATIC(uv__signal_tree_s, - uv_signal_s, tree_entry, - uv__signal_compare) - - -static void uv__signal_global_init(void) { - if (uv__make_pipe(uv__signal_lock_pipefd, 0)) - abort(); - - if (uv__signal_unlock()) - abort(); -} - - -void uv__signal_global_once_init(void) { - pthread_once(&uv__signal_global_init_guard, uv__signal_global_init); -} - - - -static int uv__signal_lock(void) { - int r; - char data; - - do { - r = read(uv__signal_lock_pipefd[0], &data, sizeof data); - } while (r < 0 && errno == EINTR); - - return (r < 0) ? -1 : 0; -} - - -static int uv__signal_unlock(void) { - int r; - char data = 42; - - do { - r = write(uv__signal_lock_pipefd[1], &data, sizeof data); - } while (r < 0 && errno == EINTR); - - return (r < 0) ? -1 : 0; -} - - -static void uv__signal_block_and_lock(sigset_t* saved_sigmask) { - sigset_t new_mask; - - if (sigfillset(&new_mask)) - abort(); - - if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask)) - abort(); - - if (uv__signal_lock()) - abort(); -} - - -static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) { - if (uv__signal_unlock()) - abort(); - - if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL)) - abort(); -} - - -static uv_signal_t* uv__signal_first_handle(int signum) { - /* This function must be called with the signal lock held. */ - uv_signal_t lookup; - uv_signal_t* handle; - - lookup.signum = signum; - lookup.loop = NULL; - - handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); - - if (handle != NULL && handle->signum == signum) - return handle; - - return NULL; -} - - -static void uv__signal_handler(int signum) { - uv__signal_msg_t msg; - uv_signal_t* handle; - int saved_errno; - - saved_errno = errno; - memset(&msg, 0, sizeof msg); - - if (uv__signal_lock()) { - errno = saved_errno; - return; - } - - for (handle = uv__signal_first_handle(signum); - handle != NULL && handle->signum == signum; - handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) { - int r; - - msg.signum = signum; - msg.handle = handle; - - /* write() should be atomic for small data chunks, so the entire message - * should be written at once. In theory the pipe could become full, in - * which case the user is out of luck. - */ - do { - r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg); - } while (r == -1 && errno == EINTR); - - assert(r == sizeof msg || - (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))); - - if (r != -1) - handle->caught_signals++; - } - - uv__signal_unlock(); - errno = saved_errno; -} - - -static int uv__signal_register_handler(int signum) { - /* When this function is called, the signal lock must be held. */ - struct sigaction sa; - - /* XXX use a separate signal stack? */ - memset(&sa, 0, sizeof(sa)); - if (sigfillset(&sa.sa_mask)) - abort(); - sa.sa_handler = uv__signal_handler; - - /* XXX save old action so we can restore it later on? */ - if (sigaction(signum, &sa, NULL)) - return -errno; - - return 0; -} - - -static void uv__signal_unregister_handler(int signum) { - /* When this function is called, the signal lock must be held. */ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - - /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a - * signal implies that it was successfully registered earlier, so EINVAL - * should never happen. - */ - if (sigaction(signum, &sa, NULL)) - abort(); -} - - -static int uv__signal_loop_once_init(uv_loop_t* loop) { - int err; - - /* Return if already initialized. */ - if (loop->signal_pipefd[0] != -1) - return 0; - - err = uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK); - if (err) - return err; - - uv__io_init(&loop->signal_io_watcher, - uv__signal_event, - loop->signal_pipefd[0]); - uv__io_start(loop, &loop->signal_io_watcher, UV__POLLIN); - - return 0; -} - - -void uv__signal_loop_cleanup(uv_loop_t* loop) { - QUEUE* q; - - /* Stop all the signal watchers that are still attached to this loop. This - * ensures that the (shared) signal tree doesn't contain any invalid entries - * entries, and that signal handlers are removed when appropriate. - */ - QUEUE_FOREACH(q, &loop->handle_queue) { - uv_handle_t* handle = QUEUE_DATA(q, uv_handle_t, handle_queue); - - if (handle->type == UV_SIGNAL) - uv__signal_stop((uv_signal_t*) handle); - } - - if (loop->signal_pipefd[0] != -1) { - uv__close(loop->signal_pipefd[0]); - loop->signal_pipefd[0] = -1; - } - - if (loop->signal_pipefd[1] != -1) { - uv__close(loop->signal_pipefd[1]); - loop->signal_pipefd[1] = -1; - } -} - - -int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - int err; - - err = uv__signal_loop_once_init(loop); - if (err) - return err; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); - handle->signum = 0; - handle->caught_signals = 0; - handle->dispatched_signals = 0; - - return 0; -} - - -void uv__signal_close(uv_signal_t* handle) { - - uv__signal_stop(handle); - - /* If there are any caught signals "trapped" in the signal pipe, we can't - * call the close callback yet. Otherwise, add the handle to the finish_close - * queue. - */ - if (handle->caught_signals == handle->dispatched_signals) { - uv__make_close_pending((uv_handle_t*) handle); - } -} - - -int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { - sigset_t saved_sigmask; - int err; - - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - - /* If the user supplies signum == 0, then return an error already. If the - * signum is otherwise invalid then uv__signal_register will find out - * eventually. - */ - if (signum == 0) - return -EINVAL; - - /* Short circuit: if the signal watcher is already watching {signum} don't - * go through the process of deregistering and registering the handler. - * Additionally, this avoids pending signals getting lost in the small time - * time frame that handle->signum == 0. - */ - if (signum == handle->signum) { - handle->signal_cb = signal_cb; - return 0; - } - - /* If the signal handler was already active, stop it first. */ - if (handle->signum != 0) { - uv__signal_stop(handle); - } - - uv__signal_block_and_lock(&saved_sigmask); - - /* If at this point there are no active signal watchers for this signum (in - * any of the loops), it's time to try and register a handler for it here. - */ - if (uv__signal_first_handle(signum) == NULL) { - err = uv__signal_register_handler(signum); - if (err) { - /* Registering the signal handler failed. Must be an invalid signal. */ - uv__signal_unlock_and_unblock(&saved_sigmask); - return err; - } - } - - handle->signum = signum; - RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); - - uv__signal_unlock_and_unblock(&saved_sigmask); - - handle->signal_cb = signal_cb; - uv__handle_start(handle); - - return 0; -} - - -static void uv__signal_event(uv_loop_t* loop, - uv__io_t* w, - unsigned int events) { - uv__signal_msg_t* msg; - uv_signal_t* handle; - char buf[sizeof(uv__signal_msg_t) * 32]; - size_t bytes, end, i; - int r; - - bytes = 0; - end = 0; - - do { - r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes); - - if (r == -1 && errno == EINTR) - continue; - - if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { - /* If there are bytes in the buffer already (which really is extremely - * unlikely if possible at all) we can't exit the function here. We'll - * spin until more bytes are read instead. - */ - if (bytes > 0) - continue; - - /* Otherwise, there was nothing there. */ - return; - } - - /* Other errors really should never happen. */ - if (r == -1) - abort(); - - bytes += r; - - /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */ - end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t); - - for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) { - msg = (uv__signal_msg_t*) (buf + i); - handle = msg->handle; - - if (msg->signum == handle->signum) { - assert(!(handle->flags & UV_CLOSING)); - handle->signal_cb(handle, handle->signum); - } - - handle->dispatched_signals++; - - /* If uv_close was called while there were caught signals that were not - * yet dispatched, the uv__finish_close was deferred. Make close pending - * now if this has happened. - */ - if ((handle->flags & UV_CLOSING) && - (handle->caught_signals == handle->dispatched_signals)) { - uv__make_close_pending((uv_handle_t*) handle); - } - } - - bytes -= end; - - /* If there are any "partial" messages left, move them to the start of the - * the buffer, and spin. This should not happen. - */ - if (bytes) { - memmove(buf, buf + end, bytes); - continue; - } - } while (end == sizeof buf); -} - - -static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { - /* Compare signums first so all watchers with the same signnum end up - * adjacent. - */ - if (w1->signum < w2->signum) return -1; - if (w1->signum > w2->signum) return 1; - - /* Sort by loop pointer, so we can easily look up the first item after - * { .signum = x, .loop = NULL }. - */ - if (w1->loop < w2->loop) return -1; - if (w1->loop > w2->loop) return 1; - - if (w1 < w2) return -1; - if (w1 > w2) return 1; - - return 0; -} - - -int uv_signal_stop(uv_signal_t* handle) { - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - uv__signal_stop(handle); - return 0; -} - - -static void uv__signal_stop(uv_signal_t* handle) { - uv_signal_t* removed_handle; - sigset_t saved_sigmask; - - /* If the watcher wasn't started, this is a no-op. */ - if (handle->signum == 0) - return; - - uv__signal_block_and_lock(&saved_sigmask); - - removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle); - assert(removed_handle == handle); - (void) removed_handle; - - /* Check if there are other active signal watchers observing this signal. If - * not, unregister the signal handler. - */ - if (uv__signal_first_handle(handle->signum) == NULL) - uv__signal_unregister_handler(handle->signum); - - uv__signal_unlock_and_unblock(&saved_sigmask); - - handle->signum = 0; - uv__handle_stop(handle); -} diff --git a/outside/libuv-v1.7.5/src/unix/spinlock.h b/outside/libuv-v1.7.5/src/unix/spinlock.h deleted file mode 100644 index a20c83cc60..0000000000 --- a/outside/libuv-v1.7.5/src/unix/spinlock.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013, Ben Noordhuis - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef UV_SPINLOCK_H_ -#define UV_SPINLOCK_H_ - -#include "internal.h" /* ACCESS_ONCE, UV_UNUSED */ -#include "atomic-ops.h" - -#define UV_SPINLOCK_INITIALIZER { 0 } - -typedef struct { - int lock; -} uv_spinlock_t; - -UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)); -UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)); -UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)); -UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)); - -UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)) { - ACCESS_ONCE(int, spinlock->lock) = 0; -} - -UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)) { - while (!uv_spinlock_trylock(spinlock)) cpu_relax(); -} - -UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)) { - ACCESS_ONCE(int, spinlock->lock) = 0; -} - -UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)) { - /* TODO(bnoordhuis) Maybe change to a ticket lock to guarantee fair queueing. - * Not really critical until we have locks that are (frequently) contended - * for by several threads. - */ - return 0 == cmpxchgi(&spinlock->lock, 0, 1); -} - -#endif /* UV_SPINLOCK_H_ */ diff --git a/outside/libuv-v1.7.5/src/unix/stream.c b/outside/libuv-v1.7.5/src/unix/stream.c deleted file mode 100644 index 183b68cf71..0000000000 --- a/outside/libuv-v1.7.5/src/unix/stream.c +++ /dev/null @@ -1,1615 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include /* IOV_MAX */ - -#if defined(__APPLE__) -# include -# include -# include - -/* Forward declaration */ -typedef struct uv__stream_select_s uv__stream_select_t; - -struct uv__stream_select_s { - uv_stream_t* stream; - uv_thread_t thread; - uv_sem_t close_sem; - uv_sem_t async_sem; - uv_async_t async; - int events; - int fake_fd; - int int_fd; - int fd; - fd_set* sread; - size_t sread_sz; - fd_set* swrite; - size_t swrite_sz; -}; -#endif /* defined(__APPLE__) */ - -static void uv__stream_connect(uv_stream_t*); -static void uv__write(uv_stream_t* stream); -static void uv__read(uv_stream_t* stream); -static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); -static void uv__write_callbacks(uv_stream_t* stream); -static size_t uv__write_req_size(uv_write_t* req); - - -void uv__stream_init(uv_loop_t* loop, - uv_stream_t* stream, - uv_handle_type type) { - int err; - - uv__handle_init(loop, (uv_handle_t*)stream, type); - stream->read_cb = NULL; - stream->alloc_cb = NULL; - stream->close_cb = NULL; - stream->connection_cb = NULL; - stream->connect_req = NULL; - stream->shutdown_req = NULL; - stream->accepted_fd = -1; - stream->queued_fds = NULL; - stream->delayed_error = 0; - QUEUE_INIT(&stream->write_queue); - QUEUE_INIT(&stream->write_completed_queue); - stream->write_queue_size = 0; - - if (loop->emfile_fd == -1) { - err = uv__open_cloexec("/dev/null", O_RDONLY); - if (err < 0) - /* In the rare case that "/dev/null" isn't mounted open "/" - * instead. - */ - err = uv__open_cloexec("/", O_RDONLY); - if (err >= 0) - loop->emfile_fd = err; - } - -#if defined(__APPLE__) - stream->select = NULL; -#endif /* defined(__APPLE_) */ - - uv__io_init(&stream->io_watcher, uv__stream_io, -1); -} - - -static void uv__stream_osx_interrupt_select(uv_stream_t* stream) { -#if defined(__APPLE__) - /* Notify select() thread about state change */ - uv__stream_select_t* s; - int r; - - s = stream->select; - if (s == NULL) - return; - - /* Interrupt select() loop - * NOTE: fake_fd and int_fd are socketpair(), thus writing to one will - * emit read event on other side - */ - do - r = write(s->fake_fd, "x", 1); - while (r == -1 && errno == EINTR); - - assert(r == 1); -#else /* !defined(__APPLE__) */ - /* No-op on any other platform */ -#endif /* !defined(__APPLE__) */ -} - - -#if defined(__APPLE__) -static void uv__stream_osx_select(void* arg) { - uv_stream_t* stream; - uv__stream_select_t* s; - char buf[1024]; - int events; - int fd; - int r; - int max_fd; - - stream = arg; - s = stream->select; - fd = s->fd; - - if (fd > s->int_fd) - max_fd = fd; - else - max_fd = s->int_fd; - - while (1) { - /* Terminate on semaphore */ - if (uv_sem_trywait(&s->close_sem) == 0) - break; - - /* Watch fd using select(2) */ - memset(s->sread, 0, s->sread_sz); - memset(s->swrite, 0, s->swrite_sz); - - if (uv__io_active(&stream->io_watcher, UV__POLLIN)) - FD_SET(fd, s->sread); - if (uv__io_active(&stream->io_watcher, UV__POLLOUT)) - FD_SET(fd, s->swrite); - FD_SET(s->int_fd, s->sread); - - /* Wait indefinitely for fd events */ - r = select(max_fd + 1, s->sread, s->swrite, NULL, NULL); - if (r == -1) { - if (errno == EINTR) - continue; - - /* XXX: Possible?! */ - abort(); - } - - /* Ignore timeouts */ - if (r == 0) - continue; - - /* Empty socketpair's buffer in case of interruption */ - if (FD_ISSET(s->int_fd, s->sread)) - while (1) { - r = read(s->int_fd, buf, sizeof(buf)); - - if (r == sizeof(buf)) - continue; - - if (r != -1) - break; - - if (errno == EAGAIN || errno == EWOULDBLOCK) - break; - - if (errno == EINTR) - continue; - - abort(); - } - - /* Handle events */ - events = 0; - if (FD_ISSET(fd, s->sread)) - events |= UV__POLLIN; - if (FD_ISSET(fd, s->swrite)) - events |= UV__POLLOUT; - - assert(events != 0 || FD_ISSET(s->int_fd, s->sread)); - if (events != 0) { - ACCESS_ONCE(int, s->events) = events; - - uv_async_send(&s->async); - uv_sem_wait(&s->async_sem); - - /* Should be processed at this stage */ - assert((s->events == 0) || (stream->flags & UV_CLOSING)); - } - } -} - - -static void uv__stream_osx_select_cb(uv_async_t* handle) { - uv__stream_select_t* s; - uv_stream_t* stream; - int events; - - s = container_of(handle, uv__stream_select_t, async); - stream = s->stream; - - /* Get and reset stream's events */ - events = s->events; - ACCESS_ONCE(int, s->events) = 0; - - assert(events != 0); - assert(events == (events & (UV__POLLIN | UV__POLLOUT))); - - /* Invoke callback on event-loop */ - if ((events & UV__POLLIN) && uv__io_active(&stream->io_watcher, UV__POLLIN)) - uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLIN); - - if ((events & UV__POLLOUT) && uv__io_active(&stream->io_watcher, UV__POLLOUT)) - uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLOUT); - - if (stream->flags & UV_CLOSING) - return; - - /* NOTE: It is important to do it here, otherwise `select()` might be called - * before the actual `uv__read()`, leading to the blocking syscall - */ - uv_sem_post(&s->async_sem); -} - - -static void uv__stream_osx_cb_close(uv_handle_t* async) { - uv__stream_select_t* s; - - s = container_of(async, uv__stream_select_t, async); - uv__free(s); -} - - -int uv__stream_try_select(uv_stream_t* stream, int* fd) { - /* - * kqueue doesn't work with some files from /dev mount on osx. - * select(2) in separate thread for those fds - */ - - struct kevent filter[1]; - struct kevent events[1]; - struct timespec timeout; - uv__stream_select_t* s; - int fds[2]; - int err; - int ret; - int kq; - int old_fd; - int max_fd; - size_t sread_sz; - size_t swrite_sz; - - kq = kqueue(); - if (kq == -1) { - perror("(libuv) kqueue()"); - return -errno; - } - - EV_SET(&filter[0], *fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0); - - /* Use small timeout, because we only want to capture EINVALs */ - timeout.tv_sec = 0; - timeout.tv_nsec = 1; - - ret = kevent(kq, filter, 1, events, 1, &timeout); - uv__close(kq); - - if (ret == -1) - return -errno; - - if (ret == 0 || (events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL) - return 0; - - /* At this point we definitely know that this fd won't work with kqueue */ - - /* - * Create fds for io watcher and to interrupt the select() loop. - * NOTE: do it ahead of malloc below to allocate enough space for fd_sets - */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) - return -errno; - - max_fd = *fd; - if (fds[1] > max_fd) - max_fd = fds[1]; - - sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY; - swrite_sz = sread_sz; - - s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz); - if (s == NULL) { - err = -ENOMEM; - goto failed_malloc; - } - - s->events = 0; - s->fd = *fd; - s->sread = (fd_set*) ((char*) s + sizeof(*s)); - s->sread_sz = sread_sz; - s->swrite = (fd_set*) ((char*) s->sread + sread_sz); - s->swrite_sz = swrite_sz; - - err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb); - if (err) - goto failed_async_init; - - s->async.flags |= UV__HANDLE_INTERNAL; - uv__handle_unref(&s->async); - - err = uv_sem_init(&s->close_sem, 0); - if (err != 0) - goto failed_close_sem_init; - - err = uv_sem_init(&s->async_sem, 0); - if (err != 0) - goto failed_async_sem_init; - - s->fake_fd = fds[0]; - s->int_fd = fds[1]; - - old_fd = *fd; - s->stream = stream; - stream->select = s; - *fd = s->fake_fd; - - err = uv_thread_create(&s->thread, uv__stream_osx_select, stream); - if (err != 0) - goto failed_thread_create; - - return 0; - -failed_thread_create: - s->stream = NULL; - stream->select = NULL; - *fd = old_fd; - - uv_sem_destroy(&s->async_sem); - -failed_async_sem_init: - uv_sem_destroy(&s->close_sem); - -failed_close_sem_init: - uv__close(fds[0]); - uv__close(fds[1]); - uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); - return err; - -failed_async_init: - uv__free(s); - -failed_malloc: - uv__close(fds[0]); - uv__close(fds[1]); - - return err; -} -#endif /* defined(__APPLE__) */ - - -int uv__stream_open(uv_stream_t* stream, int fd, int flags) { -#if defined(__APPLE__) - int enable; -#endif - - if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd)) - return -EBUSY; - - assert(fd >= 0); - stream->flags |= flags; - - if (stream->type == UV_TCP) { - if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1)) - return -errno; - - /* TODO Use delay the user passed in. */ - if ((stream->flags & UV_TCP_KEEPALIVE) && uv__tcp_keepalive(fd, 1, 60)) - return -errno; - } - -#if defined(__APPLE__) - enable = 1; - if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) && - errno != ENOTSOCK && - errno != EINVAL) { - return -errno; - } -#endif - - stream->io_watcher.fd = fd; - - return 0; -} - - -void uv__stream_flush_write_queue(uv_stream_t* stream, int error) { - uv_write_t* req; - QUEUE* q; - while (!QUEUE_EMPTY(&stream->write_queue)) { - q = QUEUE_HEAD(&stream->write_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_write_t, queue); - req->error = error; - - QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue); - } -} - - -void uv__stream_destroy(uv_stream_t* stream) { - assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT)); - assert(stream->flags & UV_CLOSED); - - if (stream->connect_req) { - uv__req_unregister(stream->loop, stream->connect_req); - stream->connect_req->cb(stream->connect_req, -ECANCELED); - stream->connect_req = NULL; - } - - uv__stream_flush_write_queue(stream, -ECANCELED); - uv__write_callbacks(stream); - - if (stream->shutdown_req) { - /* The ECANCELED error code is a lie, the shutdown(2) syscall is a - * fait accompli at this point. Maybe we should revisit this in v0.11. - * A possible reason for leaving it unchanged is that it informs the - * callee that the handle has been destroyed. - */ - uv__req_unregister(stream->loop, stream->shutdown_req); - stream->shutdown_req->cb(stream->shutdown_req, -ECANCELED); - stream->shutdown_req = NULL; - } - - assert(stream->write_queue_size == 0); -} - - -/* Implements a best effort approach to mitigating accept() EMFILE errors. - * We have a spare file descriptor stashed away that we close to get below - * the EMFILE limit. Next, we accept all pending connections and close them - * immediately to signal the clients that we're overloaded - and we are, but - * we still keep on trucking. - * - * There is one caveat: it's not reliable in a multi-threaded environment. - * The file descriptor limit is per process. Our party trick fails if another - * thread opens a file or creates a socket in the time window between us - * calling close() and accept(). - */ -static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) { - int err; - int emfile_fd; - - if (loop->emfile_fd == -1) - return -EMFILE; - - uv__close(loop->emfile_fd); - loop->emfile_fd = -1; - - do { - err = uv__accept(accept_fd); - if (err >= 0) - uv__close(err); - } while (err >= 0 || err == -EINTR); - - emfile_fd = uv__open_cloexec("/", O_RDONLY); - if (emfile_fd >= 0) - loop->emfile_fd = emfile_fd; - - return err; -} - - -#if defined(UV_HAVE_KQUEUE) -# define UV_DEC_BACKLOG(w) w->rcount--; -#else -# define UV_DEC_BACKLOG(w) /* no-op */ -#endif /* defined(UV_HAVE_KQUEUE) */ - - -void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - uv_stream_t* stream; - int err; - - stream = container_of(w, uv_stream_t, io_watcher); - assert(events == UV__POLLIN); - assert(stream->accepted_fd == -1); - assert(!(stream->flags & UV_CLOSING)); - - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); - - /* connection_cb can close the server socket while we're - * in the loop so check it on each iteration. - */ - while (uv__stream_fd(stream) != -1) { - assert(stream->accepted_fd == -1); - -#if defined(UV_HAVE_KQUEUE) - if (w->rcount <= 0) - return; -#endif /* defined(UV_HAVE_KQUEUE) */ - - err = uv__accept(uv__stream_fd(stream)); - if (err < 0) { - if (err == -EAGAIN || err == -EWOULDBLOCK) - return; /* Not an error. */ - - if (err == -ECONNABORTED) - continue; /* Ignore. Nothing we can do about that. */ - - if (err == -EMFILE || err == -ENFILE) { - err = uv__emfile_trick(loop, uv__stream_fd(stream)); - if (err == -EAGAIN || err == -EWOULDBLOCK) - break; - } - - stream->connection_cb(stream, err); - continue; - } - - UV_DEC_BACKLOG(w) - stream->accepted_fd = err; - stream->connection_cb(stream, 0); - - if (stream->accepted_fd != -1) { - /* The user hasn't yet accepted called uv_accept() */ - uv__io_stop(loop, &stream->io_watcher, UV__POLLIN); - return; - } - - if (stream->type == UV_TCP && (stream->flags & UV_TCP_SINGLE_ACCEPT)) { - /* Give other processes a chance to accept connections. */ - struct timespec timeout = { 0, 1 }; - nanosleep(&timeout, NULL); - } - } -} - - -#undef UV_DEC_BACKLOG - - -int uv_accept(uv_stream_t* server, uv_stream_t* client) { - int err; - - /* TODO document this */ - assert(server->loop == client->loop); - - if (server->accepted_fd == -1) - return -EAGAIN; - - switch (client->type) { - case UV_NAMED_PIPE: - case UV_TCP: - err = uv__stream_open(client, - server->accepted_fd, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - if (err) { - /* TODO handle error */ - uv__close(server->accepted_fd); - goto done; - } - break; - - case UV_UDP: - err = uv_udp_open((uv_udp_t*) client, server->accepted_fd); - if (err) { - uv__close(server->accepted_fd); - goto done; - } - break; - - default: - return -EINVAL; - } - -done: - /* Process queued fds */ - if (server->queued_fds != NULL) { - uv__stream_queued_fds_t* queued_fds; - - queued_fds = server->queued_fds; - - /* Read first */ - server->accepted_fd = queued_fds->fds[0]; - - /* All read, free */ - assert(queued_fds->offset > 0); - if (--queued_fds->offset == 0) { - uv__free(queued_fds); - server->queued_fds = NULL; - } else { - /* Shift rest */ - memmove(queued_fds->fds, - queued_fds->fds + 1, - queued_fds->offset * sizeof(*queued_fds->fds)); - } - } else { - server->accepted_fd = -1; - if (err == 0) - uv__io_start(server->loop, &server->io_watcher, UV__POLLIN); - } - return err; -} - - -int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { - int err; - - switch (stream->type) { - case UV_TCP: - err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); - break; - - case UV_NAMED_PIPE: - err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb); - break; - - default: - err = -EINVAL; - } - - if (err == 0) - uv__handle_start(stream); - - return err; -} - - -static void uv__drain(uv_stream_t* stream) { - uv_shutdown_t* req; - int err; - - assert(QUEUE_EMPTY(&stream->write_queue)); - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - - /* Shutdown? */ - if ((stream->flags & UV_STREAM_SHUTTING) && - !(stream->flags & UV_CLOSING) && - !(stream->flags & UV_STREAM_SHUT)) { - assert(stream->shutdown_req); - - req = stream->shutdown_req; - stream->shutdown_req = NULL; - stream->flags &= ~UV_STREAM_SHUTTING; - uv__req_unregister(stream->loop, req); - - err = 0; - if (shutdown(uv__stream_fd(stream), SHUT_WR)) - err = -errno; - - if (err == 0) - stream->flags |= UV_STREAM_SHUT; - - if (req->cb != NULL) - req->cb(req, err); - } -} - - -static size_t uv__write_req_size(uv_write_t* req) { - size_t size; - - assert(req->bufs != NULL); - size = uv__count_bufs(req->bufs + req->write_index, - req->nbufs - req->write_index); - assert(req->handle->write_queue_size >= size); - - return size; -} - - -static void uv__write_req_finish(uv_write_t* req) { - uv_stream_t* stream = req->handle; - - /* Pop the req off tcp->write_queue. */ - QUEUE_REMOVE(&req->queue); - - /* Only free when there was no error. On error, we touch up write_queue_size - * right before making the callback. The reason we don't do that right away - * is that a write_queue_size > 0 is our only way to signal to the user that - * they should stop writing - which they should if we got an error. Something - * to revisit in future revisions of the libuv API. - */ - if (req->error == 0) { - if (req->bufs != req->bufsml) - uv__free(req->bufs); - req->bufs = NULL; - } - - /* Add it to the write_completed_queue where it will have its - * callback called in the near future. - */ - QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue); - uv__io_feed(stream->loop, &stream->io_watcher); -} - - -static int uv__handle_fd(uv_handle_t* handle) { - switch (handle->type) { - case UV_NAMED_PIPE: - case UV_TCP: - return ((uv_stream_t*) handle)->io_watcher.fd; - - case UV_UDP: - return ((uv_udp_t*) handle)->io_watcher.fd; - - default: - return -1; - } -} - -static void uv__write(uv_stream_t* stream) { - struct iovec* iov; - QUEUE* q; - uv_write_t* req; - int iovmax; - int iovcnt; - ssize_t n; - -start: - - assert(uv__stream_fd(stream) >= 0); - - if (QUEUE_EMPTY(&stream->write_queue)) - return; - - q = QUEUE_HEAD(&stream->write_queue); - req = QUEUE_DATA(q, uv_write_t, queue); - assert(req->handle == stream); - - /* - * Cast to iovec. We had to have our own uv_buf_t instead of iovec - * because Windows's WSABUF is not an iovec. - */ - assert(sizeof(uv_buf_t) == sizeof(struct iovec)); - iov = (struct iovec*) &(req->bufs[req->write_index]); - iovcnt = req->nbufs - req->write_index; - - iovmax = uv__getiovmax(); - - /* Limit iov count to avoid EINVALs from writev() */ - if (iovcnt > iovmax) - iovcnt = iovmax; - - /* - * Now do the actual writev. Note that we've been updating the pointers - * inside the iov each time we write. So there is no need to offset it. - */ - - if (req->send_handle) { - struct msghdr msg; - char scratch[64]; - struct cmsghdr *cmsg; - int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); - - assert(fd_to_send >= 0); - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = iovcnt; - msg.msg_flags = 0; - - msg.msg_control = (void*) scratch; - msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send)); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(fd_to_send)); - - /* silence aliasing warning */ - { - void* pv = CMSG_DATA(cmsg); - int* pi = pv; - *pi = fd_to_send; - } - - do { - n = sendmsg(uv__stream_fd(stream), &msg, 0); - } -#if defined(__APPLE__) - /* - * Due to a possible kernel bug at least in OS X 10.10 "Yosemite", - * EPROTOTYPE can be returned while trying to write to a socket that is - * shutting down. If we retry the write, we should get the expected EPIPE - * instead. - */ - while (n == -1 && (errno == EINTR || errno == EPROTOTYPE)); -#else - while (n == -1 && errno == EINTR); -#endif - } else { - do { - if (iovcnt == 1) { - n = write(uv__stream_fd(stream), iov[0].iov_base, iov[0].iov_len); - } else { - n = writev(uv__stream_fd(stream), iov, iovcnt); - } - } -#if defined(__APPLE__) - /* - * Due to a possible kernel bug at least in OS X 10.10 "Yosemite", - * EPROTOTYPE can be returned while trying to write to a socket that is - * shutting down. If we retry the write, we should get the expected EPIPE - * instead. - */ - while (n == -1 && (errno == EINTR || errno == EPROTOTYPE)); -#else - while (n == -1 && errno == EINTR); -#endif - } - - if (n < 0) { - if (errno != EAGAIN && errno != EWOULDBLOCK) { - /* Error */ - req->error = -errno; - uv__write_req_finish(req); - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - if (!uv__io_active(&stream->io_watcher, UV__POLLIN)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - return; - } else if (stream->flags & UV_STREAM_BLOCKING) { - /* If this is a blocking stream, try again. */ - goto start; - } - } else { - /* Successful write */ - - while (n >= 0) { - uv_buf_t* buf = &(req->bufs[req->write_index]); - size_t len = buf->len; - - assert(req->write_index < req->nbufs); - - if ((size_t)n < len) { - buf->base += n; - buf->len -= n; - stream->write_queue_size -= n; - n = 0; - - /* There is more to write. */ - if (stream->flags & UV_STREAM_BLOCKING) { - /* - * If we're blocking then we should not be enabling the write - * watcher - instead we need to try again. - */ - goto start; - } else { - /* Break loop and ensure the watcher is pending. */ - break; - } - - } else { - /* Finished writing the buf at index req->write_index. */ - req->write_index++; - - assert((size_t)n >= len); - n -= len; - - assert(stream->write_queue_size >= len); - stream->write_queue_size -= len; - - if (req->write_index == req->nbufs) { - /* Then we're done! */ - assert(n == 0); - uv__write_req_finish(req); - /* TODO: start trying to write the next request. */ - return; - } - } - } - } - - /* Either we've counted n down to zero or we've got EAGAIN. */ - assert(n == 0 || n == -1); - - /* Only non-blocking streams should use the write_watcher. */ - assert(!(stream->flags & UV_STREAM_BLOCKING)); - - /* We're not done. */ - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT); - - /* Notify select() thread about state change */ - uv__stream_osx_interrupt_select(stream); -} - - -static void uv__write_callbacks(uv_stream_t* stream) { - uv_write_t* req; - QUEUE* q; - - while (!QUEUE_EMPTY(&stream->write_completed_queue)) { - /* Pop a req off write_completed_queue. */ - q = QUEUE_HEAD(&stream->write_completed_queue); - req = QUEUE_DATA(q, uv_write_t, queue); - QUEUE_REMOVE(q); - uv__req_unregister(stream->loop, req); - - if (req->bufs != NULL) { - stream->write_queue_size -= uv__write_req_size(req); - if (req->bufs != req->bufsml) - uv__free(req->bufs); - req->bufs = NULL; - } - - /* NOTE: call callback AFTER freeing the request data. */ - if (req->cb) - req->cb(req, req->error); - } - - assert(QUEUE_EMPTY(&stream->write_completed_queue)); -} - - -uv_handle_type uv__handle_type(int fd) { - struct sockaddr_storage ss; - socklen_t len; - int type; - - memset(&ss, 0, sizeof(ss)); - len = sizeof(ss); - - if (getsockname(fd, (struct sockaddr*)&ss, &len)) - return UV_UNKNOWN_HANDLE; - - len = sizeof type; - - if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len)) - return UV_UNKNOWN_HANDLE; - - if (type == SOCK_STREAM) { - switch (ss.ss_family) { - case AF_UNIX: - return UV_NAMED_PIPE; - case AF_INET: - case AF_INET6: - return UV_TCP; - } - } - - if (type == SOCK_DGRAM && - (ss.ss_family == AF_INET || ss.ss_family == AF_INET6)) - return UV_UDP; - - return UV_UNKNOWN_HANDLE; -} - - -static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { - stream->flags |= UV_STREAM_READ_EOF; - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN); - if (!uv__io_active(&stream->io_watcher, UV__POLLOUT)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - stream->read_cb(stream, UV_EOF, buf); - stream->flags &= ~UV_STREAM_READING; -} - - -static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { - uv__stream_queued_fds_t* queued_fds; - unsigned int queue_size; - - queued_fds = stream->queued_fds; - if (queued_fds == NULL) { - queue_size = 8; - queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) + - sizeof(*queued_fds)); - if (queued_fds == NULL) - return -ENOMEM; - queued_fds->size = queue_size; - queued_fds->offset = 0; - stream->queued_fds = queued_fds; - - /* Grow */ - } else if (queued_fds->size == queued_fds->offset) { - queue_size = queued_fds->size + 8; - queued_fds = uv__realloc(queued_fds, - (queue_size - 1) * sizeof(*queued_fds->fds) + - sizeof(*queued_fds)); - - /* - * Allocation failure, report back. - * NOTE: if it is fatal - sockets will be closed in uv__stream_close - */ - if (queued_fds == NULL) - return -ENOMEM; - queued_fds->size = queue_size; - stream->queued_fds = queued_fds; - } - - /* Put fd in a queue */ - queued_fds->fds[queued_fds->offset++] = fd; - - return 0; -} - - -#define UV__CMSG_FD_COUNT 64 -#define UV__CMSG_FD_SIZE (UV__CMSG_FD_COUNT * sizeof(int)) - - -static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) { - struct cmsghdr* cmsg; - - for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { - char* start; - char* end; - int err; - void* pv; - int* pi; - unsigned int i; - unsigned int count; - - if (cmsg->cmsg_type != SCM_RIGHTS) { - fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n", - cmsg->cmsg_type); - continue; - } - - /* silence aliasing warning */ - pv = CMSG_DATA(cmsg); - pi = pv; - - /* Count available fds */ - start = (char*) cmsg; - end = (char*) cmsg + cmsg->cmsg_len; - count = 0; - while (start + CMSG_LEN(count * sizeof(*pi)) < end) - count++; - assert(start + CMSG_LEN(count * sizeof(*pi)) == end); - - for (i = 0; i < count; i++) { - /* Already has accepted fd, queue now */ - if (stream->accepted_fd != -1) { - err = uv__stream_queue_fd(stream, pi[i]); - if (err != 0) { - /* Close rest */ - for (; i < count; i++) - uv__close(pi[i]); - return err; - } - } else { - stream->accepted_fd = pi[i]; - } - } - } - - return 0; -} - - -static void uv__read(uv_stream_t* stream) { - uv_buf_t buf; - ssize_t nread; - struct msghdr msg; - char cmsg_space[CMSG_SPACE(UV__CMSG_FD_SIZE)]; - int count; - int err; - int is_ipc; - - stream->flags &= ~UV_STREAM_READ_PARTIAL; - - /* Prevent loop starvation when the data comes in as fast as (or faster than) - * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. - */ - count = 32; - - is_ipc = stream->type == UV_NAMED_PIPE && ((uv_pipe_t*) stream)->ipc; - - /* XXX: Maybe instead of having UV_STREAM_READING we just test if - * tcp->read_cb is NULL or not? - */ - while (stream->read_cb - && (stream->flags & UV_STREAM_READING) - && (count-- > 0)) { - assert(stream->alloc_cb != NULL); - - stream->alloc_cb((uv_handle_t*)stream, 64 * 1024, &buf); - if (buf.len == 0) { - /* User indicates it can't or won't handle the read. */ - stream->read_cb(stream, UV_ENOBUFS, &buf); - return; - } - - assert(buf.base != NULL); - assert(uv__stream_fd(stream) >= 0); - - if (!is_ipc) { - do { - nread = read(uv__stream_fd(stream), buf.base, buf.len); - } - while (nread < 0 && errno == EINTR); - } else { - /* ipc uses recvmsg */ - msg.msg_flags = 0; - msg.msg_iov = (struct iovec*) &buf; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - /* Set up to receive a descriptor even if one isn't in the message */ - msg.msg_controllen = sizeof(cmsg_space); - msg.msg_control = cmsg_space; - - do { - nread = uv__recvmsg(uv__stream_fd(stream), &msg, 0); - } - while (nread < 0 && errno == EINTR); - } - - if (nread < 0) { - /* Error */ - if (errno == EAGAIN || errno == EWOULDBLOCK) { - /* Wait for the next one. */ - if (stream->flags & UV_STREAM_READING) { - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); - uv__stream_osx_interrupt_select(stream); - } - stream->read_cb(stream, 0, &buf); - } else { - /* Error. User should call uv_close(). */ - stream->read_cb(stream, -errno, &buf); - if (stream->flags & UV_STREAM_READING) { - stream->flags &= ~UV_STREAM_READING; - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN); - if (!uv__io_active(&stream->io_watcher, UV__POLLOUT)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - } - } - return; - } else if (nread == 0) { - uv__stream_eof(stream, &buf); - return; - } else { - /* Successful read */ - ssize_t buflen = buf.len; - - if (is_ipc) { - err = uv__stream_recv_cmsg(stream, &msg); - if (err != 0) { - stream->read_cb(stream, err, &buf); - return; - } - } - stream->read_cb(stream, nread, &buf); - - /* Return if we didn't fill the buffer, there is no more data to read. */ - if (nread < buflen) { - stream->flags |= UV_STREAM_READ_PARTIAL; - return; - } - } - } -} - - -#undef UV__CMSG_FD_COUNT -#undef UV__CMSG_FD_SIZE - - -int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { - assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE) && - "uv_shutdown (unix) only supports uv_handle_t right now"); - - if (!(stream->flags & UV_STREAM_WRITABLE) || - stream->flags & UV_STREAM_SHUT || - stream->flags & UV_STREAM_SHUTTING || - stream->flags & UV_CLOSED || - stream->flags & UV_CLOSING) { - return -ENOTCONN; - } - - assert(uv__stream_fd(stream) >= 0); - - /* Initialize request */ - uv__req_init(stream->loop, req, UV_SHUTDOWN); - req->handle = stream; - req->cb = cb; - stream->shutdown_req = req; - stream->flags |= UV_STREAM_SHUTTING; - - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - - return 0; -} - - -static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - uv_stream_t* stream; - - stream = container_of(w, uv_stream_t, io_watcher); - - assert(stream->type == UV_TCP || - stream->type == UV_NAMED_PIPE || - stream->type == UV_TTY); - assert(!(stream->flags & UV_CLOSING)); - - if (stream->connect_req) { - uv__stream_connect(stream); - return; - } - - assert(uv__stream_fd(stream) >= 0); - - /* Ignore POLLHUP here. Even it it's set, there may still be data to read. */ - if (events & (UV__POLLIN | UV__POLLERR | UV__POLLHUP)) - uv__read(stream); - - if (uv__stream_fd(stream) == -1) - return; /* read_cb closed stream. */ - - /* Short-circuit iff POLLHUP is set, the user is still interested in read - * events and uv__read() reported a partial read but not EOF. If the EOF - * flag is set, uv__read() called read_cb with err=UV_EOF and we don't - * have to do anything. If the partial read flag is not set, we can't - * report the EOF yet because there is still data to read. - */ - if ((events & UV__POLLHUP) && - (stream->flags & UV_STREAM_READING) && - (stream->flags & UV_STREAM_READ_PARTIAL) && - !(stream->flags & UV_STREAM_READ_EOF)) { - uv_buf_t buf = { NULL, 0 }; - uv__stream_eof(stream, &buf); - } - - if (uv__stream_fd(stream) == -1) - return; /* read_cb closed stream. */ - - if (events & (UV__POLLOUT | UV__POLLERR | UV__POLLHUP)) { - uv__write(stream); - uv__write_callbacks(stream); - - /* Write queue drained. */ - if (QUEUE_EMPTY(&stream->write_queue)) - uv__drain(stream); - } -} - - -/** - * We get called here from directly following a call to connect(2). - * In order to determine if we've errored out or succeeded must call - * getsockopt. - */ -static void uv__stream_connect(uv_stream_t* stream) { - int error; - uv_connect_t* req = stream->connect_req; - socklen_t errorsize = sizeof(int); - - assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE); - assert(req); - - if (stream->delayed_error) { - /* To smooth over the differences between unixes errors that - * were reported synchronously on the first connect can be delayed - * until the next tick--which is now. - */ - error = stream->delayed_error; - stream->delayed_error = 0; - } else { - /* Normal situation: we need to get the socket error from the kernel. */ - assert(uv__stream_fd(stream) >= 0); - getsockopt(uv__stream_fd(stream), - SOL_SOCKET, - SO_ERROR, - &error, - &errorsize); - error = -error; - } - - if (error == -EINPROGRESS) - return; - - stream->connect_req = NULL; - uv__req_unregister(stream->loop, req); - - if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) { - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - } - - if (req->cb) - req->cb(req, error); - - if (uv__stream_fd(stream) == -1) - return; - - if (error < 0) { - uv__stream_flush_write_queue(stream, -ECANCELED); - uv__write_callbacks(stream); - } -} - - -int uv_write2(uv_write_t* req, - uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - int empty_queue; - - assert(nbufs > 0); - assert((stream->type == UV_TCP || - stream->type == UV_NAMED_PIPE || - stream->type == UV_TTY) && - "uv_write (unix) does not yet support other types of streams"); - - if (uv__stream_fd(stream) < 0) - return -EBADF; - - if (send_handle) { - if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) - return -EINVAL; - - /* XXX We abuse uv_write2() to send over UDP handles to child processes. - * Don't call uv__stream_fd() on those handles, it's a macro that on OS X - * evaluates to a function that operates on a uv_stream_t with a couple of - * OS X specific fields. On other Unices it does (handle)->io_watcher.fd, - * which works but only by accident. - */ - if (uv__handle_fd((uv_handle_t*) send_handle) < 0) - return -EBADF; - } - - /* It's legal for write_queue_size > 0 even when the write_queue is empty; - * it means there are error-state requests in the write_completed_queue that - * will touch up write_queue_size later, see also uv__write_req_finish(). - * We could check that write_queue is empty instead but that implies making - * a write() syscall when we know that the handle is in error mode. - */ - empty_queue = (stream->write_queue_size == 0); - - /* Initialize the req */ - uv__req_init(stream->loop, req, UV_WRITE); - req->cb = cb; - req->handle = stream; - req->error = 0; - req->send_handle = send_handle; - QUEUE_INIT(&req->queue); - - req->bufs = req->bufsml; - if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = uv__malloc(nbufs * sizeof(bufs[0])); - - if (req->bufs == NULL) - return -ENOMEM; - - memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0])); - req->nbufs = nbufs; - req->write_index = 0; - stream->write_queue_size += uv__count_bufs(bufs, nbufs); - - /* Append the request to write_queue. */ - QUEUE_INSERT_TAIL(&stream->write_queue, &req->queue); - - /* If the queue was empty when this function began, we should attempt to - * do the write immediately. Otherwise start the write_watcher and wait - * for the fd to become writable. - */ - if (stream->connect_req) { - /* Still connecting, do nothing. */ - } - else if (empty_queue) { - uv__write(stream); - } - else { - /* - * blocking streams should never have anything in the queue. - * if this assert fires then somehow the blocking stream isn't being - * sufficiently flushed in uv__write. - */ - assert(!(stream->flags & UV_STREAM_BLOCKING)); - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - } - - return 0; -} - - -/* The buffers to be written must remain valid until the callback is called. - * This is not required for the uv_buf_t array. - */ -int uv_write(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - return uv_write2(req, handle, bufs, nbufs, NULL, cb); -} - - -void uv_try_write_cb(uv_write_t* req, int status) { - /* Should not be called */ - abort(); -} - - -int uv_try_write(uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs) { - int r; - int has_pollout; - size_t written; - size_t req_size; - uv_write_t req; - - /* Connecting or already writing some data */ - if (stream->connect_req != NULL || stream->write_queue_size != 0) - return -EAGAIN; - - has_pollout = uv__io_active(&stream->io_watcher, UV__POLLOUT); - - r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb); - if (r != 0) - return r; - - /* Remove not written bytes from write queue size */ - written = uv__count_bufs(bufs, nbufs); - if (req.bufs != NULL) - req_size = uv__write_req_size(&req); - else - req_size = 0; - written -= req_size; - stream->write_queue_size -= req_size; - - /* Unqueue request, regardless of immediateness */ - QUEUE_REMOVE(&req.queue); - uv__req_unregister(stream->loop, &req); - if (req.bufs != req.bufsml) - uv__free(req.bufs); - req.bufs = NULL; - - /* Do not poll for writable, if we wasn't before calling this */ - if (!has_pollout) { - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - } - - if (written == 0) - return -EAGAIN; - else - return written; -} - - -int uv_read_start(uv_stream_t* stream, - uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || - stream->type == UV_TTY); - - if (stream->flags & UV_CLOSING) - return -EINVAL; - - /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just - * expresses the desired state of the user. - */ - stream->flags |= UV_STREAM_READING; - - /* TODO: try to do the read inline? */ - /* TODO: keep track of tcp state. If we've gotten a EOF then we should - * not start the IO watcher. - */ - assert(uv__stream_fd(stream) >= 0); - assert(alloc_cb); - - stream->read_cb = read_cb; - stream->alloc_cb = alloc_cb; - - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); - uv__handle_start(stream); - uv__stream_osx_interrupt_select(stream); - - return 0; -} - - -int uv_read_stop(uv_stream_t* stream) { - if (!(stream->flags & UV_STREAM_READING)) - return 0; - - stream->flags &= ~UV_STREAM_READING; - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN); - if (!uv__io_active(&stream->io_watcher, UV__POLLOUT)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - - stream->read_cb = NULL; - stream->alloc_cb = NULL; - return 0; -} - - -int uv_is_readable(const uv_stream_t* stream) { - return !!(stream->flags & UV_STREAM_READABLE); -} - - -int uv_is_writable(const uv_stream_t* stream) { - return !!(stream->flags & UV_STREAM_WRITABLE); -} - - -#if defined(__APPLE__) -int uv___stream_fd(const uv_stream_t* handle) { - const uv__stream_select_t* s; - - assert(handle->type == UV_TCP || - handle->type == UV_TTY || - handle->type == UV_NAMED_PIPE); - - s = handle->select; - if (s != NULL) - return s->fd; - - return handle->io_watcher.fd; -} -#endif /* defined(__APPLE__) */ - - -void uv__stream_close(uv_stream_t* handle) { - unsigned int i; - uv__stream_queued_fds_t* queued_fds; - -#if defined(__APPLE__) - /* Terminate select loop first */ - if (handle->select != NULL) { - uv__stream_select_t* s; - - s = handle->select; - - uv_sem_post(&s->close_sem); - uv_sem_post(&s->async_sem); - uv__stream_osx_interrupt_select(handle); - uv_thread_join(&s->thread); - uv_sem_destroy(&s->close_sem); - uv_sem_destroy(&s->async_sem); - uv__close(s->fake_fd); - uv__close(s->int_fd); - uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); - - handle->select = NULL; - } -#endif /* defined(__APPLE__) */ - - uv__io_close(handle->loop, &handle->io_watcher); - uv_read_stop(handle); - uv__handle_stop(handle); - - if (handle->io_watcher.fd != -1) { - /* Don't close stdio file descriptors. Nothing good comes from it. */ - if (handle->io_watcher.fd > STDERR_FILENO) - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - } - - if (handle->accepted_fd != -1) { - uv__close(handle->accepted_fd); - handle->accepted_fd = -1; - } - - /* Close all queued fds */ - if (handle->queued_fds != NULL) { - queued_fds = handle->queued_fds; - for (i = 0; i < queued_fds->offset; i++) - uv__close(queued_fds->fds[i]); - uv__free(handle->queued_fds); - handle->queued_fds = NULL; - } - - assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT)); -} - - -int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { - /* Don't need to check the file descriptor, uv__nonblock() - * will fail with EBADF if it's not valid. - */ - return uv__nonblock(uv__stream_fd(handle), !blocking); -} diff --git a/outside/libuv-v1.7.5/src/unix/sunos.c b/outside/libuv-v1.7.5/src/unix/sunos.c deleted file mode 100644 index 05b7a11403..0000000000 --- a/outside/libuv-v1.7.5/src/unix/sunos.c +++ /dev/null @@ -1,763 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include - -#ifndef SUNOS_NO_IFADDRS -# include -#endif -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#define PORT_FIRED 0x69 -#define PORT_UNUSED 0x0 -#define PORT_LOADED 0x99 -#define PORT_DELETED -1 - -#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64) -#define PROCFS_FILE_OFFSET_BITS_HACK 1 -#undef _FILE_OFFSET_BITS -#else -#define PROCFS_FILE_OFFSET_BITS_HACK 0 -#endif - -#include - -#if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1) -#define _FILE_OFFSET_BITS 64 -#endif - - -int uv__platform_loop_init(uv_loop_t* loop) { - int err; - int fd; - - loop->fs_fd = -1; - loop->backend_fd = -1; - - fd = port_create(); - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err) { - uv__close(fd); - return err; - } - loop->backend_fd = fd; - - return 0; -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { - if (loop->fs_fd != -1) { - uv__close(loop->fs_fd); - loop->fs_fd = -1; - } - - if (loop->backend_fd != -1) { - uv__close(loop->backend_fd); - loop->backend_fd = -1; - } -} - - -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct port_event* events; - uintptr_t i; - uintptr_t nfds; - - assert(loop->watchers != NULL); - - events = (struct port_event*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - if (events == NULL) - return; - - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if ((int) events[i].portev_object == fd) - events[i].portev_object = -1; -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - struct port_event events[1024]; - struct port_event* pe; - struct timespec spec; - QUEUE* q; - uv__io_t* w; - sigset_t* pset; - sigset_t set; - uint64_t base; - uint64_t diff; - unsigned int nfds; - unsigned int i; - int saved_errno; - int nevents; - int count; - int err; - int fd; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - - if (port_associate(loop->backend_fd, PORT_SOURCE_FD, w->fd, w->pevents, 0)) - abort(); - - w->events = w->pevents; - } - - pset = NULL; - if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { - pset = &set; - sigemptyset(pset); - sigaddset(pset, SIGPROF); - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - - for (;;) { - if (timeout != -1) { - spec.tv_sec = timeout / 1000; - spec.tv_nsec = (timeout % 1000) * 1000000; - } - - /* Work around a kernel bug where nfds is not updated. */ - events[0].portev_source = 0; - - nfds = 1; - saved_errno = 0; - - if (pset != NULL) - pthread_sigmask(SIG_BLOCK, pset, NULL); - - err = port_getn(loop->backend_fd, - events, - ARRAY_SIZE(events), - &nfds, - timeout == -1 ? NULL : &spec); - - if (pset != NULL) - pthread_sigmask(SIG_UNBLOCK, pset, NULL); - - if (err) { - /* Work around another kernel bug: port_getn() may return events even - * on error. - */ - if (errno == EINTR || errno == ETIME) - saved_errno = errno; - else - abort(); - } - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (events[0].portev_source == 0) { - if (timeout == 0) - return; - - if (timeout == -1) - continue; - - goto update_timeout; - } - - if (nfds == 0) { - assert(timeout != -1); - return; - } - - nevents = 0; - - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = (void*) events; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - for (i = 0; i < nfds; i++) { - pe = events + i; - fd = pe->portev_object; - - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (fd == -1) - continue; - - assert(fd >= 0); - assert((unsigned) fd < loop->nwatchers); - - w = loop->watchers[fd]; - - /* File descriptor that we've stopped watching, ignore. */ - if (w == NULL) - continue; - - w->cb(loop, w, pe->portev_events); - nevents++; - - if (w != loop->watchers[fd]) - continue; /* Disabled by callback. */ - - /* Events Ports operates in oneshot mode, rearm timer on next run. */ - if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) - QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); - } - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (saved_errno == ETIME) { - assert(timeout != -1); - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - diff = loop->time - base; - if (diff >= (uint64_t) timeout) - return; - - timeout -= diff; - } -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - return gethrtime(); -} - - -/* - * We could use a static buffer for the path manipulations that we need outside - * of the function, but this function could be called by multiple consumers and - * we don't want to potentially create a race condition in the use of snprintf. - */ -int uv_exepath(char* buffer, size_t* size) { - ssize_t res; - char buf[128]; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid()); - - res = *size - 1; - if (res > 0) - res = readlink(buf, buffer, res); - - if (res == -1) - return -errno; - - buffer[res] = '\0'; - *size = res; - return 0; -} - - -uint64_t uv_get_free_memory(void) { - return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES); -} - - -uint64_t uv_get_total_memory(void) { - return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES); -} - - -void uv_loadavg(double avg[3]) { - (void) getloadavg(avg, 3); -} - - -#if defined(PORT_SOURCE_FILE) - -static int uv__fs_event_rearm(uv_fs_event_t *handle) { - if (handle->fd == -1) - return -EBADF; - - if (port_associate(handle->loop->fs_fd, - PORT_SOURCE_FILE, - (uintptr_t) &handle->fo, - FILE_ATTRIB | FILE_MODIFIED, - handle) == -1) { - return -errno; - } - handle->fd = PORT_LOADED; - - return 0; -} - - -static void uv__fs_event_read(uv_loop_t* loop, - uv__io_t* w, - unsigned int revents) { - uv_fs_event_t *handle = NULL; - timespec_t timeout; - port_event_t pe; - int events; - int r; - - (void) w; - (void) revents; - - do { - uint_t n = 1; - - /* - * Note that our use of port_getn() here (and not port_get()) is deliberate: - * there is a bug in event ports (Sun bug 6456558) whereby a zeroed timeout - * causes port_get() to return success instead of ETIME when there aren't - * actually any events (!); by using port_getn() in lieu of port_get(), - * we can at least workaround the bug by checking for zero returned events - * and treating it as we would ETIME. - */ - do { - memset(&timeout, 0, sizeof timeout); - r = port_getn(loop->fs_fd, &pe, 1, &n, &timeout); - } - while (r == -1 && errno == EINTR); - - if ((r == -1 && errno == ETIME) || n == 0) - break; - - handle = (uv_fs_event_t*) pe.portev_user; - assert((r == 0) && "unexpected port_get() error"); - - events = 0; - if (pe.portev_events & (FILE_ATTRIB | FILE_MODIFIED)) - events |= UV_CHANGE; - if (pe.portev_events & ~(FILE_ATTRIB | FILE_MODIFIED)) - events |= UV_RENAME; - assert(events != 0); - handle->fd = PORT_FIRED; - handle->cb(handle, NULL, events, 0); - - if (handle->fd != PORT_DELETED) { - r = uv__fs_event_rearm(handle); - if (r != 0) - handle->cb(handle, NULL, 0, r); - } - } - while (handle->fd != PORT_DELETED); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* path, - unsigned int flags) { - int portfd; - int first_run; - int err; - - if (uv__is_active(handle)) - return -EINVAL; - - first_run = 0; - if (handle->loop->fs_fd == -1) { - portfd = port_create(); - if (portfd == -1) - return -errno; - handle->loop->fs_fd = portfd; - first_run = 1; - } - - uv__handle_start(handle); - handle->path = uv__strdup(path); - handle->fd = PORT_UNUSED; - handle->cb = cb; - - memset(&handle->fo, 0, sizeof handle->fo); - handle->fo.fo_name = handle->path; - err = uv__fs_event_rearm(handle); - if (err != 0) - return err; - - if (first_run) { - uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); - uv__io_start(handle->loop, &handle->loop->fs_event_watcher, UV__POLLIN); - } - - return 0; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - if (!uv__is_active(handle)) - return 0; - - if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) { - port_dissociate(handle->loop->fs_fd, - PORT_SOURCE_FILE, - (uintptr_t) &handle->fo); - } - - handle->fd = PORT_DELETED; - uv__free(handle->path); - handle->path = NULL; - handle->fo.fo_name = NULL; - uv__handle_stop(handle); - - return 0; -} - -void uv__fs_event_close(uv_fs_event_t* handle) { - uv_fs_event_stop(handle); -} - -#else /* !defined(PORT_SOURCE_FILE) */ - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - return -ENOSYS; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* filename, - unsigned int flags) { - return -ENOSYS; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - return -ENOSYS; -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { - UNREACHABLE(); -} - -#endif /* defined(PORT_SOURCE_FILE) */ - - -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (size > 0) { - buffer[0] = '\0'; - } - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - psinfo_t psinfo; - int err; - int fd; - - fd = open("/proc/self/psinfo", O_RDONLY); - if (fd == -1) - return -errno; - - /* FIXME(bnoordhuis) Handle EINTR. */ - err = -EINVAL; - if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) { - *rss = (size_t)psinfo.pr_rssize * 1024; - err = 0; - } - uv__close(fd); - - return err; -} - - -int uv_uptime(double* uptime) { - kstat_ctl_t *kc; - kstat_t *ksp; - kstat_named_t *knp; - - long hz = sysconf(_SC_CLK_TCK); - - kc = kstat_open(); - if (kc == NULL) - return -EPERM; - - ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc"); - if (kstat_read(kc, ksp, NULL) == -1) { - *uptime = -1; - } else { - knp = (kstat_named_t*) kstat_data_lookup(ksp, (char*) "clk_intr"); - *uptime = knp->value.ul / hz; - } - kstat_close(kc); - - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - int lookup_instance; - kstat_ctl_t *kc; - kstat_t *ksp; - kstat_named_t *knp; - uv_cpu_info_t* cpu_info; - - kc = kstat_open(); - if (kc == NULL) - return -EPERM; - - /* Get count of cpus */ - lookup_instance = 0; - while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { - lookup_instance++; - } - - *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos)); - if (!(*cpu_infos)) { - kstat_close(kc); - return -ENOMEM; - } - - *count = lookup_instance; - - cpu_info = *cpu_infos; - lookup_instance = 0; - while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { - if (kstat_read(kc, ksp, NULL) == -1) { - cpu_info->speed = 0; - cpu_info->model = NULL; - } else { - knp = kstat_data_lookup(ksp, (char*) "clock_MHz"); - assert(knp->data_type == KSTAT_DATA_INT32 || - knp->data_type == KSTAT_DATA_INT64); - cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32 - : knp->value.i64; - - knp = kstat_data_lookup(ksp, (char*) "brand"); - assert(knp->data_type == KSTAT_DATA_STRING); - cpu_info->model = uv__strdup(KSTAT_NAMED_STR_PTR(knp)); - } - - lookup_instance++; - cpu_info++; - } - - cpu_info = *cpu_infos; - lookup_instance = 0; - for (;;) { - ksp = kstat_lookup(kc, (char*) "cpu", lookup_instance, (char*) "sys"); - - if (ksp == NULL) - break; - - if (kstat_read(kc, ksp, NULL) == -1) { - cpu_info->cpu_times.user = 0; - cpu_info->cpu_times.nice = 0; - cpu_info->cpu_times.sys = 0; - cpu_info->cpu_times.idle = 0; - cpu_info->cpu_times.irq = 0; - } else { - knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_user"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.user = knp->value.ui64; - - knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_kernel"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.sys = knp->value.ui64; - - knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_idle"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.idle = knp->value.ui64; - - knp = kstat_data_lookup(ksp, (char*) "intr"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.irq = knp->value.ui64; - cpu_info->cpu_times.nice = 0; - } - - lookup_instance++; - cpu_info++; - } - - kstat_close(kc); - - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { -#ifdef SUNOS_NO_IFADDRS - return -ENOSYS; -#else - uv_interface_address_t* address; - struct sockaddr_dl* sa_addr; - struct ifaddrs* addrs; - struct ifaddrs* ent; - int i; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!((ent->ifa_flags & IFF_PRIVATE) || - (ent->ifa_flags & IFF_LOOPBACK)); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -#endif /* SUNOS_NO_IFADDRS */ -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/outside/libuv-v1.7.5/src/unix/tcp.c b/outside/libuv-v1.7.5/src/unix/tcp.c deleted file mode 100644 index 6d213a4977..0000000000 --- a/outside/libuv-v1.7.5/src/unix/tcp.c +++ /dev/null @@ -1,362 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include - - -static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) { - int sockfd; - int err; - - if (domain == AF_UNSPEC || uv__stream_fd(handle) != -1) { - handle->flags |= flags; - return 0; - } - - err = uv__socket(domain, SOCK_STREAM, 0); - if (err < 0) - return err; - sockfd = err; - - err = uv__stream_open((uv_stream_t*) handle, sockfd, flags); - if (err) { - uv__close(sockfd); - return err; - } - - return 0; -} - - -int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* tcp, unsigned int flags) { - int domain; - - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return -EINVAL; - - if (flags & ~0xFF) - return -EINVAL; - - uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP); - - /* If anything fails beyond this point we need to remove the handle from - * the handle queue, since it was added by uv__handle_init in uv_stream_init. - */ - - if (domain != AF_UNSPEC) { - int err = maybe_new_socket(tcp, domain, 0); - if (err) { - QUEUE_REMOVE(&tcp->handle_queue); - return err; - } - } - - return 0; -} - - -int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) { - return uv_tcp_init_ex(loop, tcp, AF_UNSPEC); -} - - -int uv__tcp_bind(uv_tcp_t* tcp, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - int on; - - /* Cannot set IPv6-only mode on non-IPv6 socket. */ - if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) - return -EINVAL; - - err = maybe_new_socket(tcp, - addr->sa_family, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - if (err) - return err; - - on = 1; - if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) - return -errno; - -#ifdef IPV6_V6ONLY - if (addr->sa_family == AF_INET6) { - on = (flags & UV_TCP_IPV6ONLY) != 0; - if (setsockopt(tcp->io_watcher.fd, - IPPROTO_IPV6, - IPV6_V6ONLY, - &on, - sizeof on) == -1) { - return -errno; - } - } -#endif - - errno = 0; - if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE) { - if (errno == EAFNOSUPPORT) - /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a - * socket created with AF_INET to an AF_INET6 address or vice versa. */ - return -EINVAL; - return -errno; - } - tcp->delayed_error = -errno; - - if (addr->sa_family == AF_INET6) - tcp->flags |= UV_HANDLE_IPV6; - - return 0; -} - - -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - int err; - int r; - - assert(handle->type == UV_TCP); - - if (handle->connect_req != NULL) - return -EALREADY; /* FIXME(bnoordhuis) -EINVAL or maybe -EBUSY. */ - - err = maybe_new_socket(handle, - addr->sa_family, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - if (err) - return err; - - handle->delayed_error = 0; - - do - r = connect(uv__stream_fd(handle), addr, addrlen); - while (r == -1 && errno == EINTR); - - if (r == -1) { - if (errno == EINPROGRESS) - ; /* not an error */ - else if (errno == ECONNREFUSED) - /* If we get a ECONNREFUSED wait until the next tick to report the - * error. Solaris wants to report immediately--other unixes want to - * wait. - */ - handle->delayed_error = -errno; - else - return -errno; - } - - uv__req_init(handle->loop, req, UV_CONNECT); - req->cb = cb; - req->handle = (uv_stream_t*) handle; - QUEUE_INIT(&req->queue); - handle->connect_req = req; - - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); - - if (handle->delayed_error) - uv__io_feed(handle->loop, &handle->io_watcher); - - return 0; -} - - -int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { - int err; - - err = uv__nonblock(sock, 1); - if (err) - return err; - - return uv__stream_open((uv_stream_t*)handle, - sock, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); -} - - -int uv_tcp_getsockname(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - socklen_t socklen; - - if (handle->delayed_error) - return handle->delayed_error; - - if (uv__stream_fd(handle) < 0) - return -EINVAL; /* FIXME(bnoordhuis) -EBADF */ - - /* sizeof(socklen_t) != sizeof(int) on some systems. */ - socklen = (socklen_t) *namelen; - - if (getsockname(uv__stream_fd(handle), name, &socklen)) - return -errno; - - *namelen = (int) socklen; - return 0; -} - - -int uv_tcp_getpeername(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - socklen_t socklen; - - if (handle->delayed_error) - return handle->delayed_error; - - if (uv__stream_fd(handle) < 0) - return -EINVAL; /* FIXME(bnoordhuis) -EBADF */ - - /* sizeof(socklen_t) != sizeof(int) on some systems. */ - socklen = (socklen_t) *namelen; - - if (getpeername(uv__stream_fd(handle), name, &socklen)) - return -errno; - - *namelen = (int) socklen; - return 0; -} - - -int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { - static int single_accept = -1; - int err; - - if (tcp->delayed_error) - return tcp->delayed_error; - - if (single_accept == -1) { - const char* val = getenv("UV_TCP_SINGLE_ACCEPT"); - single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */ - } - - if (single_accept) - tcp->flags |= UV_TCP_SINGLE_ACCEPT; - - err = maybe_new_socket(tcp, AF_INET, UV_STREAM_READABLE); - if (err) - return err; - - if (listen(tcp->io_watcher.fd, backlog)) - return -errno; - - tcp->connection_cb = cb; - - /* Start listening for connections. */ - tcp->io_watcher.cb = uv__server_io; - uv__io_start(tcp->loop, &tcp->io_watcher, UV__POLLIN); - - return 0; -} - - -int uv__tcp_nodelay(int fd, int on) { - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on))) - return -errno; - return 0; -} - - -int uv__tcp_keepalive(int fd, int on, unsigned int delay) { - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) - return -errno; - -#ifdef TCP_KEEPIDLE - if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) - return -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))) - return -errno; -#endif - - return 0; -} - - -int uv_tcp_nodelay(uv_tcp_t* handle, int on) { - int err; - - if (uv__stream_fd(handle) != -1) { - err = uv__tcp_nodelay(uv__stream_fd(handle), on); - if (err) - return err; - } - - if (on) - handle->flags |= UV_TCP_NODELAY; - else - handle->flags &= ~UV_TCP_NODELAY; - - return 0; -} - - -int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) { - int err; - - if (uv__stream_fd(handle) != -1) { - err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay); - if (err) - return err; - } - - if (on) - handle->flags |= UV_TCP_KEEPALIVE; - else - handle->flags &= ~UV_TCP_KEEPALIVE; - - /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge - * uv_tcp_t with an int that's almost never used... - */ - - return 0; -} - - -int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { - if (enable) - handle->flags &= ~UV_TCP_SINGLE_ACCEPT; - else - handle->flags |= UV_TCP_SINGLE_ACCEPT; - return 0; -} - - -void uv__tcp_close(uv_tcp_t* handle) { - uv__stream_close((uv_stream_t*)handle); -} diff --git a/outside/libuv-v1.7.5/src/unix/thread.c b/outside/libuv-v1.7.5/src/unix/thread.c deleted file mode 100644 index c56a317025..0000000000 --- a/outside/libuv-v1.7.5/src/unix/thread.c +++ /dev/null @@ -1,525 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include - -#include - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - - -struct thread_ctx { - void (*entry)(void* arg); - void* arg; -}; - - -static void* uv__thread_start(void *arg) -{ - struct thread_ctx *ctx_p; - struct thread_ctx ctx; - - ctx_p = arg; - ctx = *ctx_p; - uv__free(ctx_p); - ctx.entry(ctx.arg); - - return 0; -} - - -int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { - struct thread_ctx* ctx; - int err; - - ctx = uv__malloc(sizeof(*ctx)); - if (ctx == NULL) - return UV_ENOMEM; - - ctx->entry = entry; - ctx->arg = arg; - - err = pthread_create(tid, NULL, uv__thread_start, ctx); - - if (err) - uv__free(ctx); - - return -err; -} - - -uv_thread_t uv_thread_self(void) { - return pthread_self(); -} - -int uv_thread_join(uv_thread_t *tid) { - return -pthread_join(*tid, NULL); -} - - -int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) { - return pthread_equal(*t1, *t2); -} - - -int uv_mutex_init(uv_mutex_t* mutex) { -#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK) - return -pthread_mutex_init(mutex, NULL); -#else - pthread_mutexattr_t attr; - int err; - - if (pthread_mutexattr_init(&attr)) - abort(); - - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)) - abort(); - - err = pthread_mutex_init(mutex, &attr); - - if (pthread_mutexattr_destroy(&attr)) - abort(); - - return -err; -#endif -} - - -void uv_mutex_destroy(uv_mutex_t* mutex) { - if (pthread_mutex_destroy(mutex)) - abort(); -} - - -void uv_mutex_lock(uv_mutex_t* mutex) { - if (pthread_mutex_lock(mutex)) - abort(); -} - - -int uv_mutex_trylock(uv_mutex_t* mutex) { - int err; - - err = pthread_mutex_trylock(mutex); - if (err) { - if (err != EBUSY && err != EAGAIN) - abort(); - return -EBUSY; - } - - return 0; -} - - -void uv_mutex_unlock(uv_mutex_t* mutex) { - if (pthread_mutex_unlock(mutex)) - abort(); -} - - -int uv_rwlock_init(uv_rwlock_t* rwlock) { - return -pthread_rwlock_init(rwlock, NULL); -} - - -void uv_rwlock_destroy(uv_rwlock_t* rwlock) { - if (pthread_rwlock_destroy(rwlock)) - abort(); -} - - -void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_rdlock(rwlock)) - abort(); -} - - -int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { - int err; - - err = pthread_rwlock_tryrdlock(rwlock); - if (err) { - if (err != EBUSY && err != EAGAIN) - abort(); - return -EBUSY; - } - - return 0; -} - - -void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_unlock(rwlock)) - abort(); -} - - -void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_wrlock(rwlock)) - abort(); -} - - -int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { - int err; - - err = pthread_rwlock_trywrlock(rwlock); - if (err) { - if (err != EBUSY && err != EAGAIN) - abort(); - return -EBUSY; - } - - return 0; -} - - -void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_unlock(rwlock)) - abort(); -} - - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - if (pthread_once(guard, callback)) - abort(); -} - -#if defined(__APPLE__) && defined(__MACH__) - -int uv_sem_init(uv_sem_t* sem, unsigned int value) { - kern_return_t err; - - err = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value); - if (err == KERN_SUCCESS) - return 0; - if (err == KERN_INVALID_ARGUMENT) - return -EINVAL; - if (err == KERN_RESOURCE_SHORTAGE) - return -ENOMEM; - - abort(); - return -EINVAL; /* Satisfy the compiler. */ -} - - -void uv_sem_destroy(uv_sem_t* sem) { - if (semaphore_destroy(mach_task_self(), *sem)) - abort(); -} - - -void uv_sem_post(uv_sem_t* sem) { - if (semaphore_signal(*sem)) - abort(); -} - - -void uv_sem_wait(uv_sem_t* sem) { - int r; - - do - r = semaphore_wait(*sem); - while (r == KERN_ABORTED); - - if (r != KERN_SUCCESS) - abort(); -} - - -int uv_sem_trywait(uv_sem_t* sem) { - mach_timespec_t interval; - kern_return_t err; - - interval.tv_sec = 0; - interval.tv_nsec = 0; - - err = semaphore_timedwait(*sem, interval); - if (err == KERN_SUCCESS) - return 0; - if (err == KERN_OPERATION_TIMED_OUT) - return -EAGAIN; - - abort(); - return -EINVAL; /* Satisfy the compiler. */ -} - -#else /* !(defined(__APPLE__) && defined(__MACH__)) */ - -int uv_sem_init(uv_sem_t* sem, unsigned int value) { - if (sem_init(sem, 0, value)) - return -errno; - return 0; -} - - -void uv_sem_destroy(uv_sem_t* sem) { - if (sem_destroy(sem)) - abort(); -} - - -void uv_sem_post(uv_sem_t* sem) { - if (sem_post(sem)) - abort(); -} - - -void uv_sem_wait(uv_sem_t* sem) { - int r; - - do - r = sem_wait(sem); - while (r == -1 && errno == EINTR); - - if (r) - abort(); -} - - -int uv_sem_trywait(uv_sem_t* sem) { - int r; - - do - r = sem_trywait(sem); - while (r == -1 && errno == EINTR); - - if (r) { - if (errno == EAGAIN) - return -EAGAIN; - abort(); - } - - return 0; -} - -#endif /* defined(__APPLE__) && defined(__MACH__) */ - - -#if defined(__APPLE__) && defined(__MACH__) - -int uv_cond_init(uv_cond_t* cond) { - return -pthread_cond_init(cond, NULL); -} - -#else /* !(defined(__APPLE__) && defined(__MACH__)) */ - -int uv_cond_init(uv_cond_t* cond) { - pthread_condattr_t attr; - int err; - - err = pthread_condattr_init(&attr); - if (err) - return -err; - -#if !(defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) - err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); - if (err) - goto error2; -#endif - - err = pthread_cond_init(cond, &attr); - if (err) - goto error2; - - err = pthread_condattr_destroy(&attr); - if (err) - goto error; - - return 0; - -error: - pthread_cond_destroy(cond); -error2: - pthread_condattr_destroy(&attr); - return -err; -} - -#endif /* defined(__APPLE__) && defined(__MACH__) */ - -void uv_cond_destroy(uv_cond_t* cond) { - if (pthread_cond_destroy(cond)) - abort(); -} - -void uv_cond_signal(uv_cond_t* cond) { - if (pthread_cond_signal(cond)) - abort(); -} - -void uv_cond_broadcast(uv_cond_t* cond) { - if (pthread_cond_broadcast(cond)) - abort(); -} - -void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (pthread_cond_wait(cond, mutex)) - abort(); -} - - -int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) { - int r; - struct timespec ts; - -#if defined(__APPLE__) && defined(__MACH__) - ts.tv_sec = timeout / NANOSEC; - ts.tv_nsec = timeout % NANOSEC; - r = pthread_cond_timedwait_relative_np(cond, mutex, &ts); -#else - timeout += uv__hrtime(UV_CLOCK_PRECISE); - ts.tv_sec = timeout / NANOSEC; - ts.tv_nsec = timeout % NANOSEC; -#if defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC) - /* - * The bionic pthread implementation doesn't support CLOCK_MONOTONIC, - * but has this alternative function instead. - */ - r = pthread_cond_timedwait_monotonic_np(cond, mutex, &ts); -#else - r = pthread_cond_timedwait(cond, mutex, &ts); -#endif /* __ANDROID__ */ -#endif - - - if (r == 0) - return 0; - - if (r == ETIMEDOUT) - return -ETIMEDOUT; - - abort(); - return -EINVAL; /* Satisfy the compiler. */ -} - - -#if defined(__APPLE__) && defined(__MACH__) - -int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { - int err; - - barrier->n = count; - barrier->count = 0; - - err = uv_mutex_init(&barrier->mutex); - if (err) - return -err; - - err = uv_sem_init(&barrier->turnstile1, 0); - if (err) - goto error2; - - err = uv_sem_init(&barrier->turnstile2, 1); - if (err) - goto error; - - return 0; - -error: - uv_sem_destroy(&barrier->turnstile1); -error2: - uv_mutex_destroy(&barrier->mutex); - return -err; - -} - - -void uv_barrier_destroy(uv_barrier_t* barrier) { - uv_sem_destroy(&barrier->turnstile2); - uv_sem_destroy(&barrier->turnstile1); - uv_mutex_destroy(&barrier->mutex); -} - - -int uv_barrier_wait(uv_barrier_t* barrier) { - int serial_thread; - - uv_mutex_lock(&barrier->mutex); - if (++barrier->count == barrier->n) { - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile1); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile1); - - uv_mutex_lock(&barrier->mutex); - serial_thread = (--barrier->count == 0); - if (serial_thread) { - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile2); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile2); - return serial_thread; -} - -#else /* !(defined(__APPLE__) && defined(__MACH__)) */ - -int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { - return -pthread_barrier_init(barrier, NULL, count); -} - - -void uv_barrier_destroy(uv_barrier_t* barrier) { - if (pthread_barrier_destroy(barrier)) - abort(); -} - - -int uv_barrier_wait(uv_barrier_t* barrier) { - int r = pthread_barrier_wait(barrier); - if (r && r != PTHREAD_BARRIER_SERIAL_THREAD) - abort(); - return r == PTHREAD_BARRIER_SERIAL_THREAD; -} - -#endif /* defined(__APPLE__) && defined(__MACH__) */ - -int uv_key_create(uv_key_t* key) { - return -pthread_key_create(key, NULL); -} - - -void uv_key_delete(uv_key_t* key) { - if (pthread_key_delete(*key)) - abort(); -} - - -void* uv_key_get(uv_key_t* key) { - return pthread_getspecific(*key); -} - - -void uv_key_set(uv_key_t* key, void* value) { - if (pthread_setspecific(*key, value)) - abort(); -} diff --git a/outside/libuv-v1.7.5/src/unix/timer.c b/outside/libuv-v1.7.5/src/unix/timer.c deleted file mode 100644 index ca3ec3db95..0000000000 --- a/outside/libuv-v1.7.5/src/unix/timer.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" -#include "heap-inl.h" - -#include -#include - - -static int timer_less_than(const struct heap_node* ha, - const struct heap_node* hb) { - const uv_timer_t* a; - const uv_timer_t* b; - - a = container_of(ha, const uv_timer_t, heap_node); - b = container_of(hb, const uv_timer_t, heap_node); - - if (a->timeout < b->timeout) - return 1; - if (b->timeout < a->timeout) - return 0; - - /* Compare start_id when both have the same timeout. start_id is - * allocated with loop->timer_counter in uv_timer_start(). - */ - if (a->start_id < b->start_id) - return 1; - if (b->start_id < a->start_id) - return 0; - - return 0; -} - - -int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER); - handle->timer_cb = NULL; - handle->repeat = 0; - return 0; -} - - -int uv_timer_start(uv_timer_t* handle, - uv_timer_cb cb, - uint64_t timeout, - uint64_t repeat) { - uint64_t clamped_timeout; - - if (cb == NULL) - return -EINVAL; - - if (uv__is_active(handle)) - uv_timer_stop(handle); - - clamped_timeout = handle->loop->time + timeout; - if (clamped_timeout < timeout) - clamped_timeout = (uint64_t) -1; - - handle->timer_cb = cb; - handle->timeout = clamped_timeout; - handle->repeat = repeat; - /* start_id is the second index to be compared in uv__timer_cmp() */ - handle->start_id = handle->loop->timer_counter++; - - heap_insert((struct heap*) &handle->loop->timer_heap, - (struct heap_node*) &handle->heap_node, - timer_less_than); - uv__handle_start(handle); - - return 0; -} - - -int uv_timer_stop(uv_timer_t* handle) { - if (!uv__is_active(handle)) - return 0; - - heap_remove((struct heap*) &handle->loop->timer_heap, - (struct heap_node*) &handle->heap_node, - timer_less_than); - uv__handle_stop(handle); - - return 0; -} - - -int uv_timer_again(uv_timer_t* handle) { - if (handle->timer_cb == NULL) - return -EINVAL; - - if (handle->repeat) { - uv_timer_stop(handle); - uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat); - } - - return 0; -} - - -void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) { - handle->repeat = repeat; -} - - -uint64_t uv_timer_get_repeat(const uv_timer_t* handle) { - return handle->repeat; -} - - -int uv__next_timeout(const uv_loop_t* loop) { - const struct heap_node* heap_node; - const uv_timer_t* handle; - uint64_t diff; - - heap_node = heap_min((const struct heap*) &loop->timer_heap); - if (heap_node == NULL) - return -1; /* block indefinitely */ - - handle = container_of(heap_node, const uv_timer_t, heap_node); - if (handle->timeout <= loop->time) - return 0; - - diff = handle->timeout - loop->time; - if (diff > INT_MAX) - diff = INT_MAX; - - return diff; -} - - -void uv__run_timers(uv_loop_t* loop) { - struct heap_node* heap_node; - uv_timer_t* handle; - - for (;;) { - heap_node = heap_min((struct heap*) &loop->timer_heap); - if (heap_node == NULL) - break; - - handle = container_of(heap_node, uv_timer_t, heap_node); - if (handle->timeout > loop->time) - break; - - uv_timer_stop(handle); - uv_timer_again(handle); - handle->timer_cb(handle); - } -} - - -void uv__timer_close(uv_timer_t* handle) { - uv_timer_stop(handle); -} diff --git a/outside/libuv-v1.7.5/src/unix/tty.c b/outside/libuv-v1.7.5/src/unix/tty.c deleted file mode 100644 index 54c9055a08..0000000000 --- a/outside/libuv-v1.7.5/src/unix/tty.c +++ /dev/null @@ -1,270 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" -#include "spinlock.h" - -#include -#include -#include -#include -#include - -static int orig_termios_fd = -1; -static struct termios orig_termios; -static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER; - - -int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) { - uv_handle_type type; - int flags; - int newfd; - int r; - - /* File descriptors that refer to files cannot be monitored with epoll. - * That restriction also applies to character devices like /dev/random - * (but obviously not /dev/tty.) - */ - type = uv_guess_handle(fd); - if (type == UV_FILE || type == UV_UNKNOWN_HANDLE) - return -EINVAL; - - flags = 0; - newfd = -1; - - /* Reopen the file descriptor when it refers to a tty. This lets us put the - * tty in non-blocking mode without affecting other processes that share it - * with us. - * - * Example: `node | cat` - if we put our fd 0 in non-blocking mode, it also - * affects fd 1 of `cat` because both file descriptors refer to the same - * struct file in the kernel. When we reopen our fd 0, it points to a - * different struct file, hence changing its properties doesn't affect - * other processes. - */ - if (type == UV_TTY) { - r = uv__open_cloexec("/dev/tty", O_RDWR); - - if (r < 0) { - /* fallback to using blocking writes */ - if (!readable) - flags |= UV_STREAM_BLOCKING; - goto skip; - } - - newfd = r; - - r = uv__dup2_cloexec(newfd, fd); - if (r < 0 && r != -EINVAL) { - /* EINVAL means newfd == fd which could conceivably happen if another - * thread called close(fd) between our calls to isatty() and open(). - * That's a rather unlikely event but let's handle it anyway. - */ - uv__close(newfd); - return r; - } - - fd = newfd; - } - -skip: - uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY); - - /* If anything fails beyond this point we need to remove the handle from - * the handle queue, since it was added by uv__handle_init in uv_stream_init. - */ - -#if defined(__APPLE__) - r = uv__stream_try_select((uv_stream_t*) tty, &fd); - if (r) { - if (newfd != -1) - uv__close(newfd); - QUEUE_REMOVE(&tty->handle_queue); - return r; - } -#endif - - if (readable) - flags |= UV_STREAM_READABLE; - else - flags |= UV_STREAM_WRITABLE; - - if (!(flags & UV_STREAM_BLOCKING)) - uv__nonblock(fd, 1); - - uv__stream_open((uv_stream_t*) tty, fd, flags); - tty->mode = UV_TTY_MODE_NORMAL; - - return 0; -} - -static void uv__tty_make_raw(struct termios* tio) { - assert(tio != NULL); - -#ifdef __sun - /* - * This implementation of cfmakeraw for Solaris and derivatives is taken from - * http://www.perkin.org.uk/posts/solaris-portability-cfmakeraw.html. - */ - tio->c_iflag &= ~(IMAXBEL | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | - IGNCR | ICRNL | IXON); - tio->c_oflag &= ~OPOST; - tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - tio->c_cflag &= ~(CSIZE | PARENB); - tio->c_cflag |= CS8; -#else - cfmakeraw(tio); -#endif /* #ifdef __sun */ -} - -int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { - struct termios tmp; - int fd; - - if (tty->mode == (int) mode) - return 0; - - fd = uv__stream_fd(tty); - if (tty->mode == UV_TTY_MODE_NORMAL && mode != UV_TTY_MODE_NORMAL) { - if (tcgetattr(fd, &tty->orig_termios)) - return -errno; - - /* This is used for uv_tty_reset_mode() */ - uv_spinlock_lock(&termios_spinlock); - if (orig_termios_fd == -1) { - orig_termios = tty->orig_termios; - orig_termios_fd = fd; - } - uv_spinlock_unlock(&termios_spinlock); - } - - tmp = tty->orig_termios; - switch (mode) { - case UV_TTY_MODE_NORMAL: - break; - case UV_TTY_MODE_RAW: - tmp.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - tmp.c_oflag |= (ONLCR); - tmp.c_cflag |= (CS8); - tmp.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); - tmp.c_cc[VMIN] = 1; - tmp.c_cc[VTIME] = 0; - break; - case UV_TTY_MODE_IO: - uv__tty_make_raw(&tmp); - break; - } - - /* Apply changes after draining */ - if (tcsetattr(fd, TCSADRAIN, &tmp)) - return -errno; - - tty->mode = mode; - return 0; -} - - -int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { - struct winsize ws; - - if (ioctl(uv__stream_fd(tty), TIOCGWINSZ, &ws)) - return -errno; - - *width = ws.ws_col; - *height = ws.ws_row; - - return 0; -} - - -uv_handle_type uv_guess_handle(uv_file file) { - struct sockaddr sa; - struct stat s; - socklen_t len; - int type; - - if (file < 0) - return UV_UNKNOWN_HANDLE; - - if (isatty(file)) - return UV_TTY; - - if (fstat(file, &s)) - return UV_UNKNOWN_HANDLE; - - if (S_ISREG(s.st_mode)) - return UV_FILE; - - if (S_ISCHR(s.st_mode)) - return UV_FILE; /* XXX UV_NAMED_PIPE? */ - - if (S_ISFIFO(s.st_mode)) - return UV_NAMED_PIPE; - - if (!S_ISSOCK(s.st_mode)) - return UV_UNKNOWN_HANDLE; - - len = sizeof(type); - if (getsockopt(file, SOL_SOCKET, SO_TYPE, &type, &len)) - return UV_UNKNOWN_HANDLE; - - len = sizeof(sa); - if (getsockname(file, &sa, &len)) - return UV_UNKNOWN_HANDLE; - - if (type == SOCK_DGRAM) - if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6) - return UV_UDP; - - if (type == SOCK_STREAM) { - if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6) - return UV_TCP; - if (sa.sa_family == AF_UNIX) - return UV_NAMED_PIPE; - } - - return UV_UNKNOWN_HANDLE; -} - - -/* This function is async signal-safe, meaning that it's safe to call from - * inside a signal handler _unless_ execution was inside uv_tty_set_mode()'s - * critical section when the signal was raised. - */ -int uv_tty_reset_mode(void) { - int saved_errno; - int err; - - saved_errno = errno; - if (!uv_spinlock_trylock(&termios_spinlock)) - return -EBUSY; /* In uv_tty_set_mode(). */ - - err = 0; - if (orig_termios_fd != -1) - if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios)) - err = -errno; - - uv_spinlock_unlock(&termios_spinlock); - errno = saved_errno; - - return err; -} diff --git a/outside/libuv-v1.7.5/src/unix/udp.c b/outside/libuv-v1.7.5/src/unix/udp.c deleted file mode 100644 index 66ecc4e341..0000000000 --- a/outside/libuv-v1.7.5/src/unix/udp.c +++ /dev/null @@ -1,871 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include - -#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP) -# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -#endif - -#if defined(IPV6_LEAVE_GROUP) && !defined(IPV6_DROP_MEMBERSHIP) -# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP -#endif - - -static void uv__udp_run_completed(uv_udp_t* handle); -static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents); -static void uv__udp_recvmsg(uv_udp_t* handle); -static void uv__udp_sendmsg(uv_udp_t* handle); -static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, - int domain, - unsigned int flags); - - -void uv__udp_close(uv_udp_t* handle) { - uv__io_close(handle->loop, &handle->io_watcher); - uv__handle_stop(handle); - - if (handle->io_watcher.fd != -1) { - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - } -} - - -void uv__udp_finish_close(uv_udp_t* handle) { - uv_udp_send_t* req; - QUEUE* q; - - assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT)); - assert(handle->io_watcher.fd == -1); - - while (!QUEUE_EMPTY(&handle->write_queue)) { - q = QUEUE_HEAD(&handle->write_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_udp_send_t, queue); - req->status = -ECANCELED; - QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue); - } - - uv__udp_run_completed(handle); - - assert(handle->send_queue_size == 0); - assert(handle->send_queue_count == 0); - - /* Now tear down the handle. */ - handle->recv_cb = NULL; - handle->alloc_cb = NULL; - /* but _do not_ touch close_cb */ -} - - -static void uv__udp_run_completed(uv_udp_t* handle) { - uv_udp_send_t* req; - QUEUE* q; - - assert(!(handle->flags & UV_UDP_PROCESSING)); - handle->flags |= UV_UDP_PROCESSING; - - while (!QUEUE_EMPTY(&handle->write_completed_queue)) { - q = QUEUE_HEAD(&handle->write_completed_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_udp_send_t, queue); - uv__req_unregister(handle->loop, req); - - handle->send_queue_size -= uv__count_bufs(req->bufs, req->nbufs); - handle->send_queue_count--; - - if (req->bufs != req->bufsml) - uv__free(req->bufs); - req->bufs = NULL; - - if (req->send_cb == NULL) - continue; - - /* req->status >= 0 == bytes written - * req->status < 0 == errno - */ - if (req->status >= 0) - req->send_cb(req, 0); - else - req->send_cb(req, req->status); - } - - if (QUEUE_EMPTY(&handle->write_queue)) { - /* Pending queue and completion queue empty, stop watcher. */ - uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLOUT); - if (!uv__io_active(&handle->io_watcher, UV__POLLIN)) - uv__handle_stop(handle); - } - - handle->flags &= ~UV_UDP_PROCESSING; -} - - -static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) { - uv_udp_t* handle; - - handle = container_of(w, uv_udp_t, io_watcher); - assert(handle->type == UV_UDP); - - if (revents & UV__POLLIN) - uv__udp_recvmsg(handle); - - if (revents & UV__POLLOUT) { - uv__udp_sendmsg(handle); - uv__udp_run_completed(handle); - } -} - - -static void uv__udp_recvmsg(uv_udp_t* handle) { - struct sockaddr_storage peer; - struct msghdr h; - ssize_t nread; - uv_buf_t buf; - int flags; - int count; - - assert(handle->recv_cb != NULL); - assert(handle->alloc_cb != NULL); - - /* Prevent loop starvation when the data comes in as fast as (or faster than) - * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. - */ - count = 32; - - memset(&h, 0, sizeof(h)); - h.msg_name = &peer; - - do { - handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf); - if (buf.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); - return; - } - assert(buf.base != NULL); - - h.msg_namelen = sizeof(peer); - h.msg_iov = (void*) &buf; - h.msg_iovlen = 1; - - do { - nread = recvmsg(handle->io_watcher.fd, &h, 0); - } - while (nread == -1 && errno == EINTR); - - if (nread == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - handle->recv_cb(handle, 0, &buf, NULL, 0); - else - handle->recv_cb(handle, -errno, &buf, NULL, 0); - } - else { - const struct sockaddr *addr; - if (h.msg_namelen == 0) - addr = NULL; - else - addr = (const struct sockaddr*) &peer; - - flags = 0; - if (h.msg_flags & MSG_TRUNC) - flags |= UV_UDP_PARTIAL; - - handle->recv_cb(handle, nread, &buf, addr, flags); - } - } - /* recv_cb callback may decide to pause or close the handle */ - while (nread != -1 - && count-- > 0 - && handle->io_watcher.fd != -1 - && handle->recv_cb != NULL); -} - - -static void uv__udp_sendmsg(uv_udp_t* handle) { - uv_udp_send_t* req; - QUEUE* q; - struct msghdr h; - ssize_t size; - - while (!QUEUE_EMPTY(&handle->write_queue)) { - q = QUEUE_HEAD(&handle->write_queue); - assert(q != NULL); - - req = QUEUE_DATA(q, uv_udp_send_t, queue); - assert(req != NULL); - - memset(&h, 0, sizeof h); - h.msg_name = &req->addr; - h.msg_namelen = (req->addr.ss_family == AF_INET6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); - h.msg_iov = (struct iovec*) req->bufs; - h.msg_iovlen = req->nbufs; - - do { - size = sendmsg(handle->io_watcher.fd, &h, 0); - } while (size == -1 && errno == EINTR); - - if (size == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) - break; - - req->status = (size == -1 ? -errno : size); - - /* Sending a datagram is an atomic operation: either all data - * is written or nothing is (and EMSGSIZE is raised). That is - * why we don't handle partial writes. Just pop the request - * off the write queue and onto the completed queue, done. - */ - QUEUE_REMOVE(&req->queue); - QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue); - uv__io_feed(handle->loop, &handle->io_watcher); - } -} - - -/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional - * refinements for programs that use multicast. - * - * Linux as of 3.9 has a SO_REUSEPORT socket option but with semantics that - * are different from the BSDs: it _shares_ the port rather than steal it - * from the current listener. While useful, it's not something we can emulate - * on other platforms so we don't enable it. - */ -static int uv__set_reuse(int fd) { - int yes; - -#if defined(SO_REUSEPORT) && !defined(__linux__) - yes = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) - return -errno; -#else - yes = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) - return -errno; -#endif - - return 0; -} - - -int uv__udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - int yes; - int fd; - - /* Check for bad flags. */ - if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR)) - return -EINVAL; - - /* Cannot set IPv6-only mode on non-IPv6 socket. */ - if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) - return -EINVAL; - - fd = handle->io_watcher.fd; - if (fd == -1) { - err = uv__socket(addr->sa_family, SOCK_DGRAM, 0); - if (err < 0) - return err; - fd = err; - handle->io_watcher.fd = fd; - } - - if (flags & UV_UDP_REUSEADDR) { - err = uv__set_reuse(fd); - if (err) - goto out; - } - - if (flags & UV_UDP_IPV6ONLY) { -#ifdef IPV6_V6ONLY - yes = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) { - err = -errno; - goto out; - } -#else - err = -ENOTSUP; - goto out; -#endif - } - - if (bind(fd, addr, addrlen)) { - err = -errno; - if (errno == EAFNOSUPPORT) - /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a - * socket created with AF_INET to an AF_INET6 address or vice versa. */ - err = -EINVAL; - goto out; - } - - if (addr->sa_family == AF_INET6) - handle->flags |= UV_HANDLE_IPV6; - - return 0; - -out: - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - return err; -} - - -static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, - int domain, - unsigned int flags) { - unsigned char taddr[sizeof(struct sockaddr_in6)]; - socklen_t addrlen; - - if (handle->io_watcher.fd != -1) - return 0; - - switch (domain) { - case AF_INET: - { - struct sockaddr_in* addr = (void*)&taddr; - memset(addr, 0, sizeof *addr); - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = INADDR_ANY; - addrlen = sizeof *addr; - break; - } - case AF_INET6: - { - struct sockaddr_in6* addr = (void*)&taddr; - memset(addr, 0, sizeof *addr); - addr->sin6_family = AF_INET6; - addr->sin6_addr = in6addr_any; - addrlen = sizeof *addr; - break; - } - default: - assert(0 && "unsupported address family"); - abort(); - } - - return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags); -} - - -int uv__udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb send_cb) { - int err; - int empty_queue; - - assert(nbufs > 0); - - err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0); - if (err) - return err; - - /* It's legal for send_queue_count > 0 even when the write_queue is empty; - * it means there are error-state requests in the write_completed_queue that - * will touch up send_queue_size/count later. - */ - empty_queue = (handle->send_queue_count == 0); - - uv__req_init(handle->loop, req, UV_UDP_SEND); - assert(addrlen <= sizeof(req->addr)); - memcpy(&req->addr, addr, addrlen); - req->send_cb = send_cb; - req->handle = handle; - req->nbufs = nbufs; - - req->bufs = req->bufsml; - if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = uv__malloc(nbufs * sizeof(bufs[0])); - - if (req->bufs == NULL) - return -ENOMEM; - - memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0])); - handle->send_queue_size += uv__count_bufs(req->bufs, req->nbufs); - handle->send_queue_count++; - QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue); - uv__handle_start(handle); - - if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) { - uv__udp_sendmsg(handle); - } else { - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); - } - - return 0; -} - - -int uv__udp_try_send(uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen) { - int err; - struct msghdr h; - ssize_t size; - - assert(nbufs > 0); - - /* already sending a message */ - if (handle->send_queue_count != 0) - return -EAGAIN; - - err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0); - if (err) - return err; - - memset(&h, 0, sizeof h); - h.msg_name = (struct sockaddr*) addr; - h.msg_namelen = addrlen; - h.msg_iov = (struct iovec*) bufs; - h.msg_iovlen = nbufs; - - do { - size = sendmsg(handle->io_watcher.fd, &h, 0); - } while (size == -1 && errno == EINTR); - - if (size == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - return -EAGAIN; - else - return -errno; - } - - return size; -} - - -static int uv__udp_set_membership4(uv_udp_t* handle, - const struct sockaddr_in* multicast_addr, - const char* interface_addr, - uv_membership membership) { - struct ip_mreq mreq; - int optname; - int err; - - memset(&mreq, 0, sizeof mreq); - - if (interface_addr) { - err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); - if (err) - return err; - } else { - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - } - - mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; - - switch (membership) { - case UV_JOIN_GROUP: - optname = IP_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IP_DROP_MEMBERSHIP; - break; - default: - return -EINVAL; - } - - if (setsockopt(handle->io_watcher.fd, - IPPROTO_IP, - optname, - &mreq, - sizeof(mreq))) { - return -errno; - } - - return 0; -} - - -static int uv__udp_set_membership6(uv_udp_t* handle, - const struct sockaddr_in6* multicast_addr, - const char* interface_addr, - uv_membership membership) { - int optname; - struct ipv6_mreq mreq; - struct sockaddr_in6 addr6; - - memset(&mreq, 0, sizeof mreq); - - if (interface_addr) { - if (uv_ip6_addr(interface_addr, 0, &addr6)) - return -EINVAL; - mreq.ipv6mr_interface = addr6.sin6_scope_id; - } else { - mreq.ipv6mr_interface = 0; - } - - mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr; - - switch (membership) { - case UV_JOIN_GROUP: - optname = IPV6_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IPV6_DROP_MEMBERSHIP; - break; - default: - return -EINVAL; - } - - if (setsockopt(handle->io_watcher.fd, - IPPROTO_IPV6, - optname, - &mreq, - sizeof(mreq))) { - return -errno; - } - - return 0; -} - - -int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { - int domain; - int err; - int fd; - - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return -EINVAL; - - if (flags & ~0xFF) - return -EINVAL; - - if (domain != AF_UNSPEC) { - err = uv__socket(domain, SOCK_DGRAM, 0); - if (err < 0) - return err; - fd = err; - } else { - fd = -1; - } - - uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP); - handle->alloc_cb = NULL; - handle->recv_cb = NULL; - handle->send_queue_size = 0; - handle->send_queue_count = 0; - uv__io_init(&handle->io_watcher, uv__udp_io, fd); - QUEUE_INIT(&handle->write_queue); - QUEUE_INIT(&handle->write_completed_queue); - return 0; -} - - -int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { - return uv_udp_init_ex(loop, handle, AF_UNSPEC); -} - - -int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { - int err; - - /* Check for already active socket. */ - if (handle->io_watcher.fd != -1) - return -EBUSY; - - err = uv__nonblock(sock, 1); - if (err) - return err; - - err = uv__set_reuse(sock); - if (err) - return err; - - handle->io_watcher.fd = sock; - return 0; -} - - -int uv_udp_set_membership(uv_udp_t* handle, - const char* multicast_addr, - const char* interface_addr, - uv_membership membership) { - int err; - struct sockaddr_in addr4; - struct sockaddr_in6 addr6; - - if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) { - err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR); - if (err) - return err; - return uv__udp_set_membership4(handle, &addr4, interface_addr, membership); - } else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) { - err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR); - if (err) - return err; - return uv__udp_set_membership6(handle, &addr6, interface_addr, membership); - } else { - return -EINVAL; - } -} - -static int uv__setsockopt(uv_udp_t* handle, - int option4, - int option6, - const void* val, - size_t size) { - int r; - - if (handle->flags & UV_HANDLE_IPV6) - r = setsockopt(handle->io_watcher.fd, - IPPROTO_IPV6, - option6, - val, - size); - else - r = setsockopt(handle->io_watcher.fd, - IPPROTO_IP, - option4, - val, - size); - if (r) - return -errno; - - return 0; -} - -static int uv__setsockopt_maybe_char(uv_udp_t* handle, - int option4, - int option6, - int val) { -#if defined(__sun) || defined(_AIX) - char arg = val; -#elif defined(__OpenBSD__) - unsigned char arg = val; -#else - int arg = val; -#endif - - if (val < 0 || val > 255) - return -EINVAL; - - return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg)); -} - - -int uv_udp_set_broadcast(uv_udp_t* handle, int on) { - if (setsockopt(handle->io_watcher.fd, - SOL_SOCKET, - SO_BROADCAST, - &on, - sizeof(on))) { - return -errno; - } - - return 0; -} - - -int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { - if (ttl < 1 || ttl > 255) - return -EINVAL; - -/* - * On Solaris and derivatives such as SmartOS, the length of socket options - * is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS, - * so hardcode the size of these options on this platform, - * and use the general uv__setsockopt_maybe_char call on other platforms. - */ -#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) - return uv__setsockopt(handle, - IP_TTL, - IPV6_UNICAST_HOPS, - &ttl, - sizeof(ttl)); -#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) */ - - return uv__setsockopt_maybe_char(handle, - IP_TTL, - IPV6_UNICAST_HOPS, - ttl); -} - - -int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { -/* - * On Solaris and derivatives such as SmartOS, the length of socket options - * is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for - * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case, - * and use the general uv__setsockopt_maybe_char call otherwise. - */ -#if defined(__sun) || defined(_AIX) - if (handle->flags & UV_HANDLE_IPV6) - return uv__setsockopt(handle, - IP_MULTICAST_TTL, - IPV6_MULTICAST_HOPS, - &ttl, - sizeof(ttl)); -#endif /* defined(__sun) || defined(_AIX) */ - - return uv__setsockopt_maybe_char(handle, - IP_MULTICAST_TTL, - IPV6_MULTICAST_HOPS, - ttl); -} - - -int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { -/* - * On Solaris and derivatives such as SmartOS, the length of socket options - * is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for - * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case, - * and use the general uv__setsockopt_maybe_char call otherwise. - */ -#if defined(__sun) || defined(_AIX) - if (handle->flags & UV_HANDLE_IPV6) - return uv__setsockopt(handle, - IP_MULTICAST_LOOP, - IPV6_MULTICAST_LOOP, - &on, - sizeof(on)); -#endif /* defined(__sun) || defined(_AIX) */ - - return uv__setsockopt_maybe_char(handle, - IP_MULTICAST_LOOP, - IPV6_MULTICAST_LOOP, - on); -} - -int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) { - struct sockaddr_storage addr_st; - struct sockaddr_in* addr4; - struct sockaddr_in6* addr6; - - addr4 = (struct sockaddr_in*) &addr_st; - addr6 = (struct sockaddr_in6*) &addr_st; - - if (!interface_addr) { - memset(&addr_st, 0, sizeof addr_st); - if (handle->flags & UV_HANDLE_IPV6) { - addr_st.ss_family = AF_INET6; - addr6->sin6_scope_id = 0; - } else { - addr_st.ss_family = AF_INET; - addr4->sin_addr.s_addr = htonl(INADDR_ANY); - } - } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) { - /* nothing, address was parsed */ - } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) { - /* nothing, address was parsed */ - } else { - return -EINVAL; - } - - if (addr_st.ss_family == AF_INET) { - if (setsockopt(handle->io_watcher.fd, - IPPROTO_IP, - IP_MULTICAST_IF, - (void*) &addr4->sin_addr, - sizeof(addr4->sin_addr)) == -1) { - return -errno; - } - } else if (addr_st.ss_family == AF_INET6) { - if (setsockopt(handle->io_watcher.fd, - IPPROTO_IPV6, - IPV6_MULTICAST_IF, - &addr6->sin6_scope_id, - sizeof(addr6->sin6_scope_id)) == -1) { - return -errno; - } - } else { - assert(0 && "unexpected address family"); - abort(); - } - - return 0; -} - - -int uv_udp_getsockname(const uv_udp_t* handle, - struct sockaddr* name, - int* namelen) { - socklen_t socklen; - - if (handle->io_watcher.fd == -1) - return -EINVAL; /* FIXME(bnoordhuis) -EBADF */ - - /* sizeof(socklen_t) != sizeof(int) on some systems. */ - socklen = (socklen_t) *namelen; - - if (getsockname(handle->io_watcher.fd, name, &socklen)) - return -errno; - - *namelen = (int) socklen; - return 0; -} - - -int uv__udp_recv_start(uv_udp_t* handle, - uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb) { - int err; - - if (alloc_cb == NULL || recv_cb == NULL) - return -EINVAL; - - if (uv__io_active(&handle->io_watcher, UV__POLLIN)) - return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */ - - err = uv__udp_maybe_deferred_bind(handle, AF_INET, 0); - if (err) - return err; - - handle->alloc_cb = alloc_cb; - handle->recv_cb = recv_cb; - - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN); - uv__handle_start(handle); - - return 0; -} - - -int uv__udp_recv_stop(uv_udp_t* handle) { - uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN); - - if (!uv__io_active(&handle->io_watcher, UV__POLLOUT)) - uv__handle_stop(handle); - - handle->alloc_cb = NULL; - handle->recv_cb = NULL; - - return 0; -} diff --git a/outside/libuv-v1.7.5/src/uv-common.c b/outside/libuv-v1.7.5/src/uv-common.c deleted file mode 100644 index 675a776bf4..0000000000 --- a/outside/libuv-v1.7.5/src/uv-common.c +++ /dev/null @@ -1,626 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "uv-common.h" - -#include -#include -#include -#include /* NULL */ -#include /* malloc */ -#include /* memset */ - -#if defined(_WIN32) -# include /* malloc */ -#else -# include /* if_nametoindex */ -#endif - - -typedef struct { - uv_malloc_func local_malloc; - uv_realloc_func local_realloc; - uv_calloc_func local_calloc; - uv_free_func local_free; -} uv__allocator_t; - -static uv__allocator_t uv__allocator = { - malloc, - realloc, - calloc, - free, -}; - -char* uv__strdup(const char* s) { - size_t len = strlen(s) + 1; - char* m = uv__malloc(len); - if (m == NULL) - return NULL; - return memcpy(m, s, len); -} - -char* uv__strndup(const char* s, size_t n) { - char* m; - size_t len = strlen(s); - if (n < len) - len = n; - m = uv__malloc(len + 1); - if (m == NULL) - return NULL; - m[len] = '\0'; - return memcpy(m, s, len); -} - -void* uv__malloc(size_t size) { - return uv__allocator.local_malloc(size); -} - -void uv__free(void* ptr) { - uv__allocator.local_free(ptr); -} - -void* uv__calloc(size_t count, size_t size) { - return uv__allocator.local_calloc(count, size); -} - -void* uv__realloc(void* ptr, size_t size) { - return uv__allocator.local_realloc(ptr, size); -} - -int uv_replace_allocator(uv_malloc_func malloc_func, - uv_realloc_func realloc_func, - uv_calloc_func calloc_func, - uv_free_func free_func) { - if (malloc_func == NULL || realloc_func == NULL || - calloc_func == NULL || free_func == NULL) { - return UV_EINVAL; - } - - uv__allocator.local_malloc = malloc_func; - uv__allocator.local_realloc = realloc_func; - uv__allocator.local_calloc = calloc_func; - uv__allocator.local_free = free_func; - - return 0; -} - -#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t); - -size_t uv_handle_size(uv_handle_type type) { - switch (type) { - UV_HANDLE_TYPE_MAP(XX) - default: - return -1; - } -} - -size_t uv_req_size(uv_req_type type) { - switch(type) { - UV_REQ_TYPE_MAP(XX) - default: - return -1; - } -} - -#undef XX - - -size_t uv_loop_size(void) { - return sizeof(uv_loop_t); -} - - -uv_buf_t uv_buf_init(char* base, unsigned int len) { - uv_buf_t buf; - buf.base = base; - buf.len = len; - return buf; -} - - -static const char* uv__unknown_err_code(int err) { - char buf[32]; - char* copy; - -#ifndef _WIN32 - snprintf(buf, sizeof(buf), "Unknown system error %d", err); -#else - _snprintf(buf, sizeof(buf), "Unknown system error %d", err); -#endif - copy = uv__strdup(buf); - - return copy != NULL ? copy : "Unknown system error"; -} - - -#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name; -const char* uv_err_name(int err) { - switch (err) { - UV_ERRNO_MAP(UV_ERR_NAME_GEN) - } - return uv__unknown_err_code(err); -} -#undef UV_ERR_NAME_GEN - - -#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg; -const char* uv_strerror(int err) { - switch (err) { - UV_ERRNO_MAP(UV_STRERROR_GEN) - } - return uv__unknown_err_code(err); -} -#undef UV_STRERROR_GEN - - -int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) { - memset(addr, 0, sizeof(*addr)); - addr->sin_family = AF_INET; - addr->sin_port = htons(port); - return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr)); -} - - -int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) { - char address_part[40]; - size_t address_part_size; - const char* zone_index; - - memset(addr, 0, sizeof(*addr)); - addr->sin6_family = AF_INET6; - addr->sin6_port = htons(port); - - zone_index = strchr(ip, '%'); - if (zone_index != NULL) { - address_part_size = zone_index - ip; - if (address_part_size >= sizeof(address_part)) - address_part_size = sizeof(address_part) - 1; - - memcpy(address_part, ip, address_part_size); - address_part[address_part_size] = '\0'; - ip = address_part; - - zone_index++; /* skip '%' */ - /* NOTE: unknown interface (id=0) is silently ignored */ -#ifdef _WIN32 - addr->sin6_scope_id = atoi(zone_index); -#else - addr->sin6_scope_id = if_nametoindex(zone_index); -#endif - } - - return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr); -} - - -int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) { - return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size); -} - - -int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) { - return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size); -} - - -int uv_tcp_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int flags) { - unsigned int addrlen; - - if (handle->type != UV_TCP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__tcp_bind(handle, addr, addrlen, flags); -} - - -int uv_udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int flags) { - unsigned int addrlen; - - if (handle->type != UV_UDP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__udp_bind(handle, addr, addrlen, flags); -} - - -int uv_tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - uv_connect_cb cb) { - unsigned int addrlen; - - if (handle->type != UV_TCP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__tcp_connect(req, handle, addr, addrlen, cb); -} - - -int uv_udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - uv_udp_send_cb send_cb) { - unsigned int addrlen; - - if (handle->type != UV_UDP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb); -} - - -int uv_udp_try_send(uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr) { - unsigned int addrlen; - - if (handle->type != UV_UDP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__udp_try_send(handle, bufs, nbufs, addr, addrlen); -} - - -int uv_udp_recv_start(uv_udp_t* handle, - uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb) { - if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL) - return UV_EINVAL; - else - return uv__udp_recv_start(handle, alloc_cb, recv_cb); -} - - -int uv_udp_recv_stop(uv_udp_t* handle) { - if (handle->type != UV_UDP) - return UV_EINVAL; - else - return uv__udp_recv_stop(handle); -} - - -void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) { - QUEUE* q; - uv_handle_t* h; - - QUEUE_FOREACH(q, &loop->handle_queue) { - h = QUEUE_DATA(q, uv_handle_t, handle_queue); - if (h->flags & UV__HANDLE_INTERNAL) continue; - walk_cb(h, arg); - } -} - - -#ifndef NDEBUG -static void uv__print_handles(uv_loop_t* loop, int only_active) { - const char* type; - QUEUE* q; - uv_handle_t* h; - - if (loop == NULL) - loop = uv_default_loop(); - - QUEUE_FOREACH(q, &loop->handle_queue) { - h = QUEUE_DATA(q, uv_handle_t, handle_queue); - - if (only_active && !uv__is_active(h)) - continue; - - switch (h->type) { -#define X(uc, lc) case UV_##uc: type = #lc; break; - UV_HANDLE_TYPE_MAP(X) -#undef X - default: type = ""; - } - - fprintf(stderr, - "[%c%c%c] %-8s %p\n", - "R-"[!(h->flags & UV__HANDLE_REF)], - "A-"[!(h->flags & UV__HANDLE_ACTIVE)], - "I-"[!(h->flags & UV__HANDLE_INTERNAL)], - type, - (void*)h); - } -} - - -void uv_print_all_handles(uv_loop_t* loop) { - uv__print_handles(loop, 0); -} - - -void uv_print_active_handles(uv_loop_t* loop) { - uv__print_handles(loop, 1); -} -#endif - - -void uv_ref(uv_handle_t* handle) { - uv__handle_ref(handle); -} - - -void uv_unref(uv_handle_t* handle) { - uv__handle_unref(handle); -} - - -int uv_has_ref(const uv_handle_t* handle) { - return uv__has_ref(handle); -} - - -void uv_stop(uv_loop_t* loop) { - loop->stop_flag = 1; -} - - -uint64_t uv_now(const uv_loop_t* loop) { - return loop->time; -} - - - -size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) { - unsigned int i; - size_t bytes; - - bytes = 0; - for (i = 0; i < nbufs; i++) - bytes += (size_t) bufs[i].len; - - return bytes; -} - -int uv_recv_buffer_size(uv_handle_t* handle, int* value) { - return uv__socket_sockopt(handle, SO_RCVBUF, value); -} - -int uv_send_buffer_size(uv_handle_t* handle, int *value) { - return uv__socket_sockopt(handle, SO_SNDBUF, value); -} - -int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) { - size_t required_len; - - if (!uv__is_active(handle)) { - *size = 0; - return UV_EINVAL; - } - - required_len = strlen(handle->path); - if (required_len > *size) { - *size = required_len; - return UV_ENOBUFS; - } - - memcpy(buffer, handle->path, required_len); - *size = required_len; - - return 0; -} - -/* The windows implementation does not have the same structure layout as - * the unix implementation (nbufs is not directly inside req but is - * contained in a nested union/struct) so this function locates it. -*/ -static unsigned int* uv__get_nbufs(uv_fs_t* req) { -#ifdef _WIN32 - return &req->fs.info.nbufs; -#else - return &req->nbufs; -#endif -} - -void uv__fs_scandir_cleanup(uv_fs_t* req) { - uv__dirent_t** dents; - - unsigned int* nbufs = uv__get_nbufs(req); - - dents = req->ptr; - if (*nbufs > 0 && *nbufs != (unsigned int) req->result) - (*nbufs)--; - for (; *nbufs < (unsigned int) req->result; (*nbufs)++) - uv__free(dents[*nbufs]); -} - - -int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) { - uv__dirent_t** dents; - uv__dirent_t* dent; - - unsigned int* nbufs = uv__get_nbufs(req); - - dents = req->ptr; - - /* Free previous entity */ - if (*nbufs > 0) - uv__free(dents[*nbufs - 1]); - - /* End was already reached */ - if (*nbufs == (unsigned int) req->result) { - uv__free(dents); - req->ptr = NULL; - return UV_EOF; - } - - dent = dents[(*nbufs)++]; - - ent->name = dent->d_name; -#ifdef HAVE_DIRENT_TYPES - switch (dent->d_type) { - case UV__DT_DIR: - ent->type = UV_DIRENT_DIR; - break; - case UV__DT_FILE: - ent->type = UV_DIRENT_FILE; - break; - case UV__DT_LINK: - ent->type = UV_DIRENT_LINK; - break; - case UV__DT_FIFO: - ent->type = UV_DIRENT_FIFO; - break; - case UV__DT_SOCKET: - ent->type = UV_DIRENT_SOCKET; - break; - case UV__DT_CHAR: - ent->type = UV_DIRENT_CHAR; - break; - case UV__DT_BLOCK: - ent->type = UV_DIRENT_BLOCK; - break; - default: - ent->type = UV_DIRENT_UNKNOWN; - } -#else - ent->type = UV_DIRENT_UNKNOWN; -#endif - - return 0; -} - - -int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) { - va_list ap; - int err; - - va_start(ap, option); - /* Any platform-agnostic options should be handled here. */ - err = uv__loop_configure(loop, option, ap); - va_end(ap); - - return err; -} - - -static uv_loop_t default_loop_struct; -static uv_loop_t* default_loop_ptr; - - -uv_loop_t* uv_default_loop(void) { - if (default_loop_ptr != NULL) - return default_loop_ptr; - - if (uv_loop_init(&default_loop_struct)) - return NULL; - - default_loop_ptr = &default_loop_struct; - return default_loop_ptr; -} - - -uv_loop_t* uv_loop_new(void) { - uv_loop_t* loop; - - loop = uv__malloc(sizeof(*loop)); - if (loop == NULL) - return NULL; - - if (uv_loop_init(loop)) { - uv__free(loop); - return NULL; - } - - return loop; -} - - -int uv_loop_close(uv_loop_t* loop) { - QUEUE* q; - uv_handle_t* h; - - if (!QUEUE_EMPTY(&(loop)->active_reqs)) - return UV_EBUSY; - - QUEUE_FOREACH(q, &loop->handle_queue) { - h = QUEUE_DATA(q, uv_handle_t, handle_queue); - if (!(h->flags & UV__HANDLE_INTERNAL)) - return UV_EBUSY; - } - - uv__loop_close(loop); - -#ifndef NDEBUG - memset(loop, -1, sizeof(*loop)); -#endif - if (loop == default_loop_ptr) - default_loop_ptr = NULL; - - return 0; -} - - -void uv_loop_delete(uv_loop_t* loop) { - uv_loop_t* default_loop; - int err; - - default_loop = default_loop_ptr; - - err = uv_loop_close(loop); - (void) err; /* Squelch compiler warnings. */ - assert(err == 0); - if (loop != default_loop) - uv__free(loop); -} diff --git a/outside/libuv-v1.7.5/src/uv-common.h b/outside/libuv-v1.7.5/src/uv-common.h deleted file mode 100644 index b348ec76bd..0000000000 --- a/outside/libuv-v1.7.5/src/uv-common.h +++ /dev/null @@ -1,223 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* - * This file is private to libuv. It provides common functionality to both - * Windows and Unix backends. - */ - -#ifndef UV_COMMON_H_ -#define UV_COMMON_H_ - -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include -#endif - -#include "uv.h" -#include "tree.h" -#include "queue.h" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -#define container_of(ptr, type, member) \ - ((type *) ((char *) (ptr) - offsetof(type, member))) - -#define STATIC_ASSERT(expr) \ - void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)]) - -#ifndef _WIN32 -enum { - UV__HANDLE_INTERNAL = 0x8000, - UV__HANDLE_ACTIVE = 0x4000, - UV__HANDLE_REF = 0x2000, - UV__HANDLE_CLOSING = 0 /* no-op on unix */ -}; -#else -# define UV__HANDLE_INTERNAL 0x80 -# define UV__HANDLE_ACTIVE 0x40 -# define UV__HANDLE_REF 0x20 -# define UV__HANDLE_CLOSING 0x01 -#endif - -int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap); - -void uv__loop_close(uv_loop_t* loop); - -int uv__tcp_bind(uv_tcp_t* tcp, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags); - -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb); - -int uv__udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags); - -int uv__udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb send_cb); - -int uv__udp_try_send(uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen); - -int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb, - uv_udp_recv_cb recv_cb); - -int uv__udp_recv_stop(uv_udp_t* handle); - -void uv__fs_poll_close(uv_fs_poll_t* handle); - -int uv__getaddrinfo_translate_error(int sys_err); /* EAI_* error. */ - -void uv__work_submit(uv_loop_t* loop, - struct uv__work *w, - void (*work)(struct uv__work *w), - void (*done)(struct uv__work *w, int status)); - -void uv__work_done(uv_async_t* handle); - -size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs); - -int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value); - -void uv__fs_scandir_cleanup(uv_fs_t* req); - -#define uv__has_active_reqs(loop) \ - (QUEUE_EMPTY(&(loop)->active_reqs) == 0) - -#define uv__req_register(loop, req) \ - do { \ - QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue); \ - } \ - while (0) - -#define uv__req_unregister(loop, req) \ - do { \ - assert(uv__has_active_reqs(loop)); \ - QUEUE_REMOVE(&(req)->active_queue); \ - } \ - while (0) - -#define uv__has_active_handles(loop) \ - ((loop)->active_handles > 0) - -#define uv__active_handle_add(h) \ - do { \ - (h)->loop->active_handles++; \ - } \ - while (0) - -#define uv__active_handle_rm(h) \ - do { \ - (h)->loop->active_handles--; \ - } \ - while (0) - -#define uv__is_active(h) \ - (((h)->flags & UV__HANDLE_ACTIVE) != 0) - -#define uv__is_closing(h) \ - (((h)->flags & (UV_CLOSING | UV_CLOSED)) != 0) - -#define uv__handle_start(h) \ - do { \ - assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \ - if (((h)->flags & UV__HANDLE_ACTIVE) != 0) break; \ - (h)->flags |= UV__HANDLE_ACTIVE; \ - if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_add(h); \ - } \ - while (0) - -#define uv__handle_stop(h) \ - do { \ - assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \ - if (((h)->flags & UV__HANDLE_ACTIVE) == 0) break; \ - (h)->flags &= ~UV__HANDLE_ACTIVE; \ - if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_rm(h); \ - } \ - while (0) - -#define uv__handle_ref(h) \ - do { \ - if (((h)->flags & UV__HANDLE_REF) != 0) break; \ - (h)->flags |= UV__HANDLE_REF; \ - if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \ - if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_add(h); \ - } \ - while (0) - -#define uv__handle_unref(h) \ - do { \ - if (((h)->flags & UV__HANDLE_REF) == 0) break; \ - (h)->flags &= ~UV__HANDLE_REF; \ - if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \ - if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_rm(h); \ - } \ - while (0) - -#define uv__has_ref(h) \ - (((h)->flags & UV__HANDLE_REF) != 0) - -#if defined(_WIN32) -# define uv__handle_platform_init(h) ((h)->u.fd = -1) -#else -# define uv__handle_platform_init(h) ((h)->next_closing = NULL) -#endif - -#define uv__handle_init(loop_, h, type_) \ - do { \ - (h)->loop = (loop_); \ - (h)->type = (type_); \ - (h)->flags = UV__HANDLE_REF; /* Ref the loop when active. */ \ - QUEUE_INSERT_TAIL(&(loop_)->handle_queue, &(h)->handle_queue); \ - uv__handle_platform_init(h); \ - } \ - while (0) - - -/* Allocator prototypes */ -void *uv__calloc(size_t count, size_t size); -char *uv__strdup(const char* s); -char *uv__strndup(const char* s, size_t n); -void* uv__malloc(size_t size); -void uv__free(void* ptr); -void* uv__realloc(void* ptr, size_t size); - -#endif /* UV_COMMON_H_ */ diff --git a/outside/libuv-v1.7.5/src/version.c b/outside/libuv-v1.7.5/src/version.c deleted file mode 100644 index 686dedd98d..0000000000 --- a/outside/libuv-v1.7.5/src/version.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" - -#define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v) -#define UV_STRINGIFY_HELPER(v) #v - -#define UV_VERSION_STRING_BASE UV_STRINGIFY(UV_VERSION_MAJOR) "." \ - UV_STRINGIFY(UV_VERSION_MINOR) "." \ - UV_STRINGIFY(UV_VERSION_PATCH) - -#if UV_VERSION_IS_RELEASE -# define UV_VERSION_STRING UV_VERSION_STRING_BASE -#else -# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-" UV_VERSION_SUFFIX -#endif - - -unsigned int uv_version(void) { - return UV_VERSION_HEX; -} - - -const char* uv_version_string(void) { - return UV_VERSION_STRING; -} diff --git a/outside/libuv-v1.7.5/src/win/async.c b/outside/libuv-v1.7.5/src/win/async.c deleted file mode 100644 index ad240ab897..0000000000 --- a/outside/libuv-v1.7.5/src/win/async.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "uv.h" -#include "internal.h" -#include "atomicops-inl.h" -#include "handle-inl.h" -#include "req-inl.h" - - -void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING && - !handle->async_sent) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { - uv_req_t* req; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC); - handle->async_sent = 0; - handle->async_cb = async_cb; - - req = &handle->async_req; - uv_req_init(loop, req); - req->type = UV_WAKEUP; - req->data = handle; - - uv__handle_start(handle); - - return 0; -} - - -void uv_async_close(uv_loop_t* loop, uv_async_t* handle) { - if (!((uv_async_t*)handle)->async_sent) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - uv__handle_closing(handle); -} - - -int uv_async_send(uv_async_t* handle) { - uv_loop_t* loop = handle->loop; - - if (handle->type != UV_ASYNC) { - /* Can't set errno because that's not thread-safe. */ - return -1; - } - - /* The user should make sure never to call uv_async_send to a closing */ - /* or closed handle. */ - assert(!(handle->flags & UV__HANDLE_CLOSING)); - - if (!uv__atomic_exchange_set(&handle->async_sent)) { - POST_COMPLETION_FOR_REQ(loop, &handle->async_req); - } - - return 0; -} - - -void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, - uv_req_t* req) { - assert(handle->type == UV_ASYNC); - assert(req->type == UV_WAKEUP); - - handle->async_sent = 0; - - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } else if (handle->async_cb != NULL) { - handle->async_cb(handle); - } -} diff --git a/outside/libuv-v1.7.5/src/win/atomicops-inl.h b/outside/libuv-v1.7.5/src/win/atomicops-inl.h deleted file mode 100644 index 61e006026c..0000000000 --- a/outside/libuv-v1.7.5/src/win/atomicops-inl.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_ATOMICOPS_INL_H_ -#define UV_WIN_ATOMICOPS_INL_H_ - -#include "uv.h" - - -/* Atomic set operation on char */ -#ifdef _MSC_VER /* MSVC */ - -/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */ -/* efficient than InterlockedExchange, but InterlockedExchange8 does not */ -/* exist, and interlocked operations on larger targets might require the */ -/* target to be aligned. */ -#pragma intrinsic(_InterlockedOr8) - -static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) { - return _InterlockedOr8(target, 1); -} - -#else /* GCC */ - -/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ -static inline char uv__atomic_exchange_set(char volatile* target) { - const char one = 1; - char old_value; - __asm__ __volatile__ ("lock xchgb %0, %1\n\t" - : "=r"(old_value), "=m"(*target) - : "0"(one), "m"(*target) - : "memory"); - return old_value; -} - -#endif - -#endif /* UV_WIN_ATOMICOPS_INL_H_ */ diff --git a/outside/libuv-v1.7.5/src/win/core.c b/outside/libuv-v1.7.5/src/win/core.c deleted file mode 100644 index de0483e102..0000000000 --- a/outside/libuv-v1.7.5/src/win/core.c +++ /dev/null @@ -1,457 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) -#include -#endif - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -static uv_loop_t default_loop_struct; -static uv_loop_t* default_loop_ptr; - -/* uv_once initialization guards */ -static uv_once_t uv_init_guard_ = UV_ONCE_INIT; - - -#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)) -/* Our crt debug report handler allows us to temporarily disable asserts - * just for the current thread. - */ - -UV_THREAD_LOCAL int uv__crt_assert_enabled = TRUE; - -static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) { - if (uv__crt_assert_enabled || report_type != _CRT_ASSERT) - return FALSE; - - if (ret_val) { - /* Set ret_val to 0 to continue with normal execution. - * Set ret_val to 1 to trigger a breakpoint. - */ - - if(IsDebuggerPresent()) - *ret_val = 1; - else - *ret_val = 0; - } - - /* Don't call _CrtDbgReport. */ - return TRUE; -} -#else -UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE; -#endif - - -#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800 -static void uv__crt_invalid_parameter_handler(const wchar_t* expression, - const wchar_t* function, const wchar_t * file, unsigned int line, - uintptr_t reserved) { - /* No-op. */ -} -#endif - - -static void uv_init(void) { - /* Tell Windows that we will handle critical errors. */ - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); - - /* Tell the CRT to not exit the application when an invalid parameter is - * passed. The main issue is that invalid FDs will trigger this behavior. - */ -#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800 - _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler); -#endif - - /* We also need to setup our debug report handler because some CRT - * functions (eg _get_osfhandle) raise an assert when called with invalid - * FDs even though they return the proper error code in the release build. - */ -#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)) - _CrtSetReportHook(uv__crt_dbg_report_handler); -#endif - - /* Fetch winapi function pointers. This must be done first because other - * initialization code might need these function pointers to be loaded. - */ - uv_winapi_init(); - - /* Initialize winsock */ - uv_winsock_init(); - - /* Initialize FS */ - uv_fs_init(); - - /* Initialize signal stuff */ - uv_signals_init(); - - /* Initialize console */ - uv_console_init(); - - /* Initialize utilities */ - uv__util_init(); -} - - -int uv_loop_init(uv_loop_t* loop) { - int err; - - /* Initialize libuv itself first */ - uv__once_init(); - - /* Create an I/O completion port */ - loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); - if (loop->iocp == NULL) - return uv_translate_sys_error(GetLastError()); - - /* To prevent uninitialized memory access, loop->time must be initialized - * to zero before calling uv_update_time for the first time. - */ - loop->time = 0; - uv_update_time(loop); - - QUEUE_INIT(&loop->wq); - QUEUE_INIT(&loop->handle_queue); - QUEUE_INIT(&loop->active_reqs); - loop->active_handles = 0; - - loop->pending_reqs_tail = NULL; - - loop->endgame_handles = NULL; - - RB_INIT(&loop->timers); - - loop->check_handles = NULL; - loop->prepare_handles = NULL; - loop->idle_handles = NULL; - - loop->next_prepare_handle = NULL; - loop->next_check_handle = NULL; - loop->next_idle_handle = NULL; - - memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); - - loop->active_tcp_streams = 0; - loop->active_udp_streams = 0; - - loop->timer_counter = 0; - loop->stop_flag = 0; - - err = uv_mutex_init(&loop->wq_mutex); - if (err) - goto fail_mutex_init; - - err = uv_async_init(loop, &loop->wq_async, uv__work_done); - if (err) - goto fail_async_init; - - uv__handle_unref(&loop->wq_async); - loop->wq_async.flags |= UV__HANDLE_INTERNAL; - - return 0; - -fail_async_init: - uv_mutex_destroy(&loop->wq_mutex); - -fail_mutex_init: - CloseHandle(loop->iocp); - loop->iocp = INVALID_HANDLE_VALUE; - - return err; -} - - -void uv__once_init(void) { - uv_once(&uv_init_guard_, uv_init); -} - - -void uv__loop_close(uv_loop_t* loop) { - size_t i; - - /* close the async handle without needing an extra loop iteration */ - assert(!loop->wq_async.async_sent); - loop->wq_async.close_cb = NULL; - uv__handle_closing(&loop->wq_async); - uv__handle_close(&loop->wq_async); - - for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) { - SOCKET sock = loop->poll_peer_sockets[i]; - if (sock != 0 && sock != INVALID_SOCKET) - closesocket(sock); - } - - uv_mutex_lock(&loop->wq_mutex); - assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!"); - assert(!uv__has_active_reqs(loop)); - uv_mutex_unlock(&loop->wq_mutex); - uv_mutex_destroy(&loop->wq_mutex); - - CloseHandle(loop->iocp); -} - - -int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { - return UV_ENOSYS; -} - - -int uv_backend_fd(const uv_loop_t* loop) { - return -1; -} - - -int uv_backend_timeout(const uv_loop_t* loop) { - if (loop->stop_flag != 0) - return 0; - - if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) - return 0; - - if (loop->pending_reqs_tail) - return 0; - - if (loop->endgame_handles) - return 0; - - if (loop->idle_handles) - return 0; - - return uv__next_timeout(loop); -} - - -static void uv_poll(uv_loop_t* loop, DWORD timeout) { - DWORD bytes; - ULONG_PTR key; - OVERLAPPED* overlapped; - uv_req_t* req; - - GetQueuedCompletionStatus(loop->iocp, - &bytes, - &key, - &overlapped, - timeout); - - if (overlapped) { - /* Package was dequeued */ - req = uv_overlapped_to_req(overlapped); - uv_insert_pending_req(loop, req); - - /* Some time might have passed waiting for I/O, - * so update the loop time here. - */ - uv_update_time(loop); - } else if (GetLastError() != WAIT_TIMEOUT) { - /* Serious error */ - uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus"); - } else if (timeout > 0) { - /* GetQueuedCompletionStatus can occasionally return a little early. - * Make sure that the desired timeout is reflected in the loop time. - */ - uv__time_forward(loop, timeout); - } -} - - -static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) { - BOOL success; - uv_req_t* req; - OVERLAPPED_ENTRY overlappeds[128]; - ULONG count; - ULONG i; - - success = pGetQueuedCompletionStatusEx(loop->iocp, - overlappeds, - ARRAY_SIZE(overlappeds), - &count, - timeout, - FALSE); - - if (success) { - for (i = 0; i < count; i++) { - /* Package was dequeued */ - req = uv_overlapped_to_req(overlappeds[i].lpOverlapped); - uv_insert_pending_req(loop, req); - } - - /* Some time might have passed waiting for I/O, - * so update the loop time here. - */ - uv_update_time(loop); - } else if (GetLastError() != WAIT_TIMEOUT) { - /* Serious error */ - uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx"); - } else if (timeout > 0) { - /* GetQueuedCompletionStatus can occasionally return a little early. - * Make sure that the desired timeout is reflected in the loop time. - */ - uv__time_forward(loop, timeout); - } -} - - -static int uv__loop_alive(const uv_loop_t* loop) { - return loop->active_handles > 0 || - !QUEUE_EMPTY(&loop->active_reqs) || - loop->endgame_handles != NULL; -} - - -int uv_loop_alive(const uv_loop_t* loop) { - return uv__loop_alive(loop); -} - - -int uv_run(uv_loop_t *loop, uv_run_mode mode) { - DWORD timeout; - int r; - int ran_pending; - void (*poll)(uv_loop_t* loop, DWORD timeout); - - if (pGetQueuedCompletionStatusEx) - poll = &uv_poll_ex; - else - poll = &uv_poll; - - r = uv__loop_alive(loop); - if (!r) - uv_update_time(loop); - - while (r != 0 && loop->stop_flag == 0) { - uv_update_time(loop); - uv_process_timers(loop); - - ran_pending = uv_process_reqs(loop); - uv_idle_invoke(loop); - uv_prepare_invoke(loop); - - timeout = 0; - if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) - timeout = uv_backend_timeout(loop); - - (*poll)(loop, timeout); - - uv_check_invoke(loop); - uv_process_endgames(loop); - - if (mode == UV_RUN_ONCE) { - /* UV_RUN_ONCE implies forward progress: at least one callback must have - * been invoked when it returns. uv__io_poll() can return without doing - * I/O (meaning: no callbacks) when its timeout expires - which means we - * have pending timers that satisfy the forward progress constraint. - * - * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from - * the check. - */ - uv_process_timers(loop); - } - - r = uv__loop_alive(loop); - if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT) - break; - } - - /* The if statement lets the compiler compile it to a conditional store. - * Avoids dirtying a cache line. - */ - if (loop->stop_flag != 0) - loop->stop_flag = 0; - - return r; -} - - -int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { - uv_os_fd_t fd_out; - - switch (handle->type) { - case UV_TCP: - fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket; - break; - - case UV_NAMED_PIPE: - fd_out = ((uv_pipe_t*) handle)->handle; - break; - - case UV_TTY: - fd_out = ((uv_tty_t*) handle)->handle; - break; - - case UV_UDP: - fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket; - break; - - case UV_POLL: - fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket; - break; - - default: - return UV_EINVAL; - } - - if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE) - return UV_EBADF; - - *fd = fd_out; - return 0; -} - - -int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) { - int r; - int len; - SOCKET socket; - - if (handle == NULL || value == NULL) - return UV_EINVAL; - - if (handle->type == UV_TCP) - socket = ((uv_tcp_t*) handle)->socket; - else if (handle->type == UV_UDP) - socket = ((uv_udp_t*) handle)->socket; - else - return UV_ENOTSUP; - - len = sizeof(*value); - - if (*value == 0) - r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len); - else - r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len); - - if (r == SOCKET_ERROR) - return uv_translate_sys_error(WSAGetLastError()); - - return 0; -} diff --git a/outside/libuv-v1.7.5/src/win/dl.c b/outside/libuv-v1.7.5/src/win/dl.c deleted file mode 100644 index e5f3407f8e..0000000000 --- a/outside/libuv-v1.7.5/src/win/dl.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "internal.h" - -static int uv__dlerror(uv_lib_t* lib, int errorno); - - -int uv_dlopen(const char* filename, uv_lib_t* lib) { - WCHAR filename_w[32768]; - - lib->handle = NULL; - lib->errmsg = NULL; - - if (!uv_utf8_to_utf16(filename, filename_w, ARRAY_SIZE(filename_w))) { - return uv__dlerror(lib, GetLastError()); - } - - lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if (lib->handle == NULL) { - return uv__dlerror(lib, GetLastError()); - } - - return 0; -} - - -void uv_dlclose(uv_lib_t* lib) { - if (lib->errmsg) { - LocalFree((void*)lib->errmsg); - lib->errmsg = NULL; - } - - if (lib->handle) { - /* Ignore errors. No good way to signal them without leaking memory. */ - FreeLibrary(lib->handle); - lib->handle = NULL; - } -} - - -int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { - *ptr = (void*) GetProcAddress(lib->handle, name); - return uv__dlerror(lib, *ptr ? 0 : GetLastError()); -} - - -const char* uv_dlerror(const uv_lib_t* lib) { - return lib->errmsg ? lib->errmsg : "no error"; -} - - -static void uv__format_fallback_error(uv_lib_t* lib, int errorno){ - DWORD_PTR args[1] = { (DWORD_PTR) errorno }; - LPSTR fallback_error = "error: %1!d!"; - - FormatMessageA(FORMAT_MESSAGE_FROM_STRING | - FORMAT_MESSAGE_ARGUMENT_ARRAY | - FORMAT_MESSAGE_ALLOCATE_BUFFER, - fallback_error, 0, 0, - (LPSTR) &lib->errmsg, - 0, (va_list*) args); -} - - - -static int uv__dlerror(uv_lib_t* lib, int errorno) { - DWORD res; - - if (lib->errmsg) { - LocalFree((void*)lib->errmsg); - lib->errmsg = NULL; - } - - if (errorno) { - res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPSTR) &lib->errmsg, 0, NULL); - if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) { - res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - 0, (LPSTR) &lib->errmsg, 0, NULL); - } - - if (!res) { - uv__format_fallback_error(lib, errorno); - } - } - - return errorno ? -1 : 0; -} diff --git a/outside/libuv-v1.7.5/src/win/error.c b/outside/libuv-v1.7.5/src/win/error.c deleted file mode 100644 index a265a272dc..0000000000 --- a/outside/libuv-v1.7.5/src/win/error.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#include "uv.h" -#include "internal.h" - - -/* - * Display an error message and abort the event loop. - */ -void uv_fatal_error(const int errorno, const char* syscall) { - char* buf = NULL; - const char* errmsg; - - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL); - - if (buf) { - errmsg = buf; - } else { - errmsg = "Unknown error"; - } - - /* FormatMessage messages include a newline character already, */ - /* so don't add another. */ - if (syscall) { - fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg); - } else { - fprintf(stderr, "(%d) %s", errorno, errmsg); - } - - if (buf) { - LocalFree(buf); - } - - *((char*)NULL) = 0xff; /* Force debug break */ - abort(); -} - - -int uv_translate_sys_error(int sys_errno) { - if (sys_errno <= 0) { - return sys_errno; /* If < 0 then it's already a libuv error. */ - } - - switch (sys_errno) { - case ERROR_NOACCESS: return UV_EACCES; - case WSAEACCES: return UV_EACCES; - case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE; - case WSAEADDRINUSE: return UV_EADDRINUSE; - case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL; - case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT; - case WSAEWOULDBLOCK: return UV_EAGAIN; - case WSAEALREADY: return UV_EALREADY; - case ERROR_INVALID_FLAGS: return UV_EBADF; - case ERROR_INVALID_HANDLE: return UV_EBADF; - case ERROR_LOCK_VIOLATION: return UV_EBUSY; - case ERROR_PIPE_BUSY: return UV_EBUSY; - case ERROR_SHARING_VIOLATION: return UV_EBUSY; - case ERROR_OPERATION_ABORTED: return UV_ECANCELED; - case WSAEINTR: return UV_ECANCELED; - case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET; - case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED; - case WSAECONNABORTED: return UV_ECONNABORTED; - case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED; - case WSAECONNREFUSED: return UV_ECONNREFUSED; - case ERROR_NETNAME_DELETED: return UV_ECONNRESET; - case WSAECONNRESET: return UV_ECONNRESET; - case ERROR_ALREADY_EXISTS: return UV_EEXIST; - case ERROR_FILE_EXISTS: return UV_EEXIST; - case ERROR_BUFFER_OVERFLOW: return UV_EFAULT; - case WSAEFAULT: return UV_EFAULT; - case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH; - case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; - case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL; - case ERROR_INVALID_DATA: return UV_EINVAL; - case ERROR_INVALID_PARAMETER: return UV_EINVAL; - case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL; - case WSAEINVAL: return UV_EINVAL; - case WSAEPFNOSUPPORT: return UV_EINVAL; - case WSAESOCKTNOSUPPORT: return UV_EINVAL; - case ERROR_BEGINNING_OF_MEDIA: return UV_EIO; - case ERROR_BUS_RESET: return UV_EIO; - case ERROR_CRC: return UV_EIO; - case ERROR_DEVICE_DOOR_OPEN: return UV_EIO; - case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO; - case ERROR_DISK_CORRUPT: return UV_EIO; - case ERROR_EOM_OVERFLOW: return UV_EIO; - case ERROR_FILEMARK_DETECTED: return UV_EIO; - case ERROR_GEN_FAILURE: return UV_EIO; - case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO; - case ERROR_IO_DEVICE: return UV_EIO; - case ERROR_NO_DATA_DETECTED: return UV_EIO; - case ERROR_NO_SIGNAL_SENT: return UV_EIO; - case ERROR_OPEN_FAILED: return UV_EIO; - case ERROR_SETMARK_DETECTED: return UV_EIO; - case ERROR_SIGNAL_REFUSED: return UV_EIO; - case WSAEISCONN: return UV_EISCONN; - case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP; - case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; - case WSAEMFILE: return UV_EMFILE; - case WSAEMSGSIZE: return UV_EMSGSIZE; - case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG; - case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH; - case WSAENETUNREACH: return UV_ENETUNREACH; - case WSAENOBUFS: return UV_ENOBUFS; - case ERROR_DIRECTORY: return UV_ENOENT; - case ERROR_FILE_NOT_FOUND: return UV_ENOENT; - case ERROR_INVALID_NAME: return UV_ENOENT; - case ERROR_INVALID_DRIVE: return UV_ENOENT; - case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT; - case ERROR_MOD_NOT_FOUND: return UV_ENOENT; - case ERROR_PATH_NOT_FOUND: return UV_ENOENT; - case WSAHOST_NOT_FOUND: return UV_ENOENT; - case WSANO_DATA: return UV_ENOENT; - case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM; - case ERROR_OUTOFMEMORY: return UV_ENOMEM; - case ERROR_CANNOT_MAKE: return UV_ENOSPC; - case ERROR_DISK_FULL: return UV_ENOSPC; - case ERROR_EA_TABLE_FULL: return UV_ENOSPC; - case ERROR_END_OF_MEDIA: return UV_ENOSPC; - case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC; - case ERROR_NOT_CONNECTED: return UV_ENOTCONN; - case WSAENOTCONN: return UV_ENOTCONN; - case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY; - case WSAENOTSOCK: return UV_ENOTSOCK; - case ERROR_NOT_SUPPORTED: return UV_ENOTSUP; - case ERROR_BROKEN_PIPE: return UV_EOF; - case ERROR_ACCESS_DENIED: return UV_EPERM; - case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM; - case ERROR_BAD_PIPE: return UV_EPIPE; - case ERROR_NO_DATA: return UV_EPIPE; - case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE; - case WSAESHUTDOWN: return UV_EPIPE; - case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT; - case ERROR_WRITE_PROTECT: return UV_EROFS; - case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT; - case WSAETIMEDOUT: return UV_ETIMEDOUT; - case ERROR_NOT_SAME_DEVICE: return UV_EXDEV; - case ERROR_INVALID_FUNCTION: return UV_EISDIR; - case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG; - default: return UV_UNKNOWN; - } -} diff --git a/outside/libuv-v1.7.5/src/win/fs-event.c b/outside/libuv-v1.7.5/src/win/fs-event.c deleted file mode 100644 index ba68f78c82..0000000000 --- a/outside/libuv-v1.7.5/src/win/fs-event.c +++ /dev/null @@ -1,543 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -const unsigned int uv_directory_watcher_buffer_size = 4096; - - -static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop, - uv_fs_event_t* handle) { - assert(handle->dir_handle != INVALID_HANDLE_VALUE); - assert(!handle->req_pending); - - memset(&(handle->req.u.io.overlapped), 0, - sizeof(handle->req.u.io.overlapped)); - if (!ReadDirectoryChangesW(handle->dir_handle, - handle->buffer, - uv_directory_watcher_buffer_size, - (handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE, - FILE_NOTIFY_CHANGE_FILE_NAME | - FILE_NOTIFY_CHANGE_DIR_NAME | - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY, - NULL, - &handle->req.u.io.overlapped, - NULL)) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(&handle->req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)&handle->req); - } - - handle->req_pending = 1; -} - -static int uv_relative_path(const WCHAR* filename, - const WCHAR* dir, - WCHAR** relpath) { - int dirlen = wcslen(dir); - int filelen = wcslen(filename); - if (dir[dirlen - 1] == '\\') - dirlen--; - *relpath = uv__malloc((MAX_PATH + 1) * sizeof(WCHAR)); - if (!*relpath) - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - wcsncpy(*relpath, filename + dirlen + 1, filelen - dirlen - 1); - (*relpath)[filelen - dirlen - 1] = L'\0'; - return 0; -} - -static int uv_split_path(const WCHAR* filename, WCHAR** dir, - WCHAR** file) { - int len = wcslen(filename); - int i = len; - while (i > 0 && filename[--i] != '\\' && filename[i] != '/'); - - if (i == 0) { - if (dir) { - *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR)); - if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!GetCurrentDirectoryW(MAX_PATH, *dir)) { - uv__free(*dir); - *dir = NULL; - return -1; - } - } - - *file = wcsdup(filename); - } else { - if (dir) { - *dir = (WCHAR*)uv__malloc((i + 1) * sizeof(WCHAR)); - if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - wcsncpy(*dir, filename, i); - (*dir)[i] = L'\0'; - } - - *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR)); - if (!*file) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - wcsncpy(*file, filename + i + 1, len - i - 1); - (*file)[len - i - 1] = L'\0'; - } - - return 0; -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT); - handle->dir_handle = INVALID_HANDLE_VALUE; - handle->buffer = NULL; - handle->req_pending = 0; - handle->filew = NULL; - handle->short_filew = NULL; - handle->dirw = NULL; - - uv_req_init(loop, (uv_req_t*)&handle->req); - handle->req.type = UV_FS_EVENT_REQ; - handle->req.data = handle; - - return 0; -} - - -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; - DWORD attr, last_error; - WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; - WCHAR short_path[MAX_PATH]; - - if (uv__is_active(handle)) - return UV_EINVAL; - - handle->cb = cb; - handle->path = uv__strdup(path); - if (!handle->path) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - uv__handle_start(handle); - - /* Convert name to UTF16. */ - name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR); - pathw = (WCHAR*)uv__malloc(name_size); - if (!pathw) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!uv_utf8_to_utf16(path, pathw, - name_size / sizeof(WCHAR))) { - return uv_translate_sys_error(GetLastError()); - } - - /* Determine whether path is a file or a directory. */ - attr = GetFileAttributesW(pathw); - if (attr == INVALID_FILE_ATTRIBUTES) { - last_error = GetLastError(); - goto error; - } - - is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; - - if (is_path_dir) { - /* path is a directory, so that's the directory that we will watch. */ - handle->dirw = pathw; - dir_to_watch = pathw; - } else { - /* - * path is a file. So we split path into dir & file parts, and - * watch the dir directory. - */ - - /* Convert to short path. */ - if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) { - last_error = GetLastError(); - goto error; - } - - if (uv_split_path(pathw, &dir, &handle->filew) != 0) { - last_error = GetLastError(); - goto error; - } - - if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) { - last_error = GetLastError(); - goto error; - } - - dir_to_watch = dir; - uv__free(pathw); - pathw = NULL; - } - - handle->dir_handle = CreateFileW(dir_to_watch, - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_DELETE | - FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OVERLAPPED, - NULL); - - if (dir) { - uv__free(dir); - dir = NULL; - } - - if (handle->dir_handle == INVALID_HANDLE_VALUE) { - last_error = GetLastError(); - goto error; - } - - if (CreateIoCompletionPort(handle->dir_handle, - handle->loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - last_error = GetLastError(); - goto error; - } - - if (!handle->buffer) { - handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size); - } - if (!handle->buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - memset(&(handle->req.u.io.overlapped), 0, - sizeof(handle->req.u.io.overlapped)); - - if (!ReadDirectoryChangesW(handle->dir_handle, - handle->buffer, - uv_directory_watcher_buffer_size, - (flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE, - FILE_NOTIFY_CHANGE_FILE_NAME | - FILE_NOTIFY_CHANGE_DIR_NAME | - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY, - NULL, - &handle->req.u.io.overlapped, - NULL)) { - last_error = GetLastError(); - goto error; - } - - handle->req_pending = 1; - return 0; - -error: - if (handle->path) { - uv__free(handle->path); - handle->path = NULL; - } - - if (handle->filew) { - uv__free(handle->filew); - handle->filew = NULL; - } - - if (handle->short_filew) { - uv__free(handle->short_filew); - handle->short_filew = NULL; - } - - uv__free(pathw); - - if (handle->dir_handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->dir_handle); - handle->dir_handle = INVALID_HANDLE_VALUE; - } - - if (handle->buffer) { - uv__free(handle->buffer); - handle->buffer = NULL; - } - - return uv_translate_sys_error(last_error); -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - if (!uv__is_active(handle)) - return 0; - - if (handle->dir_handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->dir_handle); - handle->dir_handle = INVALID_HANDLE_VALUE; - } - - uv__handle_stop(handle); - - if (handle->filew) { - uv__free(handle->filew); - handle->filew = NULL; - } - - if (handle->short_filew) { - uv__free(handle->short_filew); - handle->short_filew = NULL; - } - - if (handle->path) { - uv__free(handle->path); - handle->path = NULL; - } - - if (handle->dirw) { - uv__free(handle->dirw); - handle->dirw = NULL; - } - - return 0; -} - - -void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, - uv_fs_event_t* handle) { - FILE_NOTIFY_INFORMATION* file_info; - int err, sizew, size, result; - char* filename = NULL; - WCHAR* filenamew, *long_filenamew = NULL; - DWORD offset = 0; - - assert(req->type == UV_FS_EVENT_REQ); - assert(handle->req_pending); - handle->req_pending = 0; - - /* Don't report any callbacks if: - * - We're closing, just push the handle onto the endgame queue - * - We are not active, just ignore the callback - */ - if (!uv__is_active(handle)) { - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - return; - } - - file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset); - - if (REQ_SUCCESS(req)) { - if (req->u.io.overlapped.InternalHigh > 0) { - do { - file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset); - assert(!filename); - assert(!long_filenamew); - - /* - * Fire the event only if we were asked to watch a directory, - * or if the filename filter matches. - */ - if (handle->dirw || - _wcsnicmp(handle->filew, file_info->FileName, - file_info->FileNameLength / sizeof(WCHAR)) == 0 || - _wcsnicmp(handle->short_filew, file_info->FileName, - file_info->FileNameLength / sizeof(WCHAR)) == 0) { - - if (handle->dirw) { - /* - * We attempt to convert the file name to its long form for - * events that still point to valid files on disk. - * For removed and renamed events, we do not provide the file name. - */ - if (file_info->Action != FILE_ACTION_REMOVED && - file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) { - /* Construct a full path to the file. */ - size = wcslen(handle->dirw) + - file_info->FileNameLength / sizeof(WCHAR) + 2; - - filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); - if (!filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw, - file_info->FileNameLength / sizeof(WCHAR), - file_info->FileName); - - filenamew[size - 1] = L'\0'; - - /* Convert to long name. */ - size = GetLongPathNameW(filenamew, NULL, 0); - - if (size) { - long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); - if (!long_filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - size = GetLongPathNameW(filenamew, long_filenamew, size); - if (size) { - long_filenamew[size] = '\0'; - } else { - uv__free(long_filenamew); - long_filenamew = NULL; - } - } - - uv__free(filenamew); - - if (long_filenamew) { - /* Get the file name out of the long path. */ - result = uv_relative_path(long_filenamew, - handle->dirw, - &filenamew); - uv__free(long_filenamew); - - if (result == 0) { - long_filenamew = filenamew; - sizew = -1; - } else { - long_filenamew = NULL; - } - } - - /* - * If we couldn't get the long name - just use the name - * provided by ReadDirectoryChangesW. - */ - if (!long_filenamew) { - filenamew = file_info->FileName; - sizew = file_info->FileNameLength / sizeof(WCHAR); - } - } else { - /* Removed or renamed callbacks don't provide filename. */ - filenamew = NULL; - } - } else { - /* We already have the long name of the file, so just use it. */ - filenamew = handle->filew; - sizew = -1; - } - - if (filenamew) { - /* Convert the filename to utf8. */ - size = uv_utf16_to_utf8(filenamew, - sizew, - NULL, - 0); - if (size) { - filename = (char*)uv__malloc(size + 1); - if (!filename) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - size = uv_utf16_to_utf8(filenamew, - sizew, - filename, - size); - if (size) { - filename[size] = '\0'; - } else { - uv__free(filename); - filename = NULL; - } - } - } - - switch (file_info->Action) { - case FILE_ACTION_ADDED: - case FILE_ACTION_REMOVED: - case FILE_ACTION_RENAMED_OLD_NAME: - case FILE_ACTION_RENAMED_NEW_NAME: - handle->cb(handle, filename, UV_RENAME, 0); - break; - - case FILE_ACTION_MODIFIED: - handle->cb(handle, filename, UV_CHANGE, 0); - break; - } - - uv__free(filename); - filename = NULL; - uv__free(long_filenamew); - long_filenamew = NULL; - } - - offset = file_info->NextEntryOffset; - } while (offset && !(handle->flags & UV__HANDLE_CLOSING)); - } else { - handle->cb(handle, NULL, UV_CHANGE, 0); - } - } else { - err = GET_REQ_ERROR(req); - handle->cb(handle, NULL, 0, uv_translate_sys_error(err)); - } - - if (!(handle->flags & UV__HANDLE_CLOSING)) { - uv_fs_event_queue_readdirchanges(loop, handle); - } else { - uv_want_endgame(loop, (uv_handle_t*)handle); - } -} - - -void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) { - uv_fs_event_stop(handle); - - uv__handle_closing(handle); - - if (!handle->req_pending) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - -} - - -void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) { - if ((handle->flags & UV__HANDLE_CLOSING) && !handle->req_pending) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (handle->buffer) { - uv__free(handle->buffer); - handle->buffer = NULL; - } - - uv__handle_close(handle); - } -} diff --git a/outside/libuv-v1.7.5/src/win/fs.c b/outside/libuv-v1.7.5/src/win/fs.c deleted file mode 100644 index 4a17573113..0000000000 --- a/outside/libuv-v1.7.5/src/win/fs.c +++ /dev/null @@ -1,2349 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" -#include "handle-inl.h" - -#include - - -#define UV_FS_FREE_PATHS 0x0002 -#define UV_FS_FREE_PTR 0x0008 -#define UV_FS_CLEANEDUP 0x0010 - - -#define QUEUE_FS_TP_JOB(loop, req) \ - do { \ - uv__req_register(loop, req); \ - uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \ - } while (0) - -#define SET_REQ_RESULT(req, result_value) \ - do { \ - req->result = (result_value); \ - if (req->result == -1) { \ - req->sys_errno_ = _doserrno; \ - req->result = uv_translate_sys_error(req->sys_errno_); \ - } \ - } while (0) - -#define SET_REQ_WIN32_ERROR(req, sys_errno) \ - do { \ - req->sys_errno_ = (sys_errno); \ - req->result = uv_translate_sys_error(req->sys_errno_); \ - } while (0) - -#define SET_REQ_UV_ERROR(req, uv_errno, sys_errno) \ - do { \ - req->result = (uv_errno); \ - req->sys_errno_ = (sys_errno); \ - } while (0) - -#define VERIFY_FD(fd, req) \ - if (fd == -1) { \ - req->result = UV_EBADF; \ - req->sys_errno_ = ERROR_INVALID_HANDLE; \ - return; \ - } - -#define FILETIME_TO_UINT(filetime) \ - (*((uint64_t*) &(filetime)) - 116444736000000000ULL) - -#define FILETIME_TO_TIME_T(filetime) \ - (FILETIME_TO_UINT(filetime) / 10000000ULL) - -#define FILETIME_TO_TIME_NS(filetime, secs) \ - ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100) - -#define FILETIME_TO_TIMESPEC(ts, filetime) \ - do { \ - (ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime); \ - (ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \ - } while(0) - -#define TIME_T_TO_FILETIME(time, filetime_ptr) \ - do { \ - uint64_t bigtime = ((int64_t) (time) * 10000000LL) + \ - 116444736000000000ULL; \ - (filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \ - (filetime_ptr)->dwHighDateTime = bigtime >> 32; \ - } while(0) - -#define IS_SLASH(c) ((c) == L'\\' || (c) == L'/') -#define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \ - ((c) >= L'A' && (c) <= L'Z')) - -const WCHAR JUNCTION_PREFIX[] = L"\\??\\"; -const WCHAR JUNCTION_PREFIX_LEN = 4; - -const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\"; -const WCHAR LONG_PATH_PREFIX_LEN = 4; - - -void uv_fs_init() { - _fmode = _O_BINARY; -} - - -INLINE static int fs__capture_path(uv_fs_t* req, const char* path, - const char* new_path, const int copy_path) { - char* buf; - char* pos; - ssize_t buf_sz = 0, path_len, pathw_len = 0, 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 = MultiByteToWideChar(CP_UTF8, - 0, - path, - -1, - NULL, - 0); - if (pathw_len == 0) { - return GetLastError(); - } - - 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 = MultiByteToWideChar(CP_UTF8, - 0, - new_path, - -1, - NULL, - 0); - if (new_pathw_len == 0) { - return GetLastError(); - } - - 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 = (char*) uv__malloc(buf_sz); - if (buf == NULL) { - return ERROR_OUTOFMEMORY; - } - - pos = buf; - - if (path != NULL) { - DWORD r = MultiByteToWideChar(CP_UTF8, - 0, - path, - -1, - (WCHAR*) pos, - pathw_len); - assert(r == (DWORD) pathw_len); - req->file.pathw = (WCHAR*) pos; - pos += r * sizeof(WCHAR); - } else { - req->file.pathw = NULL; - } - - if (new_path != NULL) { - DWORD r = MultiByteToWideChar(CP_UTF8, - 0, - new_path, - -1, - (WCHAR*) pos, - new_pathw_len); - assert(r == (DWORD) new_pathw_len); - req->fs.info.new_pathw = (WCHAR*) pos; - pos += r * sizeof(WCHAR); - } else { - req->fs.info.new_pathw = NULL; - } - - if (!copy_path) { - req->path = path; - } else if (path) { - memcpy(pos, path, path_len); - assert(path_len == buf_sz - (pos - buf)); - req->path = pos; - } else { - req->path = NULL; - } - - 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_req_init(loop, (uv_req_t*) req); - - req->type = UV_FS; - req->loop = loop; - req->flags = 0; - req->fs_type = fs_type; - req->result = 0; - req->ptr = NULL; - req->path = NULL; - req->cb = cb; -} - - -INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, - uint64_t* target_len_ptr) { - char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer; - WCHAR *w_target; - DWORD w_target_len; - char* target; - int target_len; - DWORD bytes; - - if (!DeviceIoControl(handle, - FSCTL_GET_REPARSE_POINT, - NULL, - 0, - buffer, - sizeof buffer, - &bytes, - NULL)) { - return -1; - } - - if (reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - /* Real symlink */ - w_target = reparse_data->SymbolicLinkReparseBuffer.PathBuffer + - (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / - sizeof(WCHAR)); - w_target_len = - reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / - sizeof(WCHAR); - - /* Real symlinks can contain pretty much everything, but the only thing */ - /* we really care about is undoing the implicit conversion to an NT */ - /* namespaced path that CreateSymbolicLink will perform on absolute */ - /* paths. If the path is win32-namespaced then the user must have */ - /* explicitly made it so, and we better just return the unmodified */ - /* reparse data. */ - if (w_target_len >= 4 && - w_target[0] == L'\\' && - w_target[1] == L'?' && - w_target[2] == L'?' && - w_target[3] == L'\\') { - /* Starts with \??\ */ - if (w_target_len >= 6 && - ((w_target[4] >= L'A' && w_target[4] <= L'Z') || - (w_target[4] >= L'a' && w_target[4] <= L'z')) && - w_target[5] == L':' && - (w_target_len == 6 || w_target[6] == L'\\')) { - /* \??\:\ */ - w_target += 4; - w_target_len -= 4; - - } else if (w_target_len >= 8 && - (w_target[4] == L'U' || w_target[4] == L'u') && - (w_target[5] == L'N' || w_target[5] == L'n') && - (w_target[6] == L'C' || w_target[6] == L'c') && - w_target[7] == L'\\') { - /* \??\UNC\\\ - make sure the final path looks like */ - /* \\\\ */ - w_target += 6; - w_target[0] = L'\\'; - w_target_len -= 6; - } - } - - } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { - /* Junction. */ - w_target = reparse_data->MountPointReparseBuffer.PathBuffer + - (reparse_data->MountPointReparseBuffer.SubstituteNameOffset / - sizeof(WCHAR)); - w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength / - sizeof(WCHAR); - - /* Only treat junctions that look like \??\:\ as symlink. */ - /* Junctions can also be used as mount points, like \??\Volume{}, */ - /* but that's confusing for programs since they wouldn't be able to */ - /* actually understand such a path when returned by uv_readlink(). */ - /* UNC paths are never valid for junctions so we don't care about them. */ - if (!(w_target_len >= 6 && - w_target[0] == L'\\' && - w_target[1] == L'?' && - w_target[2] == L'?' && - w_target[3] == L'\\' && - ((w_target[4] >= L'A' && w_target[4] <= L'Z') || - (w_target[4] >= L'a' && w_target[4] <= L'z')) && - w_target[5] == L':' && - (w_target_len == 6 || w_target[6] == L'\\'))) { - SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); - return -1; - } - - /* Remove leading \??\ */ - w_target += 4; - w_target_len -= 4; - - } else { - /* Reparse tag does not indicate a symlink. */ - SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); - return -1; - } - - /* If needed, compute the length of the target. */ - if (target_ptr != NULL || target_len_ptr != NULL) { - /* Compute the length of the target. */ - target_len = WideCharToMultiByte(CP_UTF8, - 0, - w_target, - w_target_len, - NULL, - 0, - NULL, - NULL); - if (target_len == 0) { - return -1; - } - } - - /* If requested, allocate memory and convert to UTF8. */ - if (target_ptr != NULL) { - int r; - target = (char*) uv__malloc(target_len + 1); - if (target == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } - - r = WideCharToMultiByte(CP_UTF8, - 0, - w_target, - w_target_len, - target, - target_len, - NULL, - NULL); - assert(r == target_len); - target[target_len] = '\0'; - - *target_ptr = target; - } - - if (target_len_ptr != NULL) { - *target_len_ptr = target_len; - } - - return 0; -} - - -void fs__open(uv_fs_t* req) { - DWORD access; - DWORD share; - DWORD disposition; - DWORD attributes = 0; - HANDLE file; - int fd, current_umask; - int flags = req->fs.info.file_flags; - - /* Obtain the active umask. umask() never fails and returns the previous */ - /* umask. */ - current_umask = umask(0); - umask(current_umask); - - /* convert flags and mode to CreateFile parameters */ - switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { - case _O_RDONLY: - access = FILE_GENERIC_READ; - attributes |= FILE_FLAG_BACKUP_SEMANTICS; - break; - case _O_WRONLY: - access = FILE_GENERIC_WRITE; - break; - case _O_RDWR: - access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; - break; - default: - goto einval; - } - - if (flags & _O_APPEND) { - access &= ~FILE_WRITE_DATA; - access |= FILE_APPEND_DATA; - attributes &= ~FILE_FLAG_BACKUP_SEMANTICS; - } - - /* - * Here is where we deviate significantly from what CRT's _open() - * does. We indiscriminately use all the sharing modes, to match - * UNIX semantics. In particular, this ensures that the file can - * be deleted even whilst it's open, fixing issue #1449. - */ - share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - - switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) { - case 0: - case _O_EXCL: - disposition = OPEN_EXISTING; - break; - case _O_CREAT: - disposition = OPEN_ALWAYS; - break; - case _O_CREAT | _O_EXCL: - case _O_CREAT | _O_TRUNC | _O_EXCL: - disposition = CREATE_NEW; - break; - case _O_TRUNC: - case _O_TRUNC | _O_EXCL: - disposition = TRUNCATE_EXISTING; - break; - case _O_CREAT | _O_TRUNC: - disposition = CREATE_ALWAYS; - break; - default: - goto einval; - } - - attributes |= FILE_ATTRIBUTE_NORMAL; - if (flags & _O_CREAT) { - if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) { - attributes |= FILE_ATTRIBUTE_READONLY; - } - } - - if (flags & _O_TEMPORARY ) { - attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY; - access |= DELETE; - } - - if (flags & _O_SHORT_LIVED) { - attributes |= FILE_ATTRIBUTE_TEMPORARY; - } - - switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) { - case 0: - break; - case _O_SEQUENTIAL: - attributes |= FILE_FLAG_SEQUENTIAL_SCAN; - break; - case _O_RANDOM: - attributes |= FILE_FLAG_RANDOM_ACCESS; - break; - default: - goto einval; - } - - /* Setting this flag makes it possible to open a directory. */ - attributes |= FILE_FLAG_BACKUP_SEMANTICS; - - file = CreateFileW(req->file.pathw, - access, - share, - NULL, - disposition, - attributes, - NULL); - if (file == INVALID_HANDLE_VALUE) { - DWORD error = GetLastError(); - if (error == ERROR_FILE_EXISTS && (flags & _O_CREAT) && - !(flags & _O_EXCL)) { - /* Special case: when ERROR_FILE_EXISTS happens and O_CREAT was */ - /* specified, it means the path referred to a directory. */ - SET_REQ_UV_ERROR(req, UV_EISDIR, error); - } else { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } - return; - } - - fd = _open_osfhandle((intptr_t) file, flags); - if (fd < 0) { - /* The only known failure mode for _open_osfhandle() is EMFILE, in which - * case GetLastError() will return zero. However we'll try to handle other - * errors as well, should they ever occur. - */ - if (errno == EMFILE) - SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES); - else if (GetLastError() != ERROR_SUCCESS) - SET_REQ_WIN32_ERROR(req, GetLastError()); - else - SET_REQ_WIN32_ERROR(req, UV_UNKNOWN); - CloseHandle(file); - return; - } - - SET_REQ_RESULT(req, fd); - return; - - einval: - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); -} - -void fs__close(uv_fs_t* req) { - int fd = req->file.fd; - int result; - - VERIFY_FD(fd, req); - - if (fd > 2) - result = _close(fd); - else - result = 0; - - SET_REQ_RESULT(req, result); -} - - -void fs__read(uv_fs_t* req) { - int fd = req->file.fd; - int64_t offset = req->fs.info.offset; - HANDLE handle; - OVERLAPPED overlapped, *overlapped_ptr; - LARGE_INTEGER offset_; - DWORD bytes; - DWORD error; - int result; - unsigned int index; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (offset != -1) { - memset(&overlapped, 0, sizeof overlapped); - overlapped_ptr = &overlapped; - } else { - overlapped_ptr = NULL; - } - - index = 0; - bytes = 0; - do { - DWORD incremental_bytes; - - if (offset != -1) { - offset_.QuadPart = offset + bytes; - overlapped.Offset = offset_.LowPart; - overlapped.OffsetHigh = offset_.HighPart; - } - - result = ReadFile(handle, - req->fs.info.bufs[index].base, - req->fs.info.bufs[index].len, - &incremental_bytes, - overlapped_ptr); - bytes += incremental_bytes; - ++index; - } while (result && index < req->fs.info.nbufs); - - if (result || bytes > 0) { - SET_REQ_RESULT(req, bytes); - } else { - error = GetLastError(); - if (error == ERROR_HANDLE_EOF) { - SET_REQ_RESULT(req, bytes); - } else { - SET_REQ_WIN32_ERROR(req, error); - } - } -} - - -void fs__write(uv_fs_t* req) { - int fd = req->file.fd; - int64_t offset = req->fs.info.offset; - HANDLE handle; - OVERLAPPED overlapped, *overlapped_ptr; - LARGE_INTEGER offset_; - DWORD bytes; - int result; - unsigned int index; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (offset != -1) { - memset(&overlapped, 0, sizeof overlapped); - overlapped_ptr = &overlapped; - } else { - overlapped_ptr = NULL; - } - - index = 0; - bytes = 0; - do { - DWORD incremental_bytes; - - if (offset != -1) { - offset_.QuadPart = offset + bytes; - overlapped.Offset = offset_.LowPart; - overlapped.OffsetHigh = offset_.HighPart; - } - - result = WriteFile(handle, - req->fs.info.bufs[index].base, - req->fs.info.bufs[index].len, - &incremental_bytes, - overlapped_ptr); - bytes += incremental_bytes; - ++index; - } while (result && index < req->fs.info.nbufs); - - if (result || bytes > 0) { - SET_REQ_RESULT(req, bytes); - } else { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } -} - - -void fs__rmdir(uv_fs_t* req) { - int result = _wrmdir(req->file.pathw); - SET_REQ_RESULT(req, result); -} - - -void fs__unlink(uv_fs_t* req) { - const WCHAR* pathw = req->file.pathw; - HANDLE handle; - BY_HANDLE_FILE_INFORMATION info; - FILE_DISPOSITION_INFORMATION disposition; - IO_STATUS_BLOCK iosb; - NTSTATUS status; - - handle = CreateFileW(pathw, - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (!GetFileInformationByHandle(handle, &info)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - /* Do not allow deletion of directories, unless it is a symlink. When */ - /* the path refers to a non-symlink directory, report EPERM as mandated */ - /* by POSIX.1. */ - - /* Check if it is a reparse point. If it's not, it's a normal directory. */ - if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); - CloseHandle(handle); - return; - } - - /* Read the reparse point and check if it is a valid symlink. */ - /* If not, don't unlink. */ - if (fs__readlink_handle(handle, NULL, NULL) < 0) { - DWORD error = GetLastError(); - if (error == ERROR_SYMLINK_NOT_SUPPORTED) - error = ERROR_ACCESS_DENIED; - SET_REQ_WIN32_ERROR(req, error); - CloseHandle(handle); - return; - } - } - - if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { - /* Remove read-only attribute */ - FILE_BASIC_INFORMATION basic = { 0 }; - - basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY); - - status = pNtSetInformationFile(handle, - &iosb, - &basic, - sizeof basic, - FileBasicInformation); - if (!NT_SUCCESS(status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - CloseHandle(handle); - return; - } - } - - /* Try to set the delete flag. */ - disposition.DeleteFile = TRUE; - status = pNtSetInformationFile(handle, - &iosb, - &disposition, - sizeof disposition, - FileDispositionInformation); - if (NT_SUCCESS(status)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - } - - CloseHandle(handle); -} - - -void fs__mkdir(uv_fs_t* req) { - /* TODO: use req->mode. */ - int result = _wmkdir(req->file.pathw); - SET_REQ_RESULT(req, result); -} - - -/* OpenBSD original: lib/libc/stdio/mktemp.c */ -void fs__mkdtemp(uv_fs_t* req) { - static const WCHAR *tempchars = - L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static const size_t num_chars = 62; - static const size_t num_x = 6; - WCHAR *cp, *ep; - unsigned int tries, i; - size_t len; - HCRYPTPROV h_crypt_prov; - uint64_t v; - BOOL released; - - len = wcslen(req->file.pathw); - ep = req->file.pathw + len; - if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) { - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); - return; - } - - if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - tries = TMP_MAX; - do { - if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - break; - } - - cp = ep - num_x; - for (i = 0; i < num_x; i++) { - *cp++ = tempchars[v % num_chars]; - v /= num_chars; - } - - if (_wmkdir(req->file.pathw) == 0) { - len = strlen(req->path); - wcstombs((char*) req->path + len - num_x, ep - num_x, num_x); - SET_REQ_RESULT(req, 0); - break; - } else if (errno != EEXIST) { - SET_REQ_RESULT(req, -1); - break; - } - } while (--tries); - - released = CryptReleaseContext(h_crypt_prov, 0); - assert(released); - if (tries == 0) { - SET_REQ_RESULT(req, -1); - } -} - - -void fs__scandir(uv_fs_t* req) { - static const size_t dirents_initial_size = 32; - - HANDLE dir_handle = INVALID_HANDLE_VALUE; - - uv__dirent_t** dirents = NULL; - size_t dirents_size = 0; - size_t dirents_used = 0; - - IO_STATUS_BLOCK iosb; - NTSTATUS status; - - /* Buffer to hold directory entries returned by NtQueryDirectoryFile. - * It's important that this buffer can hold at least one entry, regardless - * of the length of the file names present in the enumerated directory. - * A file name is at most 256 WCHARs long. - * According to MSDN, the buffer must be aligned at an 8-byte boundary. - */ -#if _MSC_VER - __declspec(align(8)) char buffer[8192]; -#else - __attribute__ ((aligned (8))) char buffer[8192]; -#endif - - STATIC_ASSERT(sizeof buffer >= - sizeof(FILE_DIRECTORY_INFORMATION) + 256 * sizeof(WCHAR)); - - /* Open the directory. */ - dir_handle = - CreateFileW(req->file.pathw, - FILE_LIST_DIRECTORY | SYNCHRONIZE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (dir_handle == INVALID_HANDLE_VALUE) - goto win32_error; - - /* Read the first chunk. */ - status = pNtQueryDirectoryFile(dir_handle, - NULL, - NULL, - NULL, - &iosb, - &buffer, - sizeof buffer, - FileDirectoryInformation, - FALSE, - NULL, - TRUE); - - /* If the handle is not a directory, we'll get STATUS_INVALID_PARAMETER. - * This should be reported back as UV_ENOTDIR. - */ - if (status == STATUS_INVALID_PARAMETER) - goto not_a_directory_error; - - while (NT_SUCCESS(status)) { - char* position = buffer; - size_t next_entry_offset = 0; - - do { - FILE_DIRECTORY_INFORMATION* info; - uv__dirent_t* dirent; - - size_t wchar_len; - size_t utf8_len; - - /* Obtain a pointer to the current directory entry. */ - position += next_entry_offset; - info = (FILE_DIRECTORY_INFORMATION*) position; - - /* Fetch the offset to the next directory entry. */ - next_entry_offset = info->NextEntryOffset; - - /* Compute the length of the filename in WCHARs. */ - wchar_len = info->FileNameLength / sizeof info->FileName[0]; - - /* Skip over '.' and '..' entries. */ - if (wchar_len == 1 && info->FileName[0] == L'.') - continue; - if (wchar_len == 2 && info->FileName[0] == L'.' && - info->FileName[1] == L'.') - continue; - - /* Compute the space required to store the filename as UTF-8. */ - utf8_len = WideCharToMultiByte( - CP_UTF8, 0, &info->FileName[0], wchar_len, NULL, 0, NULL, NULL); - if (utf8_len == 0) - goto win32_error; - - /* Resize the dirent array if needed. */ - if (dirents_used >= dirents_size) { - size_t new_dirents_size = - dirents_size == 0 ? dirents_initial_size : dirents_size << 1; - uv__dirent_t** new_dirents = - uv__realloc(dirents, new_dirents_size * sizeof *dirents); - - if (new_dirents == NULL) - goto out_of_memory_error; - - dirents_size = new_dirents_size; - dirents = new_dirents; - } - - /* Allocate space for the uv dirent structure. The dirent structure - * includes room for the first character of the filename, but `utf8_len` - * doesn't count the NULL terminator at this point. - */ - dirent = uv__malloc(sizeof *dirent + utf8_len); - if (dirent == NULL) - goto out_of_memory_error; - - dirents[dirents_used++] = dirent; - - /* Convert file name to UTF-8. */ - if (WideCharToMultiByte(CP_UTF8, - 0, - &info->FileName[0], - wchar_len, - &dirent->d_name[0], - utf8_len, - NULL, - NULL) == 0) - goto win32_error; - - /* Add a null terminator to the filename. */ - dirent->d_name[utf8_len] = '\0'; - - /* Fill out the type field. */ - if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE) - dirent->d_type = UV__DT_CHAR; - else if (info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - dirent->d_type = UV__DT_LINK; - else if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) - dirent->d_type = UV__DT_DIR; - else - dirent->d_type = UV__DT_FILE; - } while (next_entry_offset != 0); - - /* Read the next chunk. */ - status = pNtQueryDirectoryFile(dir_handle, - NULL, - NULL, - NULL, - &iosb, - &buffer, - sizeof buffer, - FileDirectoryInformation, - FALSE, - NULL, - FALSE); - - /* After the first pNtQueryDirectoryFile call, the function may return - * STATUS_SUCCESS even if the buffer was too small to hold at least one - * directory entry. - */ - if (status == STATUS_SUCCESS && iosb.Information == 0) - status = STATUS_BUFFER_OVERFLOW; - } - - if (status != STATUS_NO_MORE_FILES) - goto nt_error; - - CloseHandle(dir_handle); - - /* Store the result in the request object. */ - req->ptr = dirents; - if (dirents != NULL) - req->flags |= UV_FS_FREE_PTR; - - SET_REQ_RESULT(req, dirents_used); - - /* `nbufs` will be used as index by uv_fs_scandir_next. */ - req->fs.info.nbufs = 0; - - return; - -nt_error: - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - goto cleanup; - -win32_error: - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto cleanup; - -not_a_directory_error: - SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY); - goto cleanup; - -out_of_memory_error: - SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); - goto cleanup; - -cleanup: - if (dir_handle != INVALID_HANDLE_VALUE) - CloseHandle(dir_handle); - while (dirents_used > 0) - uv__free(dirents[--dirents_used]); - if (dirents != NULL) - uv__free(dirents); -} - - -INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) { - FILE_ALL_INFORMATION file_info; - FILE_FS_VOLUME_INFORMATION volume_info; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - - nt_status = pNtQueryInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileAllInformation); - - /* Buffer overflow (a warning status code) is expected here. */ - if (NT_ERROR(nt_status)) { - SetLastError(pRtlNtStatusToDosError(nt_status)); - return -1; - } - - nt_status = pNtQueryVolumeInformationFile(handle, - &io_status, - &volume_info, - sizeof volume_info, - FileFsVolumeInformation); - - /* Buffer overflow (a warning status code) is expected here. */ - if (io_status.Status == STATUS_NOT_IMPLEMENTED) { - statbuf->st_dev = 0; - } else if (NT_ERROR(nt_status)) { - SetLastError(pRtlNtStatusToDosError(nt_status)); - return -1; - } else { - statbuf->st_dev = volume_info.VolumeSerialNumber; - } - - /* Todo: st_mode should probably always be 0666 for everyone. We might also - * want to report 0777 if the file is a .exe or a directory. - * - * Currently it's based on whether the 'readonly' attribute is set, which - * makes little sense because the semantics are so different: the 'read-only' - * flag is just a way for a user to protect against accidental deletion, and - * serves no security purpose. Windows uses ACLs for that. - * - * Also people now use uv_fs_chmod() to take away the writable bit for good - * reasons. Windows however just makes the file read-only, which makes it - * impossible to delete the file afterwards, since read-only files can't be - * deleted. - * - * IOW it's all just a clusterfuck and we should think of something that - * makes slightly more sense. - * - * And uv_fs_chmod should probably just fail on windows or be a total no-op. - * There's nothing sensible it can do anyway. - */ - statbuf->st_mode = 0; - - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - statbuf->st_mode |= S_IFLNK; - if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0) - return -1; - - } else if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - statbuf->st_mode |= _S_IFDIR; - statbuf->st_size = 0; - - } else { - statbuf->st_mode |= _S_IFREG; - statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart; - } - - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY) - statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6); - else - statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) | - ((_S_IREAD | _S_IWRITE) >> 6); - - FILETIME_TO_TIMESPEC(statbuf->st_atim, file_info.BasicInformation.LastAccessTime); - FILETIME_TO_TIMESPEC(statbuf->st_ctim, file_info.BasicInformation.ChangeTime); - FILETIME_TO_TIMESPEC(statbuf->st_mtim, file_info.BasicInformation.LastWriteTime); - FILETIME_TO_TIMESPEC(statbuf->st_birthtim, file_info.BasicInformation.CreationTime); - - statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart; - - /* st_blocks contains the on-disk allocation size in 512-byte units. */ - statbuf->st_blocks = - file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL; - - statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks; - - /* The st_blksize is supposed to be the 'optimal' number of bytes for reading - * and writing to the disk. That is, for any definition of 'optimal' - it's - * supposed to at least avoid read-update-write behavior when writing to the - * disk. - * - * However nobody knows this and even fewer people actually use this value, - * and in order to fill it out we'd have to make another syscall to query the - * volume for FILE_FS_SECTOR_SIZE_INFORMATION. - * - * Therefore we'll just report a sensible value that's quite commonly okay - * on modern hardware. - */ - statbuf->st_blksize = 2048; - - /* Todo: set st_flags to something meaningful. Also provide a wrapper for - * chattr(2). - */ - statbuf->st_flags = 0; - - /* Windows has nothing sensible to say about these values, so they'll just - * remain empty. - */ - statbuf->st_gid = 0; - statbuf->st_uid = 0; - statbuf->st_rdev = 0; - statbuf->st_gen = 0; - - return 0; -} - - -INLINE static void fs__stat_prepare_path(WCHAR* pathw) { - size_t len = wcslen(pathw); - - /* TODO: ignore namespaced paths. */ - if (len > 1 && pathw[len - 2] != L':' && - (pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) { - pathw[len - 1] = '\0'; - } -} - - -INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) { - HANDLE handle; - DWORD flags; - - flags = FILE_FLAG_BACKUP_SEMANTICS; - if (do_lstat) { - flags |= FILE_FLAG_OPEN_REPARSE_POINT; - } - - handle = CreateFileW(req->file.pathw, - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - flags, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__stat_handle(handle, &req->statbuf) != 0) { - DWORD error = GetLastError(); - if (do_lstat && error == ERROR_SYMLINK_NOT_SUPPORTED) { - /* We opened a reparse point but it was not a symlink. Try again. */ - fs__stat_impl(req, 0); - - } else { - /* Stat failed. */ - SET_REQ_WIN32_ERROR(req, GetLastError()); - } - - CloseHandle(handle); - return; - } - - req->ptr = &req->statbuf; - req->result = 0; - CloseHandle(handle); -} - - -static void fs__stat(uv_fs_t* req) { - fs__stat_prepare_path(req->file.pathw); - fs__stat_impl(req, 0); -} - - -static void fs__lstat(uv_fs_t* req) { - fs__stat_prepare_path(req->file.pathw); - fs__stat_impl(req, 1); -} - - -static void fs__fstat(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (fs__stat_handle(handle, &req->statbuf) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - req->ptr = &req->statbuf; - req->result = 0; -} - - -static void fs__rename(uv_fs_t* req) { - if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - SET_REQ_RESULT(req, 0); -} - - -INLINE static void fs__sync_impl(uv_fs_t* req) { - int fd = req->file.fd; - int result; - - VERIFY_FD(fd, req); - - result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1; - if (result == -1) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - SET_REQ_RESULT(req, result); - } -} - - -static void fs__fsync(uv_fs_t* req) { - fs__sync_impl(req); -} - - -static void fs__fdatasync(uv_fs_t* req) { - fs__sync_impl(req); -} - - -static void fs__ftruncate(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - NTSTATUS status; - IO_STATUS_BLOCK io_status; - FILE_END_OF_FILE_INFORMATION eof_info; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - eof_info.EndOfFile.QuadPart = req->fs.info.offset; - - status = pNtSetInformationFile(handle, - &io_status, - &eof_info, - sizeof eof_info, - FileEndOfFileInformation); - - if (NT_SUCCESS(status)) { - SET_REQ_RESULT(req, 0); - } else { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - } -} - - -static void fs__sendfile(uv_fs_t* req) { - int fd_in = req->file.fd, fd_out = req->fs.info.fd_out; - size_t length = req->fs.info.bufsml[0].len; - int64_t offset = req->fs.info.offset; - const size_t max_buf_size = 65536; - size_t buf_size = length < max_buf_size ? length : max_buf_size; - int n, result = 0; - int64_t result_offset = 0; - char* buf = (char*) uv__malloc(buf_size); - if (!buf) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (offset != -1) { - result_offset = _lseeki64(fd_in, offset, SEEK_SET); - } - - if (result_offset == -1) { - result = -1; - } else { - while (length > 0) { - n = _read(fd_in, buf, length < buf_size ? length : buf_size); - if (n == 0) { - break; - } else if (n == -1) { - result = -1; - break; - } - - length -= n; - - n = _write(fd_out, buf, n); - if (n == -1) { - result = -1; - break; - } - - result += n; - } - } - - uv__free(buf); - - SET_REQ_RESULT(req, result); -} - - -static void fs__access(uv_fs_t* req) { - DWORD attr = GetFileAttributesW(req->file.pathw); - - if (attr == INVALID_FILE_ATTRIBUTES) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - /* - * Access is possible if - * - write access wasn't requested, - * - or the file isn't read-only, - * - or it's a directory. - * (Directories cannot be read-only on Windows.) - */ - if (!(req->flags & W_OK) || - !(attr & FILE_ATTRIBUTE_READONLY) || - (attr & FILE_ATTRIBUTE_DIRECTORY)) { - SET_REQ_RESULT(req, 0); - } else { - SET_REQ_WIN32_ERROR(req, UV_EPERM); - } - -} - - -static void fs__chmod(uv_fs_t* req) { - int result = _wchmod(req->file.pathw, req->fs.info.mode); - SET_REQ_RESULT(req, result); -} - - -static void fs__fchmod(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_BASIC_INFORMATION file_info; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - nt_status = pNtQueryInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileBasicInformation); - - if (!NT_SUCCESS(nt_status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); - return; - } - - if (req->fs.info.mode & _S_IWRITE) { - file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; - } else { - file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; - } - - nt_status = pNtSetInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileBasicInformation); - - if (!NT_SUCCESS(nt_status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); - return; - } - - SET_REQ_SUCCESS(req); -} - - -INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) { - FILETIME filetime_a, filetime_m; - - TIME_T_TO_FILETIME((time_t) atime, &filetime_a); - TIME_T_TO_FILETIME((time_t) mtime, &filetime_m); - - if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) { - return -1; - } - - return 0; -} - - -static void fs__utime(uv_fs_t* req) { - HANDLE handle; - - handle = CreateFileW(req->file.pathw, - FILE_WRITE_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - CloseHandle(handle); - - req->result = 0; -} - - -static void fs__futime(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - req->result = 0; -} - - -static void fs__link(uv_fs_t* req) { - DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL); - if (r == 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - req->result = 0; - } -} - - -static void fs__create_junction(uv_fs_t* req, const WCHAR* path, - const WCHAR* new_path) { - HANDLE handle = INVALID_HANDLE_VALUE; - REPARSE_DATA_BUFFER *buffer = NULL; - int created = 0; - int target_len; - int is_absolute, is_long_path; - int needed_buf_size, used_buf_size, used_data_size, path_buf_len; - int start, len, i; - int add_slash; - DWORD bytes; - WCHAR* path_buf; - - target_len = wcslen(path); - is_long_path = wcsncmp(path, LONG_PATH_PREFIX, LONG_PATH_PREFIX_LEN) == 0; - - if (is_long_path) { - is_absolute = 1; - } else { - is_absolute = target_len >= 3 && IS_LETTER(path[0]) && - path[1] == L':' && IS_SLASH(path[2]); - } - - if (!is_absolute) { - /* Not supporting relative paths */ - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_NOT_SUPPORTED); - return; - } - - /* Do a pessimistic calculation of the required buffer size */ - needed_buf_size = - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + - JUNCTION_PREFIX_LEN * sizeof(WCHAR) + - 2 * (target_len + 2) * sizeof(WCHAR); - - /* Allocate the buffer */ - buffer = (REPARSE_DATA_BUFFER*)uv__malloc(needed_buf_size); - if (!buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - /* Grab a pointer to the part of the buffer where filenames go */ - path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer); - path_buf_len = 0; - - /* Copy the substitute (internal) target path */ - start = path_buf_len; - - wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX, - JUNCTION_PREFIX_LEN); - path_buf_len += JUNCTION_PREFIX_LEN; - - add_slash = 0; - for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { - if (IS_SLASH(path[i])) { - add_slash = 1; - continue; - } - - if (add_slash) { - path_buf[path_buf_len++] = L'\\'; - add_slash = 0; - } - - path_buf[path_buf_len++] = path[i]; - } - path_buf[path_buf_len++] = L'\\'; - len = path_buf_len - start; - - /* Set the info about the substitute name */ - buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR); - buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR); - - /* Insert null terminator */ - path_buf[path_buf_len++] = L'\0'; - - /* Copy the print name of the target path */ - start = path_buf_len; - add_slash = 0; - for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { - if (IS_SLASH(path[i])) { - add_slash = 1; - continue; - } - - if (add_slash) { - path_buf[path_buf_len++] = L'\\'; - add_slash = 0; - } - - path_buf[path_buf_len++] = path[i]; - } - len = path_buf_len - start; - if (len == 2) { - path_buf[path_buf_len++] = L'\\'; - len++; - } - - /* Set the info about the print name */ - buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR); - buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR); - - /* Insert another null terminator */ - path_buf[path_buf_len++] = L'\0'; - - /* Calculate how much buffer space was actually used */ - used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + - path_buf_len * sizeof(WCHAR); - used_data_size = used_buf_size - - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer); - - /* Put general info in the data buffer */ - buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - buffer->ReparseDataLength = used_data_size; - buffer->Reserved = 0; - - /* Create a new directory */ - if (!CreateDirectoryW(new_path, NULL)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - created = 1; - - /* Open the directory */ - handle = CreateFileW(new_path, - GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - - /* Create the actual reparse point */ - if (!DeviceIoControl(handle, - FSCTL_SET_REPARSE_POINT, - buffer, - used_buf_size, - NULL, - 0, - &bytes, - NULL)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - - /* Clean up */ - CloseHandle(handle); - uv__free(buffer); - - SET_REQ_RESULT(req, 0); - return; - -error: - uv__free(buffer); - - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - } - - if (created) { - RemoveDirectoryW(new_path); - } -} - - -static void fs__symlink(uv_fs_t* req) { - WCHAR* pathw = req->file.pathw; - WCHAR* new_pathw = req->fs.info.new_pathw; - int flags = req->fs.info.file_flags; - int result; - - - if (flags & UV_FS_SYMLINK_JUNCTION) { - fs__create_junction(req, pathw, new_pathw); - } else if (pCreateSymbolicLinkW) { - result = pCreateSymbolicLinkW(new_pathw, - pathw, - flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1; - if (result == -1) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - SET_REQ_RESULT(req, result); - } - } else { - SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED); - } -} - - -static void fs__readlink(uv_fs_t* req) { - HANDLE handle; - - handle = CreateFileW(req->file.pathw, - 0, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - req->flags |= UV_FS_FREE_PTR; - SET_REQ_RESULT(req, 0); - - CloseHandle(handle); -} - - - -static void fs__chown(uv_fs_t* req) { - req->result = 0; -} - - -static void fs__fchown(uv_fs_t* req) { - req->result = 0; -} - - -static void uv__fs_work(struct uv__work* w) { - uv_fs_t* req; - - req = container_of(w, uv_fs_t, work_req); - assert(req->type == UV_FS); - -#define XX(uc, lc) case UV_FS_##uc: fs__##lc(req); break; - switch (req->fs_type) { - XX(OPEN, open) - XX(CLOSE, close) - XX(READ, read) - XX(WRITE, write) - XX(SENDFILE, sendfile) - XX(STAT, stat) - XX(LSTAT, lstat) - XX(FSTAT, fstat) - XX(FTRUNCATE, ftruncate) - XX(UTIME, utime) - XX(FUTIME, futime) - XX(ACCESS, access) - XX(CHMOD, chmod) - XX(FCHMOD, fchmod) - XX(FSYNC, fsync) - XX(FDATASYNC, fdatasync) - XX(UNLINK, unlink) - XX(RMDIR, rmdir) - XX(MKDIR, mkdir) - XX(MKDTEMP, mkdtemp) - XX(RENAME, rename) - XX(SCANDIR, scandir) - XX(LINK, link) - XX(SYMLINK, symlink) - XX(READLINK, readlink) - XX(CHOWN, chown) - XX(FCHOWN, fchown); - default: - assert(!"bad uv_fs_type"); - } -} - - -static void uv__fs_done(struct uv__work* w, int status) { - uv_fs_t* req; - - req = container_of(w, uv_fs_t, work_req); - uv__req_unregister(req->loop, req); - - if (status == UV_ECANCELED) { - assert(req->result == 0); - req->result = UV_ECANCELED; - } - - req->cb(req); -} - - -void uv_fs_req_cleanup(uv_fs_t* req) { - if (req->flags & UV_FS_CLEANEDUP) - return; - - if (req->flags & UV_FS_FREE_PATHS) - uv__free(req->file.pathw); - - if (req->flags & UV_FS_FREE_PTR) - uv__free(req->ptr); - - req->path = NULL; - req->file.pathw = NULL; - req->fs.info.new_pathw = NULL; - req->ptr = NULL; - - req->flags |= UV_FS_CLEANEDUP; -} - - -int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, - int mode, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_OPEN, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.file_flags = flags; - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__open(req); - return req->result; - } -} - - -int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_CLOSE, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__close(req); - return req->result; - } -} - - -int uv_fs_read(uv_loop_t* loop, - uv_fs_t* req, - uv_file fd, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t offset, - uv_fs_cb cb) { - if (bufs == NULL || nbufs == 0) - return UV_EINVAL; - - uv_fs_req_init(loop, req, UV_FS_READ, cb); - - req->file.fd = fd; - - req->fs.info.nbufs = nbufs; - req->fs.info.bufs = req->fs.info.bufsml; - if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) - req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); - - if (req->fs.info.bufs == NULL) - return UV_ENOMEM; - - memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); - - req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__read(req); - return req->result; - } -} - - -int uv_fs_write(uv_loop_t* loop, - uv_fs_t* req, - uv_file fd, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t offset, - uv_fs_cb cb) { - if (bufs == NULL || nbufs == 0) - return UV_EINVAL; - - uv_fs_req_init(loop, req, UV_FS_WRITE, cb); - - req->file.fd = fd; - - req->fs.info.nbufs = nbufs; - req->fs.info.bufs = req->fs.info.bufsml; - if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) - req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); - - if (req->fs.info.bufs == NULL) - return UV_ENOMEM; - - memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); - - req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__write(req); - return req->result; - } -} - - -int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_UNLINK, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__unlink(req); - return req->result; - } -} - - -int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_MKDIR, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__mkdir(req); - return req->result; - } -} - - -int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_MKDTEMP, cb); - - err = fs__capture_path(req, tpl, NULL, TRUE); - if (err) - return uv_translate_sys_error(err); - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__mkdtemp(req); - return req->result; - } -} - - -int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_RMDIR, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rmdir(req); - return req->result; - } -} - - -int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__scandir(req); - return req->result; - } -} - - -int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_LINK, cb); - - err = fs__capture_path(req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__link(req); - return req->result; - } -} - - -int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, int flags, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb); - - err = fs__capture_path(req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__symlink(req); - return req->result; - } -} - - -int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_READLINK, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__readlink(req); - return req->result; - } -} - - -int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, - uv_gid_t gid, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_CHOWN, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chown(req); - return req->result; - } -} - - -int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid, - uv_gid_t gid, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb); - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchown(req); - return req->result; - } -} - - -int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_STAT, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__stat(req); - return req->result; - } -} - - -int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_LSTAT, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__lstat(req); - return req->result; - } -} - - -int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSTAT, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fstat(req); - return req->result; - } -} - - -int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_RENAME, cb); - - err = fs__capture_path(req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rename(req); - return req->result; - } -} - - -int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSYNC, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fsync(req); - return req->result; - } -} - - -int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fdatasync(req); - return req->result; - } -} - - -int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd, - int64_t offset, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb); - - req->file.fd = fd; - req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__ftruncate(req); - return req->result; - } -} - - - -int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out, - uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb); - - req->file.fd = fd_in; - req->fs.info.fd_out = fd_out; - req->fs.info.offset = in_offset; - req->fs.info.bufsml[0].len = length; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__sendfile(req); - return req->result; - } -} - - -int uv_fs_access(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_ACCESS, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) - return uv_translate_sys_error(err); - - req->flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } - - fs__access(req); - return req->result; -} - - -int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_CHMOD, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chmod(req); - return req->result; - } -} - - -int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode, - uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb); - - req->file.fd = fd; - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchmod(req); - return req->result; - } -} - - -int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, - double mtime, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_UTIME, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.time.atime = atime; - req->fs.time.mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__utime(req); - return req->result; - } -} - - -int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime, - double mtime, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FUTIME, cb); - - req->file.fd = fd; - req->fs.time.atime = atime; - req->fs.time.mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__futime(req); - return req->result; - } -} diff --git a/outside/libuv-v1.7.5/src/win/getaddrinfo.c b/outside/libuv-v1.7.5/src/win/getaddrinfo.c deleted file mode 100644 index 3d23660e88..0000000000 --- a/outside/libuv-v1.7.5/src/win/getaddrinfo.c +++ /dev/null @@ -1,361 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" - -/* EAI_* constants. */ -#include - - -int uv__getaddrinfo_translate_error(int sys_err) { - switch (sys_err) { - case 0: return 0; - case WSATRY_AGAIN: return UV_EAI_AGAIN; - case WSAEINVAL: return UV_EAI_BADFLAGS; - case WSANO_RECOVERY: return UV_EAI_FAIL; - case WSAEAFNOSUPPORT: return UV_EAI_FAMILY; - case WSA_NOT_ENOUGH_MEMORY: return UV_EAI_MEMORY; - case WSAHOST_NOT_FOUND: return UV_EAI_NONAME; - case WSATYPE_NOT_FOUND: return UV_EAI_SERVICE; - case WSAESOCKTNOSUPPORT: return UV_EAI_SOCKTYPE; - default: return uv_translate_sys_error(sys_err); - } -} - - -/* - * MinGW is missing this - */ -#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR) - typedef struct addrinfoW { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - WCHAR* ai_canonname; - struct sockaddr* ai_addr; - struct addrinfoW* ai_next; - } ADDRINFOW, *PADDRINFOW; - - DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node, - const WCHAR* service, - const ADDRINFOW* hints, - PADDRINFOW* result); - - DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo); -#endif - - -/* adjust size value to be multiple of 4. Use to keep pointer aligned */ -/* Do we need different versions of this for different architectures? */ -#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) - - -static void uv__getaddrinfo_work(struct uv__work* w) { - uv_getaddrinfo_t* req; - struct addrinfoW* hints; - int err; - - req = container_of(w, uv_getaddrinfo_t, work_req); - hints = req->addrinfow; - req->addrinfow = NULL; - err = GetAddrInfoW(req->node, req->service, hints, &req->addrinfow); - req->retcode = uv__getaddrinfo_translate_error(err); -} - - -/* - * Called from uv_run when complete. Call user specified callback - * then free returned addrinfo - * Returned addrinfo strings are converted from UTF-16 to UTF-8. - * - * To minimize allocation we calculate total size required, - * and copy all structs and referenced strings into the one block. - * Each size calculation is adjusted to avoid unaligned pointers. - */ -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_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); - struct addrinfoW* addrinfow_ptr; - struct addrinfo* addrinfo_ptr; - char* alloc_ptr = NULL; - char* cur_ptr = NULL; - - req = container_of(w, uv_getaddrinfo_t, work_req); - - /* release input parameter memory */ - if (req->alloc != NULL) { - uv__free(req->alloc); - req->alloc = NULL; - } - - if (status == UV_ECANCELED) { - assert(req->retcode == 0); - req->retcode = UV_EAI_CANCELED; - goto complete; - } - - if (req->retcode == 0) { - /* convert addrinfoW to addrinfo */ - /* first calculate required length */ - addrinfow_ptr = req->addrinfow; - while (addrinfow_ptr != NULL) { - addrinfo_len += addrinfo_struct_len + - ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); - if (addrinfow_ptr->ai_canonname != NULL) { - name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); - if (name_len == 0) { - req->retcode = uv_translate_sys_error(GetLastError()); - goto complete; - } - addrinfo_len += ALIGNED_SIZE(name_len); - } - addrinfow_ptr = addrinfow_ptr->ai_next; - } - - /* allocate memory for addrinfo results */ - alloc_ptr = (char*)uv__malloc(addrinfo_len); - - /* do conversions */ - if (alloc_ptr != NULL) { - cur_ptr = alloc_ptr; - addrinfow_ptr = req->addrinfow; - - while (addrinfow_ptr != NULL) { - /* copy addrinfo struct data */ - assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); - addrinfo_ptr = (struct addrinfo*)cur_ptr; - addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; - addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; - addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; - addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags; - addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen; - addrinfo_ptr->ai_canonname = NULL; - addrinfo_ptr->ai_addr = NULL; - addrinfo_ptr->ai_next = NULL; - - cur_ptr += addrinfo_struct_len; - - /* copy sockaddr */ - if (addrinfo_ptr->ai_addrlen > 0) { - assert(cur_ptr + addrinfo_ptr->ai_addrlen <= - alloc_ptr + addrinfo_len); - memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); - addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; - cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); - } - - /* convert canonical name to UTF-8 */ - if (addrinfow_ptr->ai_canonname != NULL) { - name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, - -1, - NULL, - 0); - assert(name_len > 0); - assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); - name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, - -1, - cur_ptr, - name_len); - assert(name_len > 0); - addrinfo_ptr->ai_canonname = cur_ptr; - cur_ptr += ALIGNED_SIZE(name_len); - } - assert(cur_ptr <= alloc_ptr + addrinfo_len); - - /* set next ptr */ - addrinfow_ptr = addrinfow_ptr->ai_next; - if (addrinfow_ptr != NULL) { - addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; - } - } - req->addrinfo = (struct addrinfo*)alloc_ptr; - } else { - req->retcode = UV_EAI_MEMORY; - } - } - - /* return memory to system */ - if (req->addrinfow != NULL) { - FreeAddrInfoW(req->addrinfow); - req->addrinfow = NULL; - } - -complete: - uv__req_unregister(req->loop, req); - - /* finally do callback with converted result */ - if (req->getaddrinfo_cb) - req->getaddrinfo_cb(req, req->retcode, req->addrinfo); -} - - -void uv_freeaddrinfo(struct addrinfo* ai) { - char* alloc_ptr = (char*)ai; - - /* release copied result memory */ - if (alloc_ptr != NULL) { - uv__free(alloc_ptr); - } -} - - -/* - * Entry point for getaddrinfo - * we convert the UTF-8 strings to UNICODE - * and save the UNICODE string pointers in the req - * We also copy hints so that caller does not need to keep memory until the - * callback. - * return 0 if a callback will be made - * return error code if validation fails - * - * To minimize allocation we calculate total size required, - * and copy all structs and referenced strings into the one block. - * Each size calculation is adjusted to avoid unaligned pointers. - */ -int uv_getaddrinfo(uv_loop_t* loop, - uv_getaddrinfo_t* req, - uv_getaddrinfo_cb getaddrinfo_cb, - const char* node, - const char* service, - const struct addrinfo* hints) { - int nodesize = 0; - int servicesize = 0; - int hintssize = 0; - char* alloc_ptr = NULL; - int err; - - if (req == NULL || (node == NULL && service == NULL)) { - err = WSAEINVAL; - goto error; - } - - uv_req_init(loop, (uv_req_t*)req); - - req->getaddrinfo_cb = getaddrinfo_cb; - req->addrinfo = NULL; - req->type = UV_GETADDRINFO; - req->loop = loop; - req->retcode = 0; - - /* calculate required memory size for all input values */ - if (node != NULL) { - nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR)); - if (nodesize == 0) { - err = GetLastError(); - goto error; - } - } - - if (service != NULL) { - servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) * - sizeof(WCHAR)); - if (servicesize == 0) { - err = GetLastError(); - goto error; - } - } - 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; - } - - /* save alloc_ptr now so we can free if error */ - req->alloc = (void*)alloc_ptr; - - /* convert node string to UTF16 into allocated memory and save pointer in */ - /* the request. */ - if (node != NULL) { - req->node = (WCHAR*)alloc_ptr; - if (uv_utf8_to_utf16(node, - (WCHAR*) alloc_ptr, - nodesize / sizeof(WCHAR)) == 0) { - err = GetLastError(); - goto error; - } - alloc_ptr += nodesize; - } else { - req->node = NULL; - } - - /* convert service string to UTF16 into allocated memory and save pointer */ - /* in the req. */ - if (service != NULL) { - req->service = (WCHAR*)alloc_ptr; - if (uv_utf8_to_utf16(service, - (WCHAR*) alloc_ptr, - servicesize / sizeof(WCHAR)) == 0) { - err = GetLastError(); - goto error; - } - alloc_ptr += servicesize; - } 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->ai_family = hints->ai_family; - req->addrinfow->ai_socktype = hints->ai_socktype; - req->addrinfow->ai_protocol = hints->ai_protocol; - req->addrinfow->ai_flags = hints->ai_flags; - req->addrinfow->ai_addrlen = 0; - req->addrinfow->ai_canonname = NULL; - req->addrinfow->ai_addr = NULL; - req->addrinfow->ai_next = NULL; - } else { - req->addrinfow = NULL; - } - - uv__req_register(loop, req); - - if (getaddrinfo_cb) { - uv__work_submit(loop, - &req->work_req, - uv__getaddrinfo_work, - uv__getaddrinfo_done); - return 0; - } else { - uv__getaddrinfo_work(&req->work_req); - uv__getaddrinfo_done(&req->work_req, 0); - return req->retcode; - } - -error: - if (req != NULL && req->alloc != NULL) { - uv__free(req->alloc); - } - return uv_translate_sys_error(err); -} diff --git a/outside/libuv-v1.7.5/src/win/getnameinfo.c b/outside/libuv-v1.7.5/src/win/getnameinfo.c deleted file mode 100644 index 66b64b8832..0000000000 --- a/outside/libuv-v1.7.5/src/win/getnameinfo.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to -* deal in the Software without restriction, including without limitation the -* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -* sell copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -* IN THE SOFTWARE. -*/ - -#include -#include - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" - -#ifndef GetNameInfo -int WSAAPI GetNameInfoW( - const SOCKADDR *pSockaddr, - socklen_t SockaddrLength, - PWCHAR pNodeBuffer, - DWORD NodeBufferSize, - PWCHAR pServiceBuffer, - DWORD ServiceBufferSize, - INT Flags -); -#endif - -static void uv__getnameinfo_work(struct uv__work* w) { - uv_getnameinfo_t* req; - WCHAR host[NI_MAXHOST]; - WCHAR service[NI_MAXSERV]; - int ret = 0; - - req = container_of(w, uv_getnameinfo_t, work_req); - if (GetNameInfoW((struct sockaddr*)&req->storage, - sizeof(req->storage), - host, - ARRAY_SIZE(host), - service, - ARRAY_SIZE(service), - req->flags)) { - ret = WSAGetLastError(); - } - req->retcode = uv__getaddrinfo_translate_error(ret); - - /* convert results to UTF-8 */ - WideCharToMultiByte(CP_UTF8, - 0, - host, - -1, - req->host, - sizeof(req->host), - NULL, - NULL); - - WideCharToMultiByte(CP_UTF8, - 0, - service, - -1, - req->service, - sizeof(req->service), - NULL, - NULL); -} - - -/* -* Called from uv_run when complete. -*/ -static void uv__getnameinfo_done(struct uv__work* w, int status) { - uv_getnameinfo_t* req; - char* host; - char* service; - - req = container_of(w, uv_getnameinfo_t, work_req); - uv__req_unregister(req->loop, req); - host = service = NULL; - - if (status == UV_ECANCELED) { - assert(req->retcode == 0); - req->retcode = UV_EAI_CANCELED; - } else if (req->retcode == 0) { - host = req->host; - service = req->service; - } - - if (req->getnameinfo_cb) - req->getnameinfo_cb(req, req->retcode, host, service); -} - - -/* -* Entry point for getnameinfo -* return 0 if a callback will be made -* return error code if validation fails -*/ -int uv_getnameinfo(uv_loop_t* loop, - uv_getnameinfo_t* req, - uv_getnameinfo_cb getnameinfo_cb, - const struct sockaddr* addr, - int flags) { - if (req == NULL || addr == NULL) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) { - memcpy(&req->storage, - addr, - sizeof(struct sockaddr_in)); - } else if (addr->sa_family == AF_INET6) { - memcpy(&req->storage, - addr, - sizeof(struct sockaddr_in6)); - } else { - return UV_EINVAL; - } - - uv_req_init(loop, (uv_req_t*)req); - uv__req_register(loop, req); - - req->getnameinfo_cb = getnameinfo_cb; - req->flags = flags; - req->type = UV_GETNAMEINFO; - req->loop = loop; - req->retcode = 0; - - if (getnameinfo_cb) { - uv__work_submit(loop, - &req->work_req, - uv__getnameinfo_work, - uv__getnameinfo_done); - return 0; - } else { - uv__getnameinfo_work(&req->work_req); - uv__getnameinfo_done(&req->work_req, 0); - return req->retcode; - } -} diff --git a/outside/libuv-v1.7.5/src/win/handle-inl.h b/outside/libuv-v1.7.5/src/win/handle-inl.h deleted file mode 100644 index 8d0334cc52..0000000000 --- a/outside/libuv-v1.7.5/src/win/handle-inl.h +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_HANDLE_INL_H_ -#define UV_WIN_HANDLE_INL_H_ - -#include -#include - -#include "uv.h" -#include "internal.h" - - -#define DECREASE_ACTIVE_COUNT(loop, handle) \ - do { \ - if (--(handle)->activecnt == 0 && \ - !((handle)->flags & UV__HANDLE_CLOSING)) { \ - uv__handle_stop((handle)); \ - } \ - assert((handle)->activecnt >= 0); \ - } while (0) - - -#define INCREASE_ACTIVE_COUNT(loop, handle) \ - do { \ - if ((handle)->activecnt++ == 0) { \ - uv__handle_start((handle)); \ - } \ - assert((handle)->activecnt > 0); \ - } while (0) - - -#define DECREASE_PENDING_REQ_COUNT(handle) \ - do { \ - assert(handle->reqs_pending > 0); \ - handle->reqs_pending--; \ - \ - if (handle->flags & UV__HANDLE_CLOSING && \ - handle->reqs_pending == 0) { \ - uv_want_endgame(loop, (uv_handle_t*)handle); \ - } \ - } while (0) - - -#define uv__handle_closing(handle) \ - do { \ - assert(!((handle)->flags & UV__HANDLE_CLOSING)); \ - \ - if (!(((handle)->flags & UV__HANDLE_ACTIVE) && \ - ((handle)->flags & UV__HANDLE_REF))) \ - uv__active_handle_add((uv_handle_t*) (handle)); \ - \ - (handle)->flags |= UV__HANDLE_CLOSING; \ - (handle)->flags &= ~UV__HANDLE_ACTIVE; \ - } while (0) - - -#define uv__handle_close(handle) \ - do { \ - QUEUE_REMOVE(&(handle)->handle_queue); \ - uv__active_handle_rm((uv_handle_t*) (handle)); \ - \ - (handle)->flags |= UV_HANDLE_CLOSED; \ - \ - if ((handle)->close_cb) \ - (handle)->close_cb((uv_handle_t*) (handle)); \ - } while (0) - - -INLINE static void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) { - if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) { - handle->flags |= UV_HANDLE_ENDGAME_QUEUED; - - handle->endgame_next = loop->endgame_handles; - loop->endgame_handles = handle; - } -} - - -INLINE static void uv_process_endgames(uv_loop_t* loop) { - uv_handle_t* handle; - - while (loop->endgame_handles) { - handle = loop->endgame_handles; - loop->endgame_handles = handle->endgame_next; - - handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED; - - switch (handle->type) { - case UV_TCP: - uv_tcp_endgame(loop, (uv_tcp_t*) handle); - break; - - case UV_NAMED_PIPE: - uv_pipe_endgame(loop, (uv_pipe_t*) handle); - break; - - case UV_TTY: - uv_tty_endgame(loop, (uv_tty_t*) handle); - break; - - case UV_UDP: - uv_udp_endgame(loop, (uv_udp_t*) handle); - break; - - case UV_POLL: - uv_poll_endgame(loop, (uv_poll_t*) handle); - break; - - case UV_TIMER: - uv_timer_endgame(loop, (uv_timer_t*) handle); - break; - - case UV_PREPARE: - case UV_CHECK: - case UV_IDLE: - uv_loop_watcher_endgame(loop, handle); - break; - - case UV_ASYNC: - uv_async_endgame(loop, (uv_async_t*) handle); - break; - - case UV_SIGNAL: - uv_signal_endgame(loop, (uv_signal_t*) handle); - break; - - case UV_PROCESS: - uv_process_endgame(loop, (uv_process_t*) handle); - break; - - case UV_FS_EVENT: - uv_fs_event_endgame(loop, (uv_fs_event_t*) handle); - break; - - case UV_FS_POLL: - uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle); - break; - - default: - assert(0); - break; - } - } -} - -INLINE static HANDLE uv__get_osfhandle(int fd) -{ - /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */ - /* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE */ - /* for invalid FDs in release builds (or if you let the assert continue). */ - /* So this wrapper function disables asserts when calling _get_osfhandle. */ - - HANDLE handle; - UV_BEGIN_DISABLE_CRT_ASSERT(); - handle = (HANDLE) _get_osfhandle(fd); - UV_END_DISABLE_CRT_ASSERT(); - return handle; -} - -#endif /* UV_WIN_HANDLE_INL_H_ */ diff --git a/outside/libuv-v1.7.5/src/win/handle.c b/outside/libuv-v1.7.5/src/win/handle.c deleted file mode 100644 index 72b49d9790..0000000000 --- a/outside/libuv-v1.7.5/src/win/handle.c +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -uv_handle_type uv_guess_handle(uv_file file) { - HANDLE handle; - DWORD mode; - - if (file < 0) { - return UV_UNKNOWN_HANDLE; - } - - handle = uv__get_osfhandle(file); - - switch (GetFileType(handle)) { - case FILE_TYPE_CHAR: - if (GetConsoleMode(handle, &mode)) { - return UV_TTY; - } else { - return UV_FILE; - } - - case FILE_TYPE_PIPE: - return UV_NAMED_PIPE; - - case FILE_TYPE_DISK: - return UV_FILE; - - default: - return UV_UNKNOWN_HANDLE; - } -} - - -int uv_is_active(const uv_handle_t* handle) { - return (handle->flags & UV__HANDLE_ACTIVE) && - !(handle->flags & UV__HANDLE_CLOSING); -} - - -void uv_close(uv_handle_t* handle, uv_close_cb cb) { - uv_loop_t* loop = handle->loop; - - if (handle->flags & UV__HANDLE_CLOSING) { - assert(0); - return; - } - - handle->close_cb = cb; - - /* Handle-specific close actions */ - switch (handle->type) { - case UV_TCP: - uv_tcp_close(loop, (uv_tcp_t*)handle); - return; - - case UV_NAMED_PIPE: - uv_pipe_close(loop, (uv_pipe_t*) handle); - return; - - case UV_TTY: - uv_tty_close((uv_tty_t*) handle); - return; - - case UV_UDP: - uv_udp_close(loop, (uv_udp_t*) handle); - return; - - case UV_POLL: - uv_poll_close(loop, (uv_poll_t*) handle); - return; - - case UV_TIMER: - uv_timer_stop((uv_timer_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_PREPARE: - uv_prepare_stop((uv_prepare_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_CHECK: - uv_check_stop((uv_check_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_IDLE: - uv_idle_stop((uv_idle_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_ASYNC: - uv_async_close(loop, (uv_async_t*) handle); - return; - - case UV_SIGNAL: - uv_signal_close(loop, (uv_signal_t*) handle); - return; - - case UV_PROCESS: - uv_process_close(loop, (uv_process_t*) handle); - return; - - case UV_FS_EVENT: - uv_fs_event_close(loop, (uv_fs_event_t*) handle); - return; - - case UV_FS_POLL: - uv__fs_poll_close((uv_fs_poll_t*) handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - default: - /* Not supported */ - abort(); - } -} - - -int uv_is_closing(const uv_handle_t* handle) { - return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED)); -} diff --git a/outside/libuv-v1.7.5/src/win/internal.h b/outside/libuv-v1.7.5/src/win/internal.h deleted file mode 100644 index 8d4081bdb5..0000000000 --- a/outside/libuv-v1.7.5/src/win/internal.h +++ /dev/null @@ -1,381 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_INTERNAL_H_ -#define UV_WIN_INTERNAL_H_ - -#include "uv.h" -#include "../uv-common.h" - -#include "tree.h" -#include "winapi.h" -#include "winsock.h" - -#ifdef _MSC_VER -# define INLINE __inline -# define UV_THREAD_LOCAL __declspec( thread ) -#else -# define INLINE inline -# define UV_THREAD_LOCAL __thread -#endif - - -#ifdef _DEBUG - -extern UV_THREAD_LOCAL int uv__crt_assert_enabled; - -#define UV_BEGIN_DISABLE_CRT_ASSERT() \ - { \ - int uv__saved_crt_assert_enabled = uv__crt_assert_enabled; \ - uv__crt_assert_enabled = FALSE; - - -#define UV_END_DISABLE_CRT_ASSERT() \ - uv__crt_assert_enabled = uv__saved_crt_assert_enabled; \ - } - -#else -#define UV_BEGIN_DISABLE_CRT_ASSERT() -#define UV_END_DISABLE_CRT_ASSERT() -#endif - -/* - * Handles - * (also see handle-inl.h) - */ - -/* Used by all handles. */ -#define UV_HANDLE_CLOSED 0x00000002 -#define UV_HANDLE_ENDGAME_QUEUED 0x00000008 - -/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */ -/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */ -/* uv-common.h: #define UV__HANDLE_REF 0x00000020 */ -/* uv-common.h: #define UV_HANDLE_INTERNAL 0x00000080 */ - -/* Used by streams and UDP handles. */ -#define UV_HANDLE_READING 0x00000100 -#define UV_HANDLE_BOUND 0x00000200 -#define UV_HANDLE_LISTENING 0x00000800 -#define UV_HANDLE_CONNECTION 0x00001000 -#define UV_HANDLE_READABLE 0x00008000 -#define UV_HANDLE_WRITABLE 0x00010000 -#define UV_HANDLE_READ_PENDING 0x00020000 -#define UV_HANDLE_SYNC_BYPASS_IOCP 0x00040000 -#define UV_HANDLE_ZERO_READ 0x00080000 -#define UV_HANDLE_EMULATE_IOCP 0x00100000 -#define UV_HANDLE_BLOCKING_WRITES 0x00200000 - -/* Used by uv_tcp_t and uv_udp_t handles */ -#define UV_HANDLE_IPV6 0x01000000 - -/* Only used by uv_tcp_t handles. */ -#define UV_HANDLE_TCP_NODELAY 0x02000000 -#define UV_HANDLE_TCP_KEEPALIVE 0x04000000 -#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000 -#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING 0x10000000 -#define UV_HANDLE_TCP_SOCKET_CLOSED 0x20000000 -#define UV_HANDLE_SHARED_TCP_SOCKET 0x40000000 - -/* Only used by uv_pipe_t handles. */ -#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000 -#define UV_HANDLE_PIPESERVER 0x02000000 -#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000 - -/* Only used by uv_tty_t handles. */ -#define UV_HANDLE_TTY_READABLE 0x01000000 -#define UV_HANDLE_TTY_RAW 0x02000000 -#define UV_HANDLE_TTY_SAVED_POSITION 0x04000000 -#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x08000000 - -/* Only used by uv_poll_t handles. */ -#define UV_HANDLE_POLL_SLOW 0x02000000 - - -/* - * Requests: see req-inl.h - */ - - -/* - * Streams: see stream-inl.h - */ - - -/* - * TCP - */ - -typedef struct { - WSAPROTOCOL_INFOW socket_info; - int delayed_error; -} uv__ipc_socket_info_ex; - -int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb); -int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client); -int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -int uv__tcp_try_write(uv_tcp_t* handle, const uv_buf_t bufs[], - unsigned int nbufs); - -void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req); -void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_write_t* req); -void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* req); -void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_connect_t* req); - -void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp); -void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle); - -int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex, - int tcp_connection); - -int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, - LPWSAPROTOCOL_INFOW protocol_info); - - -/* - * UDP - */ -void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req); -void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, - uv_udp_send_t* req); - -void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle); -void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle); - - -/* - * Pipes - */ -int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access, - char* name, size_t nameSize); - -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); -int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client); -int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, - uv_write_cb cb); -void uv__pipe_pause_read(uv_pipe_t* handle); -void uv__pipe_unpause_read(uv_pipe_t* handle); -void uv__pipe_stop_read(uv_pipe_t* handle); - -void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* req); -void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_write_t* req); -void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* raw_req); -void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_connect_t* req); -void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_shutdown_t* req); - -void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle); -void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle); -void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle); - - -/* - * TTY - */ -void uv_console_init(); - -int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_tty_read_stop(uv_tty_t* handle); -int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -int uv__tty_try_write(uv_tty_t* handle, const uv_buf_t bufs[], - unsigned int nbufs); -void uv_tty_close(uv_tty_t* handle); - -void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req); -void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, - uv_write_t* req); -/* TODO: remove me */ -void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* raw_req); -/* TODO: remove me */ -void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, - uv_connect_t* req); - -void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle); - - -/* - * Poll watchers - */ -void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req); - -int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle); -void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle); - - -/* - * Timers - */ -void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle); - -DWORD uv__next_timeout(const uv_loop_t* loop); -void uv__time_forward(uv_loop_t* loop, uint64_t msecs); -void uv_process_timers(uv_loop_t* loop); - - -/* - * Loop watchers - */ -void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle); - -void uv_prepare_invoke(uv_loop_t* loop); -void uv_check_invoke(uv_loop_t* loop); -void uv_idle_invoke(uv_loop_t* loop); - -void uv__once_init(); - - -/* - * Async watcher - */ -void uv_async_close(uv_loop_t* loop, uv_async_t* handle); -void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle); - -void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, - uv_req_t* req); - - -/* - * Signal watcher - */ -void uv_signals_init(); -int uv__signal_dispatch(int signum); - -void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle); -void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle); - -void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, - uv_req_t* req); - - -/* - * Spawn - */ -void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle); -void uv_process_close(uv_loop_t* loop, uv_process_t* handle); -void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle); - - -/* - * Error - */ -int uv_translate_sys_error(int sys_errno); - - -/* - * FS - */ -void uv_fs_init(); - - -/* - * FS Event - */ -void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, - uv_fs_event_t* handle); -void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle); -void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle); - - -/* - * Stat poller. - */ -void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); - - -/* - * Utilities. - */ -void uv__util_init(); - -uint64_t uv__hrtime(double scale); -int uv_parent_pid(); -__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); - - -/* - * Process stdio handles. - */ -int uv__stdio_create(uv_loop_t* loop, - const uv_process_options_t* options, - BYTE** buffer_ptr); -void uv__stdio_destroy(BYTE* buffer); -void uv__stdio_noinherit(BYTE* buffer); -int uv__stdio_verify(BYTE* buffer, WORD size); -WORD uv__stdio_size(BYTE* buffer); -HANDLE uv__stdio_handle(BYTE* buffer, int fd); - - -/* - * Winapi and ntapi utility functions - */ -void uv_winapi_init(); - - -/* - * Winsock utility functions - */ -void uv_winsock_init(); - -int uv_ntstatus_to_winsock_error(NTSTATUS status); - -BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target); -BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target); - -int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); -int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, - int* addr_len, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); - -int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, - AFD_POLL_INFO* info_out, OVERLAPPED* overlapped); - -/* Whether there are any non-IFS LSPs stacked on TCP */ -extern int uv_tcp_non_ifs_lsp_ipv4; -extern int uv_tcp_non_ifs_lsp_ipv6; - -/* Ip address used to bind to any port at any interface */ -extern struct sockaddr_in uv_addr_ip4_any_; -extern struct sockaddr_in6 uv_addr_ip6_any_; - -#endif /* UV_WIN_INTERNAL_H_ */ diff --git a/outside/libuv-v1.7.5/src/win/loop-watcher.c b/outside/libuv-v1.7.5/src/win/loop-watcher.c deleted file mode 100644 index 20e4509f83..0000000000 --- a/outside/libuv-v1.7.5/src/win/loop-watcher.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - handle->flags |= UV_HANDLE_CLOSED; - uv__handle_close(handle); - } -} - - -#define UV_LOOP_WATCHER_DEFINE(name, NAME) \ - int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ - uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \ - \ - return 0; \ - } \ - \ - \ - int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ - uv_loop_t* loop = handle->loop; \ - uv_##name##_t* old_head; \ - \ - assert(handle->type == UV_##NAME); \ - \ - if (uv__is_active(handle)) \ - return 0; \ - \ - if (cb == NULL) \ - return UV_EINVAL; \ - \ - old_head = loop->name##_handles; \ - \ - handle->name##_next = old_head; \ - handle->name##_prev = NULL; \ - \ - if (old_head) { \ - old_head->name##_prev = handle; \ - } \ - \ - loop->name##_handles = handle; \ - \ - handle->name##_cb = cb; \ - uv__handle_start(handle); \ - \ - return 0; \ - } \ - \ - \ - int uv_##name##_stop(uv_##name##_t* handle) { \ - uv_loop_t* loop = handle->loop; \ - \ - assert(handle->type == UV_##NAME); \ - \ - if (!uv__is_active(handle)) \ - return 0; \ - \ - /* Update loop head if needed */ \ - if (loop->name##_handles == handle) { \ - loop->name##_handles = handle->name##_next; \ - } \ - \ - /* Update the iterator-next pointer of needed */ \ - if (loop->next_##name##_handle == handle) { \ - loop->next_##name##_handle = handle->name##_next; \ - } \ - \ - if (handle->name##_prev) { \ - handle->name##_prev->name##_next = handle->name##_next; \ - } \ - if (handle->name##_next) { \ - handle->name##_next->name##_prev = handle->name##_prev; \ - } \ - \ - uv__handle_stop(handle); \ - \ - return 0; \ - } \ - \ - \ - void uv_##name##_invoke(uv_loop_t* loop) { \ - uv_##name##_t* handle; \ - \ - (loop)->next_##name##_handle = (loop)->name##_handles; \ - \ - while ((loop)->next_##name##_handle != NULL) { \ - handle = (loop)->next_##name##_handle; \ - (loop)->next_##name##_handle = handle->name##_next; \ - \ - handle->name##_cb(handle); \ - } \ - } - -UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) -UV_LOOP_WATCHER_DEFINE(check, CHECK) -UV_LOOP_WATCHER_DEFINE(idle, IDLE) diff --git a/outside/libuv-v1.7.5/src/win/pipe.c b/outside/libuv-v1.7.5/src/win/pipe.c deleted file mode 100644 index 8312b1ceb9..0000000000 --- a/outside/libuv-v1.7.5/src/win/pipe.c +++ /dev/null @@ -1,2114 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - -typedef struct uv__ipc_queue_item_s uv__ipc_queue_item_t; - -struct uv__ipc_queue_item_s { - /* - * NOTE: It is important for socket_info_ex to be the first field, - * because we will we assigning it to the pending_ipc_info.socket_info - */ - uv__ipc_socket_info_ex socket_info_ex; - QUEUE member; - int tcp_connection; -}; - -/* A zero-size buffer for use by uv_pipe_read */ -static char uv_zero_[] = ""; - -/* Null uv_buf_t */ -static const uv_buf_t uv_null_buf_ = { 0, NULL }; - -/* The timeout that the pipe will wait for the remote end to write data */ -/* when the local ends wants to shut it down. */ -static const int64_t eof_timeout = 50; /* ms */ - -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; - -/* IPC protocol flags. */ -#define UV_IPC_RAW_DATA 0x0001 -#define UV_IPC_TCP_SERVER 0x0002 -#define UV_IPC_TCP_CONNECTION 0x0004 - -/* IPC frame header. */ -typedef struct { - int flags; - uint64_t raw_data_length; -} uv_ipc_frame_header_t; - -/* IPC frame, which contains an imported TCP socket stream. */ -typedef struct { - uv_ipc_frame_header_t header; - uv__ipc_socket_info_ex socket_info_ex; -} uv_ipc_frame_uv_stream; - -static void eof_timer_init(uv_pipe_t* pipe); -static void eof_timer_start(uv_pipe_t* pipe); -static void eof_timer_stop(uv_pipe_t* pipe); -static void eof_timer_cb(uv_timer_t* timer); -static void eof_timer_destroy(uv_pipe_t* pipe); -static void eof_timer_close_cb(uv_handle_t* handle); - - -static void uv_unique_pipe_name(char* ptr, char* name, size_t size) { - _snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId()); -} - - -int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { - uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); - - handle->reqs_pending = 0; - handle->handle = INVALID_HANDLE_VALUE; - handle->name = NULL; - handle->pipe.conn.ipc_pid = 0; - handle->pipe.conn.remaining_ipc_rawdata_bytes = 0; - QUEUE_INIT(&handle->pipe.conn.pending_ipc_info.queue); - handle->pipe.conn.pending_ipc_info.queue_len = 0; - handle->ipc = ipc; - handle->pipe.conn.non_overlapped_writes_tail = NULL; - handle->pipe.conn.readfile_thread = NULL; - - uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req); - - return 0; -} - - -static void uv_pipe_connection_init(uv_pipe_t* handle) { - uv_connection_init((uv_stream_t*) handle); - handle->read_req.data = handle; - handle->pipe.conn.eof_timer = NULL; - assert(!(handle->flags & UV_HANDLE_PIPESERVER)); - if (pCancelSynchronousIo && - handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - uv_mutex_init(&handle->pipe.conn.readfile_mutex); - handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE; - } -} - - -static HANDLE open_named_pipe(const WCHAR* name, DWORD* duplex_flags) { - HANDLE pipeHandle; - - /* - * Assume that we have a duplex pipe first, so attempt to - * connect with GENERIC_READ | GENERIC_WRITE. - */ - pipeHandle = CreateFileW(name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - return pipeHandle; - } - - /* - * If the pipe is not duplex CreateFileW fails with - * ERROR_ACCESS_DENIED. In that case try to connect - * as a read-only or write-only. - */ - if (GetLastError() == ERROR_ACCESS_DENIED) { - pipeHandle = CreateFileW(name, - GENERIC_READ | FILE_WRITE_ATTRIBUTES, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_READABLE; - return pipeHandle; - } - } - - if (GetLastError() == ERROR_ACCESS_DENIED) { - pipeHandle = CreateFileW(name, - GENERIC_WRITE | FILE_READ_ATTRIBUTES, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_WRITABLE; - return pipeHandle; - } - } - - return INVALID_HANDLE_VALUE; -} - - -static void close_pipe(uv_pipe_t* pipe) { - assert(pipe->u.fd == -1 || pipe->u.fd > 2); - if (pipe->u.fd == -1) - CloseHandle(pipe->handle); - else - close(pipe->u.fd); - - pipe->u.fd = -1; - pipe->handle = INVALID_HANDLE_VALUE; -} - - -int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access, - char* name, size_t nameSize) { - HANDLE pipeHandle; - int err; - char* ptr = (char*)handle; - - for (;;) { - uv_unique_pipe_name(ptr, name, nameSize); - - pipeHandle = CreateNamedPipeA(name, - access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - /* No name collisions. We're done. */ - break; - } - - err = GetLastError(); - if (err != ERROR_PIPE_BUSY && err != ERROR_ACCESS_DENIED) { - goto error; - } - - /* Pipe name collision. Increment the pointer and try again. */ - ptr++; - } - - if (CreateIoCompletionPort(pipeHandle, - loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - err = GetLastError(); - goto error; - } - - uv_pipe_connection_init(handle); - handle->handle = pipeHandle; - - return 0; - - error: - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - } - - return err; -} - - -static int uv_set_pipe_handle(uv_loop_t* loop, - uv_pipe_t* handle, - HANDLE pipeHandle, - int fd, - DWORD duplex_flags) { - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_MODE_INFORMATION mode_info; - DWORD mode = PIPE_READMODE_BYTE | PIPE_WAIT; - DWORD current_mode = 0; - DWORD err = 0; - - if (!(handle->flags & UV_HANDLE_PIPESERVER) && - handle->handle != INVALID_HANDLE_VALUE) - return UV_EBUSY; - - if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED) { - /* - * SetNamedPipeHandleState can fail if the handle doesn't have either - * GENERIC_WRITE or FILE_WRITE_ATTRIBUTES. - * But if the handle already has the desired wait and blocking modes - * we can continue. - */ - if (!GetNamedPipeHandleState(pipeHandle, ¤t_mode, NULL, NULL, - NULL, NULL, 0)) { - return -1; - } else if (current_mode & PIPE_NOWAIT) { - SetLastError(ERROR_ACCESS_DENIED); - return -1; - } - } else { - /* If this returns ERROR_INVALID_PARAMETER we probably opened - * something that is not a pipe. */ - if (err == ERROR_INVALID_PARAMETER) { - SetLastError(WSAENOTSOCK); - } - return -1; - } - } - - /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */ - nt_status = pNtQueryInformationFile(pipeHandle, - &io_status, - &mode_info, - sizeof(mode_info), - FileModeInformation); - if (nt_status != STATUS_SUCCESS) { - return -1; - } - - if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT || - mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) { - /* Non-overlapped pipe. */ - handle->flags |= UV_HANDLE_NON_OVERLAPPED_PIPE; - } else { - /* Overlapped pipe. Try to associate with IOCP. */ - if (CreateIoCompletionPort(pipeHandle, - loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - handle->flags |= UV_HANDLE_EMULATE_IOCP; - } - } - - handle->handle = pipeHandle; - handle->u.fd = fd; - handle->flags |= duplex_flags; - - return 0; -} - - -static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) { - uv_loop_t* loop; - uv_pipe_t* handle; - uv_shutdown_t* req; - - req = (uv_shutdown_t*) parameter; - assert(req); - handle = (uv_pipe_t*) req->handle; - assert(handle); - loop = handle->loop; - assert(loop); - - FlushFileBuffers(handle->handle); - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { - int err; - DWORD result; - uv_shutdown_t* req; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_PIPE_LOCAL_INFORMATION pipe_info; - uv__ipc_queue_item_t* item; - - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE; - uv_mutex_destroy(&handle->pipe.conn.readfile_mutex); - } - - if ((handle->flags & UV_HANDLE_CONNECTION) && - handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - req = handle->stream.conn.shutdown_req; - - /* Clear the shutdown_req field so we don't go here again. */ - handle->stream.conn.shutdown_req = NULL; - - if (handle->flags & UV__HANDLE_CLOSING) { - UNREGISTER_HANDLE_REQ(loop, handle, req); - - /* Already closing. Cancel the shutdown. */ - if (req->cb) { - req->cb(req, UV_ECANCELED); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - /* Try to avoid flushing the pipe buffer in the thread pool. */ - nt_status = pNtQueryInformationFile(handle->handle, - &io_status, - &pipe_info, - sizeof pipe_info, - FilePipeLocalInformation); - - if (nt_status != STATUS_SUCCESS) { - /* Failure */ - UNREGISTER_HANDLE_REQ(loop, handle, req); - - handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ - if (req->cb) { - err = pRtlNtStatusToDosError(nt_status); - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) { - /* Short-circuit, no need to call FlushFileBuffers. */ - uv_insert_pending_req(loop, (uv_req_t*) req); - return; - } - - /* Run FlushFileBuffers in the thread pool. */ - result = QueueUserWorkItem(pipe_shutdown_thread_proc, - req, - WT_EXECUTELONGFUNCTION); - if (result) { - return; - - } else { - /* Failure. */ - UNREGISTER_HANDLE_REQ(loop, handle, req); - - handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ - if (req->cb) { - err = GetLastError(); - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (handle->flags & UV_HANDLE_CONNECTION) { - /* Free pending sockets */ - while (!QUEUE_EMPTY(&handle->pipe.conn.pending_ipc_info.queue)) { - QUEUE* q; - SOCKET socket; - - q = QUEUE_HEAD(&handle->pipe.conn.pending_ipc_info.queue); - QUEUE_REMOVE(q); - item = QUEUE_DATA(q, uv__ipc_queue_item_t, member); - - /* Materialize socket and close it */ - socket = WSASocketW(FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - &item->socket_info_ex.socket_info, - 0, - WSA_FLAG_OVERLAPPED); - uv__free(item); - - if (socket != INVALID_SOCKET) - closesocket(socket); - } - handle->pipe.conn.pending_ipc_info.queue_len = 0; - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->read_req.wait_handle); - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - } - if (handle->read_req.event_handle) { - CloseHandle(handle->read_req.event_handle); - handle->read_req.event_handle = NULL; - } - } - } - - if (handle->flags & UV_HANDLE_PIPESERVER) { - assert(handle->pipe.serv.accept_reqs); - uv__free(handle->pipe.serv.accept_reqs); - handle->pipe.serv.accept_reqs = NULL; - } - - uv__handle_close(handle); - } -} - - -void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { - if (handle->flags & UV_HANDLE_BOUND) - return; - handle->pipe.serv.pending_instances = count; - handle->flags |= UV_HANDLE_PIPESERVER; -} - - -/* Creates a pipe server. */ -int uv_pipe_bind(uv_pipe_t* handle, const char* name) { - uv_loop_t* loop = handle->loop; - int i, err, nameSize; - uv_pipe_accept_t* req; - - if (handle->flags & UV_HANDLE_BOUND) { - return UV_EINVAL; - } - - if (!name) { - return UV_EINVAL; - } - - if (!(handle->flags & UV_HANDLE_PIPESERVER)) { - handle->pipe.serv.pending_instances = default_pending_pipe_instances; - } - - 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"); - } - - for (i = 0; i < handle->pipe.serv.pending_instances; i++) { - req = &handle->pipe.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; - req->data = handle; - req->pipeHandle = INVALID_HANDLE_VALUE; - req->next_pending = NULL; - } - - /* Convert name to UTF16. */ - nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)uv__malloc(nameSize); - if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) { - err = GetLastError(); - goto error; - } - - /* - * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE. - * If this fails then there's already a pipe server for the given pipe name. - */ - handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | - FILE_FLAG_FIRST_PIPE_INSTANCE, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (handle->pipe.serv.accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) { - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED) { - err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */ - } else if (err == ERROR_PATH_NOT_FOUND || err == ERROR_INVALID_NAME) { - err = WSAEACCES; /* Translates to UV_EACCES. */ - } - goto error; - } - - if (uv_set_pipe_handle(loop, - handle, - handle->pipe.serv.accept_reqs[0].pipeHandle, - -1, - 0)) { - err = GetLastError(); - goto error; - } - - handle->pipe.serv.pending_accepts = NULL; - handle->flags |= UV_HANDLE_PIPESERVER; - handle->flags |= UV_HANDLE_BOUND; - - return 0; - -error: - if (handle->name) { - uv__free(handle->name); - handle->name = NULL; - } - - if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle); - handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE; - } - - return uv_translate_sys_error(err); -} - - -static DWORD WINAPI pipe_connect_thread_proc(void* parameter) { - uv_loop_t* loop; - uv_pipe_t* handle; - uv_connect_t* req; - HANDLE pipeHandle = INVALID_HANDLE_VALUE; - DWORD duplex_flags; - - req = (uv_connect_t*) parameter; - assert(req); - handle = (uv_pipe_t*) req->handle; - assert(handle); - loop = handle->loop; - assert(loop); - - /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */ - /* We wait for the pipe to become available with WaitNamedPipe. */ - while (WaitNamedPipeW(handle->name, 30000)) { - /* The pipe is now available, try to connect. */ - pipeHandle = open_named_pipe(handle->name, &duplex_flags); - if (pipeHandle != INVALID_HANDLE_VALUE) { - break; - } - - SwitchToThread(); - } - - if (pipeHandle != INVALID_HANDLE_VALUE && - !uv_set_pipe_handle(loop, handle, pipeHandle, -1, duplex_flags)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_ERROR(req, GetLastError()); - } - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, - const char* name, uv_connect_cb cb) { - uv_loop_t* loop = handle->loop; - int err, nameSize; - HANDLE pipeHandle = INVALID_HANDLE_VALUE; - DWORD duplex_flags; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - /* Convert name to UTF16. */ - nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)uv__malloc(nameSize); - if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) { - err = GetLastError(); - goto error; - } - - pipeHandle = open_named_pipe(handle->name, &duplex_flags); - if (pipeHandle == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_PIPE_BUSY) { - /* Wait for the server to make a pipe instance available. */ - if (!QueueUserWorkItem(&pipe_connect_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - err = GetLastError(); - goto error; - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - - return; - } - - err = GetLastError(); - goto error; - } - - assert(pipeHandle != INVALID_HANDLE_VALUE); - - if (uv_set_pipe_handle(loop, - (uv_pipe_t*) req->handle, - pipeHandle, - -1, - duplex_flags)) { - err = GetLastError(); - goto error; - } - - SET_REQ_SUCCESS(req); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - return; - -error: - if (handle->name) { - uv__free(handle->name); - handle->name = NULL; - } - - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - } - - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, err); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - return; -} - - -void uv__pipe_pause_read(uv_pipe_t* handle) { - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - /* Pause the ReadFile task briefly, to work - around the Windows kernel bug that causes - any access to a NamedPipe to deadlock if - any process has called ReadFile */ - HANDLE h; - uv_mutex_lock(&handle->pipe.conn.readfile_mutex); - h = handle->pipe.conn.readfile_thread; - while (h) { - /* spinlock: we expect this to finish quickly, - or we are probably about to deadlock anyways - (in the kernel), so it doesn't matter */ - pCancelSynchronousIo(h); - SwitchToThread(); /* yield thread control briefly */ - h = handle->pipe.conn.readfile_thread; - } - } -} - - -void uv__pipe_unpause_read(uv_pipe_t* handle) { - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - uv_mutex_unlock(&handle->pipe.conn.readfile_mutex); - } -} - - -void uv__pipe_stop_read(uv_pipe_t* handle) { - handle->flags &= ~UV_HANDLE_READING; - uv__pipe_pause_read((uv_pipe_t*)handle); - uv__pipe_unpause_read((uv_pipe_t*)handle); -} - - -/* Cleans up uv_pipe_t (server or connection) and all resources associated */ -/* with it. */ -void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) { - int i; - HANDLE pipeHandle; - - uv__pipe_stop_read(handle); - - if (handle->name) { - uv__free(handle->name); - handle->name = NULL; - } - - if (handle->flags & UV_HANDLE_PIPESERVER) { - for (i = 0; i < handle->pipe.serv.pending_instances; i++) { - pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle; - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE; - } - } - handle->handle = INVALID_HANDLE_VALUE; - } - - if (handle->flags & UV_HANDLE_CONNECTION) { - handle->flags &= ~UV_HANDLE_WRITABLE; - eof_timer_destroy(handle); - } - - if ((handle->flags & UV_HANDLE_CONNECTION) - && handle->handle != INVALID_HANDLE_VALUE) - close_pipe(handle); -} - - -void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) { - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - uv_pipe_cleanup(loop, handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(handle); -} - - -static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle, - uv_pipe_accept_t* req, BOOL firstInstance) { - assert(handle->flags & UV_HANDLE_LISTENING); - - if (!firstInstance) { - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - - req->pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (req->pipeHandle == INVALID_HANDLE_VALUE) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - - if (uv_set_pipe_handle(loop, handle, req->pipeHandle, -1, 0)) { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - } - - assert(req->pipeHandle != INVALID_HANDLE_VALUE); - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - - if (!ConnectNamedPipe(req->pipeHandle, &req->u.io.overlapped) && - GetLastError() != ERROR_IO_PENDING) { - if (GetLastError() == ERROR_PIPE_CONNECTED) { - SET_REQ_SUCCESS(req); - } else { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - } - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - - handle->reqs_pending++; -} - - -int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) { - uv_loop_t* loop = server->loop; - uv_pipe_t* pipe_client; - uv_pipe_accept_t* req; - QUEUE* q; - uv__ipc_queue_item_t* item; - int err; - - if (server->ipc) { - if (QUEUE_EMPTY(&server->pipe.conn.pending_ipc_info.queue)) { - /* No valid pending sockets. */ - return WSAEWOULDBLOCK; - } - - q = QUEUE_HEAD(&server->pipe.conn.pending_ipc_info.queue); - QUEUE_REMOVE(q); - server->pipe.conn.pending_ipc_info.queue_len--; - item = QUEUE_DATA(q, uv__ipc_queue_item_t, member); - - err = uv_tcp_import((uv_tcp_t*)client, - &item->socket_info_ex, - item->tcp_connection); - if (err != 0) - return err; - - uv__free(item); - - } else { - pipe_client = (uv_pipe_t*)client; - - /* Find a connection instance that has been connected, but not yet */ - /* accepted. */ - req = server->pipe.serv.pending_accepts; - - if (!req) { - /* No valid connections found, so we error out. */ - return WSAEWOULDBLOCK; - } - - /* Initialize the client handle and copy the pipeHandle to the client */ - uv_pipe_connection_init(pipe_client); - pipe_client->handle = req->pipeHandle; - pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - - /* Prepare the req to pick up a new connection */ - server->pipe.serv.pending_accepts = req->next_pending; - req->next_pending = NULL; - req->pipeHandle = INVALID_HANDLE_VALUE; - - if (!(server->flags & UV__HANDLE_CLOSING)) { - uv_pipe_queue_accept(loop, server, req, FALSE); - } - } - - return 0; -} - - -/* Starts listening for connections for the given pipe. */ -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; - int i; - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->stream.serv.connection_cb = cb; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - return WSAEINVAL; - } - - if (handle->flags & UV_HANDLE_READING) { - return WSAEISCONN; - } - - if (!(handle->flags & UV_HANDLE_PIPESERVER)) { - return ERROR_NOT_SUPPORTED; - } - - handle->flags |= UV_HANDLE_LISTENING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->stream.serv.connection_cb = cb; - - /* First pipe handle should have already been created in uv_pipe_bind */ - assert(handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE); - - for (i = 0; i < handle->pipe.serv.pending_instances; i++) { - uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0); - } - - return 0; -} - - -static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { - int result; - DWORD bytes; - uv_read_t* req = (uv_read_t*) parameter; - uv_pipe_t* handle = (uv_pipe_t*) req->data; - uv_loop_t* loop = handle->loop; - HANDLE hThread = NULL; - DWORD err; - uv_mutex_t *m = &handle->pipe.conn.readfile_mutex; - - assert(req != NULL); - assert(req->type == UV_READ); - assert(handle->type == UV_NAMED_PIPE); - - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */ - if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &hThread, - 0, TRUE, DUPLICATE_SAME_ACCESS)) { - handle->pipe.conn.readfile_thread = hThread; - } else { - hThread = NULL; - } - uv_mutex_unlock(m); - } -restart_readfile: - result = ReadFile(handle->handle, - &uv_zero_, - 0, - &bytes, - NULL); - if (!result) { - err = GetLastError(); - if (err == ERROR_OPERATION_ABORTED && - handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - if (handle->flags & UV_HANDLE_READING) { - /* just a brief break to do something else */ - handle->pipe.conn.readfile_thread = NULL; - /* resume after it is finished */ - uv_mutex_lock(m); - handle->pipe.conn.readfile_thread = hThread; - uv_mutex_unlock(m); - goto restart_readfile; - } else { - result = 1; /* successfully stopped reading */ - } - } - } - if (hThread) { - assert(hThread == handle->pipe.conn.readfile_thread); - /* mutex does not control clearing readfile_thread */ - handle->pipe.conn.readfile_thread = NULL; - uv_mutex_lock(m); - /* only when we hold the mutex lock is it safe to - open or close the handle */ - CloseHandle(hThread); - uv_mutex_unlock(m); - } - - if (!result) { - SET_REQ_ERROR(req, err); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) { - int result; - DWORD bytes; - uv_write_t* req = (uv_write_t*) parameter; - uv_pipe_t* handle = (uv_pipe_t*) req->handle; - uv_loop_t* loop = handle->loop; - - assert(req != NULL); - assert(req->type == UV_WRITE); - assert(handle->type == UV_NAMED_PIPE); - assert(req->write_buffer.base); - - result = WriteFile(handle->handle, - req->write_buffer.base, - req->write_buffer.len, - &bytes, - NULL); - - if (!result) { - SET_REQ_ERROR(req, GetLastError()); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out) { - uv_read_t* req; - uv_tcp_t* handle; - - req = (uv_read_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->data; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out) { - uv_write_t* req; - uv_tcp_t* handle; - - req = (uv_write_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->handle; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) { - uv_read_t* req; - int result; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - assert(handle->handle != INVALID_HANDLE_VALUE); - - req = &handle->read_req; - - if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - } else { - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); - } - - /* Do 0-read */ - result = ReadFile(handle->handle, - &uv_zero_, - 0, - NULL, - &req->u.io.overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (!req->event_handle) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } - if (req->wait_handle == INVALID_HANDLE_VALUE) { - if (!RegisterWaitForSingleObject(&req->wait_handle, - req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - } - } - } - - /* Start the eof timer if there is one */ - eof_timer_start(handle); - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - return; - -error: - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -int uv_pipe_read_start(uv_pipe_t* handle, - uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) - uv_pipe_queue_read(loop, handle); - - return 0; -} - - -static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle, - uv_write_t* req) { - req->next_req = NULL; - if (handle->pipe.conn.non_overlapped_writes_tail) { - req->next_req = - handle->pipe.conn.non_overlapped_writes_tail->next_req; - handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req; - handle->pipe.conn.non_overlapped_writes_tail = req; - } else { - req->next_req = (uv_req_t*)req; - handle->pipe.conn.non_overlapped_writes_tail = req; - } -} - - -static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) { - uv_write_t* req; - - if (handle->pipe.conn.non_overlapped_writes_tail) { - req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req; - - if (req == handle->pipe.conn.non_overlapped_writes_tail) { - handle->pipe.conn.non_overlapped_writes_tail = NULL; - } else { - handle->pipe.conn.non_overlapped_writes_tail->next_req = - req->next_req; - } - - return req; - } else { - /* queue empty */ - return NULL; - } -} - - -static void uv_queue_non_overlapped_write(uv_pipe_t* handle) { - uv_write_t* req = uv_remove_non_overlapped_write_req(handle); - if (req) { - if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - uv_fatal_error(GetLastError(), "QueueUserWorkItem"); - } - } -} - - -static int uv_pipe_write_impl(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - int err; - int result; - uv_tcp_t* tcp_send_handle; - uv_write_t* ipc_header_req = NULL; - uv_ipc_frame_uv_stream ipc_frame; - - if (nbufs != 1 && (nbufs != 0 || !send_handle)) { - return ERROR_NOT_SUPPORTED; - } - - /* Only TCP handles are supported for sharing. */ - if (send_handle && ((send_handle->type != UV_TCP) || - (!(send_handle->flags & UV_HANDLE_BOUND) && - !(send_handle->flags & UV_HANDLE_CONNECTION)))) { - return ERROR_NOT_SUPPORTED; - } - - assert(handle->handle != INVALID_HANDLE_VALUE); - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - req->ipc_header = 0; - req->event_handle = NULL; - req->wait_handle = INVALID_HANDLE_VALUE; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - if (handle->ipc) { - assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); - ipc_frame.header.flags = 0; - - /* Use the IPC framing protocol. */ - if (send_handle) { - tcp_send_handle = (uv_tcp_t*)send_handle; - - err = uv_tcp_duplicate_socket(tcp_send_handle, handle->pipe.conn.ipc_pid, - &ipc_frame.socket_info_ex.socket_info); - if (err) { - return err; - } - - ipc_frame.socket_info_ex.delayed_error = tcp_send_handle->delayed_error; - - ipc_frame.header.flags |= UV_IPC_TCP_SERVER; - - if (tcp_send_handle->flags & UV_HANDLE_CONNECTION) { - ipc_frame.header.flags |= UV_IPC_TCP_CONNECTION; - } - } - - if (nbufs == 1) { - ipc_frame.header.flags |= UV_IPC_RAW_DATA; - ipc_frame.header.raw_data_length = bufs[0].len; - } - - /* - * Use the provided req if we're only doing a single write. - * If we're doing multiple writes, use ipc_header_write_req to do - * the first write, and then use the provided req for the second write. - */ - if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { - ipc_header_req = req; - } else { - /* - * Try to use the preallocated write req if it's available. - * Otherwise allocate a new one. - */ - if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) { - ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req; - } else { - ipc_header_req = (uv_write_t*)uv__malloc(sizeof(uv_write_t)); - if (!ipc_header_req) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - } - - uv_req_init(loop, (uv_req_t*) ipc_header_req); - ipc_header_req->type = UV_WRITE; - ipc_header_req->handle = (uv_stream_t*) handle; - ipc_header_req->cb = NULL; - ipc_header_req->ipc_header = 1; - } - - /* Write the header or the whole frame. */ - memset(&ipc_header_req->u.io.overlapped, 0, - sizeof(ipc_header_req->u.io.overlapped)); - - /* Using overlapped IO, but wait for completion before returning. - This write is blocking because ipc_frame is on stack. */ - ipc_header_req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); - if (!ipc_header_req->u.io.overlapped.hEvent) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - result = WriteFile(handle->handle, - &ipc_frame, - ipc_frame.header.flags & UV_IPC_TCP_SERVER ? - sizeof(ipc_frame) : sizeof(ipc_frame.header), - NULL, - &ipc_header_req->u.io.overlapped); - if (!result && GetLastError() != ERROR_IO_PENDING) { - err = GetLastError(); - CloseHandle(ipc_header_req->u.io.overlapped.hEvent); - return err; - } - - if (!result) { - /* Request not completed immediately. Wait for it.*/ - if (WaitForSingleObject(ipc_header_req->u.io.overlapped.hEvent, INFINITE) != - WAIT_OBJECT_0) { - err = GetLastError(); - CloseHandle(ipc_header_req->u.io.overlapped.hEvent); - return err; - } - } - ipc_header_req->u.io.queued_bytes = 0; - CloseHandle(ipc_header_req->u.io.overlapped.hEvent); - ipc_header_req->u.io.overlapped.hEvent = NULL; - - REGISTER_HANDLE_REQ(loop, handle, ipc_header_req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - - /* If we don't have any raw data to write - we're done. */ - if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { - return 0; - } - } - - if ((handle->flags & - (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) == - (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) { - DWORD bytes; - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - &bytes, - NULL); - - if (!result) { - err = GetLastError(); - return err; - } else { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - POST_COMPLETION_FOR_REQ(loop, req); - return 0; - } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - req->write_buffer = bufs[0]; - uv_insert_non_overlapped_write_req(handle, req); - if (handle->stream.conn.write_reqs_pending == 0) { - uv_queue_non_overlapped_write(handle); - } - - /* Request queued by the kernel. */ - req->u.io.queued_bytes = bufs[0].len; - handle->write_queue_size += req->u.io.queued_bytes; - } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) { - /* Using overlapped IO, but wait for completion before returning */ - req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); - if (!req->u.io.overlapped.hEvent) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - NULL, - &req->u.io.overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - err = GetLastError(); - CloseHandle(req->u.io.overlapped.hEvent); - return err; - } - - if (result) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - } else { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = bufs[0].len; - handle->write_queue_size += req->u.io.queued_bytes; - if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) != - WAIT_OBJECT_0) { - err = GetLastError(); - CloseHandle(req->u.io.overlapped.hEvent); - return uv_translate_sys_error(err); - } - } - CloseHandle(req->u.io.overlapped.hEvent); - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - return 0; - } else { - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - NULL, - &req->u.io.overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - return GetLastError(); - } - - if (result) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - } else { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = bufs[0].len; - handle->write_queue_size += req->u.io.queued_bytes; - } - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - if (!RegisterWaitForSingleObject(&req->wait_handle, - req->u.io.overlapped.hEvent, post_completion_write_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - return GetLastError(); - } - } - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - - return 0; -} - - -int uv_pipe_write(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, NULL, cb); -} - - -int uv_pipe_write2(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - if (!handle->ipc) { - return WSAEINVAL; - } - - return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, send_handle, cb); -} - - -static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle, - uv_buf_t buf) { - /* If there is an eof timer running, we don't need it any more, */ - /* so discard it. */ - eof_timer_destroy(handle); - - handle->flags &= ~UV_HANDLE_READABLE; - uv_read_stop((uv_stream_t*) handle); - - handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf); -} - - -static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error, - uv_buf_t buf) { - /* If there is an eof timer running, we don't need it any more, */ - /* so discard it. */ - eof_timer_destroy(handle); - - uv_read_stop((uv_stream_t*) handle); - - handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(error), &buf); -} - - -static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle, - int error, uv_buf_t buf) { - if (error == ERROR_BROKEN_PIPE) { - uv_pipe_read_eof(loop, handle, buf); - } else { - uv_pipe_read_error(loop, handle, error, buf); - } -} - - -void uv__pipe_insert_pending_socket(uv_pipe_t* handle, - uv__ipc_socket_info_ex* info, - int tcp_connection) { - uv__ipc_queue_item_t* item; - - item = (uv__ipc_queue_item_t*) uv__malloc(sizeof(*item)); - if (item == NULL) - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - - memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex)); - item->tcp_connection = tcp_connection; - QUEUE_INSERT_TAIL(&handle->pipe.conn.pending_ipc_info.queue, &item->member); - handle->pipe.conn.pending_ipc_info.queue_len++; -} - - -void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* req) { - DWORD bytes, avail; - uv_buf_t buf; - uv_ipc_frame_uv_stream ipc_frame; - - assert(handle->type == UV_NAMED_PIPE); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - eof_timer_stop(handle); - - if (!REQ_SUCCESS(req)) { - /* An error occurred doing the 0-read. */ - if (handle->flags & UV_HANDLE_READING) { - uv_pipe_read_error_or_eof(loop, - handle, - GET_REQ_ERROR(req), - uv_null_buf_); - } - } else { - /* Do non-blocking reads until the buffer is empty */ - while (handle->flags & UV_HANDLE_READING) { - if (!PeekNamedPipe(handle->handle, - NULL, - 0, - NULL, - &avail, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); - break; - } - - if (avail == 0) { - /* There is nothing to read after all. */ - break; - } - - if (handle->ipc) { - /* Use the IPC framing protocol to read the incoming data. */ - if (handle->pipe.conn.remaining_ipc_rawdata_bytes == 0) { - /* We're reading a new frame. First, read the header. */ - assert(avail >= sizeof(ipc_frame.header)); - - if (!ReadFile(handle->handle, - &ipc_frame.header, - sizeof(ipc_frame.header), - &bytes, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), - uv_null_buf_); - break; - } - - assert(bytes == sizeof(ipc_frame.header)); - assert(ipc_frame.header.flags <= (UV_IPC_TCP_SERVER | UV_IPC_RAW_DATA | - UV_IPC_TCP_CONNECTION)); - - if (ipc_frame.header.flags & UV_IPC_TCP_SERVER) { - assert(avail - sizeof(ipc_frame.header) >= - sizeof(ipc_frame.socket_info_ex)); - - /* Read the TCP socket info. */ - if (!ReadFile(handle->handle, - &ipc_frame.socket_info_ex, - sizeof(ipc_frame) - sizeof(ipc_frame.header), - &bytes, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), - uv_null_buf_); - break; - } - - assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header)); - - /* Store the pending socket info. */ - uv__pipe_insert_pending_socket( - handle, - &ipc_frame.socket_info_ex, - ipc_frame.header.flags & UV_IPC_TCP_CONNECTION); - } - - if (ipc_frame.header.flags & UV_IPC_RAW_DATA) { - handle->pipe.conn.remaining_ipc_rawdata_bytes = - ipc_frame.header.raw_data_length; - continue; - } - } else { - avail = min(avail, (DWORD)handle->pipe.conn.remaining_ipc_rawdata_bytes); - } - } - - handle->alloc_cb((uv_handle_t*) handle, avail, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - break; - } - assert(buf.base != NULL); - - if (ReadFile(handle->handle, - buf.base, - buf.len, - &bytes, - NULL)) { - /* Successful read */ - if (handle->ipc) { - assert(handle->pipe.conn.remaining_ipc_rawdata_bytes >= bytes); - handle->pipe.conn.remaining_ipc_rawdata_bytes = - handle->pipe.conn.remaining_ipc_rawdata_bytes - bytes; - } - handle->read_cb((uv_stream_t*)handle, bytes, &buf); - - /* Read again only if bytes == buf.len */ - if (bytes <= buf.len) { - break; - } - } else { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf); - break; - } - } - - /* Post another 0-read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_pipe_queue_read(loop, handle); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_write_t* req) { - int err; - - assert(handle->type == UV_NAMED_PIPE); - - assert(handle->write_queue_size >= req->u.io.queued_bytes); - handle->write_queue_size -= req->u.io.queued_bytes; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - - if (req->ipc_header) { - if (req == &handle->pipe.conn.ipc_header_write_req) { - req->type = UV_UNKNOWN_REQ; - } else { - uv__free(req); - } - } else { - if (req->cb) { - err = GET_REQ_ERROR(req); - req->cb(req, uv_translate_sys_error(err)); - } - } - - handle->stream.conn.write_reqs_pending--; - - if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE && - handle->pipe.conn.non_overlapped_writes_tail) { - assert(handle->stream.conn.write_reqs_pending > 0); - uv_queue_non_overlapped_write(handle); - } - - if (handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* raw_req) { - uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req; - - assert(handle->type == UV_NAMED_PIPE); - - if (handle->flags & UV__HANDLE_CLOSING) { - /* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */ - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (REQ_SUCCESS(req)) { - assert(req->pipeHandle != INVALID_HANDLE_VALUE); - req->next_pending = handle->pipe.serv.pending_accepts; - handle->pipe.serv.pending_accepts = req; - - if (handle->stream.serv.connection_cb) { - handle->stream.serv.connection_cb((uv_stream_t*)handle, 0); - } - } else { - if (req->pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - } - if (!(handle->flags & UV__HANDLE_CLOSING)) { - uv_pipe_queue_accept(loop, handle, req, FALSE); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_connect_t* req) { - int err; - - assert(handle->type == UV_NAMED_PIPE); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = 0; - if (REQ_SUCCESS(req)) { - uv_pipe_connection_init(handle); - } else { - err = GET_REQ_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_shutdown_t* req) { - assert(handle->type == UV_NAMED_PIPE); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_READABLE) { - /* Initialize and optionally start the eof timer. Only do this if the */ - /* pipe is readable and we haven't seen EOF come in ourselves. */ - eof_timer_init(handle); - - /* If reading start the timer right now. */ - /* Otherwise uv_pipe_queue_read will start it. */ - if (handle->flags & UV_HANDLE_READ_PENDING) { - eof_timer_start(handle); - } - - } else { - /* This pipe is not readable. We can just close it to let the other end */ - /* know that we're done writing. */ - close_pipe(handle); - } - - if (req->cb) { - req->cb(req, 0); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -static void eof_timer_init(uv_pipe_t* pipe) { - int r; - - assert(pipe->pipe.conn.eof_timer == NULL); - assert(pipe->flags & UV_HANDLE_CONNECTION); - - pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer); - - r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer); - assert(r == 0); /* timers can't fail */ - pipe->pipe.conn.eof_timer->data = pipe; - uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer); -} - - -static void eof_timer_start(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->pipe.conn.eof_timer != NULL) { - uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0); - } -} - - -static void eof_timer_stop(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->pipe.conn.eof_timer != NULL) { - uv_timer_stop(pipe->pipe.conn.eof_timer); - } -} - - -static void eof_timer_cb(uv_timer_t* timer) { - uv_pipe_t* pipe = (uv_pipe_t*) timer->data; - uv_loop_t* loop = timer->loop; - - assert(pipe->type == UV_NAMED_PIPE); - - /* This should always be true, since we start the timer only */ - /* in uv_pipe_queue_read after successfully calling ReadFile, */ - /* or in uv_process_pipe_shutdown_req if a read is pending, */ - /* and we always immediately stop the timer in */ - /* uv_process_pipe_read_req. */ - assert(pipe->flags & UV_HANDLE_READ_PENDING); - - /* If there are many packets coming off the iocp then the timer callback */ - /* may be called before the read request is coming off the queue. */ - /* Therefore we check here if the read request has completed but will */ - /* be processed later. */ - if ((pipe->flags & UV_HANDLE_READ_PENDING) && - HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) { - return; - } - - /* Force both ends off the pipe. */ - close_pipe(pipe); - - /* Stop reading, so the pending read that is going to fail will */ - /* not be reported to the user. */ - uv_read_stop((uv_stream_t*) pipe); - - /* Report the eof and update flags. This will get reported even if the */ - /* user stopped reading in the meantime. TODO: is that okay? */ - uv_pipe_read_eof(loop, pipe, uv_null_buf_); -} - - -static void eof_timer_destroy(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->pipe.conn.eof_timer) { - uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb); - pipe->pipe.conn.eof_timer = NULL; - } -} - - -static void eof_timer_close_cb(uv_handle_t* handle) { - assert(handle->type == UV_TIMER); - uv__free(handle); -} - - -int uv_pipe_open(uv_pipe_t* pipe, uv_file file) { - HANDLE os_handle = uv__get_osfhandle(file); - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_ACCESS_INFORMATION access; - DWORD duplex_flags = 0; - - if (os_handle == INVALID_HANDLE_VALUE) - return UV_EBADF; - - /* In order to avoid closing a stdio file descriptor 0-2, duplicate the - * underlying OS handle and forget about the original fd. - * We could also opt to use the original OS handle and just never close it, - * but then there would be no reliable way to cancel pending read operations - * upon close. - */ - if (file <= 2) { - if (!DuplicateHandle(INVALID_HANDLE_VALUE, - os_handle, - INVALID_HANDLE_VALUE, - &os_handle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS)) - return uv_translate_sys_error(GetLastError()); - file = -1; - } - - /* Determine what kind of permissions we have on this handle. - * Cygwin opens the pipe in message mode, but we can support it, - * just query the access flags and set the stream flags accordingly. - */ - nt_status = pNtQueryInformationFile(os_handle, - &io_status, - &access, - sizeof(access), - FileAccessInformation); - if (nt_status != STATUS_SUCCESS) - return UV_EINVAL; - - if (pipe->ipc) { - if (!(access.AccessFlags & FILE_WRITE_DATA) || - !(access.AccessFlags & FILE_READ_DATA)) { - return UV_EINVAL; - } - } - - if (access.AccessFlags & FILE_WRITE_DATA) - duplex_flags |= UV_HANDLE_WRITABLE; - if (access.AccessFlags & FILE_READ_DATA) - duplex_flags |= UV_HANDLE_READABLE; - - if (os_handle == INVALID_HANDLE_VALUE || - uv_set_pipe_handle(pipe->loop, - pipe, - os_handle, - file, - duplex_flags) == -1) { - return UV_EINVAL; - } - - uv_pipe_connection_init(pipe); - - if (pipe->ipc) { - assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); - pipe->pipe.conn.ipc_pid = uv_parent_pid(); - assert(pipe->pipe.conn.ipc_pid != -1); - } - return 0; -} - - -static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) { - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - 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; - - name_info = NULL; - - if (handle->handle == INVALID_HANDLE_VALUE) { - *size = 0; - return UV_EINVAL; - } - - uv__pipe_pause_read((uv_pipe_t*)handle); /* cast away const warning */ - - nt_status = pNtQueryInformationFile(handle->handle, - &io_status, - &tmp_name_info, - sizeof tmp_name_info, - FileNameInformation); - if (nt_status == STATUS_BUFFER_OVERFLOW) { - name_size = sizeof(*name_info) + tmp_name_info.FileNameLength; - name_info = uv__malloc(name_size); - if (!name_info) { - *size = 0; - err = UV_ENOMEM; - goto cleanup; - } - - nt_status = pNtQueryInformationFile(handle->handle, - &io_status, - name_info, - name_size, - FileNameInformation); - } - - if (nt_status != STATUS_SUCCESS) { - *size = 0; - err = uv_translate_sys_error(pRtlNtStatusToDosError(nt_status)); - goto error; - } - - if (!name_info) { - /* the struct on stack was used */ - name_buf = tmp_name_info.FileName; - name_len = tmp_name_info.FileNameLength; - } else { - name_buf = name_info->FileName; - name_len = name_info->FileNameLength; - } - - if (name_len == 0) { - *size = 0; - err = 0; - goto error; - } - - 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) { - *size = 0; - err = uv_translate_sys_error(GetLastError()); - goto error; - } else if (pipe_prefix_len + addrlen > *size) { - /* "\\\\.\\pipe" + name */ - *size = pipe_prefix_len + addrlen; - 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; - } - - addrlen += pipe_prefix_len; - *size = addrlen; - - err = 0; - goto cleanup; - -error: - uv__free(name_info); - -cleanup: - uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */ - return err; -} - - -int uv_pipe_pending_count(uv_pipe_t* handle) { - if (!handle->ipc) - return 0; - return handle->pipe.conn.pending_ipc_info.queue_len; -} - - -int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) { - if (handle->flags & UV_HANDLE_BOUND) - return uv__pipe_getname(handle, buffer, size); - - if (handle->flags & UV_HANDLE_CONNECTION || - handle->handle != INVALID_HANDLE_VALUE) { - *size = 0; - return 0; - } - - return UV_EBADF; -} - - -int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) { - /* emulate unix behaviour */ - if (handle->flags & UV_HANDLE_BOUND) - return UV_ENOTCONN; - - if (handle->handle != INVALID_HANDLE_VALUE) - return uv__pipe_getname(handle, buffer, size); - - return UV_EBADF; -} - - -uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { - if (!handle->ipc) - return UV_UNKNOWN_HANDLE; - if (handle->pipe.conn.pending_ipc_info.queue_len == 0) - return UV_UNKNOWN_HANDLE; - else - return UV_TCP; -} diff --git a/outside/libuv-v1.7.5/src/win/poll.c b/outside/libuv-v1.7.5/src/win/poll.c deleted file mode 100644 index ce861d6ffc..0000000000 --- a/outside/libuv-v1.7.5/src/win/poll.c +++ /dev/null @@ -1,635 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = { - {0xe70f1aa0, 0xab8b, 0x11cf, - {0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}, - {0xf9eab0c0, 0x26d4, 0x11d0, - {0xbb, 0xbf, 0x00, 0xaa, 0x00, 0x6c, 0x34, 0xe4}}, - {0x9fc48064, 0x7298, 0x43e4, - {0xb7, 0xbd, 0x18, 0x1f, 0x20, 0x89, 0x79, 0x2a}} -}; - -typedef struct uv_single_fd_set_s { - unsigned int fd_count; - SOCKET fd_array[1]; -} uv_single_fd_set_t; - - -static OVERLAPPED overlapped_dummy_; -static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT; - -static AFD_POLL_INFO afd_poll_info_dummy_; - - -static void uv__init_overlapped_dummy(void) { - HANDLE event; - - event = CreateEvent(NULL, TRUE, TRUE, NULL); - if (event == NULL) - uv_fatal_error(GetLastError(), "CreateEvent"); - - memset(&overlapped_dummy_, 0, sizeof overlapped_dummy_); - overlapped_dummy_.hEvent = (HANDLE) ((uintptr_t) event | 1); -} - - -static OVERLAPPED* uv__get_overlapped_dummy() { - uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy); - return &overlapped_dummy_; -} - - -static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() { - return &afd_poll_info_dummy_; -} - - -static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - uv_req_t* req; - AFD_POLL_INFO* afd_poll_info; - DWORD result; - - /* Find a yet unsubmitted req to submit. */ - if (handle->submitted_events_1 == 0) { - req = &handle->poll_req_1; - afd_poll_info = &handle->afd_poll_info_1; - handle->submitted_events_1 = handle->events; - handle->mask_events_1 = 0; - handle->mask_events_2 = handle->events; - } else if (handle->submitted_events_2 == 0) { - req = &handle->poll_req_2; - afd_poll_info = &handle->afd_poll_info_2; - handle->submitted_events_2 = handle->events; - handle->mask_events_1 = handle->events; - handle->mask_events_2 = 0; - } else { - assert(0); - return; - } - - /* Setting Exclusive to TRUE makes the other poll request return if there */ - /* is any. */ - afd_poll_info->Exclusive = TRUE; - afd_poll_info->NumberOfHandles = 1; - afd_poll_info->Timeout.QuadPart = INT64_MAX; - afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket; - afd_poll_info->Handles[0].Status = 0; - afd_poll_info->Handles[0].Events = 0; - - if (handle->events & UV_READABLE) { - afd_poll_info->Handles[0].Events |= AFD_POLL_RECEIVE | - AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT; - } - if (handle->events & UV_WRITABLE) { - afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL; - } - - memset(&req->u.io.overlapped, 0, sizeof req->u.io.overlapped); - - result = uv_msafd_poll((SOCKET) handle->peer_socket, - afd_poll_info, - afd_poll_info, - &req->u.io.overlapped); - if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) { - /* Queue this req, reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - } -} - - -static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - AFD_POLL_INFO afd_poll_info; - DWORD result; - - afd_poll_info.Exclusive = TRUE; - afd_poll_info.NumberOfHandles = 1; - afd_poll_info.Timeout.QuadPart = INT64_MAX; - afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket; - afd_poll_info.Handles[0].Status = 0; - afd_poll_info.Handles[0].Events = AFD_POLL_ALL; - - result = uv_msafd_poll(handle->socket, - &afd_poll_info, - uv__get_afd_poll_info_dummy(), - uv__get_overlapped_dummy()); - - if (result == SOCKET_ERROR) { - DWORD error = WSAGetLastError(); - if (error != WSA_IO_PENDING) - return error; - } - - return 0; -} - - -static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req) { - unsigned char mask_events; - AFD_POLL_INFO* afd_poll_info; - - if (req == &handle->poll_req_1) { - afd_poll_info = &handle->afd_poll_info_1; - handle->submitted_events_1 = 0; - mask_events = handle->mask_events_1; - } else if (req == &handle->poll_req_2) { - afd_poll_info = &handle->afd_poll_info_2; - handle->submitted_events_2 = 0; - mask_events = handle->mask_events_2; - } else { - assert(0); - return; - } - - /* Report an error unless the select was just interrupted. */ - if (!REQ_SUCCESS(req)) { - DWORD error = GET_REQ_SOCK_ERROR(req); - if (error != WSAEINTR && handle->events != 0) { - handle->events = 0; /* Stop the watcher */ - handle->poll_cb(handle, uv_translate_sys_error(error), 0); - } - - } else if (afd_poll_info->NumberOfHandles >= 1) { - unsigned char events = 0; - - if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE | - AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) { - events |= UV_READABLE; - } - if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND | - AFD_POLL_CONNECT_FAIL)) != 0) { - events |= UV_WRITABLE; - } - - events &= handle->events & ~mask_events; - - if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) { - /* Stop polling. */ - handle->events = 0; - if (uv__is_active(handle)) - uv__handle_stop(handle); - } - - if (events != 0) { - handle->poll_cb(handle, 0, events); - } - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__fast_poll_submit_poll_req(loop, handle); - } else if ((handle->flags & UV__HANDLE_CLOSING) && - handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { - assert(handle->type == UV_POLL); - assert(!(handle->flags & UV__HANDLE_CLOSING)); - assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0); - - handle->events = events; - - if (handle->events != 0) { - uv__handle_start(handle); - } else { - uv__handle_stop(handle); - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__fast_poll_submit_poll_req(handle->loop, handle); - } - - return 0; -} - - -static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - handle->events = 0; - uv__handle_closing(handle); - - if (handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - return 0; - } else { - /* Cancel outstanding poll requests by executing another, unique poll */ - /* request that forces the outstanding ones to return. */ - return uv__fast_poll_cancel_poll_req(loop, handle); - } -} - - -static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp, - WSAPROTOCOL_INFOW* protocol_info) { - SOCKET sock = 0; - - sock = WSASocketW(protocol_info->iAddressFamily, - protocol_info->iSocketType, - protocol_info->iProtocol, - protocol_info, - 0, - WSA_FLAG_OVERLAPPED); - if (sock == INVALID_SOCKET) { - return INVALID_SOCKET; - } - - if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) { - goto error; - }; - - if (CreateIoCompletionPort((HANDLE) sock, - iocp, - (ULONG_PTR) sock, - 0) == NULL) { - goto error; - } - - return sock; - - error: - closesocket(sock); - return INVALID_SOCKET; -} - - -static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop, - WSAPROTOCOL_INFOW* protocol_info) { - int index, i; - SOCKET peer_socket; - - index = -1; - for (i = 0; (size_t) i < ARRAY_SIZE(uv_msafd_provider_ids); i++) { - if (memcmp((void*) &protocol_info->ProviderId, - (void*) &uv_msafd_provider_ids[i], - sizeof protocol_info->ProviderId) == 0) { - index = i; - } - } - - /* Check if the protocol uses an msafd socket. */ - if (index < 0) { - return INVALID_SOCKET; - } - - /* If we didn't (try) to create a peer socket yet, try to make one. Don't */ - /* try again if the peer socket creation failed earlier for the same */ - /* protocol. */ - peer_socket = loop->poll_peer_sockets[index]; - if (peer_socket == 0) { - peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info); - loop->poll_peer_sockets[index] = peer_socket; - } - - return peer_socket; -} - - -static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) { - uv_req_t* req = (uv_req_t*) arg; - uv_poll_t* handle = (uv_poll_t*) req->data; - unsigned char reported_events; - int r; - uv_single_fd_set_t rfds, wfds, efds; - struct timeval timeout; - - assert(handle->type == UV_POLL); - assert(req->type == UV_POLL_REQ); - - if (handle->events & UV_READABLE) { - rfds.fd_count = 1; - rfds.fd_array[0] = handle->socket; - } else { - rfds.fd_count = 0; - } - - if (handle->events & UV_WRITABLE) { - wfds.fd_count = 1; - wfds.fd_array[0] = handle->socket; - efds.fd_count = 1; - efds.fd_array[0] = handle->socket; - } else { - wfds.fd_count = 0; - efds.fd_count = 0; - } - - /* Make the select() time out after 3 minutes. If select() hangs because */ - /* the user closed the socket, we will at least not hang indefinitely. */ - timeout.tv_sec = 3 * 60; - timeout.tv_usec = 0; - - r = select(1, (fd_set*) &rfds, (fd_set*) &wfds, (fd_set*) &efds, &timeout); - if (r == SOCKET_ERROR) { - /* Queue this req, reporting an error. */ - SET_REQ_ERROR(&handle->poll_req_1, WSAGetLastError()); - POST_COMPLETION_FOR_REQ(handle->loop, req); - return 0; - } - - reported_events = 0; - - if (r > 0) { - if (rfds.fd_count > 0) { - assert(rfds.fd_count == 1); - assert(rfds.fd_array[0] == handle->socket); - reported_events |= UV_READABLE; - } - - if (wfds.fd_count > 0) { - assert(wfds.fd_count == 1); - assert(wfds.fd_array[0] == handle->socket); - reported_events |= UV_WRITABLE; - } else if (efds.fd_count > 0) { - assert(efds.fd_count == 1); - assert(efds.fd_array[0] == handle->socket); - reported_events |= UV_WRITABLE; - } - } - - SET_REQ_SUCCESS(req); - req->u.io.overlapped.InternalHigh = (DWORD) reported_events; - POST_COMPLETION_FOR_REQ(handle->loop, req); - - return 0; -} - - -static void uv__slow_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - uv_req_t* req; - - /* Find a yet unsubmitted req to submit. */ - if (handle->submitted_events_1 == 0) { - req = &handle->poll_req_1; - handle->submitted_events_1 = handle->events; - handle->mask_events_1 = 0; - handle->mask_events_2 = handle->events; - } else if (handle->submitted_events_2 == 0) { - req = &handle->poll_req_2; - handle->submitted_events_2 = handle->events; - handle->mask_events_1 = handle->events; - handle->mask_events_2 = 0; - } else { - assert(0); - return; - } - - if (!QueueUserWorkItem(uv__slow_poll_thread_proc, - (void*) req, - WT_EXECUTELONGFUNCTION)) { - /* Make this req pending, reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, req); - } -} - - - -static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req) { - unsigned char mask_events; - int err; - - if (req == &handle->poll_req_1) { - handle->submitted_events_1 = 0; - mask_events = handle->mask_events_1; - } else if (req == &handle->poll_req_2) { - handle->submitted_events_2 = 0; - mask_events = handle->mask_events_2; - } else { - assert(0); - return; - } - - if (!REQ_SUCCESS(req)) { - /* Error. */ - if (handle->events != 0) { - err = GET_REQ_ERROR(req); - handle->events = 0; /* Stop the watcher */ - handle->poll_cb(handle, uv_translate_sys_error(err), 0); - } - } else { - /* Got some events. */ - int events = req->u.io.overlapped.InternalHigh & handle->events & ~mask_events; - if (events != 0) { - handle->poll_cb(handle, 0, events); - } - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__slow_poll_submit_poll_req(loop, handle); - } else if ((handle->flags & UV__HANDLE_CLOSING) && - handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { - assert(handle->type == UV_POLL); - assert(!(handle->flags & UV__HANDLE_CLOSING)); - assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0); - - handle->events = events; - - if (handle->events != 0) { - uv__handle_start(handle); - } else { - uv__handle_stop(handle); - } - - if ((handle->events & - ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) { - uv__slow_poll_submit_poll_req(handle->loop, handle); - } - - return 0; -} - - -static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - handle->events = 0; - uv__handle_closing(handle); - - if (handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - return 0; -} - - -int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { - return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd)); -} - - -int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, - uv_os_sock_t socket) { - WSAPROTOCOL_INFOW protocol_info; - int len; - SOCKET peer_socket, base_socket; - DWORD bytes; - DWORD yes = 1; - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) - return uv_translate_sys_error(WSAGetLastError()); - - /* Try to obtain a base handle for the socket. This increases this chances */ - /* that we find an AFD handle and are able to use the fast poll mechanism. */ - /* This will always fail on windows XP/2k3, since they don't support the */ - /* SIO_BASE_HANDLE ioctl. */ -#ifndef NDEBUG - base_socket = INVALID_SOCKET; -#endif - - if (WSAIoctl(socket, - SIO_BASE_HANDLE, - NULL, - 0, - &base_socket, - sizeof base_socket, - &bytes, - NULL, - NULL) == 0) { - assert(base_socket != 0 && base_socket != INVALID_SOCKET); - socket = base_socket; - } - - uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); - handle->socket = socket; - handle->events = 0; - - /* Obtain protocol information about the socket. */ - len = sizeof protocol_info; - if (getsockopt(socket, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &len) != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - /* Get the peer socket that is needed to enable fast poll. If the returned */ - /* value is NULL, the protocol is not implemented by MSAFD and we'll have */ - /* to use slow mode. */ - peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info); - - if (peer_socket != INVALID_SOCKET) { - /* Initialize fast poll specific fields. */ - handle->peer_socket = peer_socket; - } else { - /* Initialize slow poll specific fields. */ - handle->flags |= UV_HANDLE_POLL_SLOW; - } - - /* Initialize 2 poll reqs. */ - handle->submitted_events_1 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1)); - handle->poll_req_1.type = UV_POLL_REQ; - handle->poll_req_1.data = handle; - - handle->submitted_events_2 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2)); - handle->poll_req_2.type = UV_POLL_REQ; - handle->poll_req_2.data = handle; - - return 0; -} - - -int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) { - int err; - - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - err = uv__fast_poll_set(handle->loop, handle, events); - } else { - err = uv__slow_poll_set(handle->loop, handle, events); - } - - if (err) { - return uv_translate_sys_error(err); - } - - handle->poll_cb = cb; - - return 0; -} - - -int uv_poll_stop(uv_poll_t* handle) { - int err; - - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - err = uv__fast_poll_set(handle->loop, handle, 0); - } else { - err = uv__slow_poll_set(handle->loop, handle, 0); - } - - return uv_translate_sys_error(err); -} - - -void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) { - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - uv__fast_poll_process_poll_req(loop, handle, req); - } else { - uv__slow_poll_process_poll_req(loop, handle, req); - } -} - - -int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - return uv__fast_poll_close(loop, handle); - } else { - return uv__slow_poll_close(loop, handle); - } -} - - -void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - assert(handle->submitted_events_1 == 0); - assert(handle->submitted_events_2 == 0); - - uv__handle_close(handle); -} diff --git a/outside/libuv-v1.7.5/src/win/process-stdio.c b/outside/libuv-v1.7.5/src/win/process-stdio.c deleted file mode 100644 index e3c06f57de..0000000000 --- a/outside/libuv-v1.7.5/src/win/process-stdio.c +++ /dev/null @@ -1,510 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -/* - * The `child_stdio_buffer` buffer has the following layout: - * int number_of_fds - * unsigned char crt_flags[number_of_fds] - * HANDLE os_handle[number_of_fds] - */ -#define CHILD_STDIO_SIZE(count) \ - (sizeof(int) + \ - sizeof(unsigned char) * (count) + \ - sizeof(uintptr_t) * (count)) - -#define CHILD_STDIO_COUNT(buffer) \ - *((unsigned int*) (buffer)) - -#define CHILD_STDIO_CRT_FLAGS(buffer, fd) \ - *((unsigned char*) (buffer) + sizeof(int) + fd) - -#define CHILD_STDIO_HANDLE(buffer, fd) \ - *((HANDLE*) ((unsigned char*) (buffer) + \ - sizeof(int) + \ - sizeof(unsigned char) * \ - CHILD_STDIO_COUNT((buffer)) + \ - sizeof(HANDLE) * (fd))) - - -/* CRT file descriptor mode flags */ -#define FOPEN 0x01 -#define FEOFLAG 0x02 -#define FCRLF 0x04 -#define FPIPE 0x08 -#define FNOINHERIT 0x10 -#define FAPPEND 0x20 -#define FDEV 0x40 -#define FTEXT 0x80 - - -/* - * Clear the HANDLE_FLAG_INHERIT flag from all HANDLEs that were inherited - * the parent process. Don't check for errors - the stdio handles may not be - * valid, or may be closed already. There is no guarantee that this function - * does a perfect job. - */ -void uv_disable_stdio_inheritance(void) { - HANDLE handle; - STARTUPINFOW si; - - /* Make the windows stdio handles non-inheritable. */ - handle = GetStdHandle(STD_INPUT_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - handle = GetStdHandle(STD_OUTPUT_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - handle = GetStdHandle(STD_ERROR_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - /* Make inherited CRT FDs non-inheritable. */ - GetStartupInfoW(&si); - if (uv__stdio_verify(si.lpReserved2, si.cbReserved2)) - uv__stdio_noinherit(si.lpReserved2); -} - - -static int uv__create_stdio_pipe_pair(uv_loop_t* loop, - uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) { - char pipe_name[64]; - SECURITY_ATTRIBUTES sa; - DWORD server_access = 0; - DWORD client_access = 0; - HANDLE child_pipe = INVALID_HANDLE_VALUE; - int err; - - if (flags & UV_READABLE_PIPE) { - /* The server needs inbound access too, otherwise CreateNamedPipe() */ - /* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */ - /* probe the state of the write buffer when we're trying to shutdown */ - /* the pipe. */ - server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND; - client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES; - } - if (flags & UV_WRITABLE_PIPE) { - server_access |= PIPE_ACCESS_INBOUND; - client_access |= GENERIC_WRITE | FILE_READ_ATTRIBUTES; - } - - /* Create server pipe handle. */ - err = uv_stdio_pipe_server(loop, - server_pipe, - server_access, - pipe_name, - sizeof(pipe_name)); - if (err) - goto error; - - /* Create child pipe handle. */ - sa.nLength = sizeof sa; - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - child_pipe = CreateFileA(pipe_name, - client_access, - 0, - &sa, - OPEN_EXISTING, - server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0, - NULL); - if (child_pipe == INVALID_HANDLE_VALUE) { - err = GetLastError(); - goto error; - } - -#ifndef NDEBUG - /* Validate that the pipe was opened in the right mode. */ - { - DWORD mode; - BOOL r = GetNamedPipeHandleState(child_pipe, - &mode, - NULL, - NULL, - NULL, - NULL, - 0); - assert(r == TRUE); - assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT)); - } -#endif - - /* Do a blocking ConnectNamedPipe. This should not block because we have */ - /* both ends of the pipe created. */ - if (!ConnectNamedPipe(server_pipe->handle, NULL)) { - if (GetLastError() != ERROR_PIPE_CONNECTED) { - err = GetLastError(); - goto error; - } - } - - /* The server end is now readable and/or writable. */ - if (flags & UV_READABLE_PIPE) - server_pipe->flags |= UV_HANDLE_WRITABLE; - if (flags & UV_WRITABLE_PIPE) - server_pipe->flags |= UV_HANDLE_READABLE; - - *child_pipe_ptr = child_pipe; - return 0; - - error: - if (server_pipe->handle != INVALID_HANDLE_VALUE) { - uv_pipe_cleanup(loop, server_pipe); - } - - if (child_pipe != INVALID_HANDLE_VALUE) { - CloseHandle(child_pipe); - } - - return err; -} - - -static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) { - HANDLE current_process; - - - /* _get_osfhandle will sometimes return -2 in case of an error. This seems */ - /* to happen when fd <= 2 and the process' corresponding stdio handle is */ - /* set to NULL. Unfortunately DuplicateHandle will happily duplicate */ - /* (HANDLE) -2, so this situation goes unnoticed until someone tries to */ - /* use the duplicate. Therefore we filter out known-invalid handles here. */ - if (handle == INVALID_HANDLE_VALUE || - handle == NULL || - handle == (HANDLE) -2) { - *dup = INVALID_HANDLE_VALUE; - return ERROR_INVALID_HANDLE; - } - - current_process = GetCurrentProcess(); - - if (!DuplicateHandle(current_process, - handle, - current_process, - dup, - 0, - TRUE, - DUPLICATE_SAME_ACCESS)) { - *dup = INVALID_HANDLE_VALUE; - return GetLastError(); - } - - return 0; -} - - -static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) { - HANDLE handle; - - if (fd == -1) { - *dup = INVALID_HANDLE_VALUE; - return ERROR_INVALID_HANDLE; - } - - handle = uv__get_osfhandle(fd); - return uv__duplicate_handle(loop, handle, dup); -} - - -int uv__create_nul_handle(HANDLE* handle_ptr, - DWORD access) { - HANDLE handle; - SECURITY_ATTRIBUTES sa; - - sa.nLength = sizeof sa; - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - handle = CreateFileW(L"NUL", - access, - FILE_SHARE_READ | FILE_SHARE_WRITE, - &sa, - OPEN_EXISTING, - 0, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - return GetLastError(); - } - - *handle_ptr = handle; - return 0; -} - - -int uv__stdio_create(uv_loop_t* loop, - const uv_process_options_t* options, - BYTE** buffer_ptr) { - BYTE* buffer; - int count, i; - int err; - - count = options->stdio_count; - - if (count < 0 || count > 255) { - /* Only support FDs 0-255 */ - return ERROR_NOT_SUPPORTED; - } else if (count < 3) { - /* There should always be at least 3 stdio handles. */ - count = 3; - } - - /* Allocate the child stdio buffer */ - buffer = (BYTE*) uv__malloc(CHILD_STDIO_SIZE(count)); - if (buffer == NULL) { - return ERROR_OUTOFMEMORY; - } - - /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */ - /* clean up on failure. */ - CHILD_STDIO_COUNT(buffer) = count; - for (i = 0; i < count; i++) { - CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; - } - - for (i = 0; i < count; i++) { - uv_stdio_container_t fdopt; - if (i < options->stdio_count) { - fdopt = options->stdio[i]; - } else { - fdopt.flags = UV_IGNORE; - } - - switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | - UV_INHERIT_STREAM)) { - case UV_IGNORE: - /* Starting a process with no stdin/stout/stderr can confuse it. */ - /* So no matter what the user specified, we make sure the first */ - /* three FDs are always open in their typical modes, e.g. stdin */ - /* be readable and stdout/err should be writable. For FDs > 2, don't */ - /* do anything - all handles in the stdio buffer are initialized with */ - /* INVALID_HANDLE_VALUE, which should be okay. */ - if (i <= 2) { - DWORD access = (i == 0) ? FILE_GENERIC_READ : - FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES; - - err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i), - access); - if (err) - goto error; - - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - } - break; - - case UV_CREATE_PIPE: { - /* Create a pair of two connected pipe ends; one end is turned into */ - /* an uv_pipe_t for use by the parent. The other one is given to */ - /* the child. */ - uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream; - HANDLE child_pipe = INVALID_HANDLE_VALUE; - - /* Create a new, connected pipe pair. stdio[i].stream should point */ - /* to an uninitialized, but not connected pipe handle. */ - assert(fdopt.data.stream->type == UV_NAMED_PIPE); - assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION)); - assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER)); - - err = uv__create_stdio_pipe_pair(loop, - parent_pipe, - &child_pipe, - fdopt.flags); - if (err) - goto error; - - CHILD_STDIO_HANDLE(buffer, i) = child_pipe; - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; - break; - } - - case UV_INHERIT_FD: { - /* Inherit a raw FD. */ - HANDLE child_handle; - - /* Make an inheritable duplicate of the handle. */ - err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle); - if (err) { - /* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */ - /* error. */ - if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) { - CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; - break; - } - goto error; - } - - /* Figure out what the type is. */ - switch (GetFileType(child_handle)) { - case FILE_TYPE_DISK: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN; - break; - - case FILE_TYPE_PIPE: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; - - case FILE_TYPE_CHAR: - case FILE_TYPE_REMOTE: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - break; - - case FILE_TYPE_UNKNOWN: - if (GetLastError() != 0) { - err = GetLastError(); - CloseHandle(child_handle); - goto error; - } - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - break; - - default: - assert(0); - return -1; - } - - CHILD_STDIO_HANDLE(buffer, i) = child_handle; - break; - } - - case UV_INHERIT_STREAM: { - /* Use an existing stream as the stdio handle for the child. */ - HANDLE stream_handle, child_handle; - unsigned char crt_flags; - uv_stream_t* stream = fdopt.data.stream; - - /* Leech the handle out of the stream. */ - if (stream->type == UV_TTY) { - stream_handle = ((uv_tty_t*) stream)->handle; - crt_flags = FOPEN | FDEV; - } else if (stream->type == UV_NAMED_PIPE && - stream->flags & UV_HANDLE_CONNECTION) { - stream_handle = ((uv_pipe_t*) stream)->handle; - crt_flags = FOPEN | FPIPE; - } else { - stream_handle = INVALID_HANDLE_VALUE; - crt_flags = 0; - } - - if (stream_handle == NULL || - stream_handle == INVALID_HANDLE_VALUE) { - /* The handle is already closed, or not yet created, or the */ - /* stream type is not supported. */ - err = ERROR_NOT_SUPPORTED; - goto error; - } - - /* Make an inheritable copy of the handle. */ - err = uv__duplicate_handle(loop, stream_handle, &child_handle); - if (err) - goto error; - - CHILD_STDIO_HANDLE(buffer, i) = child_handle; - CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags; - break; - } - - default: - assert(0); - return -1; - } - } - - *buffer_ptr = buffer; - return 0; - - error: - uv__stdio_destroy(buffer); - return err; -} - - -void uv__stdio_destroy(BYTE* buffer) { - int i, count; - - count = CHILD_STDIO_COUNT(buffer); - for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - } - } - - uv__free(buffer); -} - - -void uv__stdio_noinherit(BYTE* buffer) { - int i, count; - - count = CHILD_STDIO_COUNT(buffer); - for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); - if (handle != INVALID_HANDLE_VALUE) { - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - } - } -} - - -int uv__stdio_verify(BYTE* buffer, WORD size) { - unsigned int count; - - /* Check the buffer pointer. */ - if (buffer == NULL) - return 0; - - /* Verify that the buffer is at least big enough to hold the count. */ - if (size < CHILD_STDIO_SIZE(0)) - return 0; - - /* Verify if the count is within range. */ - count = CHILD_STDIO_COUNT(buffer); - if (count > 256) - return 0; - - /* Verify that the buffer size is big enough to hold info for N FDs. */ - if (size < CHILD_STDIO_SIZE(count)) - return 0; - - return 1; -} - - -WORD uv__stdio_size(BYTE* buffer) { - return (WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer))); -} - - -HANDLE uv__stdio_handle(BYTE* buffer, int fd) { - return CHILD_STDIO_HANDLE(buffer, fd); -} diff --git a/outside/libuv-v1.7.5/src/win/process.c b/outside/libuv-v1.7.5/src/win/process.c deleted file mode 100644 index 855c374081..0000000000 --- a/outside/libuv-v1.7.5/src/win/process.c +++ /dev/null @@ -1,1247 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include /* alloca */ - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -#define SIGKILL 9 - - -typedef struct env_var { - const WCHAR* const wide; - const WCHAR* const wide_eq; - const size_t len; /* including null or '=' */ -} env_var_t; - -#define E_V(str) { L##str, L##str L"=", sizeof(str) } - -static const env_var_t required_vars[] = { /* keep me sorted */ - E_V("HOMEDRIVE"), - E_V("HOMEPATH"), - E_V("LOGONSERVER"), - E_V("PATH"), - E_V("SYSTEMDRIVE"), - E_V("SYSTEMROOT"), - E_V("TEMP"), - E_V("USERDOMAIN"), - E_V("USERNAME"), - E_V("USERPROFILE"), - E_V("WINDIR"), -}; -static size_t n_required_vars = ARRAY_SIZE(required_vars); - - -static HANDLE uv_global_job_handle_; -static uv_once_t uv_global_job_handle_init_guard_ = UV_ONCE_INIT; - - -static void uv__init_global_job_handle(void) { - /* Create a job object and set it up to kill all contained processes when - * it's closed. Since this handle is made non-inheritable and we're not - * giving it to anyone, we're the only process holding a reference to it. - * That means that if this process exits it is closed and all the processes - * it contains are killed. All processes created with uv_spawn that are not - * spawned with the UV_PROCESS_DETACHED flag are assigned to this job. - * - * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the - * processes that we explicitly add are affected, and *their* subprocesses - * are not. This ensures that our child processes are not limited in their - * ability to use job control on Windows versions that don't deal with - * nested jobs (prior to Windows 8 / Server 2012). It also lets our child - * processes created detached processes without explicitly breaking away - * from job control (which uv_spawn doesn't, either). - */ - SECURITY_ATTRIBUTES attr; - JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; - - memset(&attr, 0, sizeof attr); - attr.bInheritHandle = FALSE; - - memset(&info, 0, sizeof info); - info.BasicLimitInformation.LimitFlags = - JOB_OBJECT_LIMIT_BREAKAWAY_OK | - JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK | - JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | - JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; - - uv_global_job_handle_ = CreateJobObjectW(&attr, NULL); - if (uv_global_job_handle_ == NULL) - uv_fatal_error(GetLastError(), "CreateJobObjectW"); - - if (!SetInformationJobObject(uv_global_job_handle_, - JobObjectExtendedLimitInformation, - &info, - sizeof info)) - uv_fatal_error(GetLastError(), "SetInformationJobObject"); -} - - -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; -} - - -static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS); - handle->exit_cb = NULL; - handle->pid = 0; - handle->exit_signal = 0; - handle->wait_handle = INVALID_HANDLE_VALUE; - handle->process_handle = INVALID_HANDLE_VALUE; - handle->child_stdio_buffer = NULL; - handle->exit_cb_pending = 0; - - uv_req_init(loop, (uv_req_t*)&handle->exit_req); - handle->exit_req.type = UV_PROCESS_EXIT; - handle->exit_req.data = handle; -} - - -/* - * Path search functions - */ - -/* - * Helper function for search_path - */ -static WCHAR* search_path_join_test(const WCHAR* dir, - size_t dir_len, - const WCHAR* name, - size_t name_len, - const WCHAR* ext, - size_t ext_len, - const WCHAR* cwd, - size_t cwd_len) { - WCHAR *result, *result_pos; - DWORD attrs; - if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') { - /* It's a UNC path so ignore cwd */ - cwd_len = 0; - } else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) { - /* It's a full path without drive letter, use cwd's drive letter only */ - cwd_len = 2; - } else if (dir_len >= 2 && dir[1] == L':' && - (dir_len < 3 || (dir[2] != L'/' && dir[2] != L'\\'))) { - /* It's a relative path with drive letter (ext.g. D:../some/file) - * Replace drive letter in dir by full cwd if it points to the same drive, - * otherwise use the dir only. - */ - if (cwd_len < 2 || _wcsnicmp(cwd, dir, 2) != 0) { - cwd_len = 0; - } else { - dir += 2; - dir_len -= 2; - } - } else if (dir_len > 2 && dir[1] == L':') { - /* It's an absolute path with drive letter - * Don't use the cwd at all - */ - cwd_len = 0; - } - - /* Allocate buffer for output */ - result = result_pos = (WCHAR*)uv__malloc(sizeof(WCHAR) * - (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1)); - - /* Copy cwd */ - wcsncpy(result_pos, cwd, cwd_len); - result_pos += cwd_len; - - /* Add a path separator if cwd didn't end with one */ - if (cwd_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { - result_pos[0] = L'\\'; - result_pos++; - } - - /* Copy dir */ - wcsncpy(result_pos, dir, dir_len); - result_pos += dir_len; - - /* Add a separator if the dir didn't end with one */ - if (dir_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { - result_pos[0] = L'\\'; - result_pos++; - } - - /* Copy filename */ - wcsncpy(result_pos, name, name_len); - result_pos += name_len; - - if (ext_len) { - /* Add a dot if the filename didn't end with one */ - if (name_len && result_pos[-1] != '.') { - result_pos[0] = L'.'; - result_pos++; - } - - /* Copy extension */ - wcsncpy(result_pos, ext, ext_len); - result_pos += ext_len; - } - - /* Null terminator */ - result_pos[0] = L'\0'; - - attrs = GetFileAttributesW(result); - - if (attrs != INVALID_FILE_ATTRIBUTES && - !(attrs & FILE_ATTRIBUTE_DIRECTORY)) { - return result; - } - - uv__free(result); - return NULL; -} - - -/* - * Helper function for search_path - */ -static WCHAR* path_search_walk_ext(const WCHAR *dir, - size_t dir_len, - const WCHAR *name, - size_t name_len, - WCHAR *cwd, - size_t cwd_len, - int name_has_ext) { - WCHAR* result; - - /* If the name itself has a nonempty extension, try this extension first */ - if (name_has_ext) { - result = search_path_join_test(dir, dir_len, - name, name_len, - L"", 0, - cwd, cwd_len); - if (result != NULL) { - return result; - } - } - - /* Try .com extension */ - result = search_path_join_test(dir, dir_len, - name, name_len, - L"com", 3, - cwd, cwd_len); - if (result != NULL) { - return result; - } - - /* Try .exe extension */ - result = search_path_join_test(dir, dir_len, - name, name_len, - L"exe", 3, - cwd, cwd_len); - if (result != NULL) { - return result; - } - - return NULL; -} - - -/* - * search_path searches the system path for an executable filename - - * the windows API doesn't provide this as a standalone function nor as an - * option to CreateProcess. - * - * It tries to return an absolute filename. - * - * Furthermore, it tries to follow the semantics that cmd.exe, with this - * exception that PATHEXT environment variable isn't used. Since CreateProcess - * can start only .com and .exe files, only those extensions are tried. This - * behavior equals that of msvcrt's spawn functions. - * - * - Do not search the path if the filename already contains a path (either - * relative or absolute). - * - * - If there's really only a filename, check the current directory for file, - * then search all path directories. - * - * - If filename specified has *any* extension, search for the file with the - * specified extension first. - * - * - If the literal filename is not found in a directory, try *appending* - * (not replacing) .com first and then .exe. - * - * - The path variable may contain relative paths; relative paths are relative - * to the cwd. - * - * - Directories in path may or may not end with a trailing backslash. - * - * - CMD does not trim leading/trailing whitespace from path/pathex entries - * nor from the environment variables as a whole. - * - * - When cmd.exe cannot read a directory, it will just skip it and go on - * searching. However, unlike posix-y systems, it will happily try to run a - * file that is not readable/executable; if the spawn fails it will not - * continue searching. - * - * UNC path support: we are dealing with UNC paths in both the path and the - * filename. This is a deviation from what cmd.exe does (it does not let you - * start a program by specifying an UNC path on the command line) but this is - * really a pointless restriction. - * - */ -static WCHAR* search_path(const WCHAR *file, - WCHAR *cwd, - const WCHAR *path) { - int file_has_dir; - WCHAR* result = NULL; - WCHAR *file_name_start; - WCHAR *dot; - const WCHAR *dir_start, *dir_end, *dir_path; - size_t dir_len; - int name_has_ext; - - size_t file_len = wcslen(file); - size_t cwd_len = wcslen(cwd); - - /* If the caller supplies an empty filename, - * we're not gonna return c:\windows\.exe -- GFY! - */ - if (file_len == 0 - || (file_len == 1 && file[0] == L'.')) { - return NULL; - } - - /* Find the start of the filename so we can split the directory from the */ - /* name. */ - for (file_name_start = (WCHAR*)file + file_len; - file_name_start > file - && file_name_start[-1] != L'\\' - && file_name_start[-1] != L'/' - && file_name_start[-1] != L':'; - file_name_start--); - - file_has_dir = file_name_start != file; - - /* Check if the filename includes an extension */ - dot = wcschr(file_name_start, L'.'); - name_has_ext = (dot != NULL && dot[1] != L'\0'); - - if (file_has_dir) { - /* The file has a path inside, don't use path */ - result = path_search_walk_ext( - file, file_name_start - file, - file_name_start, file_len - (file_name_start - file), - cwd, cwd_len, - name_has_ext); - - } else { - dir_end = path; - - /* The file is really only a name; look in cwd first, then scan path */ - result = path_search_walk_ext(L"", 0, - file, file_len, - cwd, cwd_len, - name_has_ext); - - while (result == NULL) { - if (*dir_end == L'\0') { - break; - } - - /* Skip the separator that dir_end now points to */ - if (dir_end != path || *path == L';') { - dir_end++; - } - - /* Next slice starts just after where the previous one ended */ - dir_start = dir_end; - - /* Slice until the next ; or \0 is found */ - dir_end = wcschr(dir_start, L';'); - if (dir_end == NULL) { - dir_end = wcschr(dir_start, L'\0'); - } - - /* If the slice is zero-length, don't bother */ - if (dir_end - dir_start == 0) { - continue; - } - - dir_path = dir_start; - dir_len = dir_end - dir_start; - - /* Adjust if the path is quoted. */ - if (dir_path[0] == '"' || dir_path[0] == '\'') { - ++dir_path; - --dir_len; - } - - if (dir_path[dir_len - 1] == '"' || dir_path[dir_len - 1] == '\'') { - --dir_len; - } - - result = path_search_walk_ext(dir_path, dir_len, - file, file_len, - cwd, cwd_len, - name_has_ext); - } - } - - return result; -} - - -/* - * Quotes command line arguments - * Returns a pointer to the end (next char to be written) of the buffer - */ -WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) { - size_t len = wcslen(source); - size_t i; - int quote_hit; - WCHAR* start; - - if (len == 0) { - /* Need double quotation for empty argument */ - *(target++) = L'"'; - *(target++) = L'"'; - return target; - } - - if (NULL == wcspbrk(source, L" \t\"")) { - /* No quotation needed */ - wcsncpy(target, source, len); - target += len; - return target; - } - - if (NULL == wcspbrk(source, L"\"\\")) { - /* - * No embedded double quotes or backlashes, so I can just wrap - * quote marks around the whole thing. - */ - *(target++) = L'"'; - wcsncpy(target, source, len); - target += len; - *(target++) = L'"'; - return target; - } - - /* - * Expected input/output: - * input : hello"world - * output: "hello\"world" - * input : hello""world - * output: "hello\"\"world" - * input : hello\world - * output: hello\world - * input : hello\\world - * output: hello\\world - * input : hello\"world - * output: "hello\\\"world" - * input : hello\\"world - * output: "hello\\\\\"world" - * input : hello world\ - * output: "hello world\" - */ - - *(target++) = L'"'; - start = target; - quote_hit = 1; - - for (i = len; i > 0; --i) { - *(target++) = source[i - 1]; - - if (quote_hit && source[i - 1] == L'\\') { - *(target++) = L'\\'; - } else if(source[i - 1] == L'"') { - quote_hit = 1; - *(target++) = L'\\'; - } else { - quote_hit = 0; - } - } - target[0] = L'\0'; - wcsrev(start); - *(target++) = L'"'; - return target; -} - - -int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { - char** arg; - WCHAR* dst = NULL; - WCHAR* temp_buffer = NULL; - size_t dst_len = 0; - size_t temp_buffer_len = 0; - WCHAR* pos; - int arg_count = 0; - int err = 0; - - /* Count the required size. */ - for (arg = args; *arg; arg++) { - DWORD arg_len; - - arg_len = MultiByteToWideChar(CP_UTF8, - 0, - *arg, - -1, - NULL, - 0); - if (arg_len == 0) { - return GetLastError(); - } - - dst_len += arg_len; - - if (arg_len > temp_buffer_len) - temp_buffer_len = arg_len; - - arg_count++; - } - - /* Adjust for potential quotes. Also assume the worst-case scenario */ - /* that every character needs escaping, so we need twice as much space. */ - dst_len = dst_len * 2 + arg_count * 2; - - /* Allocate buffer for the final command line. */ - dst = (WCHAR*) uv__malloc(dst_len * sizeof(WCHAR)); - if (dst == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - /* Allocate temporary working buffer. */ - temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR)); - if (temp_buffer == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - pos = dst; - for (arg = args; *arg; arg++) { - DWORD 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; - } - - if (verbatim_arguments) { - /* Copy verbatim. */ - wcscpy(pos, temp_buffer); - pos += arg_len - 1; - } else { - /* Quote/escape, if needed. */ - pos = quote_cmd_arg(temp_buffer, pos); - } - - *pos++ = *(arg + 1) ? L' ' : L'\0'; - } - - uv__free(temp_buffer); - - *dst_ptr = dst; - return 0; - -error: - uv__free(dst); - uv__free(temp_buffer); - return err; -} - - -int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { - wchar_t* a_eq; - wchar_t* b_eq; - wchar_t* A; - wchar_t* B; - int nb; - int r; - - if (na < 0) { - a_eq = wcschr(a, L'='); - assert(a_eq); - na = (int)(long)(a_eq - a); - } else { - na--; - } - b_eq = wcschr(b, L'='); - assert(b_eq); - nb = b_eq - b; - - A = alloca((na+1) * sizeof(wchar_t)); - B = alloca((nb+1) * sizeof(wchar_t)); - - r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na); - assert(r==na); - A[na] = L'\0'; - r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, b, nb, B, nb); - assert(r==nb); - B[nb] = L'\0'; - - while (1) { - wchar_t AA = *A++; - wchar_t BB = *B++; - if (AA < BB) { - return -1; - } else if (AA > BB) { - return 1; - } else if (!AA && !BB) { - return 0; - } - } -} - - -static int qsort_wcscmp(const void *a, const void *b) { - wchar_t* astr = *(wchar_t* const*)a; - wchar_t* bstr = *(wchar_t* const*)b; - return env_strncmp(astr, -1, bstr); -} - - -/* - * The way windows takes environment variables is different than what C does; - * Windows wants a contiguous block of null-terminated strings, terminated - * with an additional null. - * - * Windows has a few "essential" environment variables. winsock will fail - * to initialize if SYSTEMROOT is not defined; some APIs make reference to - * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that - * these get defined if the input environment block does not contain any - * values for them. - * - * Also add variables known to Cygwin to be required for correct - * subprocess operation in many cases: - * https://github.com/Alexpux/Cygwin/blob/b266b04fbbd3a595f02ea149e4306d3ab9b1fe3d/winsup/cygwin/environ.cc#L955 - * - */ -int make_program_env(char* env_block[], WCHAR** dst_ptr) { - WCHAR* dst; - WCHAR* ptr; - char** env; - size_t env_len = 0; - int len; - size_t i; - DWORD 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 = alloca(n_required_vars * sizeof(DWORD*)); - - /* first pass: determine size in UTF-16 */ - for (env = env_block; *env; env++) { - int len; - if (strchr(*env, '=')) { - len = MultiByteToWideChar(CP_UTF8, - 0, - *env, - -1, - NULL, - 0); - if (len <= 0) { - return GetLastError(); - } - env_len += len; - env_block_count++; - } - } - - /* second pass: copy to UTF-16 environment block */ - dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR)); - if (!dst_copy) { - return ERROR_OUTOFMEMORY; - } - env_copy = alloca(env_block_count * sizeof(WCHAR*)); - - ptr = dst_copy; - ptr_copy = env_copy; - for (env = env_block; *env; env++) { - 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; - } - *ptr_copy++ = ptr; - ptr += len; - } - } - *ptr_copy = NULL; - assert(env_len == ptr - dst_copy); - - /* sort our (UTF-16) copy */ - qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp); - - /* third pass: check for required variables */ - for (ptr_copy = env_copy, i = 0; i < n_required_vars; ) { - int cmp; - if (!*ptr_copy) { - cmp = -1; - } else { - cmp = env_strncmp(required_vars[i].wide_eq, - required_vars[i].len, - *ptr_copy); - } - if (cmp < 0) { - /* missing required var */ - var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); - required_vars_value_len[i] = var_size; - if (var_size != 0) { - env_len += required_vars[i].len; - env_len += var_size; - } - i++; - } else { - ptr_copy++; - if (cmp == 0) - i++; - } - } - - /* final pass: copy, in sort order, and inserting required variables */ - dst = uv__malloc((1+env_len) * sizeof(WCHAR)); - if (!dst) { - uv__free(dst_copy); - return ERROR_OUTOFMEMORY; - } - - for (ptr = dst, ptr_copy = env_copy, i = 0; - *ptr_copy || i < n_required_vars; - ptr += len) { - int cmp; - if (i >= n_required_vars) { - cmp = 1; - } else if (!*ptr_copy) { - cmp = -1; - } else { - cmp = env_strncmp(required_vars[i].wide_eq, - required_vars[i].len, - *ptr_copy); - } - if (cmp < 0) { - /* missing required var */ - len = required_vars_value_len[i]; - if (len) { - wcscpy(ptr, required_vars[i].wide_eq); - ptr += required_vars[i].len; - var_size = GetEnvironmentVariableW(required_vars[i].wide, - ptr, - (int) (env_len - (ptr - dst))); - if (var_size != len-1) { /* race condition? */ - uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); - } - } - i++; - } else { - /* copy var from env_block */ - len = wcslen(*ptr_copy) + 1; - wmemcpy(ptr, *ptr_copy, len); - ptr_copy++; - if (cmp == 0) - i++; - } - } - - /* Terminate with an extra NULL. */ - assert(env_len == (ptr - dst)); - *ptr = L'\0'; - - uv__free(dst_copy); - *dst_ptr = dst; - return 0; -} - -/* - * Attempt to find the value of the PATH environment variable in the child's - * preprocessed environment. - * - * If found, a pointer into `env` is returned. If not found, NULL is returned. - */ -static WCHAR* find_path(WCHAR *env) { - for (; env != NULL && *env != 0; env += wcslen(env) + 1) { - if (wcsncmp(env, L"PATH=", 5) == 0) - return &env[5]; - } - - return NULL; -} - -/* - * Called on Windows thread-pool thread to indicate that - * a child process has exited. - */ -static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) { - uv_process_t* process = (uv_process_t*) data; - uv_loop_t* loop = process->loop; - - assert(didTimeout == FALSE); - assert(process); - assert(!process->exit_cb_pending); - - process->exit_cb_pending = 1; - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, &process->exit_req); -} - - -/* Called on main thread after a child process has exited. */ -void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) { - int64_t exit_code; - DWORD status; - - assert(handle->exit_cb_pending); - handle->exit_cb_pending = 0; - - /* If we're closing, don't call the exit callback. Just schedule a close */ - /* callback now. */ - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*) handle); - return; - } - - /* Unregister from process notification. */ - if (handle->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->wait_handle); - handle->wait_handle = INVALID_HANDLE_VALUE; - } - - /* Set the handle to inactive: no callbacks will be made after the exit */ - /* callback.*/ - uv__handle_stop(handle); - - if (GetExitCodeProcess(handle->process_handle, &status)) { - exit_code = status; - } else { - /* Unable to to obtain the exit code. This should never happen. */ - exit_code = uv_translate_sys_error(GetLastError()); - } - - /* Fire the exit callback. */ - if (handle->exit_cb) { - handle->exit_cb(handle, exit_code, handle->exit_signal); - } -} - - -void uv_process_close(uv_loop_t* loop, uv_process_t* handle) { - uv__handle_closing(handle); - - if (handle->wait_handle != INVALID_HANDLE_VALUE) { - /* This blocks until either the wait was cancelled, or the callback has */ - /* completed. */ - BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE); - if (!r) { - /* This should never happen, and if it happens, we can't recover... */ - uv_fatal_error(GetLastError(), "UnregisterWaitEx"); - } - - handle->wait_handle = INVALID_HANDLE_VALUE; - } - - if (!handle->exit_cb_pending) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } -} - - -void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) { - assert(!handle->exit_cb_pending); - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - /* Clean-up the process handle. */ - CloseHandle(handle->process_handle); - - uv__handle_close(handle); -} - - -int uv_spawn(uv_loop_t* loop, - uv_process_t* process, - const uv_process_options_t* options) { - int i; - int err = 0; - WCHAR* path = NULL, *alloc_path = NULL; - BOOL result; - WCHAR* application_path = NULL, *application = NULL, *arguments = NULL, - *env = NULL, *cwd = NULL; - STARTUPINFOW startup; - PROCESS_INFORMATION info; - DWORD process_flags; - - uv_process_init(loop, process); - process->exit_cb = options->exit_cb; - - if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) { - return UV_ENOTSUP; - } - - if (options->file == NULL || - options->args == NULL) { - return UV_EINVAL; - } - - assert(options->file != NULL); - assert(!(options->flags & ~(UV_PROCESS_DETACHED | - UV_PROCESS_SETGID | - UV_PROCESS_SETUID | - UV_PROCESS_WINDOWS_HIDE | - UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); - - err = uv_utf8_to_utf16_alloc(options->file, &application); - if (err) - goto done; - - err = make_program_args( - options->args, - options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, - &arguments); - if (err) - goto done; - - if (options->env) { - err = make_program_env(options->env, &env); - if (err) - goto done; - } - - if (options->cwd) { - /* Explicit cwd */ - err = uv_utf8_to_utf16_alloc(options->cwd, &cwd); - if (err) - goto done; - - } else { - /* Inherit cwd */ - DWORD cwd_len, r; - - cwd_len = GetCurrentDirectoryW(0, NULL); - if (!cwd_len) { - err = GetLastError(); - goto done; - } - - cwd = (WCHAR*) uv__malloc(cwd_len * sizeof(WCHAR)); - if (cwd == NULL) { - err = ERROR_OUTOFMEMORY; - goto done; - } - - r = GetCurrentDirectoryW(cwd_len, cwd); - if (r == 0 || r >= cwd_len) { - err = GetLastError(); - goto done; - } - } - - /* Get PATH environment variable. */ - path = find_path(env); - if (path == NULL) { - DWORD path_len, r; - - path_len = GetEnvironmentVariableW(L"PATH", NULL, 0); - if (path_len == 0) { - err = GetLastError(); - goto done; - } - - 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; - } - } - - err = uv__stdio_create(loop, options, &process->child_stdio_buffer); - if (err) - goto done; - - application_path = search_path(application, - cwd, - path); - if (application_path == NULL) { - /* Not found. */ - err = ERROR_FILE_NOT_FOUND; - goto done; - } - - startup.cb = sizeof(startup); - startup.lpReserved = NULL; - startup.lpDesktop = NULL; - startup.lpTitle = NULL; - startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - - startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer); - startup.lpReserved2 = (BYTE*) process->child_stdio_buffer; - - startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0); - startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1); - startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2); - - if (options->flags & UV_PROCESS_WINDOWS_HIDE) { - /* Use SW_HIDE to avoid any potential process window. */ - startup.wShowWindow = SW_HIDE; - } else { - startup.wShowWindow = SW_SHOWDEFAULT; - } - - process_flags = CREATE_UNICODE_ENVIRONMENT; - - if (options->flags & UV_PROCESS_DETACHED) { - /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That - * means that libuv might not let you create a fully daemonized process - * when run under job control. However the type of job control that libuv - * itself creates doesn't trickle down to subprocesses so they can still - * daemonize. - * - * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the - * CreateProcess call fail if we're under job control that doesn't allow - * breakaway. - */ - process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; - } - - if (!CreateProcessW(application_path, - arguments, - NULL, - NULL, - 1, - process_flags, - env, - cwd, - &startup, - &info)) { - /* CreateProcessW failed. */ - err = GetLastError(); - 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)) { - uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle); - - if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) { - /* AssignProcessToJobObject might fail if this process is under job - * control and the job doesn't have the - * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version - * that doesn't support nested jobs. - * - * When that happens we just swallow the error and continue without - * establishing a kill-child-on-parent-exit relationship, otherwise - * there would be no way for libuv applications run under job control - * to spawn processes at all. - */ - DWORD err = GetLastError(); - if (err != ERROR_ACCESS_DENIED) - uv_fatal_error(err, "AssignProcessToJobObject"); - } - } - - /* Set IPC pid to all IPC pipes. */ - for (i = 0; i < options->stdio_count; i++) { - const uv_stdio_container_t* fdopt = &options->stdio[i]; - if (fdopt->flags & UV_CREATE_PIPE && - fdopt->data.stream->type == UV_NAMED_PIPE && - ((uv_pipe_t*) fdopt->data.stream)->ipc) { - ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId; - } - } - - /* Setup notifications for when the child process exits. */ - result = RegisterWaitForSingleObject(&process->wait_handle, - process->process_handle, exit_wait_callback, (void*)process, INFINITE, - WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); - if (!result) { - uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject"); - } - - CloseHandle(info.hThread); - - assert(!err); - - /* Make the handle active. It will remain active until the exit callback */ - /* is made or the handle is closed, whichever happens first. */ - uv__handle_start(process); - - /* Cleanup, whether we succeeded or failed. */ - done: - uv__free(application); - uv__free(application_path); - uv__free(arguments); - uv__free(cwd); - uv__free(env); - uv__free(alloc_path); - - if (process->child_stdio_buffer != NULL) { - /* Clean up child stdio handles. */ - uv__stdio_destroy(process->child_stdio_buffer); - process->child_stdio_buffer = NULL; - } - - return uv_translate_sys_error(err); -} - - -static int uv__kill(HANDLE process_handle, int signum) { - switch (signum) { - case SIGTERM: - case SIGKILL: - case SIGINT: { - /* Unconditionally terminate the process. On Windows, killed processes */ - /* normally return 1. */ - DWORD status; - int err; - - if (TerminateProcess(process_handle, 1)) - return 0; - - /* If the process already exited before TerminateProcess was called, */ - /* TerminateProcess will fail with ERROR_ACCESS_DENIED. */ - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED && - GetExitCodeProcess(process_handle, &status) && - status != STILL_ACTIVE) { - return UV_ESRCH; - } - - return uv_translate_sys_error(err); - } - - case 0: { - /* Health check: is the process still alive? */ - DWORD status; - - if (!GetExitCodeProcess(process_handle, &status)) - return uv_translate_sys_error(GetLastError()); - - if (status != STILL_ACTIVE) - return UV_ESRCH; - - return 0; - } - - default: - /* Unsupported signal. */ - return UV_ENOSYS; - } -} - - -int uv_process_kill(uv_process_t* process, int signum) { - int err; - - if (process->process_handle == INVALID_HANDLE_VALUE) { - return UV_EINVAL; - } - - err = uv__kill(process->process_handle, signum); - if (err) { - return err; /* err is already translated. */ - } - - process->exit_signal = signum; - - return 0; -} - - -int uv_kill(int pid, int signum) { - int err; - HANDLE process_handle = OpenProcess(PROCESS_TERMINATE | - PROCESS_QUERY_INFORMATION, FALSE, pid); - - if (process_handle == NULL) { - err = GetLastError(); - if (err == ERROR_INVALID_PARAMETER) { - return UV_ESRCH; - } else { - return uv_translate_sys_error(err); - } - } - - err = uv__kill(process_handle, signum); - CloseHandle(process_handle); - - return err; /* err is already translated. */ -} diff --git a/outside/libuv-v1.7.5/src/win/req-inl.h b/outside/libuv-v1.7.5/src/win/req-inl.h deleted file mode 100644 index b5e502eef5..0000000000 --- a/outside/libuv-v1.7.5/src/win/req-inl.h +++ /dev/null @@ -1,224 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_REQ_INL_H_ -#define UV_WIN_REQ_INL_H_ - -#include - -#include "uv.h" -#include "internal.h" - - -#define SET_REQ_STATUS(req, status) \ - (req)->u.io.overlapped.Internal = (ULONG_PTR) (status) - -#define SET_REQ_ERROR(req, error) \ - SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) - -#define SET_REQ_SUCCESS(req) \ - SET_REQ_STATUS((req), STATUS_SUCCESS) - -#define GET_REQ_STATUS(req) \ - ((NTSTATUS) (req)->u.io.overlapped.Internal) - -#define REQ_SUCCESS(req) \ - (NT_SUCCESS(GET_REQ_STATUS((req)))) - -#define GET_REQ_ERROR(req) \ - (pRtlNtStatusToDosError(GET_REQ_STATUS((req)))) - -#define GET_REQ_SOCK_ERROR(req) \ - (uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req)))) - - -#define REGISTER_HANDLE_REQ(loop, handle, req) \ - do { \ - INCREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_register((loop), (req)); \ - } while (0) - -#define UNREGISTER_HANDLE_REQ(loop, handle, req) \ - do { \ - DECREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_unregister((loop), (req)); \ - } while (0) - - -#define UV_SUCCEEDED_WITHOUT_IOCP(result) \ - ((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP)) - -#define UV_SUCCEEDED_WITH_IOCP(result) \ - ((result) || (GetLastError() == ERROR_IO_PENDING)) - - -#define POST_COMPLETION_FOR_REQ(loop, req) \ - if (!PostQueuedCompletionStatus((loop)->iocp, \ - 0, \ - 0, \ - &((req)->u.io.overlapped))) { \ - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \ - } - - -INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) { - req->type = UV_UNKNOWN_REQ; - SET_REQ_SUCCESS(req); -} - - -INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { - return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped); -} - - -INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) { - req->next_req = NULL; - if (loop->pending_reqs_tail) { -#ifdef _DEBUG - /* Ensure the request is not already in the queue, or the queue - * will get corrupted. - */ - uv_req_t* current = loop->pending_reqs_tail; - do { - assert(req != current); - current = current->next_req; - } while(current != loop->pending_reqs_tail); -#endif - - req->next_req = loop->pending_reqs_tail->next_req; - loop->pending_reqs_tail->next_req = req; - loop->pending_reqs_tail = req; - } else { - req->next_req = req; - loop->pending_reqs_tail = req; - } -} - - -#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \ - do { \ - switch (((uv_handle_t*) (req)->handle_at)->type) { \ - case UV_TCP: \ - uv_process_tcp_##method##_req(loop, \ - (uv_tcp_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - case UV_NAMED_PIPE: \ - uv_process_pipe_##method##_req(loop, \ - (uv_pipe_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - case UV_TTY: \ - uv_process_tty_##method##_req(loop, \ - (uv_tty_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - default: \ - assert(0); \ - } \ - } while (0) - - -INLINE static int uv_process_reqs(uv_loop_t* loop) { - uv_req_t* req; - uv_req_t* first; - uv_req_t* next; - - if (loop->pending_reqs_tail == NULL) - return 0; - - first = loop->pending_reqs_tail->next_req; - next = first; - loop->pending_reqs_tail = NULL; - - while (next != NULL) { - req = next; - next = req->next_req != first ? req->next_req : NULL; - - switch (req->type) { - case UV_READ: - DELEGATE_STREAM_REQ(loop, req, read, data); - break; - - case UV_WRITE: - DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle); - break; - - case UV_ACCEPT: - DELEGATE_STREAM_REQ(loop, req, accept, data); - break; - - case UV_CONNECT: - DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle); - break; - - case UV_SHUTDOWN: - /* Tcp shutdown requests don't come here. */ - assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE); - uv_process_pipe_shutdown_req( - loop, - (uv_pipe_t*) ((uv_shutdown_t*) req)->handle, - (uv_shutdown_t*) req); - break; - - case UV_UDP_RECV: - uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req); - break; - - case UV_UDP_SEND: - uv_process_udp_send_req(loop, - ((uv_udp_send_t*) req)->handle, - (uv_udp_send_t*) req); - break; - - case UV_WAKEUP: - uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req); - break; - - case UV_SIGNAL_REQ: - uv_process_signal_req(loop, (uv_signal_t*) req->data, req); - break; - - case UV_POLL_REQ: - uv_process_poll_req(loop, (uv_poll_t*) req->data, req); - break; - - case UV_PROCESS_EXIT: - uv_process_proc_exit(loop, (uv_process_t*) req->data); - break; - - case UV_FS_EVENT_REQ: - uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data); - break; - - default: - assert(0); - } - } - - return 1; -} - -#endif /* UV_WIN_REQ_INL_H_ */ diff --git a/outside/libuv-v1.7.5/src/win/req.c b/outside/libuv-v1.7.5/src/win/req.c deleted file mode 100644 index 111cc5e289..0000000000 --- a/outside/libuv-v1.7.5/src/win/req.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "uv.h" -#include "internal.h" diff --git a/outside/libuv-v1.7.5/src/win/signal.c b/outside/libuv-v1.7.5/src/win/signal.c deleted file mode 100644 index 2c64a55dc3..0000000000 --- a/outside/libuv-v1.7.5/src/win/signal.c +++ /dev/null @@ -1,356 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -RB_HEAD(uv_signal_tree_s, uv_signal_s); - -static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree); -static ssize_t volatile uv__signal_control_handler_refs = 0; -static CRITICAL_SECTION uv__signal_lock; - - -void uv_signals_init() { - InitializeCriticalSection(&uv__signal_lock); -} - - -static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { - /* Compare signums first so all watchers with the same signnum end up */ - /* adjacent. */ - if (w1->signum < w2->signum) return -1; - if (w1->signum > w2->signum) return 1; - - /* Sort by loop pointer, so we can easily look up the first item after */ - /* { .signum = x, .loop = NULL } */ - if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1; - if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1; - - if ((uintptr_t) w1 < (uintptr_t) w2) return -1; - if ((uintptr_t) w1 > (uintptr_t) w2) return 1; - - return 0; -} - - -RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare); - - -/* - * Dispatches signal {signum} to all active uv_signal_t watchers in all loops. - * Returns 1 if the signal was dispatched to any watcher, or 0 if there were - * no active signal watchers observing this signal. - */ -int uv__signal_dispatch(int signum) { - uv_signal_t lookup; - uv_signal_t* handle; - int dispatched = 0; - - EnterCriticalSection(&uv__signal_lock); - - lookup.signum = signum; - lookup.loop = NULL; - - for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup); - handle != NULL && handle->signum == signum; - handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) { - unsigned long previous = InterlockedExchange( - (volatile LONG*) &handle->pending_signum, signum); - - if (!previous) { - POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req); - } - - dispatched = 1; - } - - LeaveCriticalSection(&uv__signal_lock); - - return dispatched; -} - - -static BOOL WINAPI uv__signal_control_handler(DWORD type) { - switch (type) { - case CTRL_C_EVENT: - return uv__signal_dispatch(SIGINT); - - case CTRL_BREAK_EVENT: - return uv__signal_dispatch(SIGBREAK); - - case CTRL_CLOSE_EVENT: - if (uv__signal_dispatch(SIGHUP)) { - /* Windows will terminate the process after the control handler */ - /* returns. After that it will just terminate our process. Therefore */ - /* block the signal handler so the main loop has some time to pick */ - /* up the signal and do something for a few seconds. */ - Sleep(INFINITE); - return TRUE; - } - return FALSE; - - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - /* These signals are only sent to services. Services have their own */ - /* notification mechanism, so there's no point in handling these. */ - - default: - /* We don't handle these. */ - return FALSE; - } -} - - -static int uv__signal_register_control_handler() { - /* When this function is called, the uv__signal_lock must be held. */ - - /* If the console control handler has already been hooked, just add a */ - /* reference. */ - if (uv__signal_control_handler_refs > 0) { - uv__signal_control_handler_refs++; - return 0; - } - - if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE)) - return GetLastError(); - - uv__signal_control_handler_refs++; - - return 0; -} - - -static void uv__signal_unregister_control_handler() { - /* When this function is called, the uv__signal_lock must be held. */ - BOOL r; - - /* Don't unregister if the number of console control handlers exceeds one. */ - /* Just remove a reference in that case. */ - if (uv__signal_control_handler_refs > 1) { - uv__signal_control_handler_refs--; - return; - } - - assert(uv__signal_control_handler_refs == 1); - - r = SetConsoleCtrlHandler(uv__signal_control_handler, FALSE); - /* This should never fail; if it does it is probably a bug in libuv. */ - assert(r); - - uv__signal_control_handler_refs--; -} - - -static int uv__signal_register(int signum) { - switch (signum) { - case SIGINT: - case SIGBREAK: - case SIGHUP: - return uv__signal_register_control_handler(); - - case SIGWINCH: - /* SIGWINCH is generated in tty.c. No need to register anything. */ - return 0; - - case SIGILL: - case SIGABRT_COMPAT: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGABRT: - /* Signal is never raised. */ - return 0; - - default: - /* Invalid signal. */ - return ERROR_INVALID_PARAMETER; - } -} - - -static void uv__signal_unregister(int signum) { - switch (signum) { - case SIGINT: - case SIGBREAK: - case SIGHUP: - uv__signal_unregister_control_handler(); - return; - - case SIGWINCH: - /* SIGWINCH is generated in tty.c. No need to unregister anything. */ - return; - - case SIGILL: - case SIGABRT_COMPAT: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGABRT: - /* Nothing is registered for this signal. */ - return; - - default: - /* Libuv bug. */ - assert(0 && "Invalid signum"); - return; - } -} - - -int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - uv_req_t* req; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); - handle->pending_signum = 0; - handle->signum = 0; - handle->signal_cb = NULL; - - req = &handle->signal_req; - uv_req_init(loop, req); - req->type = UV_SIGNAL_REQ; - req->data = handle; - - return 0; -} - - -int uv_signal_stop(uv_signal_t* handle) { - uv_signal_t* removed_handle; - - /* If the watcher wasn't started, this is a no-op. */ - if (handle->signum == 0) - return 0; - - EnterCriticalSection(&uv__signal_lock); - - uv__signal_unregister(handle->signum); - - removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle); - assert(removed_handle == handle); - - LeaveCriticalSection(&uv__signal_lock); - - handle->signum = 0; - uv__handle_stop(handle); - - return 0; -} - - -int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { - int err; - - /* If the user supplies signum == 0, then return an error already. If the */ - /* signum is otherwise invalid then uv__signal_register will find out */ - /* eventually. */ - if (signum == 0) { - return UV_EINVAL; - } - - /* Short circuit: if the signal watcher is already watching {signum} don't */ - /* go through the process of deregistering and registering the handler. */ - /* Additionally, this avoids pending signals getting lost in the (small) */ - /* time frame that handle->signum == 0. */ - if (signum == handle->signum) { - handle->signal_cb = signal_cb; - return 0; - } - - /* If the signal handler was already active, stop it first. */ - if (handle->signum != 0) { - int r = uv_signal_stop(handle); - /* uv_signal_stop is infallible. */ - assert(r == 0); - } - - EnterCriticalSection(&uv__signal_lock); - - err = uv__signal_register(signum); - if (err) { - /* Uh-oh, didn't work. */ - LeaveCriticalSection(&uv__signal_lock); - return uv_translate_sys_error(err); - } - - handle->signum = signum; - RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); - - LeaveCriticalSection(&uv__signal_lock); - - handle->signal_cb = signal_cb; - uv__handle_start(handle); - - return 0; -} - - -void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, - uv_req_t* req) { - long dispatched_signum; - - assert(handle->type == UV_SIGNAL); - assert(req->type == UV_SIGNAL_REQ); - - dispatched_signum = InterlockedExchange( - (volatile LONG*) &handle->pending_signum, 0); - assert(dispatched_signum != 0); - - /* Check if the pending signal equals the signum that we are watching for. */ - /* These can get out of sync when the handler is stopped and restarted */ - /* while the signal_req is pending. */ - if (dispatched_signum == handle->signum) - handle->signal_cb(handle, dispatched_signum); - - if (handle->flags & UV__HANDLE_CLOSING) { - /* When it is closing, it must be stopped at this point. */ - assert(handle->signum == 0); - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) { - uv_signal_stop(handle); - uv__handle_closing(handle); - - if (handle->pending_signum == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - assert(handle->signum == 0); - assert(handle->pending_signum == 0); - - handle->flags |= UV_HANDLE_CLOSED; - - uv__handle_close(handle); -} diff --git a/outside/libuv-v1.7.5/src/win/stream-inl.h b/outside/libuv-v1.7.5/src/win/stream-inl.h deleted file mode 100644 index b7a3c11958..0000000000 --- a/outside/libuv-v1.7.5/src/win/stream-inl.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_STREAM_INL_H_ -#define UV_WIN_STREAM_INL_H_ - -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -INLINE static void uv_stream_init(uv_loop_t* loop, - uv_stream_t* handle, - uv_handle_type type) { - uv__handle_init(loop, (uv_handle_t*) handle, type); - handle->write_queue_size = 0; - handle->activecnt = 0; -} - - -INLINE static void uv_connection_init(uv_stream_t* handle) { - handle->flags |= UV_HANDLE_CONNECTION; - handle->stream.conn.write_reqs_pending = 0; - - uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req)); - handle->read_req.event_handle = NULL; - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - handle->read_req.type = UV_READ; - handle->read_req.data = handle; - - handle->stream.conn.shutdown_req = NULL; -} - - -#endif /* UV_WIN_STREAM_INL_H_ */ diff --git a/outside/libuv-v1.7.5/src/win/stream.c b/outside/libuv-v1.7.5/src/win/stream.c deleted file mode 100644 index a2466e5e9d..0000000000 --- a/outside/libuv-v1.7.5/src/win/stream.c +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { - int err; - - err = ERROR_INVALID_PARAMETER; - switch (stream->type) { - case UV_TCP: - err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_accept(uv_stream_t* server, uv_stream_t* client) { - int err; - - err = ERROR_INVALID_PARAMETER; - switch (server->type) { - case UV_TCP: - err = uv_tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client); - break; - case UV_NAMED_PIPE: - err = uv_pipe_accept((uv_pipe_t*)server, client); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - int err; - - if (handle->flags & UV_HANDLE_READING) { - return UV_EALREADY; - } - - if (!(handle->flags & UV_HANDLE_READABLE)) { - return UV_ENOTCONN; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_TCP: - err = uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb); - break; - case UV_TTY: - err = uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_read_stop(uv_stream_t* handle) { - int err; - - if (!(handle->flags & UV_HANDLE_READING)) - return 0; - - err = 0; - if (handle->type == UV_TTY) { - err = uv_tty_read_stop((uv_tty_t*) handle); - } else { - if (handle->type == UV_NAMED_PIPE) { - uv__pipe_stop_read((uv_pipe_t*) handle); - } else { - handle->flags &= ~UV_HANDLE_READING; - } - DECREASE_ACTIVE_COUNT(handle->loop, handle); - } - - return uv_translate_sys_error(err); -} - - -int uv_write(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_TCP: - err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, nbufs, cb); - break; - case UV_TTY: - err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_write2(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_NAMED_PIPE: - err = uv_pipe_write2(loop, - req, - (uv_pipe_t*) handle, - bufs, - nbufs, - send_handle, - cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_try_write(uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs) { - if (stream->flags & UV__HANDLE_CLOSING) - return UV_EBADF; - if (!(stream->flags & UV_HANDLE_WRITABLE)) - return UV_EPIPE; - - switch (stream->type) { - case UV_TCP: - return uv__tcp_try_write((uv_tcp_t*) stream, bufs, nbufs); - case UV_TTY: - return uv__tty_try_write((uv_tty_t*) stream, bufs, nbufs); - case UV_NAMED_PIPE: - return UV_EAGAIN; - default: - assert(0); - return UV_ENOSYS; - } -} - - -int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { - uv_loop_t* loop = handle->loop; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_SHUTDOWN; - req->handle = handle; - req->cb = cb; - - handle->flags &= ~UV_HANDLE_WRITABLE; - handle->stream.conn.shutdown_req = req; - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - - uv_want_endgame(loop, (uv_handle_t*)handle); - - return 0; -} - - -int uv_is_readable(const uv_stream_t* handle) { - return !!(handle->flags & UV_HANDLE_READABLE); -} - - -int uv_is_writable(const uv_stream_t* handle) { - return !!(handle->flags & UV_HANDLE_WRITABLE); -} - - -int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { - if (handle->type != UV_NAMED_PIPE) - return UV_EINVAL; - - if (blocking != 0) - handle->flags |= UV_HANDLE_BLOCKING_WRITES; - else - handle->flags &= ~UV_HANDLE_BLOCKING_WRITES; - - return 0; -} diff --git a/outside/libuv-v1.7.5/src/win/tcp.c b/outside/libuv-v1.7.5/src/win/tcp.c deleted file mode 100644 index 0f5654863e..0000000000 --- a/outside/libuv-v1.7.5/src/win/tcp.c +++ /dev/null @@ -1,1507 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -/* - * Threshold of active tcp streams for which to preallocate tcp read buffers. - * (Due to node slab allocator performing poorly under this pattern, - * the optimization is temporarily disabled (threshold=0). This will be - * revisited once node allocator is improved.) - */ -const unsigned int uv_active_tcp_streams_threshold = 0; - -/* - * Number of simultaneous pending AcceptEx calls. - */ -const unsigned int uv_simultaneous_server_accepts = 32; - -/* A zero-size buffer for use by uv_tcp_read */ -static char uv_zero_[] = ""; - -static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) { - if (setsockopt(socket, - IPPROTO_TCP, - TCP_NODELAY, - (const char*)&enable, - sizeof enable) == -1) { - return WSAGetLastError(); - } - return 0; -} - - -static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) { - if (setsockopt(socket, - SOL_SOCKET, - SO_KEEPALIVE, - (const char*)&enable, - sizeof enable) == -1) { - return WSAGetLastError(); - } - - if (enable && setsockopt(socket, - IPPROTO_TCP, - TCP_KEEPALIVE, - (const char*)&delay, - sizeof delay) == -1) { - return WSAGetLastError(); - } - - return 0; -} - - -static int uv_tcp_set_socket(uv_loop_t* loop, - uv_tcp_t* handle, - SOCKET socket, - int family, - int imported) { - DWORD yes = 1; - int non_ifs_lsp; - int err; - - if (handle->socket != INVALID_SOCKET) - return UV_EBUSY; - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) - return GetLastError(); - - /* Associate it with the I/O completion port. */ - /* Use uv_handle_t pointer as completion key. */ - if (CreateIoCompletionPort((HANDLE)socket, - loop->iocp, - (ULONG_PTR)socket, - 0) == NULL) { - if (imported) { - handle->flags |= UV_HANDLE_EMULATE_IOCP; - } else { - return GetLastError(); - } - } - - if (family == AF_INET6) { - non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6; - } else { - non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4; - } - - if (pSetFileCompletionNotificationModes && - !(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) { - if (pSetFileCompletionNotificationModes((HANDLE) socket, - FILE_SKIP_SET_EVENT_ON_HANDLE | - FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { - handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; - } else if (GetLastError() != ERROR_INVALID_FUNCTION) { - return GetLastError(); - } - } - - if (handle->flags & UV_HANDLE_TCP_NODELAY) { - err = uv__tcp_nodelay(handle, socket, 1); - if (err) - return err; - } - - /* TODO: Use stored delay. */ - if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) { - err = uv__tcp_keepalive(handle, socket, 1, 60); - if (err) - return err; - } - - handle->socket = socket; - - if (family == AF_INET6) { - handle->flags |= UV_HANDLE_IPV6; - } else { - assert(!(handle->flags & UV_HANDLE_IPV6)); - } - - return 0; -} - - -int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) { - int domain; - - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return UV_EINVAL; - - if (flags & ~0xFF) - return UV_EINVAL; - - uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP); - handle->tcp.serv.accept_reqs = NULL; - handle->tcp.serv.pending_accepts = NULL; - handle->socket = INVALID_SOCKET; - handle->reqs_pending = 0; - handle->tcp.serv.func_acceptex = NULL; - handle->tcp.conn.func_connectex = NULL; - handle->tcp.serv.processed_accepts = 0; - handle->delayed_error = 0; - - /* If anything fails beyond this point we need to remove the handle from - * the handle queue, since it was added by uv__handle_init in uv_stream_init. - */ - - if (domain != AF_UNSPEC) { - SOCKET sock; - DWORD err; - - sock = socket(domain, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - err = WSAGetLastError(); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - - err = uv_tcp_set_socket(handle->loop, handle, sock, domain, 0); - if (err) { - closesocket(sock); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - - } - - return 0; -} - - -int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) { - return uv_tcp_init_ex(loop, handle, AF_UNSPEC); -} - - -void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { - int err; - unsigned int i; - uv_tcp_accept_t* req; - - if (handle->flags & UV_HANDLE_CONNECTION && - handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - - UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req); - - err = 0; - if (handle->flags & UV__HANDLE_CLOSING) { - err = ERROR_OPERATION_ABORTED; - } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) { - err = WSAGetLastError(); - } - - if (handle->stream.conn.shutdown_req->cb) { - handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, - uv_translate_sys_error(err)); - } - - handle->stream.conn.shutdown_req = NULL; - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) { - closesocket(handle->socket); - handle->socket = INVALID_SOCKET; - handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; - } - - if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) { - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - for (i = 0; i < uv_simultaneous_server_accepts; i++) { - req = &handle->tcp.serv.accept_reqs[i]; - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - } - - uv__free(handle->tcp.serv.accept_reqs); - handle->tcp.serv.accept_reqs = NULL; - } - - if (handle->flags & UV_HANDLE_CONNECTION && - handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->read_req.wait_handle); - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - } - if (handle->read_req.event_handle) { - CloseHandle(handle->read_req.event_handle); - handle->read_req.event_handle = NULL; - } - } - - uv__handle_close(handle); - loop->active_tcp_streams--; - } -} - - -/* Unlike on Unix, here we don't set SO_REUSEADDR, because it doesn't just - * allow binding to addresses that are in use by sockets in TIME_WAIT, it - * effectively allows 'stealing' a port which is in use by another application. - * - * SO_EXCLUSIVEADDRUSE is also not good here because it does check all sockets, - * regardless of state, so we'd get an error even if the port is in use by a - * socket in TIME_WAIT state. - * - * See issue #1360. - * - */ -static int uv_tcp_try_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - DWORD err; - int r; - - if (handle->socket == INVALID_SOCKET) { - SOCKET sock; - - /* Cannot set IPv6-only mode on non-IPv6 socket. */ - if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) - return ERROR_INVALID_PARAMETER; - - sock = socket(addr->sa_family, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - return WSAGetLastError(); - } - - err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0); - if (err) { - closesocket(sock); - return err; - } - } - -#ifdef IPV6_V6ONLY - if (addr->sa_family == AF_INET6) { - int on; - - on = (flags & UV_TCP_IPV6ONLY) != 0; - - /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ - /* available, or when run on XP/2003 which have no support for dualstack */ - /* sockets. For now we're silently ignoring the error. */ - setsockopt(handle->socket, - IPPROTO_IPV6, - IPV6_V6ONLY, - (const char*)&on, - sizeof on); - } -#endif - - r = bind(handle->socket, addr, addrlen); - - if (r == SOCKET_ERROR) { - err = WSAGetLastError(); - if (err == WSAEADDRINUSE) { - /* Some errors are not to be reported until connect() or listen() */ - handle->delayed_error = err; - } else { - return err; - } - } - - handle->flags |= UV_HANDLE_BOUND; - - return 0; -} - - -static void CALLBACK post_completion(void* context, BOOLEAN timed_out) { - uv_req_t* req; - uv_tcp_t* handle; - - req = (uv_req_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->data; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) { - uv_write_t* req; - uv_tcp_t* handle; - - req = (uv_write_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->handle; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { - uv_loop_t* loop = handle->loop; - BOOL success; - DWORD bytes; - SOCKET accept_socket; - short family; - - assert(handle->flags & UV_HANDLE_LISTENING); - assert(req->accept_socket == INVALID_SOCKET); - - /* choose family and extension function */ - if (handle->flags & UV_HANDLE_IPV6) { - family = AF_INET6; - } else { - family = AF_INET; - } - - /* Open a socket for the accepted connection. */ - accept_socket = socket(family, SOCK_STREAM, 0); - if (accept_socket == INVALID_SOCKET) { - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - return; - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - closesocket(accept_socket); - return; - } - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - } - - success = handle->tcp.serv.func_acceptex(handle->socket, - accept_socket, - (void*)req->accept_buffer, - 0, - sizeof(struct sockaddr_storage), - sizeof(struct sockaddr_storage), - &bytes, - &req->u.io.overlapped); - - if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { - /* Process the req without IOCP. */ - req->accept_socket = accept_socket; - handle->reqs_pending++; - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(success)) { - /* The req will be processed with IOCP. */ - req->accept_socket = accept_socket; - handle->reqs_pending++; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - req->wait_handle == INVALID_HANDLE_VALUE && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - return; - } - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - /* Destroy the preallocated client socket. */ - closesocket(accept_socket); - /* Destroy the event handle */ - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - CloseHandle(req->u.io.overlapped.hEvent); - req->event_handle = NULL; - } - } -} - - -static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { - uv_read_t* req; - uv_buf_t buf; - int result; - DWORD bytes, flags; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - req = &handle->read_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - /* - * Preallocate a read buffer if the number of active streams is below - * the threshold. - */ - if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { - handle->flags &= ~UV_HANDLE_ZERO_READ; - handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer); - if (handle->tcp.conn.read_buffer.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer); - return; - } - assert(handle->tcp.conn.read_buffer.base != NULL); - buf = handle->tcp.conn.read_buffer; - } else { - handle->flags |= UV_HANDLE_ZERO_READ; - buf.base = (char*) &uv_zero_; - buf.len = 0; - } - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - assert(req->event_handle); - req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - } - - flags = 0; - result = WSARecv(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->u.io.overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - req->wait_handle == INVALID_HANDLE_VALUE && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - } -} - - -int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; - unsigned int i, simultaneous_accepts; - uv_tcp_accept_t* req; - int err; - - assert(backlog > 0); - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->stream.serv.connection_cb = cb; - } - - if (handle->flags & UV_HANDLE_READING) { - return WSAEISCONN; - } - - if (handle->delayed_error) { - return handle->delayed_error; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_tcp_try_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return err; - if (handle->delayed_error) - return handle->delayed_error; - } - - if (!handle->tcp.serv.func_acceptex) { - if (!uv_get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) { - return WSAEAFNOSUPPORT; - } - } - - if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) && - listen(handle->socket, backlog) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_LISTENING; - handle->stream.serv.connection_cb = cb; - INCREASE_ACTIVE_COUNT(loop, handle); - - simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1 - : uv_simultaneous_server_accepts; - - if(!handle->tcp.serv.accept_reqs) { - handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*) - uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); - if (!handle->tcp.serv.accept_reqs) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - for (i = 0; i < simultaneous_accepts; i++) { - req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*)req); - req->type = UV_ACCEPT; - req->accept_socket = INVALID_SOCKET; - req->data = handle; - - req->wait_handle = INVALID_HANDLE_VALUE; - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } else { - req->event_handle = NULL; - } - - uv_tcp_queue_accept(handle, req); - } - - /* Initialize other unused requests too, because uv_tcp_endgame */ - /* doesn't know how how many requests were initialized, so it will */ - /* try to clean up {uv_simultaneous_server_accepts} requests. */ - for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { - req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; - req->accept_socket = INVALID_SOCKET; - req->data = handle; - req->wait_handle = INVALID_HANDLE_VALUE; - req->event_handle = NULL; - } - } - - return 0; -} - - -int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) { - uv_loop_t* loop = server->loop; - int err = 0; - int family; - - uv_tcp_accept_t* req = server->tcp.serv.pending_accepts; - - if (!req) { - /* No valid connections found, so we error out. */ - return WSAEWOULDBLOCK; - } - - if (req->accept_socket == INVALID_SOCKET) { - return WSAENOTCONN; - } - - if (server->flags & UV_HANDLE_IPV6) { - family = AF_INET6; - } else { - family = AF_INET; - } - - err = uv_tcp_set_socket(client->loop, - client, - req->accept_socket, - family, - 0); - if (err) { - closesocket(req->accept_socket); - } else { - uv_connection_init((uv_stream_t*) client); - /* AcceptEx() implicitly binds the accepted socket. */ - client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - } - - /* Prepare the req to pick up a new connection */ - server->tcp.serv.pending_accepts = req->next_pending; - req->next_pending = NULL; - req->accept_socket = INVALID_SOCKET; - - if (!(server->flags & UV__HANDLE_CLOSING)) { - /* Check if we're in a middle of changing the number of pending accepts. */ - if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) { - uv_tcp_queue_accept(server, req); - } else { - /* We better be switching to a single pending accept. */ - assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT); - - server->tcp.serv.processed_accepts++; - - if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) { - server->tcp.serv.processed_accepts = 0; - /* - * All previously queued accept requests are now processed. - * We now switch to queueing just a single accept. - */ - uv_tcp_queue_accept(server, &server->tcp.serv.accept_reqs[0]); - server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; - server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; - } - } - } - - loop->active_tcp_streams++; - - return err; -} - - -int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - handle->flags |= UV_HANDLE_READING; - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - INCREASE_ACTIVE_COUNT(loop, handle); - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) { - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - !handle->read_req.event_handle) { - handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!handle->read_req.event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } - uv_tcp_queue_read(loop, handle); - } - - return 0; -} - - -static int uv_tcp_try_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - uv_loop_t* loop = handle->loop; - const struct sockaddr* bind_addr; - BOOL success; - DWORD bytes; - int err; - - if (handle->delayed_error) { - return handle->delayed_error; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } - err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0); - if (err) - return err; - if (handle->delayed_error) - return handle->delayed_error; - } - - if (!handle->tcp.conn.func_connectex) { - if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) { - return WSAEAFNOSUPPORT; - } - } - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - success = handle->tcp.conn.func_connectex(handle->socket, - addr, - addrlen, - NULL, - 0, - &bytes, - &req->u.io.overlapped); - - if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { - /* Process the req without IOCP. */ - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(success)) { - /* The req will be processed with IOCP. */ - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - } else { - return WSAGetLastError(); - } - - return 0; -} - - -int uv_tcp_getsockname(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - int result; - - if (handle->socket == INVALID_SOCKET) { - return UV_EINVAL; - } - - if (handle->delayed_error) { - return uv_translate_sys_error(handle->delayed_error); - } - - result = getsockname(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_tcp_getpeername(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - int result; - - if (handle->socket == INVALID_SOCKET) { - return UV_EINVAL; - } - - if (handle->delayed_error) { - return uv_translate_sys_error(handle->delayed_error); - } - - result = getpeername(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_tcp_write(uv_loop_t* loop, - uv_write_t* req, - uv_tcp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - int result; - DWORD bytes; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - req->wait_handle = INVALID_HANDLE_VALUE; - } - - result = WSASend(handle->socket, - (WSABUF*) bufs, - nbufs, - &bytes, - 0, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*) req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - handle->write_queue_size += req->u.io.queued_bytes; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_write_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - } else { - /* Send failed due to an error, report it later */ - req->u.io.queued_bytes = 0; - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - } - - return 0; -} - - -int uv__tcp_try_write(uv_tcp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs) { - int result; - DWORD bytes; - - if (handle->stream.conn.write_reqs_pending > 0) - return UV_EAGAIN; - - result = WSASend(handle->socket, - (WSABUF*) bufs, - nbufs, - &bytes, - 0, - NULL, - NULL); - - if (result == SOCKET_ERROR) - return uv_translate_sys_error(WSAGetLastError()); - else - return bytes; -} - - -void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* req) { - DWORD bytes, flags, err; - uv_buf_t buf; - - assert(handle->type == UV_TCP); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!REQ_SUCCESS(req)) { - /* An error occurred doing the read. */ - if ((handle->flags & UV_HANDLE_READING) || - !(handle->flags & UV_HANDLE_ZERO_READ)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - buf = (handle->flags & UV_HANDLE_ZERO_READ) ? - uv_buf_init(NULL, 0) : handle->tcp.conn.read_buffer; - - err = GET_REQ_SOCK_ERROR(req); - - if (err == WSAECONNABORTED) { - /* - * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix. - */ - err = WSAECONNRESET; - } - - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(err), - &buf); - } - } else { - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - /* The read was done with a non-zero buffer length. */ - if (req->u.io.overlapped.InternalHigh > 0) { - /* Successful read */ - handle->read_cb((uv_stream_t*)handle, - req->u.io.overlapped.InternalHigh, - &handle->tcp.conn.read_buffer); - /* Read again only if bytes == buf.len */ - if (req->u.io.overlapped.InternalHigh < handle->tcp.conn.read_buffer.len) { - goto done; - } - } else { - /* Connection closed */ - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - handle->flags &= ~UV_HANDLE_READABLE; - - buf.base = 0; - buf.len = 0; - handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->tcp.conn.read_buffer); - goto done; - } - } - - /* Do nonblocking reads until the buffer is empty */ - while (handle->flags & UV_HANDLE_READING) { - handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - break; - } - assert(buf.base != NULL); - - flags = 0; - if (WSARecv(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - NULL, - NULL) != SOCKET_ERROR) { - if (bytes > 0) { - /* Successful read */ - handle->read_cb((uv_stream_t*)handle, bytes, &buf); - /* Read again only if bytes == buf.len */ - if (bytes < buf.len) { - break; - } - } else { - /* Connection closed */ - handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); - DECREASE_ACTIVE_COUNT(loop, handle); - - handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); - break; - } - } else { - err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - /* Read buffer was completely empty, report a 0-byte read. */ - handle->read_cb((uv_stream_t*)handle, 0, &buf); - } else { - /* Ouch! serious error. */ - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - - if (err == WSAECONNABORTED) { - /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */ - /* Unix. */ - err = WSAECONNRESET; - } - - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(err), - &buf); - } - break; - } - } - -done: - /* Post another read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tcp_queue_read(loop, handle); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_write_t* req) { - int err; - - assert(handle->type == UV_TCP); - - assert(handle->write_queue_size >= req->u.io.queued_bytes); - handle->write_queue_size -= req->u.io.queued_bytes; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - - if (req->cb) { - err = uv_translate_sys_error(GET_REQ_SOCK_ERROR(req)); - if (err == UV_ECONNABORTED) { - /* use UV_ECANCELED for consistency with Unix */ - err = UV_ECANCELED; - } - req->cb(req, err); - } - - handle->stream.conn.write_reqs_pending--; - if (handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* raw_req) { - uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req; - int err; - - assert(handle->type == UV_TCP); - - /* If handle->accepted_socket is not a valid socket, then */ - /* uv_queue_accept must have failed. This is a serious error. We stop */ - /* accepting connections and report this error to the connection */ - /* callback. */ - if (req->accept_socket == INVALID_SOCKET) { - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, handle); - if (handle->stream.serv.connection_cb) { - err = GET_REQ_SOCK_ERROR(req); - handle->stream.serv.connection_cb((uv_stream_t*)handle, - uv_translate_sys_error(err)); - } - } - } else if (REQ_SUCCESS(req) && - setsockopt(req->accept_socket, - SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, - (char*)&handle->socket, - sizeof(handle->socket)) == 0) { - req->next_pending = handle->tcp.serv.pending_accepts; - handle->tcp.serv.pending_accepts = req; - - /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ - if (handle->stream.serv.connection_cb) { - handle->stream.serv.connection_cb((uv_stream_t*)handle, 0); - } - } else { - /* Error related to accepted socket is ignored because the server */ - /* socket may still be healthy. If the server socket is broken */ - /* uv_queue_accept will detect it. */ - closesocket(req->accept_socket); - req->accept_socket = INVALID_SOCKET; - if (handle->flags & UV_HANDLE_LISTENING) { - uv_tcp_queue_accept(handle, req); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_connect_t* req) { - int err; - - assert(handle->type == UV_TCP); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - err = 0; - if (REQ_SUCCESS(req)) { - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_UPDATE_CONNECT_CONTEXT, - NULL, - 0) == 0) { - uv_connection_init((uv_stream_t*)handle); - handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - loop->active_tcp_streams++; - } else { - err = WSAGetLastError(); - } - } else { - err = GET_REQ_SOCK_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex, - int tcp_connection) { - int err; - SOCKET socket = WSASocketW(FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - &socket_info_ex->socket_info, - 0, - WSA_FLAG_OVERLAPPED); - - if (socket == INVALID_SOCKET) { - return WSAGetLastError(); - } - - err = uv_tcp_set_socket(tcp->loop, - tcp, - socket, - socket_info_ex->socket_info.iAddressFamily, - 1); - if (err) { - closesocket(socket); - return err; - } - - if (tcp_connection) { - uv_connection_init((uv_stream_t*)tcp); - tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - } - - tcp->flags |= UV_HANDLE_BOUND; - tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET; - - tcp->delayed_error = socket_info_ex->delayed_error; - - tcp->loop->active_tcp_streams++; - return 0; -} - - -int uv_tcp_nodelay(uv_tcp_t* handle, int enable) { - int err; - - if (handle->socket != INVALID_SOCKET) { - err = uv__tcp_nodelay(handle, handle->socket, enable); - if (err) - return err; - } - - if (enable) { - handle->flags |= UV_HANDLE_TCP_NODELAY; - } else { - handle->flags &= ~UV_HANDLE_TCP_NODELAY; - } - - return 0; -} - - -int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { - int err; - - if (handle->socket != INVALID_SOCKET) { - err = uv__tcp_keepalive(handle, handle->socket, enable, delay); - if (err) - return err; - } - - if (enable) { - handle->flags |= UV_HANDLE_TCP_KEEPALIVE; - } else { - handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; - } - - /* TODO: Store delay if handle->socket isn't created yet. */ - - return 0; -} - - -int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, - LPWSAPROTOCOL_INFOW protocol_info) { - if (!(handle->flags & UV_HANDLE_CONNECTION)) { - /* - * We're about to share the socket with another process. Because - * this is a listening socket, we assume that the other process will - * be accepting connections on it. So, before sharing the socket - * with another process, we call listen here in the parent process. - */ - - if (!(handle->flags & UV_HANDLE_LISTENING)) { - if (!(handle->flags & UV_HANDLE_BOUND)) { - return ERROR_INVALID_PARAMETER; - } - - if (!(handle->delayed_error)) { - if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) { - handle->delayed_error = WSAGetLastError(); - } - } - } - } - - if (WSADuplicateSocketW(handle->socket, pid, protocol_info)) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET; - - return 0; -} - - -int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { - if (handle->flags & UV_HANDLE_CONNECTION) { - return UV_EINVAL; - } - - /* Check if we're already in the desired mode. */ - if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) || - (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) { - return 0; - } - - /* Don't allow switching from single pending accept to many. */ - if (enable) { - return UV_ENOTSUP; - } - - /* Check if we're in a middle of changing the number of pending accepts. */ - if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) { - return 0; - } - - handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; - - /* Flip the changing flag if we have already queued multiple accepts. */ - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; - } - - return 0; -} - - -static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) { - SOCKET socket = tcp->socket; - int non_ifs_lsp; - - /* Check if we have any non-IFS LSPs stacked on top of TCP */ - non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 : - uv_tcp_non_ifs_lsp_ipv4; - - /* If there are non-ifs LSPs then try to obtain a base handle for the */ - /* socket. This will always fail on Windows XP/3k. */ - if (non_ifs_lsp) { - DWORD bytes; - if (WSAIoctl(socket, - SIO_BASE_HANDLE, - NULL, - 0, - &socket, - sizeof socket, - &bytes, - NULL, - NULL) != 0) { - /* Failed. We can't do CancelIo. */ - return -1; - } - } - - assert(socket != 0 && socket != INVALID_SOCKET); - - if (!CancelIo((HANDLE) socket)) { - return GetLastError(); - } - - /* It worked. */ - return 0; -} - - -void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) { - int close_socket = 1; - - if (tcp->flags & UV_HANDLE_READ_PENDING) { - /* In order for winsock to do a graceful close there must not be any */ - /* any pending reads, or the socket must be shut down for writing */ - if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) { - /* Just do shutdown on non-shared sockets, which ensures graceful close. */ - shutdown(tcp->socket, SD_SEND); - - } else if (uv_tcp_try_cancel_io(tcp) == 0) { - /* In case of a shared socket, we try to cancel all outstanding I/O, */ - /* If that works, don't close the socket yet - wait for the read req to */ - /* return and close the socket in uv_tcp_endgame. */ - close_socket = 0; - - } else { - /* When cancelling isn't possible - which could happen when an LSP is */ - /* present on an old Windows version, we will have to close the socket */ - /* with a read pending. That is not nice because trailing sent bytes */ - /* may not make it to the other side. */ - } - - } else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) && - tcp->tcp.serv.accept_reqs != NULL) { - /* Under normal circumstances closesocket() will ensure that all pending */ - /* accept reqs are canceled. However, when the socket is shared the */ - /* presence of another reference to the socket in another process will */ - /* keep the accept reqs going, so we have to ensure that these are */ - /* canceled. */ - if (uv_tcp_try_cancel_io(tcp) != 0) { - /* When cancellation is not possible, there is another option: we can */ - /* close the incoming sockets, which will also cancel the accept */ - /* operations. However this is not cool because we might inadvertently */ - /* close a socket that just accepted a new connection, which will */ - /* cause the connection to be aborted. */ - unsigned int i; - for (i = 0; i < uv_simultaneous_server_accepts; i++) { - uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i]; - if (req->accept_socket != INVALID_SOCKET && - !HasOverlappedIoCompleted(&req->u.io.overlapped)) { - closesocket(req->accept_socket); - req->accept_socket = INVALID_SOCKET; - } - } - } - } - - if (tcp->flags & UV_HANDLE_READING) { - tcp->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, tcp); - } - - if (tcp->flags & UV_HANDLE_LISTENING) { - tcp->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, tcp); - } - - if (close_socket) { - closesocket(tcp->socket); - tcp->socket = INVALID_SOCKET; - tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; - } - - tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(tcp); - - if (tcp->reqs_pending == 0) { - uv_want_endgame(tcp->loop, (uv_handle_t*)tcp); - } -} - - -int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - int err; - - /* Detect the address family of the socket. */ - opt_len = (int) sizeof protocol_info; - if (getsockopt(sock, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) { - return uv_translate_sys_error(GetLastError()); - } - - err = uv_tcp_set_socket(handle->loop, - handle, - sock, - protocol_info.iAddressFamily, - 1); - if (err) { - return uv_translate_sys_error(err); - } - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__tcp_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - - err = uv_tcp_try_bind(handle, addr, addrlen, flags); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - int err; - - err = uv_tcp_try_connect(req, handle, addr, addrlen, cb); - if (err) - return uv_translate_sys_error(err); - - return 0; -} diff --git a/outside/libuv-v1.7.5/src/win/thread.c b/outside/libuv-v1.7.5/src/win/thread.c deleted file mode 100644 index 91684e9387..0000000000 --- a/outside/libuv-v1.7.5/src/win/thread.c +++ /dev/null @@ -1,697 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include - -#include "uv.h" -#include "internal.h" - - -#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL) - -static int uv_cond_fallback_init(uv_cond_t* cond); -static void uv_cond_fallback_destroy(uv_cond_t* cond); -static void uv_cond_fallback_signal(uv_cond_t* cond); -static void uv_cond_fallback_broadcast(uv_cond_t* cond); -static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex); -static int uv_cond_fallback_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout); - -static int uv_cond_condvar_init(uv_cond_t* cond); -static void uv_cond_condvar_destroy(uv_cond_t* cond); -static void uv_cond_condvar_signal(uv_cond_t* cond); -static void uv_cond_condvar_broadcast(uv_cond_t* cond); -static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex); -static int uv_cond_condvar_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout); - - -static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) { - DWORD result; - HANDLE existing_event, created_event; - - created_event = CreateEvent(NULL, 1, 0, NULL); - if (created_event == 0) { - /* Could fail in a low-memory situation? */ - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - existing_event = InterlockedCompareExchangePointer(&guard->event, - created_event, - NULL); - - if (existing_event == NULL) { - /* We won the race */ - callback(); - - result = SetEvent(created_event); - assert(result); - guard->ran = 1; - - } else { - /* We lost the race. Destroy the event we created and wait for the */ - /* existing one to become signaled. */ - CloseHandle(created_event); - result = WaitForSingleObject(existing_event, INFINITE); - assert(result == WAIT_OBJECT_0); - } -} - - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - /* Fast case - avoid WaitForSingleObject. */ - if (guard->ran) { - return; - } - - uv__once_inner(guard, callback); -} - - -/* Verify that uv_thread_t can be stored in a TLS slot. */ -STATIC_ASSERT(sizeof(uv_thread_t) <= sizeof(void*)); - -static uv_key_t uv__current_thread_key; -static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT; - - -static void uv__init_current_thread_key(void) { - if (uv_key_create(&uv__current_thread_key)) - abort(); -} - - -struct thread_ctx { - void (*entry)(void* arg); - void* arg; - uv_thread_t self; -}; - - -static UINT __stdcall uv__thread_start(void* arg) { - struct thread_ctx *ctx_p; - struct thread_ctx ctx; - - ctx_p = arg; - ctx = *ctx_p; - uv__free(ctx_p); - - uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - uv_key_set(&uv__current_thread_key, (void*) ctx.self); - - ctx.entry(ctx.arg); - - return 0; -} - - -int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { - struct thread_ctx* ctx; - int err; - HANDLE thread; - - ctx = uv__malloc(sizeof(*ctx)); - if (ctx == NULL) - return UV_ENOMEM; - - ctx->entry = entry; - ctx->arg = arg; - - /* Create the thread in suspended state so we have a chance to pass - * its own creation handle to it */ - thread = (HANDLE) _beginthreadex(NULL, - 0, - uv__thread_start, - ctx, - CREATE_SUSPENDED, - NULL); - if (thread == NULL) { - err = errno; - uv__free(ctx); - } else { - err = 0; - *tid = thread; - ctx->self = thread; - ResumeThread(thread); - } - - switch (err) { - case 0: - return 0; - case EACCES: - return UV_EACCES; - case EAGAIN: - return UV_EAGAIN; - case EINVAL: - return UV_EINVAL; - } - - return UV_EIO; -} - - -uv_thread_t uv_thread_self(void) { - uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - return (uv_thread_t) uv_key_get(&uv__current_thread_key); -} - - -int uv_thread_join(uv_thread_t *tid) { - if (WaitForSingleObject(*tid, INFINITE)) - return uv_translate_sys_error(GetLastError()); - else { - CloseHandle(*tid); - *tid = 0; - return 0; - } -} - - -int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) { - return *t1 == *t2; -} - - -int uv_mutex_init(uv_mutex_t* mutex) { - InitializeCriticalSection(mutex); - return 0; -} - - -void uv_mutex_destroy(uv_mutex_t* mutex) { - DeleteCriticalSection(mutex); -} - - -void uv_mutex_lock(uv_mutex_t* mutex) { - EnterCriticalSection(mutex); -} - - -int uv_mutex_trylock(uv_mutex_t* mutex) { - if (TryEnterCriticalSection(mutex)) - return 0; - else - return UV_EBUSY; -} - - -void uv_mutex_unlock(uv_mutex_t* mutex) { - LeaveCriticalSection(mutex); -} - - -int uv_rwlock_init(uv_rwlock_t* rwlock) { - /* Initialize the semaphore that acts as the write lock. */ - HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL); - if (handle == NULL) - return uv_translate_sys_error(GetLastError()); - rwlock->state_.write_semaphore_ = handle; - - /* Initialize the critical section protecting the reader count. */ - InitializeCriticalSection(&rwlock->state_.num_readers_lock_); - - /* Initialize the reader count. */ - rwlock->state_.num_readers_ = 0; - - return 0; -} - - -void uv_rwlock_destroy(uv_rwlock_t* rwlock) { - DeleteCriticalSection(&rwlock->state_.num_readers_lock_); - CloseHandle(rwlock->state_.write_semaphore_); -} - - -void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { - /* Acquire the lock that protects the reader count. */ - EnterCriticalSection(&rwlock->state_.num_readers_lock_); - - /* Increase the reader count, and lock for write if this is the first - * reader. - */ - if (++rwlock->state_.num_readers_ == 1) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); - if (r != WAIT_OBJECT_0) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); - } - - /* Release the lock that protects the reader count. */ - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); -} - - -int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { - int err; - - if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_)) - return UV_EBUSY; - - err = 0; - - if (rwlock->state_.num_readers_ == 0) { - /* Currently there are no other readers, which means that the write lock - * needs to be acquired. - */ - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); - if (r == WAIT_OBJECT_0) - rwlock->state_.num_readers_++; - else if (r == WAIT_TIMEOUT) - err = UV_EBUSY; - else if (r == WAIT_FAILED) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); - - } else { - /* The write lock has already been acquired because there are other - * active readers. - */ - rwlock->state_.num_readers_++; - } - - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); - return err; -} - - -void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { - EnterCriticalSection(&rwlock->state_.num_readers_lock_); - - if (--rwlock->state_.num_readers_ == 0) { - if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) - uv_fatal_error(GetLastError(), "ReleaseSemaphore"); - } - - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); -} - - -void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); - if (r != WAIT_OBJECT_0) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); -} - - -int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); - if (r == WAIT_OBJECT_0) - return 0; - else if (r == WAIT_TIMEOUT) - return UV_EBUSY; - else - uv_fatal_error(GetLastError(), "WaitForSingleObject"); -} - - -void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { - if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) - uv_fatal_error(GetLastError(), "ReleaseSemaphore"); -} - - -int uv_sem_init(uv_sem_t* sem, unsigned int value) { - *sem = CreateSemaphore(NULL, value, INT_MAX, NULL); - if (*sem == NULL) - return uv_translate_sys_error(GetLastError()); - else - return 0; -} - - -void uv_sem_destroy(uv_sem_t* sem) { - if (!CloseHandle(*sem)) - abort(); -} - - -void uv_sem_post(uv_sem_t* sem) { - if (!ReleaseSemaphore(*sem, 1, NULL)) - abort(); -} - - -void uv_sem_wait(uv_sem_t* sem) { - if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0) - abort(); -} - - -int uv_sem_trywait(uv_sem_t* sem) { - DWORD r = WaitForSingleObject(*sem, 0); - - if (r == WAIT_OBJECT_0) - return 0; - - if (r == WAIT_TIMEOUT) - return UV_EAGAIN; - - abort(); - return -1; /* Satisfy the compiler. */ -} - - -/* This condition variable implementation is based on the SetEvent solution - * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html - * We could not use the SignalObjectAndWait solution (section 3.4) because - * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and - * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs. - */ - -static int uv_cond_fallback_init(uv_cond_t* cond) { - int err; - - /* Initialize the count to 0. */ - cond->fallback.waiters_count = 0; - - InitializeCriticalSection(&cond->fallback.waiters_count_lock); - - /* Create an auto-reset event. */ - cond->fallback.signal_event = CreateEvent(NULL, /* no security */ - FALSE, /* auto-reset event */ - FALSE, /* non-signaled initially */ - NULL); /* unnamed */ - if (!cond->fallback.signal_event) { - err = GetLastError(); - goto error2; - } - - /* Create a manual-reset event. */ - cond->fallback.broadcast_event = CreateEvent(NULL, /* no security */ - TRUE, /* manual-reset */ - FALSE, /* non-signaled */ - NULL); /* unnamed */ - if (!cond->fallback.broadcast_event) { - err = GetLastError(); - goto error; - } - - return 0; - -error: - CloseHandle(cond->fallback.signal_event); -error2: - DeleteCriticalSection(&cond->fallback.waiters_count_lock); - return uv_translate_sys_error(err); -} - - -static int uv_cond_condvar_init(uv_cond_t* cond) { - pInitializeConditionVariable(&cond->cond_var); - return 0; -} - - -int uv_cond_init(uv_cond_t* cond) { - uv__once_init(); - - if (HAVE_CONDVAR_API()) - return uv_cond_condvar_init(cond); - else - return uv_cond_fallback_init(cond); -} - - -static void uv_cond_fallback_destroy(uv_cond_t* cond) { - if (!CloseHandle(cond->fallback.broadcast_event)) - abort(); - if (!CloseHandle(cond->fallback.signal_event)) - abort(); - DeleteCriticalSection(&cond->fallback.waiters_count_lock); -} - - -static void uv_cond_condvar_destroy(uv_cond_t* cond) { - /* nothing to do */ -} - - -void uv_cond_destroy(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_destroy(cond); - else - uv_cond_fallback_destroy(cond); -} - - -static void uv_cond_fallback_signal(uv_cond_t* cond) { - int have_waiters; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - have_waiters = cond->fallback.waiters_count > 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - if (have_waiters) - SetEvent(cond->fallback.signal_event); -} - - -static void uv_cond_condvar_signal(uv_cond_t* cond) { - pWakeConditionVariable(&cond->cond_var); -} - - -void uv_cond_signal(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_signal(cond); - else - uv_cond_fallback_signal(cond); -} - - -static void uv_cond_fallback_broadcast(uv_cond_t* cond) { - int have_waiters; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - have_waiters = cond->fallback.waiters_count > 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - if (have_waiters) - SetEvent(cond->fallback.broadcast_event); -} - - -static void uv_cond_condvar_broadcast(uv_cond_t* cond) { - pWakeAllConditionVariable(&cond->cond_var); -} - - -void uv_cond_broadcast(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_broadcast(cond); - else - uv_cond_fallback_broadcast(cond); -} - - -static int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex, - DWORD dwMilliseconds) { - DWORD result; - int last_waiter; - HANDLE handles[2] = { - cond->fallback.signal_event, - cond->fallback.broadcast_event - }; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - cond->fallback.waiters_count++; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - /* It's ok to release the here since Win32 manual-reset events */ - /* maintain state when used with . This avoids the "lost wakeup" */ - /* bug. */ - uv_mutex_unlock(mutex); - - /* Wait for either event to become signaled due to being */ - /* called or being called. */ - result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds); - - EnterCriticalSection(&cond->fallback.waiters_count_lock); - cond->fallback.waiters_count--; - last_waiter = result == WAIT_OBJECT_0 + 1 - && cond->fallback.waiters_count == 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - /* Some thread called . */ - if (last_waiter) { - /* We're the last waiter to be notified or to stop waiting, so reset the */ - /* the manual-reset event. */ - ResetEvent(cond->fallback.broadcast_event); - } - - /* Reacquire the . */ - uv_mutex_lock(mutex); - - if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1) - return 0; - - if (result == WAIT_TIMEOUT) - return UV_ETIMEDOUT; - - abort(); - return -1; /* Satisfy the compiler. */ -} - - -static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (uv_cond_wait_helper(cond, mutex, INFINITE)) - abort(); -} - - -static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE)) - abort(); -} - - -void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_wait(cond, mutex); - else - uv_cond_fallback_wait(cond, mutex); -} - - -static int uv_cond_fallback_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout) { - return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6)); -} - - -static int uv_cond_condvar_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout) { - if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6))) - return 0; - if (GetLastError() != ERROR_TIMEOUT) - abort(); - return UV_ETIMEDOUT; -} - - -int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, - uint64_t timeout) { - if (HAVE_CONDVAR_API()) - return uv_cond_condvar_timedwait(cond, mutex, timeout); - else - return uv_cond_fallback_timedwait(cond, mutex, timeout); -} - - -int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { - int err; - - barrier->n = count; - barrier->count = 0; - - err = uv_mutex_init(&barrier->mutex); - if (err) - return err; - - err = uv_sem_init(&barrier->turnstile1, 0); - if (err) - goto error2; - - err = uv_sem_init(&barrier->turnstile2, 1); - if (err) - goto error; - - return 0; - -error: - uv_sem_destroy(&barrier->turnstile1); -error2: - uv_mutex_destroy(&barrier->mutex); - return err; - -} - - -void uv_barrier_destroy(uv_barrier_t* barrier) { - uv_sem_destroy(&barrier->turnstile2); - uv_sem_destroy(&barrier->turnstile1); - uv_mutex_destroy(&barrier->mutex); -} - - -int uv_barrier_wait(uv_barrier_t* barrier) { - int serial_thread; - - uv_mutex_lock(&barrier->mutex); - if (++barrier->count == barrier->n) { - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile1); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile1); - - uv_mutex_lock(&barrier->mutex); - serial_thread = (--barrier->count == 0); - if (serial_thread) { - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile2); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile2); - return serial_thread; -} - - -int uv_key_create(uv_key_t* key) { - key->tls_index = TlsAlloc(); - if (key->tls_index == TLS_OUT_OF_INDEXES) - return UV_ENOMEM; - return 0; -} - - -void uv_key_delete(uv_key_t* key) { - if (TlsFree(key->tls_index) == FALSE) - abort(); - key->tls_index = TLS_OUT_OF_INDEXES; -} - - -void* uv_key_get(uv_key_t* key) { - void* value; - - value = TlsGetValue(key->tls_index); - if (value == NULL) - if (GetLastError() != ERROR_SUCCESS) - abort(); - - return value; -} - - -void uv_key_set(uv_key_t* key, void* value) { - if (TlsSetValue(key->tls_index, value) == FALSE) - abort(); -} diff --git a/outside/libuv-v1.7.5/src/win/timer.c b/outside/libuv-v1.7.5/src/win/timer.c deleted file mode 100644 index 0da541a2c8..0000000000 --- a/outside/libuv-v1.7.5/src/win/timer.c +++ /dev/null @@ -1,200 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "uv.h" -#include "internal.h" -#include "tree.h" -#include "handle-inl.h" - - -/* The number of milliseconds in one second. */ -#define UV__MILLISEC 1000 - - -void uv_update_time(uv_loop_t* loop) { - uint64_t new_time = uv__hrtime(UV__MILLISEC); - if (new_time > loop->time) { - loop->time = new_time; - } -} - -void uv__time_forward(uv_loop_t* loop, uint64_t msecs) { - loop->time += msecs; -} - - -static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) { - if (a->due < b->due) - return -1; - if (a->due > b->due) - return 1; - /* - * compare start_id when both has the same due. start_id is - * allocated with loop->timer_counter in uv_timer_start(). - */ - if (a->start_id < b->start_id) - return -1; - if (a->start_id > b->start_id) - return 1; - return 0; -} - - -RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare); - - -int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_TIMER); - handle->timer_cb = NULL; - handle->repeat = 0; - - return 0; -} - - -void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -static uint64_t get_clamped_due_time(uint64_t loop_time, uint64_t timeout) { - uint64_t clamped_timeout; - - clamped_timeout = loop_time + timeout; - if (clamped_timeout < timeout) - clamped_timeout = (uint64_t) -1; - - return clamped_timeout; -} - - -int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout, - uint64_t repeat) { - uv_loop_t* loop = handle->loop; - uv_timer_t* old; - - if (timer_cb == NULL) - return UV_EINVAL; - - if (uv__is_active(handle)) - uv_timer_stop(handle); - - handle->timer_cb = timer_cb; - handle->due = get_clamped_due_time(loop->time, timeout); - handle->repeat = repeat; - uv__handle_start(handle); - - /* start_id is the second index to be compared in uv__timer_cmp() */ - handle->start_id = handle->loop->timer_counter++; - - old = RB_INSERT(uv_timer_tree_s, &loop->timers, handle); - assert(old == NULL); - - return 0; -} - - -int uv_timer_stop(uv_timer_t* handle) { - uv_loop_t* loop = handle->loop; - - if (!uv__is_active(handle)) - return 0; - - RB_REMOVE(uv_timer_tree_s, &loop->timers, handle); - uv__handle_stop(handle); - - return 0; -} - - -int uv_timer_again(uv_timer_t* handle) { - /* If timer_cb is NULL that means that the timer was never started. */ - if (!handle->timer_cb) { - return UV_EINVAL; - } - - if (handle->repeat) { - uv_timer_stop(handle); - uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat); - } - - return 0; -} - - -void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) { - assert(handle->type == UV_TIMER); - handle->repeat = repeat; -} - - -uint64_t uv_timer_get_repeat(const uv_timer_t* handle) { - assert(handle->type == UV_TIMER); - return handle->repeat; -} - - -DWORD uv__next_timeout(const uv_loop_t* loop) { - uv_timer_t* timer; - int64_t delta; - - /* Check if there are any running timers - * Need to cast away const first, since RB_MIN doesn't know what we are - * going to do with this return value, it can't be marked const - */ - timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers); - if (timer) { - delta = timer->due - loop->time; - if (delta >= UINT_MAX - 1) { - /* A timeout value of UINT_MAX means infinite, so that's no good. */ - return UINT_MAX - 1; - } else if (delta < 0) { - /* Negative timeout values are not allowed */ - return 0; - } else { - return (DWORD)delta; - } - } else { - /* No timers */ - return INFINITE; - } -} - - -void uv_process_timers(uv_loop_t* loop) { - uv_timer_t* timer; - - /* Call timer callbacks */ - for (timer = RB_MIN(uv_timer_tree_s, &loop->timers); - timer != NULL && timer->due <= loop->time; - timer = RB_MIN(uv_timer_tree_s, &loop->timers)) { - - uv_timer_stop(timer); - uv_timer_again(timer); - timer->timer_cb((uv_timer_t*) timer); - } -} diff --git a/outside/libuv-v1.7.5/src/win/tty.c b/outside/libuv-v1.7.5/src/win/tty.c deleted file mode 100644 index b40bb42710..0000000000 --- a/outside/libuv-v1.7.5/src/win/tty.c +++ /dev/null @@ -1,2084 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include -#endif - -#ifndef COMMON_LVB_REVERSE_VIDEO -# define COMMON_LVB_REVERSE_VIDEO 0x4000 -#endif - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -#define UNICODE_REPLACEMENT_CHARACTER (0xfffd) - -#define ANSI_NORMAL 0x00 -#define ANSI_ESCAPE_SEEN 0x02 -#define ANSI_CSI 0x04 -#define ANSI_ST_CONTROL 0x08 -#define ANSI_IGNORE 0x10 -#define ANSI_IN_ARG 0x20 -#define ANSI_IN_STRING 0x40 -#define ANSI_BACKSLASH_SEEN 0x80 - -#define MAX_INPUT_BUFFER_LENGTH 8192 - - -static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info); -static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info); - - -/* Null uv_buf_t */ -static const uv_buf_t uv_null_buf_ = { 0, NULL }; - - -/* - * The console virtual window. - * - * Normally cursor movement in windows is relative to the console screen buffer, - * e.g. the application is allowed to overwrite the 'history'. This is very - * inconvenient, it makes absolute cursor movement pretty useless. There is - * also the concept of 'client rect' which is defined by the actual size of - * the console window and the scroll position of the screen buffer, but it's - * very volatile because it changes when the user scrolls. - * - * To make cursor movement behave sensibly we define a virtual window to which - * cursor movement is confined. The virtual window is always as wide as the - * console screen buffer, but it's height is defined by the size of the - * console window. The top of the virtual window aligns with the position - * of the caret when the first stdout/err handle is created, unless that would - * mean that it would extend beyond the bottom of the screen buffer - in that - * that case it's located as far down as possible. - * - * When the user writes a long text or many newlines, such that the output - * reaches beyond the bottom of the virtual window, the virtual window is - * shifted downwards, but not resized. - * - * Since all tty i/o happens on the same console, this window is shared - * between all stdout/stderr handles. - */ - -static int uv_tty_virtual_offset = -1; -static int uv_tty_virtual_height = -1; -static int uv_tty_virtual_width = -1; - -static CRITICAL_SECTION uv_tty_output_lock; - -static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE; - -static WORD uv_tty_default_text_attributes = - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - -static char uv_tty_default_fg_color = 7; -static char uv_tty_default_bg_color = 0; -static char uv_tty_default_fg_bright = 0; -static char uv_tty_default_bg_bright = 0; -static char uv_tty_default_inverse = 0; - - -void uv_console_init() { - InitializeCriticalSection(&uv_tty_output_lock); -} - - -int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { - HANDLE handle; - CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info; - - handle = (HANDLE) uv__get_osfhandle(fd); - if (handle == INVALID_HANDLE_VALUE) - return UV_EBADF; - - if (fd <= 2) { - /* In order to avoid closing a stdio file descriptor 0-2, duplicate the - * underlying OS handle and forget about the original fd. - * We could also opt to use the original OS handle and just never close it, - * but then there would be no reliable way to cancel pending read operations - * upon close. - */ - if (!DuplicateHandle(INVALID_HANDLE_VALUE, - handle, - INVALID_HANDLE_VALUE, - &handle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS)) - return uv_translate_sys_error(GetLastError()); - fd = -1; - } - - if (!readable) { - /* Obtain the screen buffer info with the output handle. */ - if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) { - return uv_translate_sys_error(GetLastError()); - } - - /* Obtain the the tty_output_lock because the virtual window state is */ - /* shared between all uv_tty_t handles. */ - EnterCriticalSection(&uv_tty_output_lock); - - /* Store the global tty output handle. This handle is used by TTY read */ - /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */ - /* is received. */ - uv_tty_output_handle = handle; - - /* Remember the original console text attributes. */ - uv_tty_capture_initial_style(&screen_buffer_info); - - uv_tty_update_virtual_window(&screen_buffer_info); - - LeaveCriticalSection(&uv_tty_output_lock); - } - - - uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY); - uv_connection_init((uv_stream_t*) tty); - - tty->handle = handle; - tty->u.fd = fd; - tty->reqs_pending = 0; - tty->flags |= UV_HANDLE_BOUND; - - if (readable) { - /* Initialize TTY input specific fields. */ - tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE; - tty->tty.rd.read_line_handle = NULL; - tty->tty.rd.read_line_buffer = uv_null_buf_; - tty->tty.rd.read_raw_wait = NULL; - - /* Init keycode-to-vt100 mapper state. */ - tty->tty.rd.last_key_len = 0; - tty->tty.rd.last_key_offset = 0; - tty->tty.rd.last_utf16_high_surrogate = 0; - memset(&tty->tty.rd.last_input_record, 0, sizeof tty->tty.rd.last_input_record); - } else { - /* TTY output specific fields. */ - tty->flags |= UV_HANDLE_WRITABLE; - - /* Init utf8-to-utf16 conversion state. */ - tty->tty.wr.utf8_bytes_left = 0; - tty->tty.wr.utf8_codepoint = 0; - - /* Initialize eol conversion state */ - tty->tty.wr.previous_eol = 0; - - /* Init ANSI parser state. */ - tty->tty.wr.ansi_parser_state = ANSI_NORMAL; - } - - return 0; -} - - -/* Set the default console text attributes based on how the console was - * configured when libuv started. - */ -static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info) { - static int style_captured = 0; - - /* Only do this once. - /* Assumption: Caller has acquired uv_tty_output_lock. */ - if (style_captured) - return; - - /* Save raw win32 attributes. */ - uv_tty_default_text_attributes = info->wAttributes; - - /* Convert black text on black background to use white text. */ - if (uv_tty_default_text_attributes == 0) - uv_tty_default_text_attributes = 7; - - /* Convert Win32 attributes to ANSI colors. */ - uv_tty_default_fg_color = 0; - uv_tty_default_bg_color = 0; - uv_tty_default_fg_bright = 0; - uv_tty_default_bg_bright = 0; - uv_tty_default_inverse = 0; - - if (uv_tty_default_text_attributes & FOREGROUND_RED) - uv_tty_default_fg_color |= 1; - - if (uv_tty_default_text_attributes & FOREGROUND_GREEN) - uv_tty_default_fg_color |= 2; - - if (uv_tty_default_text_attributes & FOREGROUND_BLUE) - uv_tty_default_fg_color |= 4; - - if (uv_tty_default_text_attributes & BACKGROUND_RED) - uv_tty_default_bg_color |= 1; - - if (uv_tty_default_text_attributes & BACKGROUND_GREEN) - uv_tty_default_bg_color |= 2; - - if (uv_tty_default_text_attributes & BACKGROUND_BLUE) - uv_tty_default_bg_color |= 4; - - if (uv_tty_default_text_attributes & FOREGROUND_INTENSITY) - uv_tty_default_fg_bright = 1; - - if (uv_tty_default_text_attributes & BACKGROUND_INTENSITY) - uv_tty_default_bg_bright = 1; - - if (uv_tty_default_text_attributes & COMMON_LVB_REVERSE_VIDEO) - uv_tty_default_inverse = 1; - - style_captured = 1; -} - - -int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { - DWORD flags; - unsigned char was_reading; - uv_alloc_cb alloc_cb; - uv_read_cb read_cb; - int err; - - if (!(tty->flags & UV_HANDLE_TTY_READABLE)) { - return UV_EINVAL; - } - - if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) { - return 0; - } - - switch (mode) { - case UV_TTY_MODE_NORMAL: - flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; - break; - case UV_TTY_MODE_RAW: - flags = ENABLE_WINDOW_INPUT; - break; - case UV_TTY_MODE_IO: - return UV_ENOTSUP; - } - - if (!SetConsoleMode(tty->handle, flags)) { - return uv_translate_sys_error(GetLastError()); - } - - /* If currently reading, stop, and restart reading. */ - if (tty->flags & UV_HANDLE_READING) { - was_reading = 1; - alloc_cb = tty->alloc_cb; - read_cb = tty->read_cb; - - if (was_reading) { - err = uv_tty_read_stop(tty); - if (err) { - return uv_translate_sys_error(err); - } - } - } else { - was_reading = 0; - } - - /* Update flag. */ - tty->flags &= ~UV_HANDLE_TTY_RAW; - tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0; - - /* If we just stopped reading, restart. */ - if (was_reading) { - err = uv_tty_read_start(tty, alloc_cb, read_cb); - if (err) { - return uv_translate_sys_error(err); - } - } - - return 0; -} - - -int uv_is_tty(uv_file file) { - DWORD result; - return GetConsoleMode((HANDLE) _get_osfhandle(file), &result) != 0; -} - - -int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { - CONSOLE_SCREEN_BUFFER_INFO info; - - if (!GetConsoleScreenBufferInfo(tty->handle, &info)) { - return uv_translate_sys_error(GetLastError()); - } - - EnterCriticalSection(&uv_tty_output_lock); - uv_tty_update_virtual_window(&info); - LeaveCriticalSection(&uv_tty_output_lock); - - *width = uv_tty_virtual_width; - *height = uv_tty_virtual_height; - - return 0; -} - - -static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) { - uv_loop_t* loop; - uv_tty_t* handle; - uv_req_t* req; - - assert(data); - assert(!didTimeout); - - req = (uv_req_t*) data; - handle = (uv_tty_t*) req->data; - loop = handle->loop; - - UnregisterWait(handle->tty.rd.read_raw_wait); - handle->tty.rd.read_raw_wait = NULL; - - SET_REQ_SUCCESS(req); - POST_COMPLETION_FOR_REQ(loop, req); -} - - -static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) { - uv_read_t* req; - BOOL r; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); - - handle->tty.rd.read_line_buffer = uv_null_buf_; - - req = &handle->read_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - r = RegisterWaitForSingleObject(&handle->tty.rd.read_raw_wait, - handle->handle, - uv_tty_post_raw_read, - (void*) req, - INFINITE, - WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); - if (!r) { - handle->tty.rd.read_raw_wait = NULL; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -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; - WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3]; - DWORD chars, read_chars; - - assert(data); - - req = (uv_req_t*) data; - handle = (uv_tty_t*) req->data; - loop = handle->loop; - - assert(handle->tty.rd.read_line_buffer.base != NULL); - assert(handle->tty.rd.read_line_buffer.len > 0); - - /* ReadConsole can't handle big buffers. */ - if (handle->tty.rd.read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) { - bytes = handle->tty.rd.read_line_buffer.len; - } else { - bytes = MAX_INPUT_BUFFER_LENGTH; - } - - /* At last, unicode! */ - /* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */ - chars = bytes / 3; - - if (ReadConsoleW(handle->tty.rd.read_line_handle, - (void*) utf16, - chars, - &read_chars, - NULL)) { - read_bytes = WideCharToMultiByte(CP_UTF8, - 0, - utf16, - read_chars, - handle->tty.rd.read_line_buffer.base, - bytes, - NULL, - NULL); - SET_REQ_SUCCESS(req); - req->u.io.overlapped.InternalHigh = read_bytes; - } else { - SET_REQ_ERROR(req, GetLastError()); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) { - uv_read_t* req; - BOOL r; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); - - req = &handle->read_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer); - if (handle->tty.rd.read_line_buffer.len == 0) { - handle->read_cb((uv_stream_t*) handle, - UV_ENOBUFS, - &handle->tty.rd.read_line_buffer); - return; - } - assert(handle->tty.rd.read_line_buffer.base != NULL); - - /* Duplicate the console handle, so if we want to cancel the read, we can */ - /* just close this handle duplicate. */ - if (handle->tty.rd.read_line_handle == NULL) { - HANDLE this_process = GetCurrentProcess(); - r = DuplicateHandle(this_process, - handle->handle, - this_process, - &handle->tty.rd.read_line_handle, - 0, - 0, - DUPLICATE_SAME_ACCESS); - if (!r) { - handle->tty.rd.read_line_handle = NULL; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - goto out; - } - } - - r = QueueUserWorkItem(uv_tty_line_read_thread, - (void*) req, - WT_EXECUTELONGFUNCTION); - if (!r) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - - out: - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -static void uv_tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) { - if (handle->flags & UV_HANDLE_TTY_RAW) { - uv_tty_queue_read_raw(loop, handle); - } else { - uv_tty_queue_read_line(loop, handle); - } -} - - -static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl, - size_t* len) { -#define VK_CASE(vk, normal_str, shift_str, ctrl_str, shift_ctrl_str) \ - case (vk): \ - if (shift && ctrl) { \ - *len = sizeof shift_ctrl_str; \ - return "\033" shift_ctrl_str; \ - } else if (shift) { \ - *len = sizeof shift_str ; \ - return "\033" shift_str; \ - } else if (ctrl) { \ - *len = sizeof ctrl_str; \ - return "\033" ctrl_str; \ - } else { \ - *len = sizeof normal_str; \ - return "\033" normal_str; \ - } - - switch (code) { - /* These mappings are the same as Cygwin's. Unmodified and alt-modified */ - /* keypad keys comply with linux console, modifiers comply with xterm */ - /* modifier usage. F1..f12 and shift-f1..f10 comply with linux console, */ - /* f6..f12 with and without modifiers comply with rxvt. */ - VK_CASE(VK_INSERT, "[2~", "[2;2~", "[2;5~", "[2;6~") - VK_CASE(VK_END, "[4~", "[4;2~", "[4;5~", "[4;6~") - VK_CASE(VK_DOWN, "[B", "[1;2B", "[1;5B", "[1;6B") - VK_CASE(VK_NEXT, "[6~", "[6;2~", "[6;5~", "[6;6~") - VK_CASE(VK_LEFT, "[D", "[1;2D", "[1;5D", "[1;6D") - VK_CASE(VK_CLEAR, "[G", "[1;2G", "[1;5G", "[1;6G") - VK_CASE(VK_RIGHT, "[C", "[1;2C", "[1;5C", "[1;6C") - VK_CASE(VK_UP, "[A", "[1;2A", "[1;5A", "[1;6A") - VK_CASE(VK_HOME, "[1~", "[1;2~", "[1;5~", "[1;6~") - VK_CASE(VK_PRIOR, "[5~", "[5;2~", "[5;5~", "[5;6~") - VK_CASE(VK_DELETE, "[3~", "[3;2~", "[3;5~", "[3;6~") - VK_CASE(VK_NUMPAD0, "[2~", "[2;2~", "[2;5~", "[2;6~") - VK_CASE(VK_NUMPAD1, "[4~", "[4;2~", "[4;5~", "[4;6~") - VK_CASE(VK_NUMPAD2, "[B", "[1;2B", "[1;5B", "[1;6B") - VK_CASE(VK_NUMPAD3, "[6~", "[6;2~", "[6;5~", "[6;6~") - VK_CASE(VK_NUMPAD4, "[D", "[1;2D", "[1;5D", "[1;6D") - VK_CASE(VK_NUMPAD5, "[G", "[1;2G", "[1;5G", "[1;6G") - VK_CASE(VK_NUMPAD6, "[C", "[1;2C", "[1;5C", "[1;6C") - VK_CASE(VK_NUMPAD7, "[A", "[1;2A", "[1;5A", "[1;6A") - VK_CASE(VK_NUMPAD8, "[1~", "[1;2~", "[1;5~", "[1;6~") - VK_CASE(VK_NUMPAD9, "[5~", "[5;2~", "[5;5~", "[5;6~") - VK_CASE(VK_DECIMAL, "[3~", "[3;2~", "[3;5~", "[3;6~") - VK_CASE(VK_F1, "[[A", "[23~", "[11^", "[23^" ) - VK_CASE(VK_F2, "[[B", "[24~", "[12^", "[24^" ) - VK_CASE(VK_F3, "[[C", "[25~", "[13^", "[25^" ) - VK_CASE(VK_F4, "[[D", "[26~", "[14^", "[26^" ) - VK_CASE(VK_F5, "[[E", "[28~", "[15^", "[28^" ) - VK_CASE(VK_F6, "[17~", "[29~", "[17^", "[29^" ) - VK_CASE(VK_F7, "[18~", "[31~", "[18^", "[31^" ) - VK_CASE(VK_F8, "[19~", "[32~", "[19^", "[32^" ) - VK_CASE(VK_F9, "[20~", "[33~", "[20^", "[33^" ) - VK_CASE(VK_F10, "[21~", "[34~", "[21^", "[34^" ) - VK_CASE(VK_F11, "[23~", "[23$", "[23^", "[23@" ) - VK_CASE(VK_F12, "[24~", "[24$", "[24^", "[24@" ) - - default: - *len = 0; - return NULL; - } -#undef VK_CASE -} - - -void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - /* Shortcut for handle->tty.rd.last_input_record.Event.KeyEvent. */ -#define KEV handle->tty.rd.last_input_record.Event.KeyEvent - - DWORD records_left, records_read; - uv_buf_t buf; - off_t buf_used; - - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!(handle->flags & UV_HANDLE_READING) || - !(handle->flags & UV_HANDLE_TTY_RAW)) { - goto out; - } - - if (!REQ_SUCCESS(req)) { - /* An error occurred while waiting for the event. */ - if ((handle->flags & UV_HANDLE_READING)) { - handle->flags &= ~UV_HANDLE_READING; - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(GET_REQ_ERROR(req)), - &uv_null_buf_); - } - goto out; - } - - /* Fetch the number of events */ - if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(GetLastError()), - &uv_null_buf_); - goto out; - } - - /* Windows sends a lot of events that we're not interested in, so buf */ - /* will be allocated on demand, when there's actually something to emit. */ - buf = uv_null_buf_; - buf_used = 0; - - while ((records_left > 0 || handle->tty.rd.last_key_len > 0) && - (handle->flags & UV_HANDLE_READING)) { - if (handle->tty.rd.last_key_len == 0) { - /* Read the next input record */ - if (!ReadConsoleInputW(handle->handle, - &handle->tty.rd.last_input_record, - 1, - &records_read)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GetLastError()), - &buf); - goto out; - } - records_left--; - - /* If the window was resized, recompute the virtual window size. This */ - /* will trigger a SIGWINCH signal if the window size changed in an */ - /* way that matters to libuv. */ - if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) { - CONSOLE_SCREEN_BUFFER_INFO info; - - EnterCriticalSection(&uv_tty_output_lock); - - if (uv_tty_output_handle != INVALID_HANDLE_VALUE && - GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) { - uv_tty_update_virtual_window(&info); - } - - LeaveCriticalSection(&uv_tty_output_lock); - - continue; - } - - /* Ignore other events that are not key or resize events. */ - if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) { - continue; - } - - /* Ignore keyup events, unless the left alt key was held and a valid */ - /* unicode character was emitted. */ - if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) || - KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) { - continue; - } - - /* Ignore keypresses to numpad number keys if the left alt is held */ - /* because the user is composing a character, or windows simulating */ - /* this. */ - if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) && - !(KEV.dwControlKeyState & ENHANCED_KEY) && - (KEV.wVirtualKeyCode == VK_INSERT || - KEV.wVirtualKeyCode == VK_END || - KEV.wVirtualKeyCode == VK_DOWN || - KEV.wVirtualKeyCode == VK_NEXT || - KEV.wVirtualKeyCode == VK_LEFT || - KEV.wVirtualKeyCode == VK_CLEAR || - KEV.wVirtualKeyCode == VK_RIGHT || - KEV.wVirtualKeyCode == VK_HOME || - KEV.wVirtualKeyCode == VK_UP || - KEV.wVirtualKeyCode == VK_PRIOR || - KEV.wVirtualKeyCode == VK_NUMPAD0 || - KEV.wVirtualKeyCode == VK_NUMPAD1 || - KEV.wVirtualKeyCode == VK_NUMPAD2 || - KEV.wVirtualKeyCode == VK_NUMPAD3 || - KEV.wVirtualKeyCode == VK_NUMPAD4 || - KEV.wVirtualKeyCode == VK_NUMPAD5 || - KEV.wVirtualKeyCode == VK_NUMPAD6 || - KEV.wVirtualKeyCode == VK_NUMPAD7 || - KEV.wVirtualKeyCode == VK_NUMPAD8 || - KEV.wVirtualKeyCode == VK_NUMPAD9)) { - continue; - } - - if (KEV.uChar.UnicodeChar != 0) { - int prefix_len, char_len; - - /* Character key pressed */ - if (KEV.uChar.UnicodeChar >= 0xD800 && - KEV.uChar.UnicodeChar < 0xDC00) { - /* UTF-16 high surrogate */ - handle->tty.rd.last_utf16_high_surrogate = KEV.uChar.UnicodeChar; - continue; - } - - /* Prefix with \u033 if alt was held, but alt was not used as part */ - /* a compose sequence. */ - if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) - && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED | - RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) { - handle->tty.rd.last_key[0] = '\033'; - prefix_len = 1; - } else { - prefix_len = 0; - } - - if (KEV.uChar.UnicodeChar >= 0xDC00 && - KEV.uChar.UnicodeChar < 0xE000) { - /* UTF-16 surrogate pair */ - WCHAR utf16_buffer[2] = { handle->tty.rd.last_utf16_high_surrogate, - 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); - } 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); - } - - /* 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) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GetLastError()), - &buf); - goto out; - } - - handle->tty.rd.last_key_len = (unsigned char) (prefix_len + char_len); - handle->tty.rd.last_key_offset = 0; - continue; - - } else { - /* Function key pressed */ - const char* vt100; - size_t prefix_len, vt100_len; - - vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode, - !!(KEV.dwControlKeyState & SHIFT_PRESSED), - !!(KEV.dwControlKeyState & ( - LEFT_CTRL_PRESSED | - RIGHT_CTRL_PRESSED)), - &vt100_len); - - /* If we were unable to map to a vt100 sequence, just ignore. */ - if (!vt100) { - continue; - } - - /* Prefix with \x033 when the alt key was held. */ - if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) { - handle->tty.rd.last_key[0] = '\033'; - prefix_len = 1; - } else { - prefix_len = 0; - } - - /* Copy the vt100 sequence to the handle buffer. */ - assert(prefix_len + vt100_len < sizeof handle->tty.rd.last_key); - memcpy(&handle->tty.rd.last_key[prefix_len], vt100, vt100_len); - - handle->tty.rd.last_key_len = (unsigned char) (prefix_len + vt100_len); - handle->tty.rd.last_key_offset = 0; - continue; - } - } else { - /* Copy any bytes left from the last keypress to the user buffer. */ - if (handle->tty.rd.last_key_offset < handle->tty.rd.last_key_len) { - /* Allocate a buffer if needed */ - if (buf_used == 0) { - handle->alloc_cb((uv_handle_t*) handle, 1024, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - goto out; - } - assert(buf.base != NULL); - } - - buf.base[buf_used++] = handle->tty.rd.last_key[handle->tty.rd.last_key_offset++]; - - /* If the buffer is full, emit it */ - if ((size_t) buf_used == buf.len) { - handle->read_cb((uv_stream_t*) handle, buf_used, &buf); - buf = uv_null_buf_; - buf_used = 0; - } - - continue; - } - - /* Apply dwRepeat from the last input record. */ - if (--KEV.wRepeatCount > 0) { - handle->tty.rd.last_key_offset = 0; - continue; - } - - handle->tty.rd.last_key_len = 0; - continue; - } - } - - /* Send the buffer back to the user */ - if (buf_used > 0) { - handle->read_cb((uv_stream_t*) handle, buf_used, &buf); - } - - out: - /* Wait for more input events. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tty_queue_read(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); - -#undef KEV -} - - - -void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - uv_buf_t buf; - - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - - buf = handle->tty.rd.read_line_buffer; - - handle->flags &= ~UV_HANDLE_READ_PENDING; - handle->tty.rd.read_line_buffer = uv_null_buf_; - - if (!REQ_SUCCESS(req)) { - /* Read was not successful */ - if ((handle->flags & UV_HANDLE_READING) && - handle->tty.rd.read_line_handle != NULL) { - /* Real error */ - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GET_REQ_ERROR(req)), - &buf); - } else { - /* The read was cancelled, or whatever we don't care */ - handle->read_cb((uv_stream_t*) handle, 0, &buf); - } - - } else { - /* Read successful */ - /* TODO: read unicode, convert to utf-8 */ - DWORD bytes = req->u.io.overlapped.InternalHigh; - handle->read_cb((uv_stream_t*) handle, bytes, &buf); - } - - /* Wait for more input events. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tty_queue_read(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - - /* If the read_line_buffer member is zero, it must have been an raw read. */ - /* Otherwise it was a line-buffered read. */ - /* FIXME: This is quite obscure. Use a flag or something. */ - if (handle->tty.rd.read_line_buffer.len == 0) { - uv_process_tty_read_raw_req(loop, handle, req); - } else { - uv_process_tty_read_line_req(loop, handle, req); - } -} - - -int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - if (!(handle->flags & UV_HANDLE_TTY_READABLE)) { - return ERROR_INVALID_PARAMETER; - } - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (handle->flags & UV_HANDLE_READ_PENDING) { - return 0; - } - - /* Maybe the user stopped reading half-way while processing key events. */ - /* Short-circuit if this could be the case. */ - if (handle->tty.rd.last_key_len > 0) { - SET_REQ_SUCCESS(&handle->read_req); - uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req); - return 0; - } - - uv_tty_queue_read(loop, handle); - - return 0; -} - - -int uv_tty_read_stop(uv_tty_t* handle) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(handle->loop, handle); - - /* Cancel raw read */ - if ((handle->flags & UV_HANDLE_READ_PENDING) && - (handle->flags & UV_HANDLE_TTY_RAW)) { - /* Write some bullshit event to force the console wait to return. */ - INPUT_RECORD record; - DWORD written; - memset(&record, 0, sizeof record); - if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) { - return GetLastError(); - } - } - - /* Cancel line-buffered read */ - if (handle->tty.rd.read_line_handle != NULL) { - /* Closing this handle will cancel the ReadConsole operation */ - CloseHandle(handle->tty.rd.read_line_handle); - handle->tty.rd.read_line_handle = NULL; - } - - - return 0; -} - - -static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) { - int old_virtual_width = uv_tty_virtual_width; - int old_virtual_height = uv_tty_virtual_height; - - uv_tty_virtual_width = info->dwSize.X; - uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1; - - /* Recompute virtual window offset row. */ - if (uv_tty_virtual_offset == -1) { - uv_tty_virtual_offset = info->dwCursorPosition.Y; - } else if (uv_tty_virtual_offset < info->dwCursorPosition.Y - - uv_tty_virtual_height + 1) { - /* If suddenly find the cursor outside of the virtual window, it must */ - /* have somehow scrolled. Update the virtual window offset. */ - uv_tty_virtual_offset = info->dwCursorPosition.Y - - uv_tty_virtual_height + 1; - } - if (uv_tty_virtual_offset + uv_tty_virtual_height > info->dwSize.Y) { - uv_tty_virtual_offset = info->dwSize.Y - uv_tty_virtual_height; - } - if (uv_tty_virtual_offset < 0) { - uv_tty_virtual_offset = 0; - } - - /* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */ - /* if this was the first time the virtual window size was computed. */ - if (old_virtual_width != -1 && old_virtual_height != -1 && - (uv_tty_virtual_width != old_virtual_width || - uv_tty_virtual_height != old_virtual_height)) { - uv__signal_dispatch(SIGWINCH); - } -} - - -static COORD uv_tty_make_real_coord(uv_tty_t* handle, - CONSOLE_SCREEN_BUFFER_INFO* info, int x, unsigned char x_relative, int y, - unsigned char y_relative) { - COORD result; - - uv_tty_update_virtual_window(info); - - /* Adjust y position */ - if (y_relative) { - y = info->dwCursorPosition.Y + y; - } else { - y = uv_tty_virtual_offset + y; - } - /* Clip y to virtual client rectangle */ - if (y < uv_tty_virtual_offset) { - y = uv_tty_virtual_offset; - } else if (y >= uv_tty_virtual_offset + uv_tty_virtual_height) { - y = uv_tty_virtual_offset + uv_tty_virtual_height - 1; - } - - /* Adjust x */ - if (x_relative) { - x = info->dwCursorPosition.X + x; - } - /* Clip x */ - if (x < 0) { - x = 0; - } else if (x >= uv_tty_virtual_width) { - x = uv_tty_virtual_width - 1; - } - - result.X = (unsigned short) x; - result.Y = (unsigned short) y; - return result; -} - - -static int uv_tty_emit_text(uv_tty_t* handle, WCHAR buffer[], DWORD length, - DWORD* error) { - DWORD written; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (!WriteConsoleW(handle->handle, - (void*) buffer, - length, - &written, - NULL)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - - -static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative, - int y, unsigned char y_relative, DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - COORD pos; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - } - - pos = uv_tty_make_real_coord(handle, &info, x, x_relative, y, y_relative); - - if (!SetConsoleCursorPosition(handle->handle, pos)) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - - -static int uv_tty_reset(uv_tty_t* handle, DWORD* error) { - const COORD origin = {0, 0}; - const WORD char_attrs = uv_tty_default_text_attributes; - CONSOLE_SCREEN_BUFFER_INFO info; - DWORD count, written; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - /* Reset original text attributes. */ - if (!SetConsoleTextAttribute(handle->handle, char_attrs)) { - *error = GetLastError(); - return -1; - } - - /* Move the cursor position to (0, 0). */ - if (!SetConsoleCursorPosition(handle->handle, origin)) { - *error = GetLastError(); - return -1; - } - - /* Clear the screen buffer. */ - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - count = info.dwSize.X * info.dwSize.Y; - - if (!(FillConsoleOutputCharacterW(handle->handle, - L'\x20', - count, - origin, - &written) && - FillConsoleOutputAttribute(handle->handle, - char_attrs, - written, - origin, - &written))) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - /* Move the virtual window up to the top. */ - uv_tty_virtual_offset = 0; - uv_tty_update_virtual_window(&info); - - return 0; -} - - -static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen, - DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - COORD start, end; - DWORD count, written; - - int x1, x2, y1, y2; - int x1r, x2r, y1r, y2r; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (dir == 0) { - /* Clear from current position */ - x1 = 0; - x1r = 1; - } else { - /* Clear from column 0 */ - x1 = 0; - x1r = 0; - } - - if (dir == 1) { - /* Clear to current position */ - x2 = 0; - x2r = 1; - } else { - /* Clear to end of row. We pretend the console is 65536 characters wide, */ - /* uv_tty_make_real_coord will clip it to the actual console width. */ - x2 = 0xffff; - x2r = 0; - } - - if (!entire_screen) { - /* Stay on our own row */ - y1 = y2 = 0; - y1r = y2r = 1; - } else { - /* Apply columns direction to row */ - y1 = x1; - y1r = x1r; - y2 = x2; - y2r = x2r; - } - - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - start = uv_tty_make_real_coord(handle, &info, x1, x1r, y1, y1r); - end = uv_tty_make_real_coord(handle, &info, x2, x2r, y2, y2r); - count = (end.Y * info.dwSize.X + end.X) - - (start.Y * info.dwSize.X + start.X) + 1; - - if (!(FillConsoleOutputCharacterW(handle->handle, - L'\x20', - count, - start, - &written) && - FillConsoleOutputAttribute(handle->handle, - info.wAttributes, - written, - start, - &written))) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - -#define FLIP_FGBG \ - do { \ - WORD fg = info.wAttributes & 0xF; \ - WORD bg = info.wAttributes & 0xF0; \ - info.wAttributes &= 0xFF00; \ - info.wAttributes |= fg << 4; \ - info.wAttributes |= bg >> 4; \ - } while (0) - -static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { - unsigned short argc = handle->tty.wr.ansi_csi_argc; - unsigned short* argv = handle->tty.wr.ansi_csi_argv; - int i; - CONSOLE_SCREEN_BUFFER_INFO info; - - char fg_color = -1, bg_color = -1; - char fg_bright = -1, bg_bright = -1; - char inverse = -1; - - if (argc == 0) { - /* Reset mode */ - fg_color = uv_tty_default_fg_color; - bg_color = uv_tty_default_bg_color; - fg_bright = uv_tty_default_fg_bright; - bg_bright = uv_tty_default_bg_bright; - inverse = uv_tty_default_inverse; - } - - for (i = 0; i < argc; i++) { - short arg = argv[i]; - - if (arg == 0) { - /* Reset mode */ - fg_color = uv_tty_default_fg_color; - bg_color = uv_tty_default_bg_color; - fg_bright = uv_tty_default_fg_bright; - bg_bright = uv_tty_default_bg_bright; - inverse = uv_tty_default_inverse; - - } else if (arg == 1) { - /* Foreground bright on */ - fg_bright = 1; - - } else if (arg == 2) { - /* Both bright off */ - fg_bright = 0; - bg_bright = 0; - - } else if (arg == 5) { - /* Background bright on */ - bg_bright = 1; - - } else if (arg == 7) { - /* Inverse: on */ - inverse = 1; - - } else if (arg == 21 || arg == 22) { - /* Foreground bright off */ - fg_bright = 0; - - } else if (arg == 25) { - /* Background bright off */ - bg_bright = 0; - - } else if (arg == 27) { - /* Inverse: off */ - inverse = 0; - - } else if (arg >= 30 && arg <= 37) { - /* Set foreground color */ - fg_color = arg - 30; - - } else if (arg == 39) { - /* Default text color */ - fg_color = uv_tty_default_fg_color; - fg_bright = uv_tty_default_fg_bright; - - } else if (arg >= 40 && arg <= 47) { - /* Set background color */ - bg_color = arg - 40; - - } else if (arg == 49) { - /* Default background color */ - bg_color = uv_tty_default_bg_color; - bg_bright = uv_tty_default_bg_bright; - - } else if (arg >= 90 && arg <= 97) { - /* Set bold foreground color */ - fg_bright = 1; - fg_color = arg - 90; - - } else if (arg >= 100 && arg <= 107) { - /* Set bold background color */ - bg_bright = 1; - bg_color = arg - 100; - - } - } - - if (fg_color == -1 && bg_color == -1 && fg_bright == -1 && - bg_bright == -1 && inverse == -1) { - /* Nothing changed */ - return 0; - } - - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) { - FLIP_FGBG; - } - - if (fg_color != -1) { - info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - if (fg_color & 1) info.wAttributes |= FOREGROUND_RED; - if (fg_color & 2) info.wAttributes |= FOREGROUND_GREEN; - if (fg_color & 4) info.wAttributes |= FOREGROUND_BLUE; - } - - if (fg_bright != -1) { - if (fg_bright) { - info.wAttributes |= FOREGROUND_INTENSITY; - } else { - info.wAttributes &= ~FOREGROUND_INTENSITY; - } - } - - if (bg_color != -1) { - info.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); - if (bg_color & 1) info.wAttributes |= BACKGROUND_RED; - if (bg_color & 2) info.wAttributes |= BACKGROUND_GREEN; - if (bg_color & 4) info.wAttributes |= BACKGROUND_BLUE; - } - - if (bg_bright != -1) { - if (bg_bright) { - info.wAttributes |= BACKGROUND_INTENSITY; - } else { - info.wAttributes &= ~BACKGROUND_INTENSITY; - } - } - - if (inverse != -1) { - if (inverse) { - info.wAttributes |= COMMON_LVB_REVERSE_VIDEO; - } else { - info.wAttributes &= ~COMMON_LVB_REVERSE_VIDEO; - } - } - - if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) { - FLIP_FGBG; - } - - if (!SetConsoleTextAttribute(handle->handle, info.wAttributes)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - - -static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes, - DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - uv_tty_update_virtual_window(&info); - - handle->tty.wr.saved_position.X = info.dwCursorPosition.X; - handle->tty.wr.saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset; - handle->flags |= UV_HANDLE_TTY_SAVED_POSITION; - - if (save_attributes) { - handle->tty.wr.saved_attributes = info.wAttributes & - (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); - handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES; - } - - return 0; -} - - -static int uv_tty_restore_state(uv_tty_t* handle, - unsigned char restore_attributes, DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - WORD new_attributes; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) { - if (uv_tty_move_caret(handle, - handle->tty.wr.saved_position.X, - 0, - handle->tty.wr.saved_position.Y, - 0, - error) != 0) { - return -1; - } - } - - if (restore_attributes && - (handle->flags & UV_HANDLE_TTY_SAVED_ATTRIBUTES)) { - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - new_attributes = info.wAttributes; - new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); - new_attributes |= handle->tty.wr.saved_attributes; - - if (!SetConsoleTextAttribute(handle->handle, new_attributes)) { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - -static int uv_tty_set_cursor_visibility(uv_tty_t* handle, - BOOL visible, - DWORD* error) { - CONSOLE_CURSOR_INFO cursor_info; - - if (!GetConsoleCursorInfo(handle->handle, &cursor_info)) { - *error = GetLastError(); - return -1; - } - - cursor_info.bVisible = visible; - - if (!SetConsoleCursorInfo(handle->handle, &cursor_info)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - -static int uv_tty_write_bufs(uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - DWORD* error) { - /* We can only write 8k characters at a time. Windows can't handle */ - /* much more characters in a single console write anyway. */ - WCHAR utf16_buf[8192]; - DWORD utf16_buf_used = 0; - unsigned int i; - -#define FLUSH_TEXT() \ - do { \ - if (utf16_buf_used > 0) { \ - uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); \ - utf16_buf_used = 0; \ - } \ - } while (0) - -#define ENSURE_BUFFER_SPACE(wchars_needed) \ - if (wchars_needed > ARRAY_SIZE(utf16_buf) - utf16_buf_used) { \ - FLUSH_TEXT(); \ - } - - /* Cache for fast access */ - unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left; - unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint; - unsigned char previous_eol = handle->tty.wr.previous_eol; - unsigned char ansi_parser_state = handle->tty.wr.ansi_parser_state; - - /* Store the error here. If we encounter an error, stop trying to do i/o */ - /* but keep parsing the buffer so we leave the parser in a consistent */ - /* state. */ - *error = ERROR_SUCCESS; - - EnterCriticalSection(&uv_tty_output_lock); - - for (i = 0; i < nbufs; i++) { - uv_buf_t buf = bufs[i]; - unsigned int j; - - for (j = 0; j < buf.len; j++) { - unsigned char c = buf.base[j]; - - /* Run the character through the utf8 decoder We happily accept non */ - /* shortest form encodings and invalid code points - there's no real */ - /* harm that can be done. */ - if (utf8_bytes_left == 0) { - /* Read utf-8 start byte */ - DWORD first_zero_bit; - unsigned char not_c = ~c; -#ifdef _MSC_VER /* msvc */ - if (_BitScanReverse(&first_zero_bit, not_c)) { -#else /* assume gcc */ - if (c != 0) { - first_zero_bit = (sizeof(int) * 8) - 1 - __builtin_clz(not_c); -#endif - if (first_zero_bit == 7) { - /* Ascii - pass right through */ - utf8_codepoint = (unsigned int) c; - - } else if (first_zero_bit <= 5) { - /* Multibyte sequence */ - utf8_codepoint = (0xff >> (8 - first_zero_bit)) & c; - utf8_bytes_left = (char) (6 - first_zero_bit); - - } else { - /* Invalid continuation */ - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - } else { - /* 0xff -- invalid */ - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - } else if ((c & 0xc0) == 0x80) { - /* Valid continuation of utf-8 multibyte sequence */ - utf8_bytes_left--; - utf8_codepoint <<= 6; - utf8_codepoint |= ((unsigned int) c & 0x3f); - - } else { - /* Start byte where continuation was expected. */ - utf8_bytes_left = 0; - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - /* Patch buf offset so this character will be parsed again as a */ - /* start byte. */ - j--; - } - - /* Maybe we need to parse more bytes to find a character. */ - if (utf8_bytes_left != 0) { - continue; - } - - /* Parse vt100/ansi escape codes */ - if (ansi_parser_state == ANSI_NORMAL) { - switch (utf8_codepoint) { - case '\033': - ansi_parser_state = ANSI_ESCAPE_SEEN; - continue; - - case 0233: - ansi_parser_state = ANSI_CSI; - handle->tty.wr.ansi_csi_argc = 0; - continue; - } - - } else if (ansi_parser_state == ANSI_ESCAPE_SEEN) { - switch (utf8_codepoint) { - case '[': - ansi_parser_state = ANSI_CSI; - handle->tty.wr.ansi_csi_argc = 0; - continue; - - case '^': - case '_': - case 'P': - case ']': - /* Not supported, but we'll have to parse until we see a stop */ - /* code, e.g. ESC \ or BEL. */ - ansi_parser_state = ANSI_ST_CONTROL; - continue; - - case '\033': - /* Ignore double escape. */ - continue; - - case 'c': - /* Full console reset. */ - FLUSH_TEXT(); - uv_tty_reset(handle, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - case '7': - /* Save the cursor position and text attributes. */ - FLUSH_TEXT(); - uv_tty_save_state(handle, 1, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - case '8': - /* Restore the cursor position and text attributes */ - FLUSH_TEXT(); - uv_tty_restore_state(handle, 1, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - default: - if (utf8_codepoint >= '@' && utf8_codepoint <= '_') { - /* Single-char control. */ - ansi_parser_state = ANSI_NORMAL; - continue; - } else { - /* Invalid - proceed as normal, */ - ansi_parser_state = ANSI_NORMAL; - } - } - - } else if (ansi_parser_state & ANSI_CSI) { - if (!(ansi_parser_state & ANSI_IGNORE)) { - if (utf8_codepoint >= '0' && utf8_codepoint <= '9') { - /* Parsing a numerical argument */ - - if (!(ansi_parser_state & ANSI_IN_ARG)) { - /* We were not currently parsing a number */ - - /* Check for too many arguments */ - if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - ansi_parser_state |= ANSI_IN_ARG; - handle->tty.wr.ansi_csi_argc++; - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = - (unsigned short) utf8_codepoint - '0'; - continue; - } else { - /* We were already parsing a number. Parse next digit. */ - uint32_t value = 10 * - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1]; - - /* Check for overflow. */ - if (value > UINT16_MAX) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = - (unsigned short) value + (utf8_codepoint - '0'); - continue; - } - - } else if (utf8_codepoint == ';') { - /* Denotes the end of an argument. */ - if (ansi_parser_state & ANSI_IN_ARG) { - ansi_parser_state &= ~ANSI_IN_ARG; - continue; - - } else { - /* If ANSI_IN_ARG is not set, add another argument and */ - /* default it to 0. */ - /* Check for too many arguments */ - if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - handle->tty.wr.ansi_csi_argc++; - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0; - continue; - } - - } else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) && - handle->tty.wr.ansi_csi_argc == 0) { - /* Ignores '?' if it is the first character after CSI[ */ - /* This is an extension character from the VT100 codeset */ - /* that is supported and used by most ANSI terminals today. */ - continue; - - } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' && - (handle->tty.wr.ansi_csi_argc > 0 || utf8_codepoint != '[')) { - int x, y, d; - - /* Command byte */ - switch (utf8_codepoint) { - case 'A': - /* cursor up */ - FLUSH_TEXT(); - y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, 0, 1, y, 1, error); - break; - - case 'B': - /* cursor down */ - FLUSH_TEXT(); - y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, 0, 1, y, 1, error); - break; - - case 'C': - /* cursor forward */ - FLUSH_TEXT(); - x = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, x, 1, 0, 1, error); - break; - - case 'D': - /* cursor back */ - FLUSH_TEXT(); - x = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, x, 1, 0, 1, error); - break; - - case 'E': - /* cursor next line */ - FLUSH_TEXT(); - y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, 0, 0, y, 1, error); - break; - - case 'F': - /* cursor previous line */ - FLUSH_TEXT(); - y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, 0, 0, y, 1, error); - break; - - case 'G': - /* cursor horizontal move absolute */ - FLUSH_TEXT(); - x = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0]) - ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0; - uv_tty_move_caret(handle, x, 0, 0, 1, error); - break; - - case 'H': - case 'f': - /* cursor move absolute */ - FLUSH_TEXT(); - y = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0]) - ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0; - x = (handle->tty.wr.ansi_csi_argc >= 2 && handle->tty.wr.ansi_csi_argv[1]) - ? handle->tty.wr.ansi_csi_argv[1] - 1 : 0; - uv_tty_move_caret(handle, x, 0, y, 0, error); - break; - - case 'J': - /* Erase screen */ - FLUSH_TEXT(); - d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0; - if (d >= 0 && d <= 2) { - uv_tty_clear(handle, d, 1, error); - } - break; - - case 'K': - /* Erase line */ - FLUSH_TEXT(); - d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0; - if (d >= 0 && d <= 2) { - uv_tty_clear(handle, d, 0, error); - } - break; - - case 'm': - /* Set style */ - FLUSH_TEXT(); - uv_tty_set_style(handle, error); - break; - - case 's': - /* Save the cursor position. */ - FLUSH_TEXT(); - uv_tty_save_state(handle, 0, error); - break; - - case 'u': - /* Restore the cursor position */ - FLUSH_TEXT(); - uv_tty_restore_state(handle, 0, error); - break; - - case 'l': - /* Hide the cursor */ - if (handle->tty.wr.ansi_csi_argc == 1 && - handle->tty.wr.ansi_csi_argv[0] == 25) { - FLUSH_TEXT(); - uv_tty_set_cursor_visibility(handle, 0, error); - } - break; - - case 'h': - /* Show the cursor */ - if (handle->tty.wr.ansi_csi_argc == 1 && - handle->tty.wr.ansi_csi_argv[0] == 25) { - FLUSH_TEXT(); - uv_tty_set_cursor_visibility(handle, 1, error); - } - break; - } - - /* Sequence ended - go back to normal state. */ - ansi_parser_state = ANSI_NORMAL; - continue; - - } else { - /* We don't support commands that use private mode characters or */ - /* intermediaries. Ignore the rest of the sequence. */ - ansi_parser_state |= ANSI_IGNORE; - continue; - } - } else { - /* We're ignoring this command. Stop only on command character. */ - if (utf8_codepoint >= '@' && utf8_codepoint <= '~') { - ansi_parser_state = ANSI_NORMAL; - } - continue; - } - - } else if (ansi_parser_state & ANSI_ST_CONTROL) { - /* Unsupported control code */ - /* Ignore everything until we see BEL or ESC \ */ - if (ansi_parser_state & ANSI_IN_STRING) { - if (!(ansi_parser_state & ANSI_BACKSLASH_SEEN)) { - if (utf8_codepoint == '"') { - ansi_parser_state &= ~ANSI_IN_STRING; - } else if (utf8_codepoint == '\\') { - ansi_parser_state |= ANSI_BACKSLASH_SEEN; - } - } else { - ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; - } - } else { - if (utf8_codepoint == '\007' || (utf8_codepoint == '\\' && - (ansi_parser_state & ANSI_ESCAPE_SEEN))) { - /* End of sequence */ - ansi_parser_state = ANSI_NORMAL; - } else if (utf8_codepoint == '\033') { - /* Escape character */ - ansi_parser_state |= ANSI_ESCAPE_SEEN; - } else if (utf8_codepoint == '"') { - /* String starting */ - ansi_parser_state |= ANSI_IN_STRING; - ansi_parser_state &= ~ANSI_ESCAPE_SEEN; - ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; - } else { - ansi_parser_state &= ~ANSI_ESCAPE_SEEN; - } - } - continue; - } else { - /* Inconsistent state */ - abort(); - } - - /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the */ - /* windows console doesn't really support UTF-16, so just emit the */ - /* replacement character. */ - if (utf8_codepoint > 0xffff) { - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) { - /* EOL conversion - emit \r\n when we see \n. */ - - if (utf8_codepoint == 0x0a && previous_eol != 0x0d) { - /* \n was not preceded by \r; print \r\n. */ - ENSURE_BUFFER_SPACE(2); - utf16_buf[utf16_buf_used++] = L'\r'; - utf16_buf[utf16_buf_used++] = L'\n'; - } else if (utf8_codepoint == 0x0d && previous_eol == 0x0a) { - /* \n was followed by \r; do not print the \r, since */ - /* the source was either \r\n\r (so the second \r is */ - /* redundant) or was \n\r (so the \n was processed */ - /* by the last case and an \r automatically inserted). */ - } else { - /* \r without \n; print \r as-is. */ - ENSURE_BUFFER_SPACE(1); - utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; - } - - previous_eol = (char) utf8_codepoint; - - } else if (utf8_codepoint <= 0xffff) { - /* Encode character into utf-16 buffer. */ - ENSURE_BUFFER_SPACE(1); - utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; - previous_eol = 0; - } - } - } - - /* Flush remaining characters */ - FLUSH_TEXT(); - - /* Copy cached values back to struct. */ - handle->tty.wr.utf8_bytes_left = utf8_bytes_left; - handle->tty.wr.utf8_codepoint = utf8_codepoint; - handle->tty.wr.previous_eol = previous_eol; - handle->tty.wr.ansi_parser_state = ansi_parser_state; - - LeaveCriticalSection(&uv_tty_output_lock); - - if (*error == STATUS_SUCCESS) { - return 0; - } else { - return -1; - } - -#undef FLUSH_TEXT -} - - -int uv_tty_write(uv_loop_t* loop, - uv_write_t* req, - uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - DWORD error; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - - req->u.io.queued_bytes = 0; - - if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_ERROR(req, error); - } - - uv_insert_pending_req(loop, (uv_req_t*) req); - - return 0; -} - - -int uv__tty_try_write(uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs) { - DWORD error; - - if (handle->stream.conn.write_reqs_pending > 0) - return UV_EAGAIN; - - if (uv_tty_write_bufs(handle, bufs, nbufs, &error)) - return uv_translate_sys_error(error); - - return uv__count_bufs(bufs, nbufs); -} - - -void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, - uv_write_t* req) { - int err; - - handle->write_queue_size -= req->u.io.queued_bytes; - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = GET_REQ_ERROR(req); - req->cb(req, uv_translate_sys_error(err)); - } - - handle->stream.conn.write_reqs_pending--; - if (handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_tty_close(uv_tty_t* handle) { - assert(handle->u.fd == -1 || handle->u.fd > 2); - if (handle->u.fd == -1) - CloseHandle(handle->handle); - else - close(handle->u.fd); - - if (handle->flags & UV_HANDLE_READING) - uv_tty_read_stop(handle); - - handle->u.fd = -1; - handle->handle = INVALID_HANDLE_VALUE; - handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(handle->loop, (uv_handle_t*) handle); - } -} - - -void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { - if (!(handle->flags & UV_HANDLE_TTY_READABLE) && - handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req); - - /* TTY shutdown is really just a no-op */ - if (handle->stream.conn.shutdown_req->cb) { - if (handle->flags & UV__HANDLE_CLOSING) { - handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED); - } else { - handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, 0); - } - } - - handle->stream.conn.shutdown_req = NULL; - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - /* The console handle duplicate used for line reading should be destroyed */ - /* by uv_tty_read_stop. */ - assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || - handle->tty.rd.read_line_handle == NULL); - - /* The wait handle used for raw reading should be unregistered when the */ - /* wait callback runs. */ - assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || - handle->tty.rd.read_raw_wait == NULL); - - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -/* TODO: remove me */ -void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* raw_req) { - abort(); -} - - -/* TODO: remove me */ -void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, - uv_connect_t* req) { - abort(); -} - - -int uv_tty_reset_mode(void) { - /* Not necessary to do anything. */ - return 0; -} diff --git a/outside/libuv-v1.7.5/src/win/udp.c b/outside/libuv-v1.7.5/src/win/udp.c deleted file mode 100644 index 24792ec067..0000000000 --- a/outside/libuv-v1.7.5/src/win/udp.c +++ /dev/null @@ -1,926 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -/* - * Threshold of active udp streams for which to preallocate udp read buffers. - */ -const unsigned int uv_active_udp_streams_threshold = 0; - -/* A zero-size buffer for use by uv_udp_read */ -static char uv_zero_[] = ""; - -int uv_udp_getsockname(const uv_udp_t* handle, - struct sockaddr* name, - int* namelen) { - int result; - - if (handle->socket == INVALID_SOCKET) { - return UV_EINVAL; - } - - result = getsockname(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket, - int family) { - DWORD yes = 1; - WSAPROTOCOL_INFOW info; - int opt_len; - - if (handle->socket != INVALID_SOCKET) - return UV_EBUSY; - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { - return GetLastError(); - } - - /* Associate it with the I/O completion port. */ - /* Use uv_handle_t pointer as completion key. */ - if (CreateIoCompletionPort((HANDLE)socket, - loop->iocp, - (ULONG_PTR)socket, - 0) == NULL) { - return GetLastError(); - } - - if (pSetFileCompletionNotificationModes) { - /* All known Windows that support SetFileCompletionNotificationModes */ - /* have a bug that makes it impossible to use this function in */ - /* conjunction with datagram sockets. We can work around that but only */ - /* if the user is using the default UDP driver (AFD) and has no other */ - /* LSPs stacked on top. Here we check whether that is the case. */ - opt_len = (int) sizeof info; - if (getsockopt(socket, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &info, - &opt_len) == SOCKET_ERROR) { - return GetLastError(); - } - - if (info.ProtocolChain.ChainLen == 1) { - if (pSetFileCompletionNotificationModes((HANDLE)socket, - FILE_SKIP_SET_EVENT_ON_HANDLE | - FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { - handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; - handle->func_wsarecv = uv_wsarecv_workaround; - handle->func_wsarecvfrom = uv_wsarecvfrom_workaround; - } else if (GetLastError() != ERROR_INVALID_FUNCTION) { - return GetLastError(); - } - } - } - - handle->socket = socket; - - if (family == AF_INET6) { - handle->flags |= UV_HANDLE_IPV6; - } else { - assert(!(handle->flags & UV_HANDLE_IPV6)); - } - - return 0; -} - - -int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { - int domain; - - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return UV_EINVAL; - - if (flags & ~0xFF) - return UV_EINVAL; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP); - handle->socket = INVALID_SOCKET; - handle->reqs_pending = 0; - handle->activecnt = 0; - handle->func_wsarecv = WSARecv; - handle->func_wsarecvfrom = WSARecvFrom; - handle->send_queue_size = 0; - handle->send_queue_count = 0; - uv_req_init(loop, (uv_req_t*) &(handle->recv_req)); - handle->recv_req.type = UV_UDP_RECV; - handle->recv_req.data = handle; - - /* If anything fails beyond this point we need to remove the handle from - * the handle queue, since it was added by uv__handle_init. - */ - - if (domain != AF_UNSPEC) { - SOCKET sock; - DWORD err; - - sock = socket(domain, SOCK_DGRAM, 0); - if (sock == INVALID_SOCKET) { - err = WSAGetLastError(); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - - err = uv_udp_set_socket(handle->loop, handle, sock, domain); - if (err) { - closesocket(sock); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - } - - return 0; -} - - -int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { - return uv_udp_init_ex(loop, handle, AF_UNSPEC); -} - - -void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) { - uv_udp_recv_stop(handle); - closesocket(handle->socket); - handle->socket = INVALID_SOCKET; - - uv__handle_closing(handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -static int uv_udp_maybe_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int r; - int err; - DWORD no = 0; - - if (handle->flags & UV_HANDLE_BOUND) - return 0; - - if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) { - /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ - return ERROR_INVALID_PARAMETER; - } - - if (handle->socket == INVALID_SOCKET) { - SOCKET sock = socket(addr->sa_family, SOCK_DGRAM, 0); - if (sock == INVALID_SOCKET) { - return WSAGetLastError(); - } - - err = uv_udp_set_socket(handle->loop, handle, sock, addr->sa_family); - if (err) { - closesocket(sock); - return err; - } - } - - if (flags & UV_UDP_REUSEADDR) { - DWORD yes = 1; - /* Set SO_REUSEADDR on the socket. */ - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_REUSEADDR, - (char*) &yes, - sizeof yes) == SOCKET_ERROR) { - err = WSAGetLastError(); - return err; - } - } - - if (addr->sa_family == AF_INET6) - handle->flags |= UV_HANDLE_IPV6; - - if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) { - /* On windows IPV6ONLY is on by default. */ - /* If the user doesn't specify it libuv turns it off. */ - - /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ - /* available, or when run on XP/2003 which have no support for dualstack */ - /* sockets. For now we're silently ignoring the error. */ - setsockopt(handle->socket, - IPPROTO_IPV6, - IPV6_V6ONLY, - (char*) &no, - sizeof no); - } - - r = bind(handle->socket, addr, addrlen); - if (r == SOCKET_ERROR) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_BOUND; - - return 0; -} - - -static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { - uv_req_t* req; - uv_buf_t buf; - DWORD bytes, flags; - int result; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - req = &handle->recv_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - /* - * Preallocate a read buffer if the number of active streams is below - * the threshold. - */ - if (loop->active_udp_streams < uv_active_udp_streams_threshold) { - handle->flags &= ~UV_HANDLE_ZERO_READ; - - handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer); - if (handle->recv_buffer.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0); - return; - } - assert(handle->recv_buffer.base != NULL); - - buf = handle->recv_buffer; - memset(&handle->recv_from, 0, sizeof handle->recv_from); - handle->recv_from_len = sizeof handle->recv_from; - flags = 0; - - result = handle->func_wsarecvfrom(handle->socket, - (WSABUF*) &buf, - 1, - &bytes, - &flags, - (struct sockaddr*) &handle->recv_from, - &handle->recv_from_len, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->u.io.overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - handle->reqs_pending++; - } - - } else { - handle->flags |= UV_HANDLE_ZERO_READ; - - buf.base = (char*) uv_zero_; - buf.len = 0; - flags = MSG_PEEK; - - result = handle->func_wsarecv(handle->socket, - (WSABUF*) &buf, - 1, - &bytes, - &flags, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->u.io.overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - handle->reqs_pending++; - } - } -} - - -int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (handle->flags & UV_HANDLE_READING) { - return WSAEALREADY; - } - - err = uv_udp_maybe_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return err; - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - loop->active_udp_streams++; - - handle->recv_cb = recv_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* recv request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) - uv_udp_queue_recv(loop, handle); - - return 0; -} - - -int uv__udp_recv_stop(uv_udp_t* handle) { - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - handle->loop->active_udp_streams--; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - return 0; -} - - -static int uv__send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb cb) { - uv_loop_t* loop = handle->loop; - DWORD result, bytes; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_UDP_SEND; - req->handle = handle; - req->cb = cb; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - result = WSASendTo(handle->socket, - (WSABUF*)bufs, - nbufs, - &bytes, - 0, - addr, - addrlen, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - handle->reqs_pending++; - handle->send_queue_size += req->u.io.queued_bytes; - handle->send_queue_count++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); - handle->reqs_pending++; - handle->send_queue_size += req->u.io.queued_bytes; - handle->send_queue_count++; - REGISTER_HANDLE_REQ(loop, handle, req); - } else { - /* Send failed due to an error. */ - return WSAGetLastError(); - } - - return 0; -} - - -void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, - uv_req_t* req) { - uv_buf_t buf; - int partial; - - assert(handle->type == UV_UDP); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!REQ_SUCCESS(req)) { - DWORD err = GET_REQ_SOCK_ERROR(req); - if (err == WSAEMSGSIZE) { - /* Not a real error, it just indicates that the received packet */ - /* was bigger than the receive buffer. */ - } else if (err == WSAECONNRESET || err == WSAENETRESET) { - /* A previous sendto operation failed; ignore this error. If */ - /* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */ - /* MSG_PEEK flag to clear out the error queue. For nonzero reads, */ - /* immediately queue a new receive. */ - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - goto done; - } - } else { - /* A real error occurred. Report the error to the user only if we're */ - /* currently reading. */ - if (handle->flags & UV_HANDLE_READING) { - uv_udp_recv_stop(handle); - buf = (handle->flags & UV_HANDLE_ZERO_READ) ? - uv_buf_init(NULL, 0) : handle->recv_buffer; - handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); - } - goto done; - } - } - - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - /* Successful read */ - partial = !REQ_SUCCESS(req); - handle->recv_cb(handle, - req->u.io.overlapped.InternalHigh, - &handle->recv_buffer, - (const struct sockaddr*) &handle->recv_from, - partial ? UV_UDP_PARTIAL : 0); - } else if (handle->flags & UV_HANDLE_READING) { - DWORD bytes, err, flags; - struct sockaddr_storage from; - int from_len; - - /* Do a nonblocking receive */ - /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */ - handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); - if (buf.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); - goto done; - } - assert(buf.base != NULL); - - memset(&from, 0, sizeof from); - from_len = sizeof from; - - flags = 0; - - if (WSARecvFrom(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - (struct sockaddr*) &from, - &from_len, - NULL, - NULL) != SOCKET_ERROR) { - - /* Message received */ - handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0); - } else { - err = WSAGetLastError(); - if (err == WSAEMSGSIZE) { - /* Message truncated */ - handle->recv_cb(handle, - bytes, - &buf, - (const struct sockaddr*) &from, - UV_UDP_PARTIAL); - } else if (err == WSAEWOULDBLOCK) { - /* Kernel buffer empty */ - handle->recv_cb(handle, 0, &buf, NULL, 0); - } else if (err == WSAECONNRESET || err == WSAENETRESET) { - /* WSAECONNRESET/WSANETRESET is ignored because this just indicates - * that a previous sendto operation failed. - */ - handle->recv_cb(handle, 0, &buf, NULL, 0); - } else { - /* Any other error that we want to report back to the user. */ - uv_udp_recv_stop(handle); - handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); - } - } - } - -done: - /* Post another read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_udp_queue_recv(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, - uv_udp_send_t* req) { - int err; - - assert(handle->type == UV_UDP); - - assert(handle->send_queue_size >= req->u.io.queued_bytes); - assert(handle->send_queue_count >= 1); - handle->send_queue_size -= req->u.io.queued_bytes; - handle->send_queue_count--; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = 0; - if (!REQ_SUCCESS(req)) { - err = GET_REQ_SOCK_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -static int uv__udp_set_membership4(uv_udp_t* handle, - const struct sockaddr_in* multicast_addr, - const char* interface_addr, - uv_membership membership) { - int err; - int optname; - struct ip_mreq mreq; - - if (handle->flags & UV_HANDLE_IPV6) - return UV_EINVAL; - - /* If the socket is unbound, bind to inaddr_any. */ - err = uv_udp_maybe_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - UV_UDP_REUSEADDR); - if (err) - return uv_translate_sys_error(err); - - memset(&mreq, 0, sizeof mreq); - - if (interface_addr) { - err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); - if (err) - return err; - } else { - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - } - - mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; - - switch (membership) { - case UV_JOIN_GROUP: - optname = IP_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IP_DROP_MEMBERSHIP; - break; - default: - return UV_EINVAL; - } - - if (setsockopt(handle->socket, - IPPROTO_IP, - optname, - (char*) &mreq, - sizeof mreq) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv__udp_set_membership6(uv_udp_t* handle, - const struct sockaddr_in6* multicast_addr, - const char* interface_addr, - uv_membership membership) { - int optname; - int err; - struct ipv6_mreq mreq; - struct sockaddr_in6 addr6; - - if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6)) - return UV_EINVAL; - - err = uv_udp_maybe_bind(handle, - (const struct sockaddr*) &uv_addr_ip6_any_, - sizeof(uv_addr_ip6_any_), - UV_UDP_REUSEADDR); - - if (err) - return uv_translate_sys_error(err); - - memset(&mreq, 0, sizeof(mreq)); - - if (interface_addr) { - if (uv_ip6_addr(interface_addr, 0, &addr6)) - return UV_EINVAL; - mreq.ipv6mr_interface = addr6.sin6_scope_id; - } else { - mreq.ipv6mr_interface = 0; - } - - mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr; - - switch (membership) { - case UV_JOIN_GROUP: - optname = IPV6_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IPV6_DROP_MEMBERSHIP; - break; - default: - return UV_EINVAL; - } - - if (setsockopt(handle->socket, - IPPROTO_IPV6, - optname, - (char*) &mreq, - sizeof mreq) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_udp_set_membership(uv_udp_t* handle, - const char* multicast_addr, - const char* interface_addr, - uv_membership membership) { - struct sockaddr_in addr4; - struct sockaddr_in6 addr6; - - if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) - return uv__udp_set_membership4(handle, &addr4, interface_addr, membership); - else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) - return uv__udp_set_membership6(handle, &addr6, interface_addr, membership); - else - return UV_EINVAL; -} - - -int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) { - struct sockaddr_storage addr_st; - struct sockaddr_in* addr4; - struct sockaddr_in6* addr6; - - addr4 = (struct sockaddr_in*) &addr_st; - addr6 = (struct sockaddr_in6*) &addr_st; - - if (!interface_addr) { - memset(&addr_st, 0, sizeof addr_st); - if (handle->flags & UV_HANDLE_IPV6) { - addr_st.ss_family = AF_INET6; - addr6->sin6_scope_id = 0; - } else { - addr_st.ss_family = AF_INET; - addr4->sin_addr.s_addr = htonl(INADDR_ANY); - } - } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) { - /* nothing, address was parsed */ - } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) { - /* nothing, address was parsed */ - } else { - return UV_EINVAL; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) - return UV_EBADF; - - if (addr_st.ss_family == AF_INET) { - if (setsockopt(handle->socket, - IPPROTO_IP, - IP_MULTICAST_IF, - (char*) &addr4->sin_addr, - sizeof(addr4->sin_addr)) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - } else if (addr_st.ss_family == AF_INET6) { - if (setsockopt(handle->socket, - IPPROTO_IPV6, - IPV6_MULTICAST_IF, - (char*) &addr6->sin6_scope_id, - sizeof(addr6->sin6_scope_id)) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - } else { - assert(0 && "unexpected address family"); - abort(); - } - - return 0; -} - - -int uv_udp_set_broadcast(uv_udp_t* handle, int value) { - BOOL optval = (BOOL) value; - - if (!(handle->flags & UV_HANDLE_BOUND)) - return UV_EBADF; - - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_BROADCAST, - (char*) &optval, - sizeof optval)) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - int err; - - /* Detect the address family of the socket. */ - opt_len = (int) sizeof protocol_info; - if (getsockopt(sock, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) { - return uv_translate_sys_error(GetLastError()); - } - - err = uv_udp_set_socket(handle->loop, - handle, - sock, - protocol_info.iAddressFamily); - return uv_translate_sys_error(err); -} - - -#define SOCKOPT_SETTER(name, option4, option6, validate) \ - int uv_udp_set_##name(uv_udp_t* handle, int value) { \ - DWORD optval = (DWORD) value; \ - \ - if (!(validate(value))) { \ - return UV_EINVAL; \ - } \ - \ - if (!(handle->flags & UV_HANDLE_BOUND)) \ - return UV_EBADF; \ - \ - if (!(handle->flags & UV_HANDLE_IPV6)) { \ - /* Set IPv4 socket option */ \ - if (setsockopt(handle->socket, \ - IPPROTO_IP, \ - option4, \ - (char*) &optval, \ - sizeof optval)) { \ - return uv_translate_sys_error(WSAGetLastError()); \ - } \ - } else { \ - /* Set IPv6 socket option */ \ - if (setsockopt(handle->socket, \ - IPPROTO_IPV6, \ - option6, \ - (char*) &optval, \ - sizeof optval)) { \ - return uv_translate_sys_error(WSAGetLastError()); \ - } \ - } \ - return 0; \ - } - -#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255) -#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255) -#define VALIDATE_MULTICAST_LOOP(value) (1) - -SOCKOPT_SETTER(ttl, - IP_TTL, - IPV6_HOPLIMIT, - VALIDATE_TTL) -SOCKOPT_SETTER(multicast_ttl, - IP_MULTICAST_TTL, - IPV6_MULTICAST_HOPS, - VALIDATE_MULTICAST_TTL) -SOCKOPT_SETTER(multicast_loop, - IP_MULTICAST_LOOP, - IPV6_MULTICAST_LOOP, - VALIDATE_MULTICAST_LOOP) - -#undef SOCKOPT_SETTER -#undef VALIDATE_TTL -#undef VALIDATE_MULTICAST_TTL -#undef VALIDATE_MULTICAST_LOOP - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - - err = uv_udp_maybe_bind(handle, addr, addrlen, flags); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb send_cb) { - const struct sockaddr* bind_addr; - int err; - - if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } - err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); - if (err) - return uv_translate_sys_error(err); - } - - err = uv__send(req, handle, bufs, nbufs, addr, addrlen, send_cb); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -int uv__udp_try_send(uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen) { - return UV_ENOSYS; -} diff --git a/outside/libuv-v1.7.5/src/win/util.c b/outside/libuv-v1.7.5/src/win/util.c deleted file mode 100644 index a0d1307f8a..0000000000 --- a/outside/libuv-v1.7.5/src/win/util.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "uv.h" -#include "internal.h" - -#include -#include -#include -#include -#include -#include -#include - - -/* - * Max title length; the only thing MSDN tells us about the maximum length - * of the console title is that it is smaller than 64K. However in practice - * it is much smaller, and there is no way to figure out what the exact length - * of the title is or can be, at least not on XP. To make it even more - * annoying, GetConsoleTitle fails when the buffer to be read into is bigger - * than the actual maximum length. So we make a conservative guess here; - * just don't put the novel you're writing in the title, unless the plot - * survives truncation. - */ -#define MAX_TITLE_LENGTH 8192 - -/* The number of nanoseconds in one second. */ -#define UV__NANOSEC 1000000000 - - -/* Cached copy of the process title, plus a mutex guarding it. */ -static char *process_title; -static CRITICAL_SECTION process_title_lock; - -/* Interval (in seconds) of the high-resolution clock. */ -static double hrtime_interval_ = 0; - - -/* - * One-time initialization code for functionality defined in util.c. - */ -void uv__util_init() { - LARGE_INTEGER perf_frequency; - - /* Initialize process title access mutex. */ - InitializeCriticalSection(&process_title_lock); - - /* Retrieve high-resolution timer frequency - * and precompute its reciprocal. - */ - if (QueryPerformanceFrequency(&perf_frequency)) { - hrtime_interval_ = 1.0 / perf_frequency.QuadPart; - } else { - hrtime_interval_= 0; - } -} - - -int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size, - char* utf8Buffer, size_t utf8Size) { - return WideCharToMultiByte(CP_UTF8, - 0, - utf16Buffer, - utf16Size, - utf8Buffer, - utf8Size, - NULL, - NULL); -} - - -int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer, - size_t utf16Size) { - return MultiByteToWideChar(CP_UTF8, - 0, - utf8Buffer, - -1, - utf16Buffer, - utf16Size); -} - - -int uv_exepath(char* buffer, size_t* size_ptr) { - int utf8_len, utf16_buffer_len, utf16_len; - WCHAR* utf16_buffer; - int err; - - if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) { - return UV_EINVAL; - } - - if (*size_ptr > 32768) { - /* Windows paths can never be longer than this. */ - utf16_buffer_len = 32768; - } else { - utf16_buffer_len = (int) *size_ptr; - } - - utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len); - if (!utf16_buffer) { - return UV_ENOMEM; - } - - /* Get the path as UTF-16. */ - utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len); - if (utf16_len <= 0) { - err = GetLastError(); - goto error; - } - - /* utf16_len contains the length, *not* including the terminating null. */ - utf16_buffer[utf16_len] = L'\0'; - - /* Convert to UTF-8 */ - utf8_len = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - buffer, - *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr, - NULL, - NULL); - if (utf8_len == 0) { - err = GetLastError(); - goto error; - } - - 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; - - error: - uv__free(utf16_buffer); - return uv_translate_sys_error(err); -} - - -int uv_cwd(char* buffer, size_t* size) { - DWORD utf16_len; - WCHAR utf16_buffer[MAX_PATH]; - int r; - - if (buffer == NULL || size == NULL) { - return UV_EINVAL; - } - - utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer); - if (utf16_len == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (utf16_len > MAX_PATH) { - /* This should be impossible; however the CRT has a code path to deal */ - /* with this scenario, so I added a check anyway. */ - return UV_EIO; - } - - /* utf16_len contains the length, *not* including the terminating null. */ - utf16_buffer[utf16_len] = L'\0'; - - /* The returned directory should not have a trailing slash, unless it */ - /* points at a drive root, like c:\. Remove it if needed.*/ - if (utf16_buffer[utf16_len - 1] == L'\\' && - !(utf16_len == 3 && utf16_buffer[1] == L':')) { - utf16_len--; - utf16_buffer[utf16_len] = L'\0'; - } - - /* Check how much space we need */ - r = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - NULL, - 0, - NULL, - NULL); - if (r == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (r > (int) *size) { - *size = r -1; - return UV_ENOBUFS; - } - - /* Convert to UTF-8 */ - r = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - buffer, - *size > INT_MAX ? INT_MAX : (int) *size, - NULL, - NULL); - if (r == 0) { - return uv_translate_sys_error(GetLastError()); - } - - *size = r - 1; - return 0; -} - - -int uv_chdir(const char* dir) { - WCHAR utf16_buffer[MAX_PATH]; - size_t utf16_len; - WCHAR drive_letter, env_var[4]; - - if (dir == NULL) { - return UV_EINVAL; - } - - if (MultiByteToWideChar(CP_UTF8, - 0, - dir, - -1, - utf16_buffer, - MAX_PATH) == 0) { - DWORD error = GetLastError(); - /* The maximum length of the current working directory is 260 chars, */ - /* including terminating null. If it doesn't fit, the path name must be */ - /* too long. */ - if (error == ERROR_INSUFFICIENT_BUFFER) { - return UV_ENAMETOOLONG; - } else { - return uv_translate_sys_error(error); - } - } - - if (!SetCurrentDirectoryW(utf16_buffer)) { - return uv_translate_sys_error(GetLastError()); - } - - /* Windows stores the drive-local path in an "hidden" environment variable, */ - /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */ - /* update this, so we'll have to do it. */ - utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer); - if (utf16_len == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (utf16_len > MAX_PATH) { - return UV_EIO; - } - - /* The returned directory should not have a trailing slash, unless it */ - /* points at a drive root, like c:\. Remove it if needed. */ - if (utf16_buffer[utf16_len - 1] == L'\\' && - !(utf16_len == 3 && utf16_buffer[1] == L':')) { - utf16_len--; - utf16_buffer[utf16_len] = L'\0'; - } - - if (utf16_len < 2 || utf16_buffer[1] != L':') { - /* Doesn't look like a drive letter could be there - probably an UNC */ - /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */ - drive_letter = 0; - } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') { - drive_letter = utf16_buffer[0]; - } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') { - /* Convert to uppercase. */ - drive_letter = utf16_buffer[0] - L'a' + L'A'; - } else { - /* Not valid. */ - drive_letter = 0; - } - - if (drive_letter != 0) { - /* Construct the environment variable name and set it. */ - env_var[0] = L'='; - env_var[1] = drive_letter; - env_var[2] = L':'; - env_var[3] = L'\0'; - - if (!SetEnvironmentVariableW(env_var, utf16_buffer)) { - return uv_translate_sys_error(GetLastError()); - } - } - - return 0; -} - - -void uv_loadavg(double avg[3]) { - /* Can't be implemented */ - avg[0] = avg[1] = avg[2] = 0; -} - - -uint64_t uv_get_free_memory(void) { - MEMORYSTATUSEX memory_status; - memory_status.dwLength = sizeof(memory_status); - - if (!GlobalMemoryStatusEx(&memory_status)) { - return -1; - } - - return (uint64_t)memory_status.ullAvailPhys; -} - - -uint64_t uv_get_total_memory(void) { - MEMORYSTATUSEX memory_status; - memory_status.dwLength = sizeof(memory_status); - - if (!GlobalMemoryStatusEx(&memory_status)) { - return -1; - } - - return (uint64_t)memory_status.ullTotalPhys; -} - - -int uv_parent_pid() { - int parent_pid = -1; - HANDLE handle; - PROCESSENTRY32 pe; - DWORD current_pid = GetCurrentProcessId(); - - pe.dwSize = sizeof(PROCESSENTRY32); - handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - - if (Process32First(handle, &pe)) { - do { - if (pe.th32ProcessID == current_pid) { - parent_pid = pe.th32ParentProcessID; - break; - } - } while( Process32Next(handle, &pe)); - } - - CloseHandle(handle); - return parent_pid; -} - - -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - int err; - int length; - WCHAR* title_w = NULL; - - uv__once_init(); - - /* Find out how big the buffer for the wide-char title must be */ - length = uv_utf8_to_utf16(title, 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 = uv_utf8_to_utf16(title, title_w, length); - if (!length) { - err = GetLastError(); - goto done; - } - - /* If the title must be truncated insert a \0 terminator there */ - if (length > MAX_TITLE_LENGTH) { - title_w[MAX_TITLE_LENGTH - 1] = L'\0'; - } - - if (!SetConsoleTitleW(title_w)) { - err = GetLastError(); - goto done; - } - - EnterCriticalSection(&process_title_lock); - uv__free(process_title); - process_title = uv__strdup(title); - LeaveCriticalSection(&process_title_lock); - - err = 0; - -done: - uv__free(title_w); - return uv_translate_sys_error(err); -} - - -static int uv__get_process_title() { - WCHAR title_w[MAX_TITLE_LENGTH]; - int length; - - if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { - return -1; - } - - /* Find out what the size of the buffer is that we need */ - length = uv_utf16_to_utf8(title_w, -1, NULL, 0); - if (!length) { - return -1; - } - - assert(!process_title); - process_title = (char*)uv__malloc(length); - if (!process_title) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - /* Do utf16 -> utf8 conversion here */ - if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) { - uv__free(process_title); - return -1; - } - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - uv__once_init(); - - EnterCriticalSection(&process_title_lock); - /* - * 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()); - } - - assert(process_title); - strncpy(buffer, process_title, size); - LeaveCriticalSection(&process_title_lock); - - return 0; -} - - -uint64_t uv_hrtime(void) { - uv__once_init(); - return uv__hrtime(UV__NANOSEC); -} - -uint64_t uv__hrtime(double scale) { - LARGE_INTEGER counter; - - /* If the performance interval is zero, there's no support. */ - if (hrtime_interval_ == 0) { - return 0; - } - - if (!QueryPerformanceCounter(&counter)) { - return 0; - } - - /* Because we have no guarantee about the order of magnitude of the - * performance counter interval, integer math could cause this computation - * to overflow. Therefore we resort to floating point math. - */ - return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale); -} - - -int uv_resident_set_memory(size_t* rss) { - HANDLE current_process; - PROCESS_MEMORY_COUNTERS pmc; - - current_process = GetCurrentProcess(); - - if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) { - return uv_translate_sys_error(GetLastError()); - } - - *rss = pmc.WorkingSetSize; - - return 0; -} - - -int uv_uptime(double* uptime) { - BYTE stack_buffer[4096]; - BYTE* malloced_buffer = NULL; - BYTE* buffer = (BYTE*) stack_buffer; - size_t buffer_size = sizeof(stack_buffer); - DWORD data_size; - - PERF_DATA_BLOCK* data_block; - PERF_OBJECT_TYPE* object_type; - PERF_COUNTER_DEFINITION* counter_definition; - - DWORD i; - - for (;;) { - LONG result; - - data_size = (DWORD) buffer_size; - result = RegQueryValueExW(HKEY_PERFORMANCE_DATA, - L"2", - NULL, - NULL, - buffer, - &data_size); - if (result == ERROR_SUCCESS) { - break; - } else if (result != ERROR_MORE_DATA) { - *uptime = 0; - return uv_translate_sys_error(result); - } - - buffer_size *= 2; - /* Don't let the buffer grow infinitely. */ - if (buffer_size > 1 << 20) { - goto internalError; - } - - uv__free(malloced_buffer); - - buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size); - if (malloced_buffer == NULL) { - *uptime = 0; - return UV_ENOMEM; - } - } - - if (data_size < sizeof(*data_block)) - goto internalError; - - data_block = (PERF_DATA_BLOCK*) buffer; - - if (wmemcmp(data_block->Signature, L"PERF", 4) != 0) - goto internalError; - - if (data_size < data_block->HeaderLength + sizeof(*object_type)) - goto internalError; - - object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength); - - if (object_type->NumInstances != PERF_NO_INSTANCES) - goto internalError; - - counter_definition = (PERF_COUNTER_DEFINITION*) (buffer + - data_block->HeaderLength + object_type->HeaderLength); - for (i = 0; i < object_type->NumCounters; i++) { - if ((BYTE*) counter_definition + sizeof(*counter_definition) > - buffer + data_size) { - break; - } - - if (counter_definition->CounterNameTitleIndex == 674 && - counter_definition->CounterSize == sizeof(uint64_t)) { - if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size || - !(counter_definition->CounterType & PERF_OBJECT_TIMER)) { - goto internalError; - } else { - BYTE* address = (BYTE*) object_type + object_type->DefinitionLength + - counter_definition->CounterOffset; - uint64_t value = *((uint64_t*) address); - *uptime = (double) (object_type->PerfTime.QuadPart - value) / - (double) object_type->PerfFreq.QuadPart; - uv__free(malloced_buffer); - return 0; - } - } - - counter_definition = (PERF_COUNTER_DEFINITION*) - ((BYTE*) counter_definition + counter_definition->ByteLength); - } - - /* If we get here, the uptime value was not found. */ - uv__free(malloced_buffer); - *uptime = 0; - return UV_ENOSYS; - - internalError: - uv__free(malloced_buffer); - *uptime = 0; - return UV_EIO; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { - uv_cpu_info_t* cpu_infos; - SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; - DWORD sppi_size; - SYSTEM_INFO system_info; - DWORD cpu_count, r, i; - NTSTATUS status; - ULONG result_size; - int err; - uv_cpu_info_t* cpu_info; - - cpu_infos = NULL; - cpu_count = 0; - sppi = NULL; - - uv__once_init(); - - GetSystemInfo(&system_info); - cpu_count = system_info.dwNumberOfProcessors; - - cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos); - if (cpu_infos == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - sppi_size = cpu_count * sizeof(*sppi); - sppi = uv__malloc(sppi_size); - if (sppi == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, - sppi, - sppi_size, - &result_size); - if (!NT_SUCCESS(status)) { - err = pRtlNtStatusToDosError(status); - goto error; - } - - assert(result_size == sppi_size); - - for (i = 0; i < cpu_count; i++) { - WCHAR key_name[128]; - HKEY processor_key; - DWORD cpu_speed; - DWORD cpu_speed_size = sizeof(cpu_speed); - WCHAR cpu_brand[256]; - DWORD cpu_brand_size = sizeof(cpu_brand); - size_t len; - - len = _snwprintf(key_name, - ARRAY_SIZE(key_name), - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", - i); - - assert(len > 0 && len < ARRAY_SIZE(key_name)); - - r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - key_name, - 0, - KEY_QUERY_VALUE, - &processor_key); - if (r != ERROR_SUCCESS) { - err = GetLastError(); - goto error; - } - - if (RegQueryValueExW(processor_key, - L"~MHz", - NULL, - NULL, - (BYTE*) &cpu_speed, - &cpu_speed_size) != ERROR_SUCCESS) { - err = GetLastError(); - RegCloseKey(processor_key); - goto error; - } - - if (RegQueryValueExW(processor_key, - L"ProcessorNameString", - NULL, - NULL, - (BYTE*) &cpu_brand, - &cpu_brand_size) != ERROR_SUCCESS) { - err = GetLastError(); - RegCloseKey(processor_key); - goto error; - } - - RegCloseKey(processor_key); - - cpu_info = &cpu_infos[i]; - cpu_info->speed = cpu_speed; - cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; - cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - - sppi[i].IdleTime.QuadPart) / 10000; - cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; - cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; - cpu_info->cpu_times.nice = 0; - - - len = WideCharToMultiByte(CP_UTF8, - 0, - cpu_brand, - cpu_brand_size / sizeof(WCHAR), - NULL, - 0, - NULL, - NULL); - if (len == 0) { - err = GetLastError(); - goto error; - } - - assert(len > 0); - - /* Allocate 1 extra byte for the null terminator. */ - cpu_info->model = uv__malloc(len + 1); - if (cpu_info->model == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - if (WideCharToMultiByte(CP_UTF8, - 0, - cpu_brand, - cpu_brand_size / sizeof(WCHAR), - cpu_info->model, - len, - NULL, - NULL) == 0) { - err = GetLastError(); - goto error; - } - - /* Ensure that cpu_info->model is null terminated. */ - cpu_info->model[len] = '\0'; - } - - uv__free(sppi); - - *cpu_count_ptr = cpu_count; - *cpu_infos_ptr = cpu_infos; - - return 0; - - error: - /* This is safe because the cpu_infos array is zeroed on allocation. */ - for (i = 0; i < cpu_count; i++) - uv__free(cpu_infos[i].model); - - uv__free(cpu_infos); - uv__free(sppi); - - return uv_translate_sys_error(err); -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -static int is_windows_version_or_greater(DWORD os_major, - DWORD os_minor, - WORD service_pack_major, - WORD service_pack_minor) { - OSVERSIONINFOEX osvi; - DWORDLONG condition_mask = 0; - int op = VER_GREATER_EQUAL; - - /* Initialize the OSVERSIONINFOEX structure. */ - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - osvi.dwMajorVersion = os_major; - osvi.dwMinorVersion = os_minor; - osvi.wServicePackMajor = service_pack_major; - osvi.wServicePackMinor = service_pack_minor; - - /* Initialize the condition mask. */ - VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, op); - VER_SET_CONDITION(condition_mask, VER_MINORVERSION, op); - VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, op); - VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, op); - - /* Perform the test. */ - return (int) VerifyVersionInfo( - &osvi, - VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - condition_mask); -} - - -static int address_prefix_match(int family, - struct sockaddr* address, - struct sockaddr* prefix_address, - int prefix_len) { - uint8_t* address_data; - uint8_t* prefix_address_data; - int i; - - assert(address->sa_family == family); - assert(prefix_address->sa_family == family); - - if (family == AF_INET6) { - address_data = (uint8_t*) &(((struct sockaddr_in6 *) address)->sin6_addr); - prefix_address_data = - (uint8_t*) &(((struct sockaddr_in6 *) prefix_address)->sin6_addr); - } else { - address_data = (uint8_t*) &(((struct sockaddr_in *) address)->sin_addr); - prefix_address_data = - (uint8_t*) &(((struct sockaddr_in *) prefix_address)->sin_addr); - } - - for (i = 0; i < prefix_len >> 3; i++) { - if (address_data[i] != prefix_address_data[i]) - return 0; - } - - if (prefix_len % 8) - return prefix_address_data[i] == - (address_data[i] & (0xff << (8 - prefix_len % 8))); - - return 1; -} - - -int uv_interface_addresses(uv_interface_address_t** addresses_ptr, - int* count_ptr) { - IP_ADAPTER_ADDRESSES* win_address_buf; - ULONG win_address_buf_size; - IP_ADAPTER_ADDRESSES* adapter; - - uv_interface_address_t* uv_address_buf; - char* name_buf; - size_t uv_address_buf_size; - uv_interface_address_t* uv_address; - - int count; - - int is_vista_or_greater; - ULONG flags; - - is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0); - if (is_vista_or_greater) { - flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER; - } else { - /* We need at least XP SP1. */ - if (!is_windows_version_or_greater(5, 1, 1, 0)) - return UV_ENOTSUP; - - flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX; - } - - - /* Fetch the size of the adapters reported by windows, and then get the */ - /* list itself. */ - win_address_buf_size = 0; - win_address_buf = NULL; - - for (;;) { - ULONG r; - - /* If win_address_buf is 0, then GetAdaptersAddresses will fail with */ - /* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */ - /* win_address_buf_size. */ - r = GetAdaptersAddresses(AF_UNSPEC, - flags, - NULL, - win_address_buf, - &win_address_buf_size); - - if (r == ERROR_SUCCESS) - break; - - uv__free(win_address_buf); - - switch (r) { - case ERROR_BUFFER_OVERFLOW: - /* This happens when win_address_buf is NULL or too small to hold */ - /* all adapters. */ - win_address_buf = uv__malloc(win_address_buf_size); - if (win_address_buf == NULL) - return UV_ENOMEM; - - continue; - - case ERROR_NO_DATA: { - /* No adapters were found. */ - uv_address_buf = uv__malloc(1); - if (uv_address_buf == NULL) - return UV_ENOMEM; - - *count_ptr = 0; - *addresses_ptr = uv_address_buf; - - return 0; - } - - case ERROR_ADDRESS_NOT_ASSOCIATED: - return UV_EAGAIN; - - case ERROR_INVALID_PARAMETER: - /* MSDN says: - * "This error is returned for any of the following conditions: the - * SizePointer parameter is NULL, the Address parameter is not - * AF_INET, AF_INET6, or AF_UNSPEC, or the address information for - * the parameters requested is greater than ULONG_MAX." - * Since the first two conditions are not met, it must be that the - * adapter data is too big. - */ - return UV_ENOBUFS; - - default: - /* Other (unspecified) errors can happen, but we don't have any */ - /* special meaning for them. */ - assert(r != ERROR_SUCCESS); - return uv_translate_sys_error(r); - } - } - - /* Count the number of enabled interfaces and compute how much space is */ - /* needed to store their info. */ - count = 0; - uv_address_buf_size = 0; - - for (adapter = win_address_buf; - adapter != NULL; - adapter = adapter->Next) { - IP_ADAPTER_UNICAST_ADDRESS* unicast_address; - int name_size; - - /* Interfaces that are not 'up' should not be reported. Also skip */ - /* interfaces that have no associated unicast address, as to avoid */ - /* allocating space for the name for this interface. */ - if (adapter->OperStatus != IfOperStatusUp || - adapter->FirstUnicastAddress == NULL) - 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; - - /* Count the number of addresses associated with this interface, and */ - /* compute the size. */ - for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) - adapter->FirstUnicastAddress; - unicast_address != NULL; - unicast_address = unicast_address->Next) { - count++; - uv_address_buf_size += sizeof(uv_interface_address_t); - } - } - - /* Allocate space to store interface data plus adapter names. */ - uv_address_buf = uv__malloc(uv_address_buf_size); - if (uv_address_buf == NULL) { - uv__free(win_address_buf); - return UV_ENOMEM; - } - - /* Compute the start of the uv_interface_address_t array, and the place in */ - /* the buffer where the interface names will be stored. */ - uv_address = uv_address_buf; - name_buf = (char*) (uv_address_buf + count); - - /* Fill out the output buffer. */ - for (adapter = win_address_buf; - adapter != NULL; - adapter = adapter->Next) { - IP_ADAPTER_UNICAST_ADDRESS* unicast_address; - int name_size; - size_t max_name_size; - - 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) { - uv__free(win_address_buf); - uv__free(uv_address_buf); - return uv_translate_sys_error(GetLastError()); - } - - /* Add an uv_interface_address_t element for every unicast address. */ - for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) - adapter->FirstUnicastAddress; - unicast_address != NULL; - unicast_address = unicast_address->Next) { - struct sockaddr* sa; - ULONG prefix_len; - - sa = unicast_address->Address.lpSockaddr; - - /* XP has no OnLinkPrefixLength field. */ - if (is_vista_or_greater) { - prefix_len = - ((IP_ADAPTER_UNICAST_ADDRESS_LH*) unicast_address)->OnLinkPrefixLength; - } else { - /* Prior to Windows Vista the FirstPrefix pointed to the list with - * single prefix for each IP address assigned to the adapter. - * Order of FirstPrefix does not match order of FirstUnicastAddress, - * so we need to find corresponding prefix. - */ - IP_ADAPTER_PREFIX* prefix; - prefix_len = 0; - - for (prefix = adapter->FirstPrefix; prefix; prefix = prefix->Next) { - /* We want the longest matching prefix. */ - if (prefix->Address.lpSockaddr->sa_family != sa->sa_family || - prefix->PrefixLength <= prefix_len) - continue; - - if (address_prefix_match(sa->sa_family, sa, - prefix->Address.lpSockaddr, prefix->PrefixLength)) { - prefix_len = prefix->PrefixLength; - } - } - - /* If there is no matching prefix information, return a single-host - * subnet mask (e.g. 255.255.255.255 for IPv4). - */ - if (!prefix_len) - prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32; - } - - memset(uv_address, 0, sizeof *uv_address); - - uv_address->name = name_buf; - - if (adapter->PhysicalAddressLength == sizeof(uv_address->phys_addr)) { - memcpy(uv_address->phys_addr, - adapter->PhysicalAddress, - sizeof(uv_address->phys_addr)); - } - - uv_address->is_internal = - (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK); - - if (sa->sa_family == AF_INET6) { - uv_address->address.address6 = *((struct sockaddr_in6 *) sa); - - uv_address->netmask.netmask6.sin6_family = AF_INET6; - memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3); - /* This check ensures that we don't write past the size of the data. */ - if (prefix_len % 8) { - uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] = - 0xff << (8 - prefix_len % 8); - } - - } else { - uv_address->address.address4 = *((struct sockaddr_in *) sa); - - uv_address->netmask.netmask4.sin_family = AF_INET; - uv_address->netmask.netmask4.sin_addr.s_addr = (prefix_len > 0) ? - htonl(0xffffffff << (32 - prefix_len)) : 0; - } - - uv_address++; - } - - name_buf += name_size; - } - - uv__free(win_address_buf); - - *addresses_ptr = uv_address_buf; - *count_ptr = count; - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - uv__free(addresses); -} - - -int uv_getrusage(uv_rusage_t *uv_rusage) { - FILETIME createTime, exitTime, kernelTime, userTime; - SYSTEMTIME kernelSystemTime, userSystemTime; - int ret; - - ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime); - if (ret == 0) { - return uv_translate_sys_error(GetLastError()); - } - - ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime); - if (ret == 0) { - return uv_translate_sys_error(GetLastError()); - } - - ret = FileTimeToSystemTime(&userTime, &userSystemTime); - if (ret == 0) { - return uv_translate_sys_error(GetLastError()); - } - - memset(uv_rusage, 0, sizeof(*uv_rusage)); - - uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 + - userSystemTime.wMinute * 60 + - userSystemTime.wSecond; - uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000; - - uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 + - kernelSystemTime.wMinute * 60 + - kernelSystemTime.wSecond; - uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000; - - return 0; -} - - -int uv_os_homedir(char* buffer, size_t* size) { - HANDLE token; - wchar_t path[MAX_PATH]; - DWORD bufsize; - size_t len; - int r; - - if (buffer == NULL || size == NULL || *size == 0) - return UV_EINVAL; - - /* Check if the USERPROFILE environment variable is set first */ - len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH); - - if (len == 0) { - r = GetLastError(); - /* Don't return an error if USERPROFILE was not found */ - if (r != ERROR_ENVVAR_NOT_FOUND) - return uv_translate_sys_error(r); - } else if (len > MAX_PATH) { - /* This should not be possible */ - return UV_EIO; - } else { - goto convert_buffer; - } - - /* USERPROFILE is not set, so call GetUserProfileDirectoryW() */ - if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0) - return uv_translate_sys_error(GetLastError()); - - bufsize = MAX_PATH; - if (!GetUserProfileDirectoryW(token, path, &bufsize)) { - r = GetLastError(); - CloseHandle(token); - - /* This should not be possible */ - if (r == ERROR_INSUFFICIENT_BUFFER) - return UV_EIO; - - return uv_translate_sys_error(r); - } - - CloseHandle(token); - -convert_buffer: - - /* Check how much space we need */ - bufsize = uv_utf16_to_utf8(path, -1, NULL, 0); - if (bufsize == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (bufsize > *size) { - *size = bufsize - 1; - return UV_ENOBUFS; - } - - /* Convert to UTF-8 */ - bufsize = uv_utf16_to_utf8(path, -1, buffer, *size); - if (bufsize == 0) - return uv_translate_sys_error(GetLastError()); - - *size = bufsize - 1; - return 0; -} diff --git a/outside/libuv-v1.7.5/src/win/winapi.c b/outside/libuv-v1.7.5/src/win/winapi.c deleted file mode 100644 index b0b7fd825f..0000000000 --- a/outside/libuv-v1.7.5/src/win/winapi.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "uv.h" -#include "internal.h" - - -/* Ntdll function pointers */ -sRtlNtStatusToDosError pRtlNtStatusToDosError; -sNtDeviceIoControlFile pNtDeviceIoControlFile; -sNtQueryInformationFile pNtQueryInformationFile; -sNtSetInformationFile pNtSetInformationFile; -sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; -sNtQueryDirectoryFile pNtQueryDirectoryFile; -sNtQuerySystemInformation pNtQuerySystemInformation; - - -/* Kernel32 function pointers */ -sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; -sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; -sCreateSymbolicLinkW pCreateSymbolicLinkW; -sCancelIoEx pCancelIoEx; -sInitializeConditionVariable pInitializeConditionVariable; -sSleepConditionVariableCS pSleepConditionVariableCS; -sSleepConditionVariableSRW pSleepConditionVariableSRW; -sWakeAllConditionVariable pWakeAllConditionVariable; -sWakeConditionVariable pWakeConditionVariable; -sCancelSynchronousIo pCancelSynchronousIo; - - -void uv_winapi_init() { - HMODULE ntdll_module; - HMODULE kernel32_module; - - ntdll_module = GetModuleHandleA("ntdll.dll"); - if (ntdll_module == NULL) { - uv_fatal_error(GetLastError(), "GetModuleHandleA"); - } - - pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress( - ntdll_module, - "RtlNtStatusToDosError"); - if (pRtlNtStatusToDosError == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress( - ntdll_module, - "NtDeviceIoControlFile"); - if (pNtDeviceIoControlFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress( - ntdll_module, - "NtQueryInformationFile"); - if (pNtQueryInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress( - ntdll_module, - "NtSetInformationFile"); - if (pNtSetInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile) - GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile"); - if (pNtQueryVolumeInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryDirectoryFile = (sNtQueryDirectoryFile) - GetProcAddress(ntdll_module, "NtQueryDirectoryFile"); - if (pNtQueryVolumeInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress( - ntdll_module, - "NtQuerySystemInformation"); - if (pNtQuerySystemInformation == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - kernel32_module = GetModuleHandleA("kernel32.dll"); - if (kernel32_module == NULL) { - uv_fatal_error(GetLastError(), "GetModuleHandleA"); - } - - pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress( - kernel32_module, - "GetQueuedCompletionStatusEx"); - - pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes) - GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes"); - - pCreateSymbolicLinkW = (sCreateSymbolicLinkW) - GetProcAddress(kernel32_module, "CreateSymbolicLinkW"); - - pCancelIoEx = (sCancelIoEx) - GetProcAddress(kernel32_module, "CancelIoEx"); - - pInitializeConditionVariable = (sInitializeConditionVariable) - GetProcAddress(kernel32_module, "InitializeConditionVariable"); - - pSleepConditionVariableCS = (sSleepConditionVariableCS) - GetProcAddress(kernel32_module, "SleepConditionVariableCS"); - - pSleepConditionVariableSRW = (sSleepConditionVariableSRW) - GetProcAddress(kernel32_module, "SleepConditionVariableSRW"); - - pWakeAllConditionVariable = (sWakeAllConditionVariable) - GetProcAddress(kernel32_module, "WakeAllConditionVariable"); - - pWakeConditionVariable = (sWakeConditionVariable) - GetProcAddress(kernel32_module, "WakeConditionVariable"); - - pCancelSynchronousIo = (sCancelSynchronousIo) - GetProcAddress(kernel32_module, "CancelSynchronousIo"); -} diff --git a/outside/libuv-v1.7.5/src/win/winapi.h b/outside/libuv-v1.7.5/src/win/winapi.h deleted file mode 100644 index 5bc79bcab2..0000000000 --- a/outside/libuv-v1.7.5/src/win/winapi.h +++ /dev/null @@ -1,4703 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_WINAPI_H_ -#define UV_WIN_WINAPI_H_ - -#include - - -/* - * Ntdll headers - */ -#ifndef STATUS_SEVERITY_SUCCESS -# define STATUS_SEVERITY_SUCCESS 0x0 -#endif - -#ifndef STATUS_SEVERITY_INFORMATIONAL -# define STATUS_SEVERITY_INFORMATIONAL 0x1 -#endif - -#ifndef STATUS_SEVERITY_WARNING -# define STATUS_SEVERITY_WARNING 0x2 -#endif - -#ifndef STATUS_SEVERITY_ERROR -# define STATUS_SEVERITY_ERROR 0x3 -#endif - -#ifndef FACILITY_NTWIN32 -# define FACILITY_NTWIN32 0x7 -#endif - -#ifndef NT_SUCCESS -# define NT_SUCCESS(status) (((NTSTATUS) (status)) >= 0) -#endif - -#ifndef NT_INFORMATION -# define NT_INFORMATION(status) ((((ULONG) (status)) >> 30) == 1) -#endif - -#ifndef NT_WARNING -# define NT_WARNING(status) ((((ULONG) (status)) >> 30) == 2) -#endif - -#ifndef NT_ERROR -# define NT_ERROR(status) ((((ULONG) (status)) >> 30) == 3) -#endif - -#ifndef STATUS_SUCCESS -# define STATUS_SUCCESS ((NTSTATUS) 0x00000000L) -#endif - -#ifndef STATUS_WAIT_0 -# define STATUS_WAIT_0 ((NTSTATUS) 0x00000000L) -#endif - -#ifndef STATUS_WAIT_1 -# define STATUS_WAIT_1 ((NTSTATUS) 0x00000001L) -#endif - -#ifndef STATUS_WAIT_2 -# define STATUS_WAIT_2 ((NTSTATUS) 0x00000002L) -#endif - -#ifndef STATUS_WAIT_3 -# define STATUS_WAIT_3 ((NTSTATUS) 0x00000003L) -#endif - -#ifndef STATUS_WAIT_63 -# define STATUS_WAIT_63 ((NTSTATUS) 0x0000003FL) -#endif - -#ifndef STATUS_ABANDONED -# define STATUS_ABANDONED ((NTSTATUS) 0x00000080L) -#endif - -#ifndef STATUS_ABANDONED_WAIT_0 -# define STATUS_ABANDONED_WAIT_0 ((NTSTATUS) 0x00000080L) -#endif - -#ifndef STATUS_ABANDONED_WAIT_63 -# define STATUS_ABANDONED_WAIT_63 ((NTSTATUS) 0x000000BFL) -#endif - -#ifndef STATUS_USER_APC -# define STATUS_USER_APC ((NTSTATUS) 0x000000C0L) -#endif - -#ifndef STATUS_KERNEL_APC -# define STATUS_KERNEL_APC ((NTSTATUS) 0x00000100L) -#endif - -#ifndef STATUS_ALERTED -# define STATUS_ALERTED ((NTSTATUS) 0x00000101L) -#endif - -#ifndef STATUS_TIMEOUT -# define STATUS_TIMEOUT ((NTSTATUS) 0x00000102L) -#endif - -#ifndef STATUS_PENDING -# define STATUS_PENDING ((NTSTATUS) 0x00000103L) -#endif - -#ifndef STATUS_REPARSE -# define STATUS_REPARSE ((NTSTATUS) 0x00000104L) -#endif - -#ifndef STATUS_MORE_ENTRIES -# define STATUS_MORE_ENTRIES ((NTSTATUS) 0x00000105L) -#endif - -#ifndef STATUS_NOT_ALL_ASSIGNED -# define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106L) -#endif - -#ifndef STATUS_SOME_NOT_MAPPED -# define STATUS_SOME_NOT_MAPPED ((NTSTATUS) 0x00000107L) -#endif - -#ifndef STATUS_OPLOCK_BREAK_IN_PROGRESS -# define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS) 0x00000108L) -#endif - -#ifndef STATUS_VOLUME_MOUNTED -# define STATUS_VOLUME_MOUNTED ((NTSTATUS) 0x00000109L) -#endif - -#ifndef STATUS_RXACT_COMMITTED -# define STATUS_RXACT_COMMITTED ((NTSTATUS) 0x0000010AL) -#endif - -#ifndef STATUS_NOTIFY_CLEANUP -# define STATUS_NOTIFY_CLEANUP ((NTSTATUS) 0x0000010BL) -#endif - -#ifndef STATUS_NOTIFY_ENUM_DIR -# define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS) 0x0000010CL) -#endif - -#ifndef STATUS_NO_QUOTAS_FOR_ACCOUNT -# define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS) 0x0000010DL) -#endif - -#ifndef STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED -# define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS) 0x0000010EL) -#endif - -#ifndef STATUS_PAGE_FAULT_TRANSITION -# define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS) 0x00000110L) -#endif - -#ifndef STATUS_PAGE_FAULT_DEMAND_ZERO -# define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS) 0x00000111L) -#endif - -#ifndef STATUS_PAGE_FAULT_COPY_ON_WRITE -# define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS) 0x00000112L) -#endif - -#ifndef STATUS_PAGE_FAULT_GUARD_PAGE -# define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS) 0x00000113L) -#endif - -#ifndef STATUS_PAGE_FAULT_PAGING_FILE -# define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS) 0x00000114L) -#endif - -#ifndef STATUS_CACHE_PAGE_LOCKED -# define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS) 0x00000115L) -#endif - -#ifndef STATUS_CRASH_DUMP -# define STATUS_CRASH_DUMP ((NTSTATUS) 0x00000116L) -#endif - -#ifndef STATUS_BUFFER_ALL_ZEROS -# define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS) 0x00000117L) -#endif - -#ifndef STATUS_REPARSE_OBJECT -# define STATUS_REPARSE_OBJECT ((NTSTATUS) 0x00000118L) -#endif - -#ifndef STATUS_RESOURCE_REQUIREMENTS_CHANGED -# define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS) 0x00000119L) -#endif - -#ifndef STATUS_TRANSLATION_COMPLETE -# define STATUS_TRANSLATION_COMPLETE ((NTSTATUS) 0x00000120L) -#endif - -#ifndef STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY -# define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS) 0x00000121L) -#endif - -#ifndef STATUS_NOTHING_TO_TERMINATE -# define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS) 0x00000122L) -#endif - -#ifndef STATUS_PROCESS_NOT_IN_JOB -# define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS) 0x00000123L) -#endif - -#ifndef STATUS_PROCESS_IN_JOB -# define STATUS_PROCESS_IN_JOB ((NTSTATUS) 0x00000124L) -#endif - -#ifndef STATUS_VOLSNAP_HIBERNATE_READY -# define STATUS_VOLSNAP_HIBERNATE_READY ((NTSTATUS) 0x00000125L) -#endif - -#ifndef STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY -# define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((NTSTATUS) 0x00000126L) -#endif - -#ifndef STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED -# define STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED ((NTSTATUS) 0x00000127L) -#endif - -#ifndef STATUS_INTERRUPT_STILL_CONNECTED -# define STATUS_INTERRUPT_STILL_CONNECTED ((NTSTATUS) 0x00000128L) -#endif - -#ifndef STATUS_PROCESS_CLONED -# define STATUS_PROCESS_CLONED ((NTSTATUS) 0x00000129L) -#endif - -#ifndef STATUS_FILE_LOCKED_WITH_ONLY_READERS -# define STATUS_FILE_LOCKED_WITH_ONLY_READERS ((NTSTATUS) 0x0000012AL) -#endif - -#ifndef STATUS_FILE_LOCKED_WITH_WRITERS -# define STATUS_FILE_LOCKED_WITH_WRITERS ((NTSTATUS) 0x0000012BL) -#endif - -#ifndef STATUS_RESOURCEMANAGER_READ_ONLY -# define STATUS_RESOURCEMANAGER_READ_ONLY ((NTSTATUS) 0x00000202L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_EMPTY -# define STATUS_RING_PREVIOUSLY_EMPTY ((NTSTATUS) 0x00000210L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_FULL -# define STATUS_RING_PREVIOUSLY_FULL ((NTSTATUS) 0x00000211L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_ABOVE_QUOTA -# define STATUS_RING_PREVIOUSLY_ABOVE_QUOTA ((NTSTATUS) 0x00000212L) -#endif - -#ifndef STATUS_RING_NEWLY_EMPTY -# define STATUS_RING_NEWLY_EMPTY ((NTSTATUS) 0x00000213L) -#endif - -#ifndef STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT -# define STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT ((NTSTATUS) 0x00000214L) -#endif - -#ifndef STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE -# define STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ((NTSTATUS) 0x00000215L) -#endif - -#ifndef STATUS_OPLOCK_HANDLE_CLOSED -# define STATUS_OPLOCK_HANDLE_CLOSED ((NTSTATUS) 0x00000216L) -#endif - -#ifndef STATUS_WAIT_FOR_OPLOCK -# define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS) 0x00000367L) -#endif - -#ifndef STATUS_OBJECT_NAME_EXISTS -# define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000L) -#endif - -#ifndef STATUS_THREAD_WAS_SUSPENDED -# define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS) 0x40000001L) -#endif - -#ifndef STATUS_WORKING_SET_LIMIT_RANGE -# define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS) 0x40000002L) -#endif - -#ifndef STATUS_IMAGE_NOT_AT_BASE -# define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS) 0x40000003L) -#endif - -#ifndef STATUS_RXACT_STATE_CREATED -# define STATUS_RXACT_STATE_CREATED ((NTSTATUS) 0x40000004L) -#endif - -#ifndef STATUS_SEGMENT_NOTIFICATION -# define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS) 0x40000005L) -#endif - -#ifndef STATUS_LOCAL_USER_SESSION_KEY -# define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS) 0x40000006L) -#endif - -#ifndef STATUS_BAD_CURRENT_DIRECTORY -# define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS) 0x40000007L) -#endif - -#ifndef STATUS_SERIAL_MORE_WRITES -# define STATUS_SERIAL_MORE_WRITES ((NTSTATUS) 0x40000008L) -#endif - -#ifndef STATUS_REGISTRY_RECOVERED -# define STATUS_REGISTRY_RECOVERED ((NTSTATUS) 0x40000009L) -#endif - -#ifndef STATUS_FT_READ_RECOVERY_FROM_BACKUP -# define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS) 0x4000000AL) -#endif - -#ifndef STATUS_FT_WRITE_RECOVERY -# define STATUS_FT_WRITE_RECOVERY ((NTSTATUS) 0x4000000BL) -#endif - -#ifndef STATUS_SERIAL_COUNTER_TIMEOUT -# define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS) 0x4000000CL) -#endif - -#ifndef STATUS_NULL_LM_PASSWORD -# define STATUS_NULL_LM_PASSWORD ((NTSTATUS) 0x4000000DL) -#endif - -#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH -# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS) 0x4000000EL) -#endif - -#ifndef STATUS_RECEIVE_PARTIAL -# define STATUS_RECEIVE_PARTIAL ((NTSTATUS) 0x4000000FL) -#endif - -#ifndef STATUS_RECEIVE_EXPEDITED -# define STATUS_RECEIVE_EXPEDITED ((NTSTATUS) 0x40000010L) -#endif - -#ifndef STATUS_RECEIVE_PARTIAL_EXPEDITED -# define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS) 0x40000011L) -#endif - -#ifndef STATUS_EVENT_DONE -# define STATUS_EVENT_DONE ((NTSTATUS) 0x40000012L) -#endif - -#ifndef STATUS_EVENT_PENDING -# define STATUS_EVENT_PENDING ((NTSTATUS) 0x40000013L) -#endif - -#ifndef STATUS_CHECKING_FILE_SYSTEM -# define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS) 0x40000014L) -#endif - -#ifndef STATUS_FATAL_APP_EXIT -# define STATUS_FATAL_APP_EXIT ((NTSTATUS) 0x40000015L) -#endif - -#ifndef STATUS_PREDEFINED_HANDLE -# define STATUS_PREDEFINED_HANDLE ((NTSTATUS) 0x40000016L) -#endif - -#ifndef STATUS_WAS_UNLOCKED -# define STATUS_WAS_UNLOCKED ((NTSTATUS) 0x40000017L) -#endif - -#ifndef STATUS_SERVICE_NOTIFICATION -# define STATUS_SERVICE_NOTIFICATION ((NTSTATUS) 0x40000018L) -#endif - -#ifndef STATUS_WAS_LOCKED -# define STATUS_WAS_LOCKED ((NTSTATUS) 0x40000019L) -#endif - -#ifndef STATUS_LOG_HARD_ERROR -# define STATUS_LOG_HARD_ERROR ((NTSTATUS) 0x4000001AL) -#endif - -#ifndef STATUS_ALREADY_WIN32 -# define STATUS_ALREADY_WIN32 ((NTSTATUS) 0x4000001BL) -#endif - -#ifndef STATUS_WX86_UNSIMULATE -# define STATUS_WX86_UNSIMULATE ((NTSTATUS) 0x4000001CL) -#endif - -#ifndef STATUS_WX86_CONTINUE -# define STATUS_WX86_CONTINUE ((NTSTATUS) 0x4000001DL) -#endif - -#ifndef STATUS_WX86_SINGLE_STEP -# define STATUS_WX86_SINGLE_STEP ((NTSTATUS) 0x4000001EL) -#endif - -#ifndef STATUS_WX86_BREAKPOINT -# define STATUS_WX86_BREAKPOINT ((NTSTATUS) 0x4000001FL) -#endif - -#ifndef STATUS_WX86_EXCEPTION_CONTINUE -# define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS) 0x40000020L) -#endif - -#ifndef STATUS_WX86_EXCEPTION_LASTCHANCE -# define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS) 0x40000021L) -#endif - -#ifndef STATUS_WX86_EXCEPTION_CHAIN -# define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS) 0x40000022L) -#endif - -#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE -# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS) 0x40000023L) -#endif - -#ifndef STATUS_NO_YIELD_PERFORMED -# define STATUS_NO_YIELD_PERFORMED ((NTSTATUS) 0x40000024L) -#endif - -#ifndef STATUS_TIMER_RESUME_IGNORED -# define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS) 0x40000025L) -#endif - -#ifndef STATUS_ARBITRATION_UNHANDLED -# define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS) 0x40000026L) -#endif - -#ifndef STATUS_CARDBUS_NOT_SUPPORTED -# define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS) 0x40000027L) -#endif - -#ifndef STATUS_WX86_CREATEWX86TIB -# define STATUS_WX86_CREATEWX86TIB ((NTSTATUS) 0x40000028L) -#endif - -#ifndef STATUS_MP_PROCESSOR_MISMATCH -# define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS) 0x40000029L) -#endif - -#ifndef STATUS_HIBERNATED -# define STATUS_HIBERNATED ((NTSTATUS) 0x4000002AL) -#endif - -#ifndef STATUS_RESUME_HIBERNATION -# define STATUS_RESUME_HIBERNATION ((NTSTATUS) 0x4000002BL) -#endif - -#ifndef STATUS_FIRMWARE_UPDATED -# define STATUS_FIRMWARE_UPDATED ((NTSTATUS) 0x4000002CL) -#endif - -#ifndef STATUS_DRIVERS_LEAKING_LOCKED_PAGES -# define STATUS_DRIVERS_LEAKING_LOCKED_PAGES ((NTSTATUS) 0x4000002DL) -#endif - -#ifndef STATUS_MESSAGE_RETRIEVED -# define STATUS_MESSAGE_RETRIEVED ((NTSTATUS) 0x4000002EL) -#endif - -#ifndef STATUS_SYSTEM_POWERSTATE_TRANSITION -# define STATUS_SYSTEM_POWERSTATE_TRANSITION ((NTSTATUS) 0x4000002FL) -#endif - -#ifndef STATUS_ALPC_CHECK_COMPLETION_LIST -# define STATUS_ALPC_CHECK_COMPLETION_LIST ((NTSTATUS) 0x40000030L) -#endif - -#ifndef STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION -# define STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION ((NTSTATUS) 0x40000031L) -#endif - -#ifndef STATUS_ACCESS_AUDIT_BY_POLICY -# define STATUS_ACCESS_AUDIT_BY_POLICY ((NTSTATUS) 0x40000032L) -#endif - -#ifndef STATUS_ABANDON_HIBERFILE -# define STATUS_ABANDON_HIBERFILE ((NTSTATUS) 0x40000033L) -#endif - -#ifndef STATUS_BIZRULES_NOT_ENABLED -# define STATUS_BIZRULES_NOT_ENABLED ((NTSTATUS) 0x40000034L) -#endif - -#ifndef STATUS_GUARD_PAGE_VIOLATION -# define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS) 0x80000001L) -#endif - -#ifndef STATUS_DATATYPE_MISALIGNMENT -# define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS) 0x80000002L) -#endif - -#ifndef STATUS_BREAKPOINT -# define STATUS_BREAKPOINT ((NTSTATUS) 0x80000003L) -#endif - -#ifndef STATUS_SINGLE_STEP -# define STATUS_SINGLE_STEP ((NTSTATUS) 0x80000004L) -#endif - -#ifndef STATUS_BUFFER_OVERFLOW -# define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005L) -#endif - -#ifndef STATUS_NO_MORE_FILES -# define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006L) -#endif - -#ifndef STATUS_WAKE_SYSTEM_DEBUGGER -# define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS) 0x80000007L) -#endif - -#ifndef STATUS_HANDLES_CLOSED -# define STATUS_HANDLES_CLOSED ((NTSTATUS) 0x8000000AL) -#endif - -#ifndef STATUS_NO_INHERITANCE -# define STATUS_NO_INHERITANCE ((NTSTATUS) 0x8000000BL) -#endif - -#ifndef STATUS_GUID_SUBSTITUTION_MADE -# define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS) 0x8000000CL) -#endif - -#ifndef STATUS_PARTIAL_COPY -# define STATUS_PARTIAL_COPY ((NTSTATUS) 0x8000000DL) -#endif - -#ifndef STATUS_DEVICE_PAPER_EMPTY -# define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS) 0x8000000EL) -#endif - -#ifndef STATUS_DEVICE_POWERED_OFF -# define STATUS_DEVICE_POWERED_OFF ((NTSTATUS) 0x8000000FL) -#endif - -#ifndef STATUS_DEVICE_OFF_LINE -# define STATUS_DEVICE_OFF_LINE ((NTSTATUS) 0x80000010L) -#endif - -#ifndef STATUS_DEVICE_BUSY -# define STATUS_DEVICE_BUSY ((NTSTATUS) 0x80000011L) -#endif - -#ifndef STATUS_NO_MORE_EAS -# define STATUS_NO_MORE_EAS ((NTSTATUS) 0x80000012L) -#endif - -#ifndef STATUS_INVALID_EA_NAME -# define STATUS_INVALID_EA_NAME ((NTSTATUS) 0x80000013L) -#endif - -#ifndef STATUS_EA_LIST_INCONSISTENT -# define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS) 0x80000014L) -#endif - -#ifndef STATUS_INVALID_EA_FLAG -# define STATUS_INVALID_EA_FLAG ((NTSTATUS) 0x80000015L) -#endif - -#ifndef STATUS_VERIFY_REQUIRED -# define STATUS_VERIFY_REQUIRED ((NTSTATUS) 0x80000016L) -#endif - -#ifndef STATUS_EXTRANEOUS_INFORMATION -# define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS) 0x80000017L) -#endif - -#ifndef STATUS_RXACT_COMMIT_NECESSARY -# define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS) 0x80000018L) -#endif - -#ifndef STATUS_NO_MORE_ENTRIES -# define STATUS_NO_MORE_ENTRIES ((NTSTATUS) 0x8000001AL) -#endif - -#ifndef STATUS_FILEMARK_DETECTED -# define STATUS_FILEMARK_DETECTED ((NTSTATUS) 0x8000001BL) -#endif - -#ifndef STATUS_MEDIA_CHANGED -# define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL) -#endif - -#ifndef STATUS_BUS_RESET -# define STATUS_BUS_RESET ((NTSTATUS) 0x8000001DL) -#endif - -#ifndef STATUS_END_OF_MEDIA -# define STATUS_END_OF_MEDIA ((NTSTATUS) 0x8000001EL) -#endif - -#ifndef STATUS_BEGINNING_OF_MEDIA -# define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS) 0x8000001FL) -#endif - -#ifndef STATUS_MEDIA_CHECK -# define STATUS_MEDIA_CHECK ((NTSTATUS) 0x80000020L) -#endif - -#ifndef STATUS_SETMARK_DETECTED -# define STATUS_SETMARK_DETECTED ((NTSTATUS) 0x80000021L) -#endif - -#ifndef STATUS_NO_DATA_DETECTED -# define STATUS_NO_DATA_DETECTED ((NTSTATUS) 0x80000022L) -#endif - -#ifndef STATUS_REDIRECTOR_HAS_OPEN_HANDLES -# define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000023L) -#endif - -#ifndef STATUS_SERVER_HAS_OPEN_HANDLES -# define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000024L) -#endif - -#ifndef STATUS_ALREADY_DISCONNECTED -# define STATUS_ALREADY_DISCONNECTED ((NTSTATUS) 0x80000025L) -#endif - -#ifndef STATUS_LONGJUMP -# define STATUS_LONGJUMP ((NTSTATUS) 0x80000026L) -#endif - -#ifndef STATUS_CLEANER_CARTRIDGE_INSTALLED -# define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS) 0x80000027L) -#endif - -#ifndef STATUS_PLUGPLAY_QUERY_VETOED -# define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS) 0x80000028L) -#endif - -#ifndef STATUS_UNWIND_CONSOLIDATE -# define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS) 0x80000029L) -#endif - -#ifndef STATUS_REGISTRY_HIVE_RECOVERED -# define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS) 0x8000002AL) -#endif - -#ifndef STATUS_DLL_MIGHT_BE_INSECURE -# define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS) 0x8000002BL) -#endif - -#ifndef STATUS_DLL_MIGHT_BE_INCOMPATIBLE -# define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS) 0x8000002CL) -#endif - -#ifndef STATUS_STOPPED_ON_SYMLINK -# define STATUS_STOPPED_ON_SYMLINK ((NTSTATUS) 0x8000002DL) -#endif - -#ifndef STATUS_CANNOT_GRANT_REQUESTED_OPLOCK -# define STATUS_CANNOT_GRANT_REQUESTED_OPLOCK ((NTSTATUS) 0x8000002EL) -#endif - -#ifndef STATUS_NO_ACE_CONDITION -# define STATUS_NO_ACE_CONDITION ((NTSTATUS) 0x8000002FL) -#endif - -#ifndef STATUS_UNSUCCESSFUL -# define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) -#endif - -#ifndef STATUS_NOT_IMPLEMENTED -# define STATUS_NOT_IMPLEMENTED ((NTSTATUS) 0xC0000002L) -#endif - -#ifndef STATUS_INVALID_INFO_CLASS -# define STATUS_INVALID_INFO_CLASS ((NTSTATUS) 0xC0000003L) -#endif - -#ifndef STATUS_INFO_LENGTH_MISMATCH -# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L) -#endif - -#ifndef STATUS_ACCESS_VIOLATION -# define STATUS_ACCESS_VIOLATION ((NTSTATUS) 0xC0000005L) -#endif - -#ifndef STATUS_IN_PAGE_ERROR -# define STATUS_IN_PAGE_ERROR ((NTSTATUS) 0xC0000006L) -#endif - -#ifndef STATUS_PAGEFILE_QUOTA -# define STATUS_PAGEFILE_QUOTA ((NTSTATUS) 0xC0000007L) -#endif - -#ifndef STATUS_INVALID_HANDLE -# define STATUS_INVALID_HANDLE ((NTSTATUS) 0xC0000008L) -#endif - -#ifndef STATUS_BAD_INITIAL_STACK -# define STATUS_BAD_INITIAL_STACK ((NTSTATUS) 0xC0000009L) -#endif - -#ifndef STATUS_BAD_INITIAL_PC -# define STATUS_BAD_INITIAL_PC ((NTSTATUS) 0xC000000AL) -#endif - -#ifndef STATUS_INVALID_CID -# define STATUS_INVALID_CID ((NTSTATUS) 0xC000000BL) -#endif - -#ifndef STATUS_TIMER_NOT_CANCELED -# define STATUS_TIMER_NOT_CANCELED ((NTSTATUS) 0xC000000CL) -#endif - -#ifndef STATUS_INVALID_PARAMETER -# define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL) -#endif - -#ifndef STATUS_NO_SUCH_DEVICE -# define STATUS_NO_SUCH_DEVICE ((NTSTATUS) 0xC000000EL) -#endif - -#ifndef STATUS_NO_SUCH_FILE -# define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xC000000FL) -#endif - -#ifndef STATUS_INVALID_DEVICE_REQUEST -# define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xC0000010L) -#endif - -#ifndef STATUS_END_OF_FILE -# define STATUS_END_OF_FILE ((NTSTATUS) 0xC0000011L) -#endif - -#ifndef STATUS_WRONG_VOLUME -# define STATUS_WRONG_VOLUME ((NTSTATUS) 0xC0000012L) -#endif - -#ifndef STATUS_NO_MEDIA_IN_DEVICE -# define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xC0000013L) -#endif - -#ifndef STATUS_UNRECOGNIZED_MEDIA -# define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS) 0xC0000014L) -#endif - -#ifndef STATUS_NONEXISTENT_SECTOR -# define STATUS_NONEXISTENT_SECTOR ((NTSTATUS) 0xC0000015L) -#endif - -#ifndef STATUS_MORE_PROCESSING_REQUIRED -# define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS) 0xC0000016L) -#endif - -#ifndef STATUS_NO_MEMORY -# define STATUS_NO_MEMORY ((NTSTATUS) 0xC0000017L) -#endif - -#ifndef STATUS_CONFLICTING_ADDRESSES -# define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS) 0xC0000018L) -#endif - -#ifndef STATUS_NOT_MAPPED_VIEW -# define STATUS_NOT_MAPPED_VIEW ((NTSTATUS) 0xC0000019L) -#endif - -#ifndef STATUS_UNABLE_TO_FREE_VM -# define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS) 0xC000001AL) -#endif - -#ifndef STATUS_UNABLE_TO_DELETE_SECTION -# define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS) 0xC000001BL) -#endif - -#ifndef STATUS_INVALID_SYSTEM_SERVICE -# define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS) 0xC000001CL) -#endif - -#ifndef STATUS_ILLEGAL_INSTRUCTION -# define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS) 0xC000001DL) -#endif - -#ifndef STATUS_INVALID_LOCK_SEQUENCE -# define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS) 0xC000001EL) -#endif - -#ifndef STATUS_INVALID_VIEW_SIZE -# define STATUS_INVALID_VIEW_SIZE ((NTSTATUS) 0xC000001FL) -#endif - -#ifndef STATUS_INVALID_FILE_FOR_SECTION -# define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS) 0xC0000020L) -#endif - -#ifndef STATUS_ALREADY_COMMITTED -# define STATUS_ALREADY_COMMITTED ((NTSTATUS) 0xC0000021L) -#endif - -#ifndef STATUS_ACCESS_DENIED -# define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L) -#endif - -#ifndef STATUS_BUFFER_TOO_SMALL -# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L) -#endif - -#ifndef STATUS_OBJECT_TYPE_MISMATCH -# define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS) 0xC0000024L) -#endif - -#ifndef STATUS_NONCONTINUABLE_EXCEPTION -# define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS) 0xC0000025L) -#endif - -#ifndef STATUS_INVALID_DISPOSITION -# define STATUS_INVALID_DISPOSITION ((NTSTATUS) 0xC0000026L) -#endif - -#ifndef STATUS_UNWIND -# define STATUS_UNWIND ((NTSTATUS) 0xC0000027L) -#endif - -#ifndef STATUS_BAD_STACK -# define STATUS_BAD_STACK ((NTSTATUS) 0xC0000028L) -#endif - -#ifndef STATUS_INVALID_UNWIND_TARGET -# define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS) 0xC0000029L) -#endif - -#ifndef STATUS_NOT_LOCKED -# define STATUS_NOT_LOCKED ((NTSTATUS) 0xC000002AL) -#endif - -#ifndef STATUS_PARITY_ERROR -# define STATUS_PARITY_ERROR ((NTSTATUS) 0xC000002BL) -#endif - -#ifndef STATUS_UNABLE_TO_DECOMMIT_VM -# define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS) 0xC000002CL) -#endif - -#ifndef STATUS_NOT_COMMITTED -# define STATUS_NOT_COMMITTED ((NTSTATUS) 0xC000002DL) -#endif - -#ifndef STATUS_INVALID_PORT_ATTRIBUTES -# define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS) 0xC000002EL) -#endif - -#ifndef STATUS_PORT_MESSAGE_TOO_LONG -# define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS) 0xC000002FL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_MIX -# define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS) 0xC0000030L) -#endif - -#ifndef STATUS_INVALID_QUOTA_LOWER -# define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS) 0xC0000031L) -#endif - -#ifndef STATUS_DISK_CORRUPT_ERROR -# define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L) -#endif - -#ifndef STATUS_OBJECT_NAME_INVALID -# define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xC0000033L) -#endif - -#ifndef STATUS_OBJECT_NAME_NOT_FOUND -# define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xC0000034L) -#endif - -#ifndef STATUS_OBJECT_NAME_COLLISION -# define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS) 0xC0000035L) -#endif - -#ifndef STATUS_PORT_DISCONNECTED -# define STATUS_PORT_DISCONNECTED ((NTSTATUS) 0xC0000037L) -#endif - -#ifndef STATUS_DEVICE_ALREADY_ATTACHED -# define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L) -#endif - -#ifndef STATUS_OBJECT_PATH_INVALID -# define STATUS_OBJECT_PATH_INVALID ((NTSTATUS) 0xC0000039L) -#endif - -#ifndef STATUS_OBJECT_PATH_NOT_FOUND -# define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xC000003AL) -#endif - -#ifndef STATUS_OBJECT_PATH_SYNTAX_BAD -# define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS) 0xC000003BL) -#endif - -#ifndef STATUS_DATA_OVERRUN -# define STATUS_DATA_OVERRUN ((NTSTATUS) 0xC000003CL) -#endif - -#ifndef STATUS_DATA_LATE_ERROR -# define STATUS_DATA_LATE_ERROR ((NTSTATUS) 0xC000003DL) -#endif - -#ifndef STATUS_DATA_ERROR -# define STATUS_DATA_ERROR ((NTSTATUS) 0xC000003EL) -#endif - -#ifndef STATUS_CRC_ERROR -# define STATUS_CRC_ERROR ((NTSTATUS) 0xC000003FL) -#endif - -#ifndef STATUS_SECTION_TOO_BIG -# define STATUS_SECTION_TOO_BIG ((NTSTATUS) 0xC0000040L) -#endif - -#ifndef STATUS_PORT_CONNECTION_REFUSED -# define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS) 0xC0000041L) -#endif - -#ifndef STATUS_INVALID_PORT_HANDLE -# define STATUS_INVALID_PORT_HANDLE ((NTSTATUS) 0xC0000042L) -#endif - -#ifndef STATUS_SHARING_VIOLATION -# define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xC0000043L) -#endif - -#ifndef STATUS_QUOTA_EXCEEDED -# define STATUS_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000044L) -#endif - -#ifndef STATUS_INVALID_PAGE_PROTECTION -# define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS) 0xC0000045L) -#endif - -#ifndef STATUS_MUTANT_NOT_OWNED -# define STATUS_MUTANT_NOT_OWNED ((NTSTATUS) 0xC0000046L) -#endif - -#ifndef STATUS_SEMAPHORE_LIMIT_EXCEEDED -# define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000047L) -#endif - -#ifndef STATUS_PORT_ALREADY_SET -# define STATUS_PORT_ALREADY_SET ((NTSTATUS) 0xC0000048L) -#endif - -#ifndef STATUS_SECTION_NOT_IMAGE -# define STATUS_SECTION_NOT_IMAGE ((NTSTATUS) 0xC0000049L) -#endif - -#ifndef STATUS_SUSPEND_COUNT_EXCEEDED -# define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS) 0xC000004AL) -#endif - -#ifndef STATUS_THREAD_IS_TERMINATING -# define STATUS_THREAD_IS_TERMINATING ((NTSTATUS) 0xC000004BL) -#endif - -#ifndef STATUS_BAD_WORKING_SET_LIMIT -# define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS) 0xC000004CL) -#endif - -#ifndef STATUS_INCOMPATIBLE_FILE_MAP -# define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS) 0xC000004DL) -#endif - -#ifndef STATUS_SECTION_PROTECTION -# define STATUS_SECTION_PROTECTION ((NTSTATUS) 0xC000004EL) -#endif - -#ifndef STATUS_EAS_NOT_SUPPORTED -# define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xC000004FL) -#endif - -#ifndef STATUS_EA_TOO_LARGE -# define STATUS_EA_TOO_LARGE ((NTSTATUS) 0xC0000050L) -#endif - -#ifndef STATUS_NONEXISTENT_EA_ENTRY -# define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS) 0xC0000051L) -#endif - -#ifndef STATUS_NO_EAS_ON_FILE -# define STATUS_NO_EAS_ON_FILE ((NTSTATUS) 0xC0000052L) -#endif - -#ifndef STATUS_EA_CORRUPT_ERROR -# define STATUS_EA_CORRUPT_ERROR ((NTSTATUS) 0xC0000053L) -#endif - -#ifndef STATUS_FILE_LOCK_CONFLICT -# define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS) 0xC0000054L) -#endif - -#ifndef STATUS_LOCK_NOT_GRANTED -# define STATUS_LOCK_NOT_GRANTED ((NTSTATUS) 0xC0000055L) -#endif - -#ifndef STATUS_DELETE_PENDING -# define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056L) -#endif - -#ifndef STATUS_CTL_FILE_NOT_SUPPORTED -# define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS) 0xC0000057L) -#endif - -#ifndef STATUS_UNKNOWN_REVISION -# define STATUS_UNKNOWN_REVISION ((NTSTATUS) 0xC0000058L) -#endif - -#ifndef STATUS_REVISION_MISMATCH -# define STATUS_REVISION_MISMATCH ((NTSTATUS) 0xC0000059L) -#endif - -#ifndef STATUS_INVALID_OWNER -# define STATUS_INVALID_OWNER ((NTSTATUS) 0xC000005AL) -#endif - -#ifndef STATUS_INVALID_PRIMARY_GROUP -# define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS) 0xC000005BL) -#endif - -#ifndef STATUS_NO_IMPERSONATION_TOKEN -# define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS) 0xC000005CL) -#endif - -#ifndef STATUS_CANT_DISABLE_MANDATORY -# define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS) 0xC000005DL) -#endif - -#ifndef STATUS_NO_LOGON_SERVERS -# define STATUS_NO_LOGON_SERVERS ((NTSTATUS) 0xC000005EL) -#endif - -#ifndef STATUS_NO_SUCH_LOGON_SESSION -# define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS) 0xC000005FL) -#endif - -#ifndef STATUS_NO_SUCH_PRIVILEGE -# define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS) 0xC0000060L) -#endif - -#ifndef STATUS_PRIVILEGE_NOT_HELD -# define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS) 0xC0000061L) -#endif - -#ifndef STATUS_INVALID_ACCOUNT_NAME -# define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS) 0xC0000062L) -#endif - -#ifndef STATUS_USER_EXISTS -# define STATUS_USER_EXISTS ((NTSTATUS) 0xC0000063L) -#endif - -#ifndef STATUS_NO_SUCH_USER -# define STATUS_NO_SUCH_USER ((NTSTATUS) 0xC0000064L) -#endif - -#ifndef STATUS_GROUP_EXISTS -# define STATUS_GROUP_EXISTS ((NTSTATUS) 0xC0000065L) -#endif - -#ifndef STATUS_NO_SUCH_GROUP -# define STATUS_NO_SUCH_GROUP ((NTSTATUS) 0xC0000066L) -#endif - -#ifndef STATUS_MEMBER_IN_GROUP -# define STATUS_MEMBER_IN_GROUP ((NTSTATUS) 0xC0000067L) -#endif - -#ifndef STATUS_MEMBER_NOT_IN_GROUP -# define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS) 0xC0000068L) -#endif - -#ifndef STATUS_LAST_ADMIN -# define STATUS_LAST_ADMIN ((NTSTATUS) 0xC0000069L) -#endif - -#ifndef STATUS_WRONG_PASSWORD -# define STATUS_WRONG_PASSWORD ((NTSTATUS) 0xC000006AL) -#endif - -#ifndef STATUS_ILL_FORMED_PASSWORD -# define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS) 0xC000006BL) -#endif - -#ifndef STATUS_PASSWORD_RESTRICTION -# define STATUS_PASSWORD_RESTRICTION ((NTSTATUS) 0xC000006CL) -#endif - -#ifndef STATUS_LOGON_FAILURE -# define STATUS_LOGON_FAILURE ((NTSTATUS) 0xC000006DL) -#endif - -#ifndef STATUS_ACCOUNT_RESTRICTION -# define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS) 0xC000006EL) -#endif - -#ifndef STATUS_INVALID_LOGON_HOURS -# define STATUS_INVALID_LOGON_HOURS ((NTSTATUS) 0xC000006FL) -#endif - -#ifndef STATUS_INVALID_WORKSTATION -# define STATUS_INVALID_WORKSTATION ((NTSTATUS) 0xC0000070L) -#endif - -#ifndef STATUS_PASSWORD_EXPIRED -# define STATUS_PASSWORD_EXPIRED ((NTSTATUS) 0xC0000071L) -#endif - -#ifndef STATUS_ACCOUNT_DISABLED -# define STATUS_ACCOUNT_DISABLED ((NTSTATUS) 0xC0000072L) -#endif - -#ifndef STATUS_NONE_MAPPED -# define STATUS_NONE_MAPPED ((NTSTATUS) 0xC0000073L) -#endif - -#ifndef STATUS_TOO_MANY_LUIDS_REQUESTED -# define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS) 0xC0000074L) -#endif - -#ifndef STATUS_LUIDS_EXHAUSTED -# define STATUS_LUIDS_EXHAUSTED ((NTSTATUS) 0xC0000075L) -#endif - -#ifndef STATUS_INVALID_SUB_AUTHORITY -# define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS) 0xC0000076L) -#endif - -#ifndef STATUS_INVALID_ACL -# define STATUS_INVALID_ACL ((NTSTATUS) 0xC0000077L) -#endif - -#ifndef STATUS_INVALID_SID -# define STATUS_INVALID_SID ((NTSTATUS) 0xC0000078L) -#endif - -#ifndef STATUS_INVALID_SECURITY_DESCR -# define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS) 0xC0000079L) -#endif - -#ifndef STATUS_PROCEDURE_NOT_FOUND -# define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS) 0xC000007AL) -#endif - -#ifndef STATUS_INVALID_IMAGE_FORMAT -# define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS) 0xC000007BL) -#endif - -#ifndef STATUS_NO_TOKEN -# define STATUS_NO_TOKEN ((NTSTATUS) 0xC000007CL) -#endif - -#ifndef STATUS_BAD_INHERITANCE_ACL -# define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS) 0xC000007DL) -#endif - -#ifndef STATUS_RANGE_NOT_LOCKED -# define STATUS_RANGE_NOT_LOCKED ((NTSTATUS) 0xC000007EL) -#endif - -#ifndef STATUS_DISK_FULL -# define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL) -#endif - -#ifndef STATUS_SERVER_DISABLED -# define STATUS_SERVER_DISABLED ((NTSTATUS) 0xC0000080L) -#endif - -#ifndef STATUS_SERVER_NOT_DISABLED -# define STATUS_SERVER_NOT_DISABLED ((NTSTATUS) 0xC0000081L) -#endif - -#ifndef STATUS_TOO_MANY_GUIDS_REQUESTED -# define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS) 0xC0000082L) -#endif - -#ifndef STATUS_GUIDS_EXHAUSTED -# define STATUS_GUIDS_EXHAUSTED ((NTSTATUS) 0xC0000083L) -#endif - -#ifndef STATUS_INVALID_ID_AUTHORITY -# define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS) 0xC0000084L) -#endif - -#ifndef STATUS_AGENTS_EXHAUSTED -# define STATUS_AGENTS_EXHAUSTED ((NTSTATUS) 0xC0000085L) -#endif - -#ifndef STATUS_INVALID_VOLUME_LABEL -# define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS) 0xC0000086L) -#endif - -#ifndef STATUS_SECTION_NOT_EXTENDED -# define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS) 0xC0000087L) -#endif - -#ifndef STATUS_NOT_MAPPED_DATA -# define STATUS_NOT_MAPPED_DATA ((NTSTATUS) 0xC0000088L) -#endif - -#ifndef STATUS_RESOURCE_DATA_NOT_FOUND -# define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS) 0xC0000089L) -#endif - -#ifndef STATUS_RESOURCE_TYPE_NOT_FOUND -# define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS) 0xC000008AL) -#endif - -#ifndef STATUS_RESOURCE_NAME_NOT_FOUND -# define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS) 0xC000008BL) -#endif - -#ifndef STATUS_ARRAY_BOUNDS_EXCEEDED -# define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS) 0xC000008CL) -#endif - -#ifndef STATUS_FLOAT_DENORMAL_OPERAND -# define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS) 0xC000008DL) -#endif - -#ifndef STATUS_FLOAT_DIVIDE_BY_ZERO -# define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS) 0xC000008EL) -#endif - -#ifndef STATUS_FLOAT_INEXACT_RESULT -# define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS) 0xC000008FL) -#endif - -#ifndef STATUS_FLOAT_INVALID_OPERATION -# define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS) 0xC0000090L) -#endif - -#ifndef STATUS_FLOAT_OVERFLOW -# define STATUS_FLOAT_OVERFLOW ((NTSTATUS) 0xC0000091L) -#endif - -#ifndef STATUS_FLOAT_STACK_CHECK -# define STATUS_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000092L) -#endif - -#ifndef STATUS_FLOAT_UNDERFLOW -# define STATUS_FLOAT_UNDERFLOW ((NTSTATUS) 0xC0000093L) -#endif - -#ifndef STATUS_INTEGER_DIVIDE_BY_ZERO -# define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS) 0xC0000094L) -#endif - -#ifndef STATUS_INTEGER_OVERFLOW -# define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L) -#endif - -#ifndef STATUS_PRIVILEGED_INSTRUCTION -# define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS) 0xC0000096L) -#endif - -#ifndef STATUS_TOO_MANY_PAGING_FILES -# define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS) 0xC0000097L) -#endif - -#ifndef STATUS_FILE_INVALID -# define STATUS_FILE_INVALID ((NTSTATUS) 0xC0000098L) -#endif - -#ifndef STATUS_ALLOTTED_SPACE_EXCEEDED -# define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS) 0xC0000099L) -#endif - -#ifndef STATUS_INSUFFICIENT_RESOURCES -# define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL) -#endif - -#ifndef STATUS_DFS_EXIT_PATH_FOUND -# define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS) 0xC000009BL) -#endif - -#ifndef STATUS_DEVICE_DATA_ERROR -# define STATUS_DEVICE_DATA_ERROR ((NTSTATUS) 0xC000009CL) -#endif - -#ifndef STATUS_DEVICE_NOT_CONNECTED -# define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS) 0xC000009DL) -#endif - -#ifndef STATUS_DEVICE_POWER_FAILURE -# define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS) 0xC000009EL) -#endif - -#ifndef STATUS_FREE_VM_NOT_AT_BASE -# define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS) 0xC000009FL) -#endif - -#ifndef STATUS_MEMORY_NOT_ALLOCATED -# define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS) 0xC00000A0L) -#endif - -#ifndef STATUS_WORKING_SET_QUOTA -# define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xC00000A1L) -#endif - -#ifndef STATUS_MEDIA_WRITE_PROTECTED -# define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L) -#endif - -#ifndef STATUS_DEVICE_NOT_READY -# define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L) -#endif - -#ifndef STATUS_INVALID_GROUP_ATTRIBUTES -# define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS) 0xC00000A4L) -#endif - -#ifndef STATUS_BAD_IMPERSONATION_LEVEL -# define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS) 0xC00000A5L) -#endif - -#ifndef STATUS_CANT_OPEN_ANONYMOUS -# define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS) 0xC00000A6L) -#endif - -#ifndef STATUS_BAD_VALIDATION_CLASS -# define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS) 0xC00000A7L) -#endif - -#ifndef STATUS_BAD_TOKEN_TYPE -# define STATUS_BAD_TOKEN_TYPE ((NTSTATUS) 0xC00000A8L) -#endif - -#ifndef STATUS_BAD_MASTER_BOOT_RECORD -# define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS) 0xC00000A9L) -#endif - -#ifndef STATUS_INSTRUCTION_MISALIGNMENT -# define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS) 0xC00000AAL) -#endif - -#ifndef STATUS_INSTANCE_NOT_AVAILABLE -# define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ABL) -#endif - -#ifndef STATUS_PIPE_NOT_AVAILABLE -# define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ACL) -#endif - -#ifndef STATUS_INVALID_PIPE_STATE -# define STATUS_INVALID_PIPE_STATE ((NTSTATUS) 0xC00000ADL) -#endif - -#ifndef STATUS_PIPE_BUSY -# define STATUS_PIPE_BUSY ((NTSTATUS) 0xC00000AEL) -#endif - -#ifndef STATUS_ILLEGAL_FUNCTION -# define STATUS_ILLEGAL_FUNCTION ((NTSTATUS) 0xC00000AFL) -#endif - -#ifndef STATUS_PIPE_DISCONNECTED -# define STATUS_PIPE_DISCONNECTED ((NTSTATUS) 0xC00000B0L) -#endif - -#ifndef STATUS_PIPE_CLOSING -# define STATUS_PIPE_CLOSING ((NTSTATUS) 0xC00000B1L) -#endif - -#ifndef STATUS_PIPE_CONNECTED -# define STATUS_PIPE_CONNECTED ((NTSTATUS) 0xC00000B2L) -#endif - -#ifndef STATUS_PIPE_LISTENING -# define STATUS_PIPE_LISTENING ((NTSTATUS) 0xC00000B3L) -#endif - -#ifndef STATUS_INVALID_READ_MODE -# define STATUS_INVALID_READ_MODE ((NTSTATUS) 0xC00000B4L) -#endif - -#ifndef STATUS_IO_TIMEOUT -# define STATUS_IO_TIMEOUT ((NTSTATUS) 0xC00000B5L) -#endif - -#ifndef STATUS_FILE_FORCED_CLOSED -# define STATUS_FILE_FORCED_CLOSED ((NTSTATUS) 0xC00000B6L) -#endif - -#ifndef STATUS_PROFILING_NOT_STARTED -# define STATUS_PROFILING_NOT_STARTED ((NTSTATUS) 0xC00000B7L) -#endif - -#ifndef STATUS_PROFILING_NOT_STOPPED -# define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS) 0xC00000B8L) -#endif - -#ifndef STATUS_COULD_NOT_INTERPRET -# define STATUS_COULD_NOT_INTERPRET ((NTSTATUS) 0xC00000B9L) -#endif - -#ifndef STATUS_FILE_IS_A_DIRECTORY -# define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS) 0xC00000BAL) -#endif - -#ifndef STATUS_NOT_SUPPORTED -# define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xC00000BBL) -#endif - -#ifndef STATUS_REMOTE_NOT_LISTENING -# define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS) 0xC00000BCL) -#endif - -#ifndef STATUS_DUPLICATE_NAME -# define STATUS_DUPLICATE_NAME ((NTSTATUS) 0xC00000BDL) -#endif - -#ifndef STATUS_BAD_NETWORK_PATH -# define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xC00000BEL) -#endif - -#ifndef STATUS_NETWORK_BUSY -# define STATUS_NETWORK_BUSY ((NTSTATUS) 0xC00000BFL) -#endif - -#ifndef STATUS_DEVICE_DOES_NOT_EXIST -# define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS) 0xC00000C0L) -#endif - -#ifndef STATUS_TOO_MANY_COMMANDS -# define STATUS_TOO_MANY_COMMANDS ((NTSTATUS) 0xC00000C1L) -#endif - -#ifndef STATUS_ADAPTER_HARDWARE_ERROR -# define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS) 0xC00000C2L) -#endif - -#ifndef STATUS_INVALID_NETWORK_RESPONSE -# define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xC00000C3L) -#endif - -#ifndef STATUS_UNEXPECTED_NETWORK_ERROR -# define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS) 0xC00000C4L) -#endif - -#ifndef STATUS_BAD_REMOTE_ADAPTER -# define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS) 0xC00000C5L) -#endif - -#ifndef STATUS_PRINT_QUEUE_FULL -# define STATUS_PRINT_QUEUE_FULL ((NTSTATUS) 0xC00000C6L) -#endif - -#ifndef STATUS_NO_SPOOL_SPACE -# define STATUS_NO_SPOOL_SPACE ((NTSTATUS) 0xC00000C7L) -#endif - -#ifndef STATUS_PRINT_CANCELLED -# define STATUS_PRINT_CANCELLED ((NTSTATUS) 0xC00000C8L) -#endif - -#ifndef STATUS_NETWORK_NAME_DELETED -# define STATUS_NETWORK_NAME_DELETED ((NTSTATUS) 0xC00000C9L) -#endif - -#ifndef STATUS_NETWORK_ACCESS_DENIED -# define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS) 0xC00000CAL) -#endif - -#ifndef STATUS_BAD_DEVICE_TYPE -# define STATUS_BAD_DEVICE_TYPE ((NTSTATUS) 0xC00000CBL) -#endif - -#ifndef STATUS_BAD_NETWORK_NAME -# define STATUS_BAD_NETWORK_NAME ((NTSTATUS) 0xC00000CCL) -#endif - -#ifndef STATUS_TOO_MANY_NAMES -# define STATUS_TOO_MANY_NAMES ((NTSTATUS) 0xC00000CDL) -#endif - -#ifndef STATUS_TOO_MANY_SESSIONS -# define STATUS_TOO_MANY_SESSIONS ((NTSTATUS) 0xC00000CEL) -#endif - -#ifndef STATUS_SHARING_PAUSED -# define STATUS_SHARING_PAUSED ((NTSTATUS) 0xC00000CFL) -#endif - -#ifndef STATUS_REQUEST_NOT_ACCEPTED -# define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS) 0xC00000D0L) -#endif - -#ifndef STATUS_REDIRECTOR_PAUSED -# define STATUS_REDIRECTOR_PAUSED ((NTSTATUS) 0xC00000D1L) -#endif - -#ifndef STATUS_NET_WRITE_FAULT -# define STATUS_NET_WRITE_FAULT ((NTSTATUS) 0xC00000D2L) -#endif - -#ifndef STATUS_PROFILING_AT_LIMIT -# define STATUS_PROFILING_AT_LIMIT ((NTSTATUS) 0xC00000D3L) -#endif - -#ifndef STATUS_NOT_SAME_DEVICE -# define STATUS_NOT_SAME_DEVICE ((NTSTATUS) 0xC00000D4L) -#endif - -#ifndef STATUS_FILE_RENAMED -# define STATUS_FILE_RENAMED ((NTSTATUS) 0xC00000D5L) -#endif - -#ifndef STATUS_VIRTUAL_CIRCUIT_CLOSED -# define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS) 0xC00000D6L) -#endif - -#ifndef STATUS_NO_SECURITY_ON_OBJECT -# define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS) 0xC00000D7L) -#endif - -#ifndef STATUS_CANT_WAIT -# define STATUS_CANT_WAIT ((NTSTATUS) 0xC00000D8L) -#endif - -#ifndef STATUS_PIPE_EMPTY -# define STATUS_PIPE_EMPTY ((NTSTATUS) 0xC00000D9L) -#endif - -#ifndef STATUS_CANT_ACCESS_DOMAIN_INFO -# define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS) 0xC00000DAL) -#endif - -#ifndef STATUS_CANT_TERMINATE_SELF -# define STATUS_CANT_TERMINATE_SELF ((NTSTATUS) 0xC00000DBL) -#endif - -#ifndef STATUS_INVALID_SERVER_STATE -# define STATUS_INVALID_SERVER_STATE ((NTSTATUS) 0xC00000DCL) -#endif - -#ifndef STATUS_INVALID_DOMAIN_STATE -# define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS) 0xC00000DDL) -#endif - -#ifndef STATUS_INVALID_DOMAIN_ROLE -# define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS) 0xC00000DEL) -#endif - -#ifndef STATUS_NO_SUCH_DOMAIN -# define STATUS_NO_SUCH_DOMAIN ((NTSTATUS) 0xC00000DFL) -#endif - -#ifndef STATUS_DOMAIN_EXISTS -# define STATUS_DOMAIN_EXISTS ((NTSTATUS) 0xC00000E0L) -#endif - -#ifndef STATUS_DOMAIN_LIMIT_EXCEEDED -# define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00000E1L) -#endif - -#ifndef STATUS_OPLOCK_NOT_GRANTED -# define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS) 0xC00000E2L) -#endif - -#ifndef STATUS_INVALID_OPLOCK_PROTOCOL -# define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS) 0xC00000E3L) -#endif - -#ifndef STATUS_INTERNAL_DB_CORRUPTION -# define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS) 0xC00000E4L) -#endif - -#ifndef STATUS_INTERNAL_ERROR -# define STATUS_INTERNAL_ERROR ((NTSTATUS) 0xC00000E5L) -#endif - -#ifndef STATUS_GENERIC_NOT_MAPPED -# define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS) 0xC00000E6L) -#endif - -#ifndef STATUS_BAD_DESCRIPTOR_FORMAT -# define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS) 0xC00000E7L) -#endif - -#ifndef STATUS_INVALID_USER_BUFFER -# define STATUS_INVALID_USER_BUFFER ((NTSTATUS) 0xC00000E8L) -#endif - -#ifndef STATUS_UNEXPECTED_IO_ERROR -# define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS) 0xC00000E9L) -#endif - -#ifndef STATUS_UNEXPECTED_MM_CREATE_ERR -# define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS) 0xC00000EAL) -#endif - -#ifndef STATUS_UNEXPECTED_MM_MAP_ERROR -# define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS) 0xC00000EBL) -#endif - -#ifndef STATUS_UNEXPECTED_MM_EXTEND_ERR -# define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS) 0xC00000ECL) -#endif - -#ifndef STATUS_NOT_LOGON_PROCESS -# define STATUS_NOT_LOGON_PROCESS ((NTSTATUS) 0xC00000EDL) -#endif - -#ifndef STATUS_LOGON_SESSION_EXISTS -# define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS) 0xC00000EEL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_1 -# define STATUS_INVALID_PARAMETER_1 ((NTSTATUS) 0xC00000EFL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_2 -# define STATUS_INVALID_PARAMETER_2 ((NTSTATUS) 0xC00000F0L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_3 -# define STATUS_INVALID_PARAMETER_3 ((NTSTATUS) 0xC00000F1L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_4 -# define STATUS_INVALID_PARAMETER_4 ((NTSTATUS) 0xC00000F2L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_5 -# define STATUS_INVALID_PARAMETER_5 ((NTSTATUS) 0xC00000F3L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_6 -# define STATUS_INVALID_PARAMETER_6 ((NTSTATUS) 0xC00000F4L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_7 -# define STATUS_INVALID_PARAMETER_7 ((NTSTATUS) 0xC00000F5L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_8 -# define STATUS_INVALID_PARAMETER_8 ((NTSTATUS) 0xC00000F6L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_9 -# define STATUS_INVALID_PARAMETER_9 ((NTSTATUS) 0xC00000F7L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_10 -# define STATUS_INVALID_PARAMETER_10 ((NTSTATUS) 0xC00000F8L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_11 -# define STATUS_INVALID_PARAMETER_11 ((NTSTATUS) 0xC00000F9L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_12 -# define STATUS_INVALID_PARAMETER_12 ((NTSTATUS) 0xC00000FAL) -#endif - -#ifndef STATUS_REDIRECTOR_NOT_STARTED -# define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS) 0xC00000FBL) -#endif - -#ifndef STATUS_REDIRECTOR_STARTED -# define STATUS_REDIRECTOR_STARTED ((NTSTATUS) 0xC00000FCL) -#endif - -#ifndef STATUS_STACK_OVERFLOW -# define STATUS_STACK_OVERFLOW ((NTSTATUS) 0xC00000FDL) -#endif - -#ifndef STATUS_NO_SUCH_PACKAGE -# define STATUS_NO_SUCH_PACKAGE ((NTSTATUS) 0xC00000FEL) -#endif - -#ifndef STATUS_BAD_FUNCTION_TABLE -# define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS) 0xC00000FFL) -#endif - -#ifndef STATUS_VARIABLE_NOT_FOUND -# define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS) 0xC0000100L) -#endif - -#ifndef STATUS_DIRECTORY_NOT_EMPTY -# define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xC0000101L) -#endif - -#ifndef STATUS_FILE_CORRUPT_ERROR -# define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS) 0xC0000102L) -#endif - -#ifndef STATUS_NOT_A_DIRECTORY -# define STATUS_NOT_A_DIRECTORY ((NTSTATUS) 0xC0000103L) -#endif - -#ifndef STATUS_BAD_LOGON_SESSION_STATE -# define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS) 0xC0000104L) -#endif - -#ifndef STATUS_LOGON_SESSION_COLLISION -# define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS) 0xC0000105L) -#endif - -#ifndef STATUS_NAME_TOO_LONG -# define STATUS_NAME_TOO_LONG ((NTSTATUS) 0xC0000106L) -#endif - -#ifndef STATUS_FILES_OPEN -# define STATUS_FILES_OPEN ((NTSTATUS) 0xC0000107L) -#endif - -#ifndef STATUS_CONNECTION_IN_USE -# define STATUS_CONNECTION_IN_USE ((NTSTATUS) 0xC0000108L) -#endif - -#ifndef STATUS_MESSAGE_NOT_FOUND -# define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS) 0xC0000109L) -#endif - -#ifndef STATUS_PROCESS_IS_TERMINATING -# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS) 0xC000010AL) -#endif - -#ifndef STATUS_INVALID_LOGON_TYPE -# define STATUS_INVALID_LOGON_TYPE ((NTSTATUS) 0xC000010BL) -#endif - -#ifndef STATUS_NO_GUID_TRANSLATION -# define STATUS_NO_GUID_TRANSLATION ((NTSTATUS) 0xC000010CL) -#endif - -#ifndef STATUS_CANNOT_IMPERSONATE -# define STATUS_CANNOT_IMPERSONATE ((NTSTATUS) 0xC000010DL) -#endif - -#ifndef STATUS_IMAGE_ALREADY_LOADED -# define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS) 0xC000010EL) -#endif - -#ifndef STATUS_ABIOS_NOT_PRESENT -# define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS) 0xC000010FL) -#endif - -#ifndef STATUS_ABIOS_LID_NOT_EXIST -# define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS) 0xC0000110L) -#endif - -#ifndef STATUS_ABIOS_LID_ALREADY_OWNED -# define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS) 0xC0000111L) -#endif - -#ifndef STATUS_ABIOS_NOT_LID_OWNER -# define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS) 0xC0000112L) -#endif - -#ifndef STATUS_ABIOS_INVALID_COMMAND -# define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS) 0xC0000113L) -#endif - -#ifndef STATUS_ABIOS_INVALID_LID -# define STATUS_ABIOS_INVALID_LID ((NTSTATUS) 0xC0000114L) -#endif - -#ifndef STATUS_ABIOS_SELECTOR_NOT_AVAILABLE -# define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS) 0xC0000115L) -#endif - -#ifndef STATUS_ABIOS_INVALID_SELECTOR -# define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS) 0xC0000116L) -#endif - -#ifndef STATUS_NO_LDT -# define STATUS_NO_LDT ((NTSTATUS) 0xC0000117L) -#endif - -#ifndef STATUS_INVALID_LDT_SIZE -# define STATUS_INVALID_LDT_SIZE ((NTSTATUS) 0xC0000118L) -#endif - -#ifndef STATUS_INVALID_LDT_OFFSET -# define STATUS_INVALID_LDT_OFFSET ((NTSTATUS) 0xC0000119L) -#endif - -#ifndef STATUS_INVALID_LDT_DESCRIPTOR -# define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS) 0xC000011AL) -#endif - -#ifndef STATUS_INVALID_IMAGE_NE_FORMAT -# define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS) 0xC000011BL) -#endif - -#ifndef STATUS_RXACT_INVALID_STATE -# define STATUS_RXACT_INVALID_STATE ((NTSTATUS) 0xC000011CL) -#endif - -#ifndef STATUS_RXACT_COMMIT_FAILURE -# define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS) 0xC000011DL) -#endif - -#ifndef STATUS_MAPPED_FILE_SIZE_ZERO -# define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS) 0xC000011EL) -#endif - -#ifndef STATUS_TOO_MANY_OPENED_FILES -# define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS) 0xC000011FL) -#endif - -#ifndef STATUS_CANCELLED -# define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L) -#endif - -#ifndef STATUS_CANNOT_DELETE -# define STATUS_CANNOT_DELETE ((NTSTATUS) 0xC0000121L) -#endif - -#ifndef STATUS_INVALID_COMPUTER_NAME -# define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS) 0xC0000122L) -#endif - -#ifndef STATUS_FILE_DELETED -# define STATUS_FILE_DELETED ((NTSTATUS) 0xC0000123L) -#endif - -#ifndef STATUS_SPECIAL_ACCOUNT -# define STATUS_SPECIAL_ACCOUNT ((NTSTATUS) 0xC0000124L) -#endif - -#ifndef STATUS_SPECIAL_GROUP -# define STATUS_SPECIAL_GROUP ((NTSTATUS) 0xC0000125L) -#endif - -#ifndef STATUS_SPECIAL_USER -# define STATUS_SPECIAL_USER ((NTSTATUS) 0xC0000126L) -#endif - -#ifndef STATUS_MEMBERS_PRIMARY_GROUP -# define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS) 0xC0000127L) -#endif - -#ifndef STATUS_FILE_CLOSED -# define STATUS_FILE_CLOSED ((NTSTATUS) 0xC0000128L) -#endif - -#ifndef STATUS_TOO_MANY_THREADS -# define STATUS_TOO_MANY_THREADS ((NTSTATUS) 0xC0000129L) -#endif - -#ifndef STATUS_THREAD_NOT_IN_PROCESS -# define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS) 0xC000012AL) -#endif - -#ifndef STATUS_TOKEN_ALREADY_IN_USE -# define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS) 0xC000012BL) -#endif - -#ifndef STATUS_PAGEFILE_QUOTA_EXCEEDED -# define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS) 0xC000012CL) -#endif - -#ifndef STATUS_COMMITMENT_LIMIT -# define STATUS_COMMITMENT_LIMIT ((NTSTATUS) 0xC000012DL) -#endif - -#ifndef STATUS_INVALID_IMAGE_LE_FORMAT -# define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS) 0xC000012EL) -#endif - -#ifndef STATUS_INVALID_IMAGE_NOT_MZ -# define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS) 0xC000012FL) -#endif - -#ifndef STATUS_INVALID_IMAGE_PROTECT -# define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS) 0xC0000130L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_16 -# define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS) 0xC0000131L) -#endif - -#ifndef STATUS_LOGON_SERVER_CONFLICT -# define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS) 0xC0000132L) -#endif - -#ifndef STATUS_TIME_DIFFERENCE_AT_DC -# define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS) 0xC0000133L) -#endif - -#ifndef STATUS_SYNCHRONIZATION_REQUIRED -# define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS) 0xC0000134L) -#endif - -#ifndef STATUS_DLL_NOT_FOUND -# define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135L) -#endif - -#ifndef STATUS_OPEN_FAILED -# define STATUS_OPEN_FAILED ((NTSTATUS) 0xC0000136L) -#endif - -#ifndef STATUS_IO_PRIVILEGE_FAILED -# define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS) 0xC0000137L) -#endif - -#ifndef STATUS_ORDINAL_NOT_FOUND -# define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000138L) -#endif - -#ifndef STATUS_ENTRYPOINT_NOT_FOUND -# define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139L) -#endif - -#ifndef STATUS_CONTROL_C_EXIT -# define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013AL) -#endif - -#ifndef STATUS_LOCAL_DISCONNECT -# define STATUS_LOCAL_DISCONNECT ((NTSTATUS) 0xC000013BL) -#endif - -#ifndef STATUS_REMOTE_DISCONNECT -# define STATUS_REMOTE_DISCONNECT ((NTSTATUS) 0xC000013CL) -#endif - -#ifndef STATUS_REMOTE_RESOURCES -# define STATUS_REMOTE_RESOURCES ((NTSTATUS) 0xC000013DL) -#endif - -#ifndef STATUS_LINK_FAILED -# define STATUS_LINK_FAILED ((NTSTATUS) 0xC000013EL) -#endif - -#ifndef STATUS_LINK_TIMEOUT -# define STATUS_LINK_TIMEOUT ((NTSTATUS) 0xC000013FL) -#endif - -#ifndef STATUS_INVALID_CONNECTION -# define STATUS_INVALID_CONNECTION ((NTSTATUS) 0xC0000140L) -#endif - -#ifndef STATUS_INVALID_ADDRESS -# define STATUS_INVALID_ADDRESS ((NTSTATUS) 0xC0000141L) -#endif - -#ifndef STATUS_DLL_INIT_FAILED -# define STATUS_DLL_INIT_FAILED ((NTSTATUS) 0xC0000142L) -#endif - -#ifndef STATUS_MISSING_SYSTEMFILE -# define STATUS_MISSING_SYSTEMFILE ((NTSTATUS) 0xC0000143L) -#endif - -#ifndef STATUS_UNHANDLED_EXCEPTION -# define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS) 0xC0000144L) -#endif - -#ifndef STATUS_APP_INIT_FAILURE -# define STATUS_APP_INIT_FAILURE ((NTSTATUS) 0xC0000145L) -#endif - -#ifndef STATUS_PAGEFILE_CREATE_FAILED -# define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS) 0xC0000146L) -#endif - -#ifndef STATUS_NO_PAGEFILE -# define STATUS_NO_PAGEFILE ((NTSTATUS) 0xC0000147L) -#endif - -#ifndef STATUS_INVALID_LEVEL -# define STATUS_INVALID_LEVEL ((NTSTATUS) 0xC0000148L) -#endif - -#ifndef STATUS_WRONG_PASSWORD_CORE -# define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS) 0xC0000149L) -#endif - -#ifndef STATUS_ILLEGAL_FLOAT_CONTEXT -# define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS) 0xC000014AL) -#endif - -#ifndef STATUS_PIPE_BROKEN -# define STATUS_PIPE_BROKEN ((NTSTATUS) 0xC000014BL) -#endif - -#ifndef STATUS_REGISTRY_CORRUPT -# define STATUS_REGISTRY_CORRUPT ((NTSTATUS) 0xC000014CL) -#endif - -#ifndef STATUS_REGISTRY_IO_FAILED -# define STATUS_REGISTRY_IO_FAILED ((NTSTATUS) 0xC000014DL) -#endif - -#ifndef STATUS_NO_EVENT_PAIR -# define STATUS_NO_EVENT_PAIR ((NTSTATUS) 0xC000014EL) -#endif - -#ifndef STATUS_UNRECOGNIZED_VOLUME -# define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS) 0xC000014FL) -#endif - -#ifndef STATUS_SERIAL_NO_DEVICE_INITED -# define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS) 0xC0000150L) -#endif - -#ifndef STATUS_NO_SUCH_ALIAS -# define STATUS_NO_SUCH_ALIAS ((NTSTATUS) 0xC0000151L) -#endif - -#ifndef STATUS_MEMBER_NOT_IN_ALIAS -# define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS) 0xC0000152L) -#endif - -#ifndef STATUS_MEMBER_IN_ALIAS -# define STATUS_MEMBER_IN_ALIAS ((NTSTATUS) 0xC0000153L) -#endif - -#ifndef STATUS_ALIAS_EXISTS -# define STATUS_ALIAS_EXISTS ((NTSTATUS) 0xC0000154L) -#endif - -#ifndef STATUS_LOGON_NOT_GRANTED -# define STATUS_LOGON_NOT_GRANTED ((NTSTATUS) 0xC0000155L) -#endif - -#ifndef STATUS_TOO_MANY_SECRETS -# define STATUS_TOO_MANY_SECRETS ((NTSTATUS) 0xC0000156L) -#endif - -#ifndef STATUS_SECRET_TOO_LONG -# define STATUS_SECRET_TOO_LONG ((NTSTATUS) 0xC0000157L) -#endif - -#ifndef STATUS_INTERNAL_DB_ERROR -# define STATUS_INTERNAL_DB_ERROR ((NTSTATUS) 0xC0000158L) -#endif - -#ifndef STATUS_FULLSCREEN_MODE -# define STATUS_FULLSCREEN_MODE ((NTSTATUS) 0xC0000159L) -#endif - -#ifndef STATUS_TOO_MANY_CONTEXT_IDS -# define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS) 0xC000015AL) -#endif - -#ifndef STATUS_LOGON_TYPE_NOT_GRANTED -# define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS) 0xC000015BL) -#endif - -#ifndef STATUS_NOT_REGISTRY_FILE -# define STATUS_NOT_REGISTRY_FILE ((NTSTATUS) 0xC000015CL) -#endif - -#ifndef STATUS_NT_CROSS_ENCRYPTION_REQUIRED -# define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000015DL) -#endif - -#ifndef STATUS_DOMAIN_CTRLR_CONFIG_ERROR -# define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS) 0xC000015EL) -#endif - -#ifndef STATUS_FT_MISSING_MEMBER -# define STATUS_FT_MISSING_MEMBER ((NTSTATUS) 0xC000015FL) -#endif - -#ifndef STATUS_ILL_FORMED_SERVICE_ENTRY -# define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS) 0xC0000160L) -#endif - -#ifndef STATUS_ILLEGAL_CHARACTER -# define STATUS_ILLEGAL_CHARACTER ((NTSTATUS) 0xC0000161L) -#endif - -#ifndef STATUS_UNMAPPABLE_CHARACTER -# define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS) 0xC0000162L) -#endif - -#ifndef STATUS_UNDEFINED_CHARACTER -# define STATUS_UNDEFINED_CHARACTER ((NTSTATUS) 0xC0000163L) -#endif - -#ifndef STATUS_FLOPPY_VOLUME -# define STATUS_FLOPPY_VOLUME ((NTSTATUS) 0xC0000164L) -#endif - -#ifndef STATUS_FLOPPY_ID_MARK_NOT_FOUND -# define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS) 0xC0000165L) -#endif - -#ifndef STATUS_FLOPPY_WRONG_CYLINDER -# define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS) 0xC0000166L) -#endif - -#ifndef STATUS_FLOPPY_UNKNOWN_ERROR -# define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS) 0xC0000167L) -#endif - -#ifndef STATUS_FLOPPY_BAD_REGISTERS -# define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS) 0xC0000168L) -#endif - -#ifndef STATUS_DISK_RECALIBRATE_FAILED -# define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS) 0xC0000169L) -#endif - -#ifndef STATUS_DISK_OPERATION_FAILED -# define STATUS_DISK_OPERATION_FAILED ((NTSTATUS) 0xC000016AL) -#endif - -#ifndef STATUS_DISK_RESET_FAILED -# define STATUS_DISK_RESET_FAILED ((NTSTATUS) 0xC000016BL) -#endif - -#ifndef STATUS_SHARED_IRQ_BUSY -# define STATUS_SHARED_IRQ_BUSY ((NTSTATUS) 0xC000016CL) -#endif - -#ifndef STATUS_FT_ORPHANING -# define STATUS_FT_ORPHANING ((NTSTATUS) 0xC000016DL) -#endif - -#ifndef STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT -# define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS) 0xC000016EL) -#endif - -#ifndef STATUS_PARTITION_FAILURE -# define STATUS_PARTITION_FAILURE ((NTSTATUS) 0xC0000172L) -#endif - -#ifndef STATUS_INVALID_BLOCK_LENGTH -# define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS) 0xC0000173L) -#endif - -#ifndef STATUS_DEVICE_NOT_PARTITIONED -# define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS) 0xC0000174L) -#endif - -#ifndef STATUS_UNABLE_TO_LOCK_MEDIA -# define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS) 0xC0000175L) -#endif - -#ifndef STATUS_UNABLE_TO_UNLOAD_MEDIA -# define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS) 0xC0000176L) -#endif - -#ifndef STATUS_EOM_OVERFLOW -# define STATUS_EOM_OVERFLOW ((NTSTATUS) 0xC0000177L) -#endif - -#ifndef STATUS_NO_MEDIA -# define STATUS_NO_MEDIA ((NTSTATUS) 0xC0000178L) -#endif - -#ifndef STATUS_NO_SUCH_MEMBER -# define STATUS_NO_SUCH_MEMBER ((NTSTATUS) 0xC000017AL) -#endif - -#ifndef STATUS_INVALID_MEMBER -# define STATUS_INVALID_MEMBER ((NTSTATUS) 0xC000017BL) -#endif - -#ifndef STATUS_KEY_DELETED -# define STATUS_KEY_DELETED ((NTSTATUS) 0xC000017CL) -#endif - -#ifndef STATUS_NO_LOG_SPACE -# define STATUS_NO_LOG_SPACE ((NTSTATUS) 0xC000017DL) -#endif - -#ifndef STATUS_TOO_MANY_SIDS -# define STATUS_TOO_MANY_SIDS ((NTSTATUS) 0xC000017EL) -#endif - -#ifndef STATUS_LM_CROSS_ENCRYPTION_REQUIRED -# define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000017FL) -#endif - -#ifndef STATUS_KEY_HAS_CHILDREN -# define STATUS_KEY_HAS_CHILDREN ((NTSTATUS) 0xC0000180L) -#endif - -#ifndef STATUS_CHILD_MUST_BE_VOLATILE -# define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS) 0xC0000181L) -#endif - -#ifndef STATUS_DEVICE_CONFIGURATION_ERROR -# define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS) 0xC0000182L) -#endif - -#ifndef STATUS_DRIVER_INTERNAL_ERROR -# define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS) 0xC0000183L) -#endif - -#ifndef STATUS_INVALID_DEVICE_STATE -# define STATUS_INVALID_DEVICE_STATE ((NTSTATUS) 0xC0000184L) -#endif - -#ifndef STATUS_IO_DEVICE_ERROR -# define STATUS_IO_DEVICE_ERROR ((NTSTATUS) 0xC0000185L) -#endif - -#ifndef STATUS_DEVICE_PROTOCOL_ERROR -# define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS) 0xC0000186L) -#endif - -#ifndef STATUS_BACKUP_CONTROLLER -# define STATUS_BACKUP_CONTROLLER ((NTSTATUS) 0xC0000187L) -#endif - -#ifndef STATUS_LOG_FILE_FULL -# define STATUS_LOG_FILE_FULL ((NTSTATUS) 0xC0000188L) -#endif - -#ifndef STATUS_TOO_LATE -# define STATUS_TOO_LATE ((NTSTATUS) 0xC0000189L) -#endif - -#ifndef STATUS_NO_TRUST_LSA_SECRET -# define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS) 0xC000018AL) -#endif - -#ifndef STATUS_NO_TRUST_SAM_ACCOUNT -# define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS) 0xC000018BL) -#endif - -#ifndef STATUS_TRUSTED_DOMAIN_FAILURE -# define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS) 0xC000018CL) -#endif - -#ifndef STATUS_TRUSTED_RELATIONSHIP_FAILURE -# define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS) 0xC000018DL) -#endif - -#ifndef STATUS_EVENTLOG_FILE_CORRUPT -# define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS) 0xC000018EL) -#endif - -#ifndef STATUS_EVENTLOG_CANT_START -# define STATUS_EVENTLOG_CANT_START ((NTSTATUS) 0xC000018FL) -#endif - -#ifndef STATUS_TRUST_FAILURE -# define STATUS_TRUST_FAILURE ((NTSTATUS) 0xC0000190L) -#endif - -#ifndef STATUS_MUTANT_LIMIT_EXCEEDED -# define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000191L) -#endif - -#ifndef STATUS_NETLOGON_NOT_STARTED -# define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS) 0xC0000192L) -#endif - -#ifndef STATUS_ACCOUNT_EXPIRED -# define STATUS_ACCOUNT_EXPIRED ((NTSTATUS) 0xC0000193L) -#endif - -#ifndef STATUS_POSSIBLE_DEADLOCK -# define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS) 0xC0000194L) -#endif - -#ifndef STATUS_NETWORK_CREDENTIAL_CONFLICT -# define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS) 0xC0000195L) -#endif - -#ifndef STATUS_REMOTE_SESSION_LIMIT -# define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS) 0xC0000196L) -#endif - -#ifndef STATUS_EVENTLOG_FILE_CHANGED -# define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS) 0xC0000197L) -#endif - -#ifndef STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT -# define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS) 0xC0000198L) -#endif - -#ifndef STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT -# define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS) 0xC0000199L) -#endif - -#ifndef STATUS_NOLOGON_SERVER_TRUST_ACCOUNT -# define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS) 0xC000019AL) -#endif - -#ifndef STATUS_DOMAIN_TRUST_INCONSISTENT -# define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS) 0xC000019BL) -#endif - -#ifndef STATUS_FS_DRIVER_REQUIRED -# define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS) 0xC000019CL) -#endif - -#ifndef STATUS_IMAGE_ALREADY_LOADED_AS_DLL -# define STATUS_IMAGE_ALREADY_LOADED_AS_DLL ((NTSTATUS) 0xC000019DL) -#endif - -#ifndef STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING -# define STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING ((NTSTATUS) 0xC000019EL) -#endif - -#ifndef STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME -# define STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME ((NTSTATUS) 0xC000019FL) -#endif - -#ifndef STATUS_SECURITY_STREAM_IS_INCONSISTENT -# define STATUS_SECURITY_STREAM_IS_INCONSISTENT ((NTSTATUS) 0xC00001A0L) -#endif - -#ifndef STATUS_INVALID_LOCK_RANGE -# define STATUS_INVALID_LOCK_RANGE ((NTSTATUS) 0xC00001A1L) -#endif - -#ifndef STATUS_INVALID_ACE_CONDITION -# define STATUS_INVALID_ACE_CONDITION ((NTSTATUS) 0xC00001A2L) -#endif - -#ifndef STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT -# define STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT ((NTSTATUS) 0xC00001A3L) -#endif - -#ifndef STATUS_NOTIFICATION_GUID_ALREADY_DEFINED -# define STATUS_NOTIFICATION_GUID_ALREADY_DEFINED ((NTSTATUS) 0xC00001A4L) -#endif - -#ifndef STATUS_NETWORK_OPEN_RESTRICTION -# define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS) 0xC0000201L) -#endif - -#ifndef STATUS_NO_USER_SESSION_KEY -# define STATUS_NO_USER_SESSION_KEY ((NTSTATUS) 0xC0000202L) -#endif - -#ifndef STATUS_USER_SESSION_DELETED -# define STATUS_USER_SESSION_DELETED ((NTSTATUS) 0xC0000203L) -#endif - -#ifndef STATUS_RESOURCE_LANG_NOT_FOUND -# define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS) 0xC0000204L) -#endif - -#ifndef STATUS_INSUFF_SERVER_RESOURCES -# define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS) 0xC0000205L) -#endif - -#ifndef STATUS_INVALID_BUFFER_SIZE -# define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS) 0xC0000206L) -#endif - -#ifndef STATUS_INVALID_ADDRESS_COMPONENT -# define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS) 0xC0000207L) -#endif - -#ifndef STATUS_INVALID_ADDRESS_WILDCARD -# define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS) 0xC0000208L) -#endif - -#ifndef STATUS_TOO_MANY_ADDRESSES -# define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS) 0xC0000209L) -#endif - -#ifndef STATUS_ADDRESS_ALREADY_EXISTS -# define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS) 0xC000020AL) -#endif - -#ifndef STATUS_ADDRESS_CLOSED -# define STATUS_ADDRESS_CLOSED ((NTSTATUS) 0xC000020BL) -#endif - -#ifndef STATUS_CONNECTION_DISCONNECTED -# define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS) 0xC000020CL) -#endif - -#ifndef STATUS_CONNECTION_RESET -# define STATUS_CONNECTION_RESET ((NTSTATUS) 0xC000020DL) -#endif - -#ifndef STATUS_TOO_MANY_NODES -# define STATUS_TOO_MANY_NODES ((NTSTATUS) 0xC000020EL) -#endif - -#ifndef STATUS_TRANSACTION_ABORTED -# define STATUS_TRANSACTION_ABORTED ((NTSTATUS) 0xC000020FL) -#endif - -#ifndef STATUS_TRANSACTION_TIMED_OUT -# define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS) 0xC0000210L) -#endif - -#ifndef STATUS_TRANSACTION_NO_RELEASE -# define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS) 0xC0000211L) -#endif - -#ifndef STATUS_TRANSACTION_NO_MATCH -# define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS) 0xC0000212L) -#endif - -#ifndef STATUS_TRANSACTION_RESPONDED -# define STATUS_TRANSACTION_RESPONDED ((NTSTATUS) 0xC0000213L) -#endif - -#ifndef STATUS_TRANSACTION_INVALID_ID -# define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS) 0xC0000214L) -#endif - -#ifndef STATUS_TRANSACTION_INVALID_TYPE -# define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS) 0xC0000215L) -#endif - -#ifndef STATUS_NOT_SERVER_SESSION -# define STATUS_NOT_SERVER_SESSION ((NTSTATUS) 0xC0000216L) -#endif - -#ifndef STATUS_NOT_CLIENT_SESSION -# define STATUS_NOT_CLIENT_SESSION ((NTSTATUS) 0xC0000217L) -#endif - -#ifndef STATUS_CANNOT_LOAD_REGISTRY_FILE -# define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS) 0xC0000218L) -#endif - -#ifndef STATUS_DEBUG_ATTACH_FAILED -# define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS) 0xC0000219L) -#endif - -#ifndef STATUS_SYSTEM_PROCESS_TERMINATED -# define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS) 0xC000021AL) -#endif - -#ifndef STATUS_DATA_NOT_ACCEPTED -# define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS) 0xC000021BL) -#endif - -#ifndef STATUS_NO_BROWSER_SERVERS_FOUND -# define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS) 0xC000021CL) -#endif - -#ifndef STATUS_VDM_HARD_ERROR -# define STATUS_VDM_HARD_ERROR ((NTSTATUS) 0xC000021DL) -#endif - -#ifndef STATUS_DRIVER_CANCEL_TIMEOUT -# define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS) 0xC000021EL) -#endif - -#ifndef STATUS_REPLY_MESSAGE_MISMATCH -# define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS) 0xC000021FL) -#endif - -#ifndef STATUS_MAPPED_ALIGNMENT -# define STATUS_MAPPED_ALIGNMENT ((NTSTATUS) 0xC0000220L) -#endif - -#ifndef STATUS_IMAGE_CHECKSUM_MISMATCH -# define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS) 0xC0000221L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA -# define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS) 0xC0000222L) -#endif - -#ifndef STATUS_CLIENT_SERVER_PARAMETERS_INVALID -# define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS) 0xC0000223L) -#endif - -#ifndef STATUS_PASSWORD_MUST_CHANGE -# define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS) 0xC0000224L) -#endif - -#ifndef STATUS_NOT_FOUND -# define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L) -#endif - -#ifndef STATUS_NOT_TINY_STREAM -# define STATUS_NOT_TINY_STREAM ((NTSTATUS) 0xC0000226L) -#endif - -#ifndef STATUS_RECOVERY_FAILURE -# define STATUS_RECOVERY_FAILURE ((NTSTATUS) 0xC0000227L) -#endif - -#ifndef STATUS_STACK_OVERFLOW_READ -# define STATUS_STACK_OVERFLOW_READ ((NTSTATUS) 0xC0000228L) -#endif - -#ifndef STATUS_FAIL_CHECK -# define STATUS_FAIL_CHECK ((NTSTATUS) 0xC0000229L) -#endif - -#ifndef STATUS_DUPLICATE_OBJECTID -# define STATUS_DUPLICATE_OBJECTID ((NTSTATUS) 0xC000022AL) -#endif - -#ifndef STATUS_OBJECTID_EXISTS -# define STATUS_OBJECTID_EXISTS ((NTSTATUS) 0xC000022BL) -#endif - -#ifndef STATUS_CONVERT_TO_LARGE -# define STATUS_CONVERT_TO_LARGE ((NTSTATUS) 0xC000022CL) -#endif - -#ifndef STATUS_RETRY -# define STATUS_RETRY ((NTSTATUS) 0xC000022DL) -#endif - -#ifndef STATUS_FOUND_OUT_OF_SCOPE -# define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS) 0xC000022EL) -#endif - -#ifndef STATUS_ALLOCATE_BUCKET -# define STATUS_ALLOCATE_BUCKET ((NTSTATUS) 0xC000022FL) -#endif - -#ifndef STATUS_PROPSET_NOT_FOUND -# define STATUS_PROPSET_NOT_FOUND ((NTSTATUS) 0xC0000230L) -#endif - -#ifndef STATUS_MARSHALL_OVERFLOW -# define STATUS_MARSHALL_OVERFLOW ((NTSTATUS) 0xC0000231L) -#endif - -#ifndef STATUS_INVALID_VARIANT -# define STATUS_INVALID_VARIANT ((NTSTATUS) 0xC0000232L) -#endif - -#ifndef STATUS_DOMAIN_CONTROLLER_NOT_FOUND -# define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS) 0xC0000233L) -#endif - -#ifndef STATUS_ACCOUNT_LOCKED_OUT -# define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS) 0xC0000234L) -#endif - -#ifndef STATUS_HANDLE_NOT_CLOSABLE -# define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS) 0xC0000235L) -#endif - -#ifndef STATUS_CONNECTION_REFUSED -# define STATUS_CONNECTION_REFUSED ((NTSTATUS) 0xC0000236L) -#endif - -#ifndef STATUS_GRACEFUL_DISCONNECT -# define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS) 0xC0000237L) -#endif - -#ifndef STATUS_ADDRESS_ALREADY_ASSOCIATED -# define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS) 0xC0000238L) -#endif - -#ifndef STATUS_ADDRESS_NOT_ASSOCIATED -# define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS) 0xC0000239L) -#endif - -#ifndef STATUS_CONNECTION_INVALID -# define STATUS_CONNECTION_INVALID ((NTSTATUS) 0xC000023AL) -#endif - -#ifndef STATUS_CONNECTION_ACTIVE -# define STATUS_CONNECTION_ACTIVE ((NTSTATUS) 0xC000023BL) -#endif - -#ifndef STATUS_NETWORK_UNREACHABLE -# define STATUS_NETWORK_UNREACHABLE ((NTSTATUS) 0xC000023CL) -#endif - -#ifndef STATUS_HOST_UNREACHABLE -# define STATUS_HOST_UNREACHABLE ((NTSTATUS) 0xC000023DL) -#endif - -#ifndef STATUS_PROTOCOL_UNREACHABLE -# define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS) 0xC000023EL) -#endif - -#ifndef STATUS_PORT_UNREACHABLE -# define STATUS_PORT_UNREACHABLE ((NTSTATUS) 0xC000023FL) -#endif - -#ifndef STATUS_REQUEST_ABORTED -# define STATUS_REQUEST_ABORTED ((NTSTATUS) 0xC0000240L) -#endif - -#ifndef STATUS_CONNECTION_ABORTED -# define STATUS_CONNECTION_ABORTED ((NTSTATUS) 0xC0000241L) -#endif - -#ifndef STATUS_BAD_COMPRESSION_BUFFER -# define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS) 0xC0000242L) -#endif - -#ifndef STATUS_USER_MAPPED_FILE -# define STATUS_USER_MAPPED_FILE ((NTSTATUS) 0xC0000243L) -#endif - -#ifndef STATUS_AUDIT_FAILED -# define STATUS_AUDIT_FAILED ((NTSTATUS) 0xC0000244L) -#endif - -#ifndef STATUS_TIMER_RESOLUTION_NOT_SET -# define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS) 0xC0000245L) -#endif - -#ifndef STATUS_CONNECTION_COUNT_LIMIT -# define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS) 0xC0000246L) -#endif - -#ifndef STATUS_LOGIN_TIME_RESTRICTION -# define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS) 0xC0000247L) -#endif - -#ifndef STATUS_LOGIN_WKSTA_RESTRICTION -# define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS) 0xC0000248L) -#endif - -#ifndef STATUS_IMAGE_MP_UP_MISMATCH -# define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS) 0xC0000249L) -#endif - -#ifndef STATUS_INSUFFICIENT_LOGON_INFO -# define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS) 0xC0000250L) -#endif - -#ifndef STATUS_BAD_DLL_ENTRYPOINT -# define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251L) -#endif - -#ifndef STATUS_BAD_SERVICE_ENTRYPOINT -# define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS) 0xC0000252L) -#endif - -#ifndef STATUS_LPC_REPLY_LOST -# define STATUS_LPC_REPLY_LOST ((NTSTATUS) 0xC0000253L) -#endif - -#ifndef STATUS_IP_ADDRESS_CONFLICT1 -# define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS) 0xC0000254L) -#endif - -#ifndef STATUS_IP_ADDRESS_CONFLICT2 -# define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS) 0xC0000255L) -#endif - -#ifndef STATUS_REGISTRY_QUOTA_LIMIT -# define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS) 0xC0000256L) -#endif - -#ifndef STATUS_PATH_NOT_COVERED -# define STATUS_PATH_NOT_COVERED ((NTSTATUS) 0xC0000257L) -#endif - -#ifndef STATUS_NO_CALLBACK_ACTIVE -# define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS) 0xC0000258L) -#endif - -#ifndef STATUS_LICENSE_QUOTA_EXCEEDED -# define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000259L) -#endif - -#ifndef STATUS_PWD_TOO_SHORT -# define STATUS_PWD_TOO_SHORT ((NTSTATUS) 0xC000025AL) -#endif - -#ifndef STATUS_PWD_TOO_RECENT -# define STATUS_PWD_TOO_RECENT ((NTSTATUS) 0xC000025BL) -#endif - -#ifndef STATUS_PWD_HISTORY_CONFLICT -# define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS) 0xC000025CL) -#endif - -#ifndef STATUS_PLUGPLAY_NO_DEVICE -# define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS) 0xC000025EL) -#endif - -#ifndef STATUS_UNSUPPORTED_COMPRESSION -# define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS) 0xC000025FL) -#endif - -#ifndef STATUS_INVALID_HW_PROFILE -# define STATUS_INVALID_HW_PROFILE ((NTSTATUS) 0xC0000260L) -#endif - -#ifndef STATUS_INVALID_PLUGPLAY_DEVICE_PATH -# define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS) 0xC0000261L) -#endif - -#ifndef STATUS_DRIVER_ORDINAL_NOT_FOUND -# define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000262L) -#endif - -#ifndef STATUS_DRIVER_ENTRYPOINT_NOT_FOUND -# define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000263L) -#endif - -#ifndef STATUS_RESOURCE_NOT_OWNED -# define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS) 0xC0000264L) -#endif - -#ifndef STATUS_TOO_MANY_LINKS -# define STATUS_TOO_MANY_LINKS ((NTSTATUS) 0xC0000265L) -#endif - -#ifndef STATUS_QUOTA_LIST_INCONSISTENT -# define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS) 0xC0000266L) -#endif - -#ifndef STATUS_FILE_IS_OFFLINE -# define STATUS_FILE_IS_OFFLINE ((NTSTATUS) 0xC0000267L) -#endif - -#ifndef STATUS_EVALUATION_EXPIRATION -# define STATUS_EVALUATION_EXPIRATION ((NTSTATUS) 0xC0000268L) -#endif - -#ifndef STATUS_ILLEGAL_DLL_RELOCATION -# define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269L) -#endif - -#ifndef STATUS_LICENSE_VIOLATION -# define STATUS_LICENSE_VIOLATION ((NTSTATUS) 0xC000026AL) -#endif - -#ifndef STATUS_DLL_INIT_FAILED_LOGOFF -# define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS) 0xC000026BL) -#endif - -#ifndef STATUS_DRIVER_UNABLE_TO_LOAD -# define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS) 0xC000026CL) -#endif - -#ifndef STATUS_DFS_UNAVAILABLE -# define STATUS_DFS_UNAVAILABLE ((NTSTATUS) 0xC000026DL) -#endif - -#ifndef STATUS_VOLUME_DISMOUNTED -# define STATUS_VOLUME_DISMOUNTED ((NTSTATUS) 0xC000026EL) -#endif - -#ifndef STATUS_WX86_INTERNAL_ERROR -# define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS) 0xC000026FL) -#endif - -#ifndef STATUS_WX86_FLOAT_STACK_CHECK -# define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000270L) -#endif - -#ifndef STATUS_VALIDATE_CONTINUE -# define STATUS_VALIDATE_CONTINUE ((NTSTATUS) 0xC0000271L) -#endif - -#ifndef STATUS_NO_MATCH -# define STATUS_NO_MATCH ((NTSTATUS) 0xC0000272L) -#endif - -#ifndef STATUS_NO_MORE_MATCHES -# define STATUS_NO_MORE_MATCHES ((NTSTATUS) 0xC0000273L) -#endif - -#ifndef STATUS_NOT_A_REPARSE_POINT -# define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS) 0xC0000275L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_INVALID -# define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS) 0xC0000276L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_MISMATCH -# define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS) 0xC0000277L) -#endif - -#ifndef STATUS_IO_REPARSE_DATA_INVALID -# define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS) 0xC0000278L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_NOT_HANDLED -# define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS) 0xC0000279L) -#endif - -#ifndef STATUS_REPARSE_POINT_NOT_RESOLVED -# define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000280L) -#endif - -#ifndef STATUS_DIRECTORY_IS_A_REPARSE_POINT -# define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS) 0xC0000281L) -#endif - -#ifndef STATUS_RANGE_LIST_CONFLICT -# define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS) 0xC0000282L) -#endif - -#ifndef STATUS_SOURCE_ELEMENT_EMPTY -# define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS) 0xC0000283L) -#endif - -#ifndef STATUS_DESTINATION_ELEMENT_FULL -# define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS) 0xC0000284L) -#endif - -#ifndef STATUS_ILLEGAL_ELEMENT_ADDRESS -# define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS) 0xC0000285L) -#endif - -#ifndef STATUS_MAGAZINE_NOT_PRESENT -# define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS) 0xC0000286L) -#endif - -#ifndef STATUS_REINITIALIZATION_NEEDED -# define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS) 0xC0000287L) -#endif - -#ifndef STATUS_DEVICE_REQUIRES_CLEANING -# define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS) 0x80000288L) -#endif - -#ifndef STATUS_DEVICE_DOOR_OPEN -# define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS) 0x80000289L) -#endif - -#ifndef STATUS_ENCRYPTION_FAILED -# define STATUS_ENCRYPTION_FAILED ((NTSTATUS) 0xC000028AL) -#endif - -#ifndef STATUS_DECRYPTION_FAILED -# define STATUS_DECRYPTION_FAILED ((NTSTATUS) 0xC000028BL) -#endif - -#ifndef STATUS_RANGE_NOT_FOUND -# define STATUS_RANGE_NOT_FOUND ((NTSTATUS) 0xC000028CL) -#endif - -#ifndef STATUS_NO_RECOVERY_POLICY -# define STATUS_NO_RECOVERY_POLICY ((NTSTATUS) 0xC000028DL) -#endif - -#ifndef STATUS_NO_EFS -# define STATUS_NO_EFS ((NTSTATUS) 0xC000028EL) -#endif - -#ifndef STATUS_WRONG_EFS -# define STATUS_WRONG_EFS ((NTSTATUS) 0xC000028FL) -#endif - -#ifndef STATUS_NO_USER_KEYS -# define STATUS_NO_USER_KEYS ((NTSTATUS) 0xC0000290L) -#endif - -#ifndef STATUS_FILE_NOT_ENCRYPTED -# define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS) 0xC0000291L) -#endif - -#ifndef STATUS_NOT_EXPORT_FORMAT -# define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS) 0xC0000292L) -#endif - -#ifndef STATUS_FILE_ENCRYPTED -# define STATUS_FILE_ENCRYPTED ((NTSTATUS) 0xC0000293L) -#endif - -#ifndef STATUS_WAKE_SYSTEM -# define STATUS_WAKE_SYSTEM ((NTSTATUS) 0x40000294L) -#endif - -#ifndef STATUS_WMI_GUID_NOT_FOUND -# define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS) 0xC0000295L) -#endif - -#ifndef STATUS_WMI_INSTANCE_NOT_FOUND -# define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS) 0xC0000296L) -#endif - -#ifndef STATUS_WMI_ITEMID_NOT_FOUND -# define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS) 0xC0000297L) -#endif - -#ifndef STATUS_WMI_TRY_AGAIN -# define STATUS_WMI_TRY_AGAIN ((NTSTATUS) 0xC0000298L) -#endif - -#ifndef STATUS_SHARED_POLICY -# define STATUS_SHARED_POLICY ((NTSTATUS) 0xC0000299L) -#endif - -#ifndef STATUS_POLICY_OBJECT_NOT_FOUND -# define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS) 0xC000029AL) -#endif - -#ifndef STATUS_POLICY_ONLY_IN_DS -# define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS) 0xC000029BL) -#endif - -#ifndef STATUS_VOLUME_NOT_UPGRADED -# define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS) 0xC000029CL) -#endif - -#ifndef STATUS_REMOTE_STORAGE_NOT_ACTIVE -# define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS) 0xC000029DL) -#endif - -#ifndef STATUS_REMOTE_STORAGE_MEDIA_ERROR -# define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS) 0xC000029EL) -#endif - -#ifndef STATUS_NO_TRACKING_SERVICE -# define STATUS_NO_TRACKING_SERVICE ((NTSTATUS) 0xC000029FL) -#endif - -#ifndef STATUS_SERVER_SID_MISMATCH -# define STATUS_SERVER_SID_MISMATCH ((NTSTATUS) 0xC00002A0L) -#endif - -#ifndef STATUS_DS_NO_ATTRIBUTE_OR_VALUE -# define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS) 0xC00002A1L) -#endif - -#ifndef STATUS_DS_INVALID_ATTRIBUTE_SYNTAX -# define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS) 0xC00002A2L) -#endif - -#ifndef STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED -# define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS) 0xC00002A3L) -#endif - -#ifndef STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS -# define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS) 0xC00002A4L) -#endif - -#ifndef STATUS_DS_BUSY -# define STATUS_DS_BUSY ((NTSTATUS) 0xC00002A5L) -#endif - -#ifndef STATUS_DS_UNAVAILABLE -# define STATUS_DS_UNAVAILABLE ((NTSTATUS) 0xC00002A6L) -#endif - -#ifndef STATUS_DS_NO_RIDS_ALLOCATED -# define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS) 0xC00002A7L) -#endif - -#ifndef STATUS_DS_NO_MORE_RIDS -# define STATUS_DS_NO_MORE_RIDS ((NTSTATUS) 0xC00002A8L) -#endif - -#ifndef STATUS_DS_INCORRECT_ROLE_OWNER -# define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS) 0xC00002A9L) -#endif - -#ifndef STATUS_DS_RIDMGR_INIT_ERROR -# define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS) 0xC00002AAL) -#endif - -#ifndef STATUS_DS_OBJ_CLASS_VIOLATION -# define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS) 0xC00002ABL) -#endif - -#ifndef STATUS_DS_CANT_ON_NON_LEAF -# define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS) 0xC00002ACL) -#endif - -#ifndef STATUS_DS_CANT_ON_RDN -# define STATUS_DS_CANT_ON_RDN ((NTSTATUS) 0xC00002ADL) -#endif - -#ifndef STATUS_DS_CANT_MOD_OBJ_CLASS -# define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS) 0xC00002AEL) -#endif - -#ifndef STATUS_DS_CROSS_DOM_MOVE_FAILED -# define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS) 0xC00002AFL) -#endif - -#ifndef STATUS_DS_GC_NOT_AVAILABLE -# define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS) 0xC00002B0L) -#endif - -#ifndef STATUS_DIRECTORY_SERVICE_REQUIRED -# define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS) 0xC00002B1L) -#endif - -#ifndef STATUS_REPARSE_ATTRIBUTE_CONFLICT -# define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS) 0xC00002B2L) -#endif - -#ifndef STATUS_CANT_ENABLE_DENY_ONLY -# define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS) 0xC00002B3L) -#endif - -#ifndef STATUS_FLOAT_MULTIPLE_FAULTS -# define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS) 0xC00002B4L) -#endif - -#ifndef STATUS_FLOAT_MULTIPLE_TRAPS -# define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS) 0xC00002B5L) -#endif - -#ifndef STATUS_DEVICE_REMOVED -# define STATUS_DEVICE_REMOVED ((NTSTATUS) 0xC00002B6L) -#endif - -#ifndef STATUS_JOURNAL_DELETE_IN_PROGRESS -# define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS) 0xC00002B7L) -#endif - -#ifndef STATUS_JOURNAL_NOT_ACTIVE -# define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS) 0xC00002B8L) -#endif - -#ifndef STATUS_NOINTERFACE -# define STATUS_NOINTERFACE ((NTSTATUS) 0xC00002B9L) -#endif - -#ifndef STATUS_DS_ADMIN_LIMIT_EXCEEDED -# define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00002C1L) -#endif - -#ifndef STATUS_DRIVER_FAILED_SLEEP -# define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS) 0xC00002C2L) -#endif - -#ifndef STATUS_MUTUAL_AUTHENTICATION_FAILED -# define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS) 0xC00002C3L) -#endif - -#ifndef STATUS_CORRUPT_SYSTEM_FILE -# define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS) 0xC00002C4L) -#endif - -#ifndef STATUS_DATATYPE_MISALIGNMENT_ERROR -# define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS) 0xC00002C5L) -#endif - -#ifndef STATUS_WMI_READ_ONLY -# define STATUS_WMI_READ_ONLY ((NTSTATUS) 0xC00002C6L) -#endif - -#ifndef STATUS_WMI_SET_FAILURE -# define STATUS_WMI_SET_FAILURE ((NTSTATUS) 0xC00002C7L) -#endif - -#ifndef STATUS_COMMITMENT_MINIMUM -# define STATUS_COMMITMENT_MINIMUM ((NTSTATUS) 0xC00002C8L) -#endif - -#ifndef STATUS_REG_NAT_CONSUMPTION -# define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS) 0xC00002C9L) -#endif - -#ifndef STATUS_TRANSPORT_FULL -# define STATUS_TRANSPORT_FULL ((NTSTATUS) 0xC00002CAL) -#endif - -#ifndef STATUS_DS_SAM_INIT_FAILURE -# define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002CBL) -#endif - -#ifndef STATUS_ONLY_IF_CONNECTED -# define STATUS_ONLY_IF_CONNECTED ((NTSTATUS) 0xC00002CCL) -#endif - -#ifndef STATUS_DS_SENSITIVE_GROUP_VIOLATION -# define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS) 0xC00002CDL) -#endif - -#ifndef STATUS_PNP_RESTART_ENUMERATION -# define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS) 0xC00002CEL) -#endif - -#ifndef STATUS_JOURNAL_ENTRY_DELETED -# define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS) 0xC00002CFL) -#endif - -#ifndef STATUS_DS_CANT_MOD_PRIMARYGROUPID -# define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS) 0xC00002D0L) -#endif - -#ifndef STATUS_SYSTEM_IMAGE_BAD_SIGNATURE -# define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS) 0xC00002D1L) -#endif - -#ifndef STATUS_PNP_REBOOT_REQUIRED -# define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS) 0xC00002D2L) -#endif - -#ifndef STATUS_POWER_STATE_INVALID -# define STATUS_POWER_STATE_INVALID ((NTSTATUS) 0xC00002D3L) -#endif - -#ifndef STATUS_DS_INVALID_GROUP_TYPE -# define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS) 0xC00002D4L) -#endif - -#ifndef STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN -# define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D5L) -#endif - -#ifndef STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN -# define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D6L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D7L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC00002D8L) -#endif - -#ifndef STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER -# define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D9L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS) 0xC00002DAL) -#endif - -#ifndef STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER -# define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS) 0xC00002DBL) -#endif - -#ifndef STATUS_DS_HAVE_PRIMARY_MEMBERS -# define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS) 0xC00002DCL) -#endif - -#ifndef STATUS_WMI_NOT_SUPPORTED -# define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS) 0xC00002DDL) -#endif - -#ifndef STATUS_INSUFFICIENT_POWER -# define STATUS_INSUFFICIENT_POWER ((NTSTATUS) 0xC00002DEL) -#endif - -#ifndef STATUS_SAM_NEED_BOOTKEY_PASSWORD -# define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS) 0xC00002DFL) -#endif - -#ifndef STATUS_SAM_NEED_BOOTKEY_FLOPPY -# define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS) 0xC00002E0L) -#endif - -#ifndef STATUS_DS_CANT_START -# define STATUS_DS_CANT_START ((NTSTATUS) 0xC00002E1L) -#endif - -#ifndef STATUS_DS_INIT_FAILURE -# define STATUS_DS_INIT_FAILURE ((NTSTATUS) 0xC00002E2L) -#endif - -#ifndef STATUS_SAM_INIT_FAILURE -# define STATUS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002E3L) -#endif - -#ifndef STATUS_DS_GC_REQUIRED -# define STATUS_DS_GC_REQUIRED ((NTSTATUS) 0xC00002E4L) -#endif - -#ifndef STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY -# define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS) 0xC00002E5L) -#endif - -#ifndef STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS -# define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS) 0xC00002E6L) -#endif - -#ifndef STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED -# define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS) 0xC00002E7L) -#endif - -#ifndef STATUS_MULTIPLE_FAULT_VIOLATION -# define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS) 0xC00002E8L) -#endif - -#ifndef STATUS_CURRENT_DOMAIN_NOT_ALLOWED -# define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS) 0xC00002E9L) -#endif - -#ifndef STATUS_CANNOT_MAKE -# define STATUS_CANNOT_MAKE ((NTSTATUS) 0xC00002EAL) -#endif - -#ifndef STATUS_SYSTEM_SHUTDOWN -# define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS) 0xC00002EBL) -#endif - -#ifndef STATUS_DS_INIT_FAILURE_CONSOLE -# define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002ECL) -#endif - -#ifndef STATUS_DS_SAM_INIT_FAILURE_CONSOLE -# define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002EDL) -#endif - -#ifndef STATUS_UNFINISHED_CONTEXT_DELETED -# define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS) 0xC00002EEL) -#endif - -#ifndef STATUS_NO_TGT_REPLY -# define STATUS_NO_TGT_REPLY ((NTSTATUS) 0xC00002EFL) -#endif - -#ifndef STATUS_OBJECTID_NOT_FOUND -# define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS) 0xC00002F0L) -#endif - -#ifndef STATUS_NO_IP_ADDRESSES -# define STATUS_NO_IP_ADDRESSES ((NTSTATUS) 0xC00002F1L) -#endif - -#ifndef STATUS_WRONG_CREDENTIAL_HANDLE -# define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS) 0xC00002F2L) -#endif - -#ifndef STATUS_CRYPTO_SYSTEM_INVALID -# define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS) 0xC00002F3L) -#endif - -#ifndef STATUS_MAX_REFERRALS_EXCEEDED -# define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS) 0xC00002F4L) -#endif - -#ifndef STATUS_MUST_BE_KDC -# define STATUS_MUST_BE_KDC ((NTSTATUS) 0xC00002F5L) -#endif - -#ifndef STATUS_STRONG_CRYPTO_NOT_SUPPORTED -# define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS) 0xC00002F6L) -#endif - -#ifndef STATUS_TOO_MANY_PRINCIPALS -# define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS) 0xC00002F7L) -#endif - -#ifndef STATUS_NO_PA_DATA -# define STATUS_NO_PA_DATA ((NTSTATUS) 0xC00002F8L) -#endif - -#ifndef STATUS_PKINIT_NAME_MISMATCH -# define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS) 0xC00002F9L) -#endif - -#ifndef STATUS_SMARTCARD_LOGON_REQUIRED -# define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS) 0xC00002FAL) -#endif - -#ifndef STATUS_KDC_INVALID_REQUEST -# define STATUS_KDC_INVALID_REQUEST ((NTSTATUS) 0xC00002FBL) -#endif - -#ifndef STATUS_KDC_UNABLE_TO_REFER -# define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS) 0xC00002FCL) -#endif - -#ifndef STATUS_KDC_UNKNOWN_ETYPE -# define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS) 0xC00002FDL) -#endif - -#ifndef STATUS_SHUTDOWN_IN_PROGRESS -# define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FEL) -#endif - -#ifndef STATUS_SERVER_SHUTDOWN_IN_PROGRESS -# define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FFL) -#endif - -#ifndef STATUS_NOT_SUPPORTED_ON_SBS -# define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS) 0xC0000300L) -#endif - -#ifndef STATUS_WMI_GUID_DISCONNECTED -# define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS) 0xC0000301L) -#endif - -#ifndef STATUS_WMI_ALREADY_DISABLED -# define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS) 0xC0000302L) -#endif - -#ifndef STATUS_WMI_ALREADY_ENABLED -# define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS) 0xC0000303L) -#endif - -#ifndef STATUS_MFT_TOO_FRAGMENTED -# define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS) 0xC0000304L) -#endif - -#ifndef STATUS_COPY_PROTECTION_FAILURE -# define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS) 0xC0000305L) -#endif - -#ifndef STATUS_CSS_AUTHENTICATION_FAILURE -# define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS) 0xC0000306L) -#endif - -#ifndef STATUS_CSS_KEY_NOT_PRESENT -# define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS) 0xC0000307L) -#endif - -#ifndef STATUS_CSS_KEY_NOT_ESTABLISHED -# define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS) 0xC0000308L) -#endif - -#ifndef STATUS_CSS_SCRAMBLED_SECTOR -# define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS) 0xC0000309L) -#endif - -#ifndef STATUS_CSS_REGION_MISMATCH -# define STATUS_CSS_REGION_MISMATCH ((NTSTATUS) 0xC000030AL) -#endif - -#ifndef STATUS_CSS_RESETS_EXHAUSTED -# define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS) 0xC000030BL) -#endif - -#ifndef STATUS_PKINIT_FAILURE -# define STATUS_PKINIT_FAILURE ((NTSTATUS) 0xC0000320L) -#endif - -#ifndef STATUS_SMARTCARD_SUBSYSTEM_FAILURE -# define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS) 0xC0000321L) -#endif - -#ifndef STATUS_NO_KERB_KEY -# define STATUS_NO_KERB_KEY ((NTSTATUS) 0xC0000322L) -#endif - -#ifndef STATUS_HOST_DOWN -# define STATUS_HOST_DOWN ((NTSTATUS) 0xC0000350L) -#endif - -#ifndef STATUS_UNSUPPORTED_PREAUTH -# define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS) 0xC0000351L) -#endif - -#ifndef STATUS_EFS_ALG_BLOB_TOO_BIG -# define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS) 0xC0000352L) -#endif - -#ifndef STATUS_PORT_NOT_SET -# define STATUS_PORT_NOT_SET ((NTSTATUS) 0xC0000353L) -#endif - -#ifndef STATUS_DEBUGGER_INACTIVE -# define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354L) -#endif - -#ifndef STATUS_DS_VERSION_CHECK_FAILURE -# define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS) 0xC0000355L) -#endif - -#ifndef STATUS_AUDITING_DISABLED -# define STATUS_AUDITING_DISABLED ((NTSTATUS) 0xC0000356L) -#endif - -#ifndef STATUS_PRENT4_MACHINE_ACCOUNT -# define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS) 0xC0000357L) -#endif - -#ifndef STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER -# define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC0000358L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_32 -# define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS) 0xC0000359L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_64 -# define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS) 0xC000035AL) -#endif - -#ifndef STATUS_BAD_BINDINGS -# define STATUS_BAD_BINDINGS ((NTSTATUS) 0xC000035BL) -#endif - -#ifndef STATUS_NETWORK_SESSION_EXPIRED -# define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS) 0xC000035CL) -#endif - -#ifndef STATUS_APPHELP_BLOCK -# define STATUS_APPHELP_BLOCK ((NTSTATUS) 0xC000035DL) -#endif - -#ifndef STATUS_ALL_SIDS_FILTERED -# define STATUS_ALL_SIDS_FILTERED ((NTSTATUS) 0xC000035EL) -#endif - -#ifndef STATUS_NOT_SAFE_MODE_DRIVER -# define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS) 0xC000035FL) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT -# define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS) 0xC0000361L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PATH -# define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS) 0xC0000362L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER -# define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS) 0xC0000363L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_OTHER -# define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS) 0xC0000364L) -#endif - -#ifndef STATUS_FAILED_DRIVER_ENTRY -# define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS) 0xC0000365L) -#endif - -#ifndef STATUS_DEVICE_ENUMERATION_ERROR -# define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS) 0xC0000366L) -#endif - -#ifndef STATUS_MOUNT_POINT_NOT_RESOLVED -# define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000368L) -#endif - -#ifndef STATUS_INVALID_DEVICE_OBJECT_PARAMETER -# define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS) 0xC0000369L) -#endif - -#ifndef STATUS_MCA_OCCURED -# define STATUS_MCA_OCCURED ((NTSTATUS) 0xC000036AL) -#endif - -#ifndef STATUS_DRIVER_BLOCKED_CRITICAL -# define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS) 0xC000036BL) -#endif - -#ifndef STATUS_DRIVER_BLOCKED -# define STATUS_DRIVER_BLOCKED ((NTSTATUS) 0xC000036CL) -#endif - -#ifndef STATUS_DRIVER_DATABASE_ERROR -# define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS) 0xC000036DL) -#endif - -#ifndef STATUS_SYSTEM_HIVE_TOO_LARGE -# define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS) 0xC000036EL) -#endif - -#ifndef STATUS_INVALID_IMPORT_OF_NON_DLL -# define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS) 0xC000036FL) -#endif - -#ifndef STATUS_DS_SHUTTING_DOWN -# define STATUS_DS_SHUTTING_DOWN ((NTSTATUS) 0x40000370L) -#endif - -#ifndef STATUS_NO_SECRETS -# define STATUS_NO_SECRETS ((NTSTATUS) 0xC0000371L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY -# define STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY ((NTSTATUS) 0xC0000372L) -#endif - -#ifndef STATUS_FAILED_STACK_SWITCH -# define STATUS_FAILED_STACK_SWITCH ((NTSTATUS) 0xC0000373L) -#endif - -#ifndef STATUS_HEAP_CORRUPTION -# define STATUS_HEAP_CORRUPTION ((NTSTATUS) 0xC0000374L) -#endif - -#ifndef STATUS_SMARTCARD_WRONG_PIN -# define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS) 0xC0000380L) -#endif - -#ifndef STATUS_SMARTCARD_CARD_BLOCKED -# define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS) 0xC0000381L) -#endif - -#ifndef STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED -# define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS) 0xC0000382L) -#endif - -#ifndef STATUS_SMARTCARD_NO_CARD -# define STATUS_SMARTCARD_NO_CARD ((NTSTATUS) 0xC0000383L) -#endif - -#ifndef STATUS_SMARTCARD_NO_KEY_CONTAINER -# define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS) 0xC0000384L) -#endif - -#ifndef STATUS_SMARTCARD_NO_CERTIFICATE -# define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS) 0xC0000385L) -#endif - -#ifndef STATUS_SMARTCARD_NO_KEYSET -# define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS) 0xC0000386L) -#endif - -#ifndef STATUS_SMARTCARD_IO_ERROR -# define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS) 0xC0000387L) -#endif - -#ifndef STATUS_DOWNGRADE_DETECTED -# define STATUS_DOWNGRADE_DETECTED ((NTSTATUS) 0xC0000388L) -#endif - -#ifndef STATUS_SMARTCARD_CERT_REVOKED -# define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS) 0xC0000389L) -#endif - -#ifndef STATUS_ISSUING_CA_UNTRUSTED -# define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS) 0xC000038AL) -#endif - -#ifndef STATUS_REVOCATION_OFFLINE_C -# define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS) 0xC000038BL) -#endif - -#ifndef STATUS_PKINIT_CLIENT_FAILURE -# define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS) 0xC000038CL) -#endif - -#ifndef STATUS_SMARTCARD_CERT_EXPIRED -# define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS) 0xC000038DL) -#endif - -#ifndef STATUS_DRIVER_FAILED_PRIOR_UNLOAD -# define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS) 0xC000038EL) -#endif - -#ifndef STATUS_SMARTCARD_SILENT_CONTEXT -# define STATUS_SMARTCARD_SILENT_CONTEXT ((NTSTATUS) 0xC000038FL) -#endif - -#ifndef STATUS_PER_USER_TRUST_QUOTA_EXCEEDED -# define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000401L) -#endif - -#ifndef STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED -# define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000402L) -#endif - -#ifndef STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED -# define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000403L) -#endif - -#ifndef STATUS_DS_NAME_NOT_UNIQUE -# define STATUS_DS_NAME_NOT_UNIQUE ((NTSTATUS) 0xC0000404L) -#endif - -#ifndef STATUS_DS_DUPLICATE_ID_FOUND -# define STATUS_DS_DUPLICATE_ID_FOUND ((NTSTATUS) 0xC0000405L) -#endif - -#ifndef STATUS_DS_GROUP_CONVERSION_ERROR -# define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS) 0xC0000406L) -#endif - -#ifndef STATUS_VOLSNAP_PREPARE_HIBERNATE -# define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS) 0xC0000407L) -#endif - -#ifndef STATUS_USER2USER_REQUIRED -# define STATUS_USER2USER_REQUIRED ((NTSTATUS) 0xC0000408L) -#endif - -#ifndef STATUS_STACK_BUFFER_OVERRUN -# define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS) 0xC0000409L) -#endif - -#ifndef STATUS_NO_S4U_PROT_SUPPORT -# define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS) 0xC000040AL) -#endif - -#ifndef STATUS_CROSSREALM_DELEGATION_FAILURE -# define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS) 0xC000040BL) -#endif - -#ifndef STATUS_REVOCATION_OFFLINE_KDC -# define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS) 0xC000040CL) -#endif - -#ifndef STATUS_ISSUING_CA_UNTRUSTED_KDC -# define STATUS_ISSUING_CA_UNTRUSTED_KDC ((NTSTATUS) 0xC000040DL) -#endif - -#ifndef STATUS_KDC_CERT_EXPIRED -# define STATUS_KDC_CERT_EXPIRED ((NTSTATUS) 0xC000040EL) -#endif - -#ifndef STATUS_KDC_CERT_REVOKED -# define STATUS_KDC_CERT_REVOKED ((NTSTATUS) 0xC000040FL) -#endif - -#ifndef STATUS_PARAMETER_QUOTA_EXCEEDED -# define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000410L) -#endif - -#ifndef STATUS_HIBERNATION_FAILURE -# define STATUS_HIBERNATION_FAILURE ((NTSTATUS) 0xC0000411L) -#endif - -#ifndef STATUS_DELAY_LOAD_FAILED -# define STATUS_DELAY_LOAD_FAILED ((NTSTATUS) 0xC0000412L) -#endif - -#ifndef STATUS_AUTHENTICATION_FIREWALL_FAILED -# define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS) 0xC0000413L) -#endif - -#ifndef STATUS_VDM_DISALLOWED -# define STATUS_VDM_DISALLOWED ((NTSTATUS) 0xC0000414L) -#endif - -#ifndef STATUS_HUNG_DISPLAY_DRIVER_THREAD -# define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS) 0xC0000415L) -#endif - -#ifndef STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE -# define STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE ((NTSTATUS) 0xC0000416L) -#endif - -#ifndef STATUS_INVALID_CRUNTIME_PARAMETER -# define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS) 0xC0000417L) -#endif - -#ifndef STATUS_NTLM_BLOCKED -# define STATUS_NTLM_BLOCKED ((NTSTATUS) 0xC0000418L) -#endif - -#ifndef STATUS_DS_SRC_SID_EXISTS_IN_FOREST -# define STATUS_DS_SRC_SID_EXISTS_IN_FOREST ((NTSTATUS) 0xC0000419L) -#endif - -#ifndef STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST -# define STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041AL) -#endif - -#ifndef STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST -# define STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041BL) -#endif - -#ifndef STATUS_INVALID_USER_PRINCIPAL_NAME -# define STATUS_INVALID_USER_PRINCIPAL_NAME ((NTSTATUS) 0xC000041CL) -#endif - -#ifndef STATUS_FATAL_USER_CALLBACK_EXCEPTION -# define STATUS_FATAL_USER_CALLBACK_EXCEPTION ((NTSTATUS) 0xC000041DL) -#endif - -#ifndef STATUS_ASSERTION_FAILURE -# define STATUS_ASSERTION_FAILURE ((NTSTATUS) 0xC0000420L) -#endif - -#ifndef STATUS_VERIFIER_STOP -# define STATUS_VERIFIER_STOP ((NTSTATUS) 0xC0000421L) -#endif - -#ifndef STATUS_CALLBACK_POP_STACK -# define STATUS_CALLBACK_POP_STACK ((NTSTATUS) 0xC0000423L) -#endif - -#ifndef STATUS_INCOMPATIBLE_DRIVER_BLOCKED -# define STATUS_INCOMPATIBLE_DRIVER_BLOCKED ((NTSTATUS) 0xC0000424L) -#endif - -#ifndef STATUS_HIVE_UNLOADED -# define STATUS_HIVE_UNLOADED ((NTSTATUS) 0xC0000425L) -#endif - -#ifndef STATUS_COMPRESSION_DISABLED -# define STATUS_COMPRESSION_DISABLED ((NTSTATUS) 0xC0000426L) -#endif - -#ifndef STATUS_FILE_SYSTEM_LIMITATION -# define STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS) 0xC0000427L) -#endif - -#ifndef STATUS_INVALID_IMAGE_HASH -# define STATUS_INVALID_IMAGE_HASH ((NTSTATUS) 0xC0000428L) -#endif - -#ifndef STATUS_NOT_CAPABLE -# define STATUS_NOT_CAPABLE ((NTSTATUS) 0xC0000429L) -#endif - -#ifndef STATUS_REQUEST_OUT_OF_SEQUENCE -# define STATUS_REQUEST_OUT_OF_SEQUENCE ((NTSTATUS) 0xC000042AL) -#endif - -#ifndef STATUS_IMPLEMENTATION_LIMIT -# define STATUS_IMPLEMENTATION_LIMIT ((NTSTATUS) 0xC000042BL) -#endif - -#ifndef STATUS_ELEVATION_REQUIRED -# define STATUS_ELEVATION_REQUIRED ((NTSTATUS) 0xC000042CL) -#endif - -#ifndef STATUS_NO_SECURITY_CONTEXT -# define STATUS_NO_SECURITY_CONTEXT ((NTSTATUS) 0xC000042DL) -#endif - -#ifndef STATUS_PKU2U_CERT_FAILURE -# define STATUS_PKU2U_CERT_FAILURE ((NTSTATUS) 0xC000042FL) -#endif - -#ifndef STATUS_BEYOND_VDL -# define STATUS_BEYOND_VDL ((NTSTATUS) 0xC0000432L) -#endif - -#ifndef STATUS_ENCOUNTERED_WRITE_IN_PROGRESS -# define STATUS_ENCOUNTERED_WRITE_IN_PROGRESS ((NTSTATUS) 0xC0000433L) -#endif - -#ifndef STATUS_PTE_CHANGED -# define STATUS_PTE_CHANGED ((NTSTATUS) 0xC0000434L) -#endif - -#ifndef STATUS_PURGE_FAILED -# define STATUS_PURGE_FAILED ((NTSTATUS) 0xC0000435L) -#endif - -#ifndef STATUS_CRED_REQUIRES_CONFIRMATION -# define STATUS_CRED_REQUIRES_CONFIRMATION ((NTSTATUS) 0xC0000440L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE -# define STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE ((NTSTATUS) 0xC0000441L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER -# define STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER ((NTSTATUS) 0xC0000442L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE -# define STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE ((NTSTATUS) 0xC0000443L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE -# define STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE ((NTSTATUS) 0xC0000444L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_FILE_NOT_CSE -# define STATUS_CS_ENCRYPTION_FILE_NOT_CSE ((NTSTATUS) 0xC0000445L) -#endif - -#ifndef STATUS_INVALID_LABEL -# define STATUS_INVALID_LABEL ((NTSTATUS) 0xC0000446L) -#endif - -#ifndef STATUS_DRIVER_PROCESS_TERMINATED -# define STATUS_DRIVER_PROCESS_TERMINATED ((NTSTATUS) 0xC0000450L) -#endif - -#ifndef STATUS_AMBIGUOUS_SYSTEM_DEVICE -# define STATUS_AMBIGUOUS_SYSTEM_DEVICE ((NTSTATUS) 0xC0000451L) -#endif - -#ifndef STATUS_SYSTEM_DEVICE_NOT_FOUND -# define STATUS_SYSTEM_DEVICE_NOT_FOUND ((NTSTATUS) 0xC0000452L) -#endif - -#ifndef STATUS_RESTART_BOOT_APPLICATION -# define STATUS_RESTART_BOOT_APPLICATION ((NTSTATUS) 0xC0000453L) -#endif - -#ifndef STATUS_INSUFFICIENT_NVRAM_RESOURCES -# define STATUS_INSUFFICIENT_NVRAM_RESOURCES ((NTSTATUS) 0xC0000454L) -#endif - -#ifndef STATUS_INVALID_TASK_NAME -# define STATUS_INVALID_TASK_NAME ((NTSTATUS) 0xC0000500L) -#endif - -#ifndef STATUS_INVALID_TASK_INDEX -# define STATUS_INVALID_TASK_INDEX ((NTSTATUS) 0xC0000501L) -#endif - -#ifndef STATUS_THREAD_ALREADY_IN_TASK -# define STATUS_THREAD_ALREADY_IN_TASK ((NTSTATUS) 0xC0000502L) -#endif - -#ifndef STATUS_CALLBACK_BYPASS -# define STATUS_CALLBACK_BYPASS ((NTSTATUS) 0xC0000503L) -#endif - -#ifndef STATUS_FAIL_FAST_EXCEPTION -# define STATUS_FAIL_FAST_EXCEPTION ((NTSTATUS) 0xC0000602L) -#endif - -#ifndef STATUS_IMAGE_CERT_REVOKED -# define STATUS_IMAGE_CERT_REVOKED ((NTSTATUS) 0xC0000603L) -#endif - -#ifndef STATUS_PORT_CLOSED -# define STATUS_PORT_CLOSED ((NTSTATUS) 0xC0000700L) -#endif - -#ifndef STATUS_MESSAGE_LOST -# define STATUS_MESSAGE_LOST ((NTSTATUS) 0xC0000701L) -#endif - -#ifndef STATUS_INVALID_MESSAGE -# define STATUS_INVALID_MESSAGE ((NTSTATUS) 0xC0000702L) -#endif - -#ifndef STATUS_REQUEST_CANCELED -# define STATUS_REQUEST_CANCELED ((NTSTATUS) 0xC0000703L) -#endif - -#ifndef STATUS_RECURSIVE_DISPATCH -# define STATUS_RECURSIVE_DISPATCH ((NTSTATUS) 0xC0000704L) -#endif - -#ifndef STATUS_LPC_RECEIVE_BUFFER_EXPECTED -# define STATUS_LPC_RECEIVE_BUFFER_EXPECTED ((NTSTATUS) 0xC0000705L) -#endif - -#ifndef STATUS_LPC_INVALID_CONNECTION_USAGE -# define STATUS_LPC_INVALID_CONNECTION_USAGE ((NTSTATUS) 0xC0000706L) -#endif - -#ifndef STATUS_LPC_REQUESTS_NOT_ALLOWED -# define STATUS_LPC_REQUESTS_NOT_ALLOWED ((NTSTATUS) 0xC0000707L) -#endif - -#ifndef STATUS_RESOURCE_IN_USE -# define STATUS_RESOURCE_IN_USE ((NTSTATUS) 0xC0000708L) -#endif - -#ifndef STATUS_HARDWARE_MEMORY_ERROR -# define STATUS_HARDWARE_MEMORY_ERROR ((NTSTATUS) 0xC0000709L) -#endif - -#ifndef STATUS_THREADPOOL_HANDLE_EXCEPTION -# define STATUS_THREADPOOL_HANDLE_EXCEPTION ((NTSTATUS) 0xC000070AL) -#endif - -#ifndef STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070BL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070CL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070DL) -#endif - -#ifndef STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070EL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASED_DURING_OPERATION -# define STATUS_THREADPOOL_RELEASED_DURING_OPERATION ((NTSTATUS) 0xC000070FL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING -# define STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000710L) -#endif - -#ifndef STATUS_APC_RETURNED_WHILE_IMPERSONATING -# define STATUS_APC_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000711L) -#endif - -#ifndef STATUS_PROCESS_IS_PROTECTED -# define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS) 0xC0000712L) -#endif - -#ifndef STATUS_MCA_EXCEPTION -# define STATUS_MCA_EXCEPTION ((NTSTATUS) 0xC0000713L) -#endif - -#ifndef STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE -# define STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE ((NTSTATUS) 0xC0000714L) -#endif - -#ifndef STATUS_SYMLINK_CLASS_DISABLED -# define STATUS_SYMLINK_CLASS_DISABLED ((NTSTATUS) 0xC0000715L) -#endif - -#ifndef STATUS_INVALID_IDN_NORMALIZATION -# define STATUS_INVALID_IDN_NORMALIZATION ((NTSTATUS) 0xC0000716L) -#endif - -#ifndef STATUS_NO_UNICODE_TRANSLATION -# define STATUS_NO_UNICODE_TRANSLATION ((NTSTATUS) 0xC0000717L) -#endif - -#ifndef STATUS_ALREADY_REGISTERED -# define STATUS_ALREADY_REGISTERED ((NTSTATUS) 0xC0000718L) -#endif - -#ifndef STATUS_CONTEXT_MISMATCH -# define STATUS_CONTEXT_MISMATCH ((NTSTATUS) 0xC0000719L) -#endif - -#ifndef STATUS_PORT_ALREADY_HAS_COMPLETION_LIST -# define STATUS_PORT_ALREADY_HAS_COMPLETION_LIST ((NTSTATUS) 0xC000071AL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_THREAD_PRIORITY -# define STATUS_CALLBACK_RETURNED_THREAD_PRIORITY ((NTSTATUS) 0xC000071BL) -#endif - -#ifndef STATUS_INVALID_THREAD -# define STATUS_INVALID_THREAD ((NTSTATUS) 0xC000071CL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_TRANSACTION -# define STATUS_CALLBACK_RETURNED_TRANSACTION ((NTSTATUS) 0xC000071DL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_LDR_LOCK -# define STATUS_CALLBACK_RETURNED_LDR_LOCK ((NTSTATUS) 0xC000071EL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_LANG -# define STATUS_CALLBACK_RETURNED_LANG ((NTSTATUS) 0xC000071FL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_PRI_BACK -# define STATUS_CALLBACK_RETURNED_PRI_BACK ((NTSTATUS) 0xC0000720L) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_THREAD_AFFINITY -# define STATUS_CALLBACK_RETURNED_THREAD_AFFINITY ((NTSTATUS) 0xC0000721L) -#endif - -#ifndef STATUS_DISK_REPAIR_DISABLED -# define STATUS_DISK_REPAIR_DISABLED ((NTSTATUS) 0xC0000800L) -#endif - -#ifndef STATUS_DS_DOMAIN_RENAME_IN_PROGRESS -# define STATUS_DS_DOMAIN_RENAME_IN_PROGRESS ((NTSTATUS) 0xC0000801L) -#endif - -#ifndef STATUS_DISK_QUOTA_EXCEEDED -# define STATUS_DISK_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000802L) -#endif - -#ifndef STATUS_DATA_LOST_REPAIR -# define STATUS_DATA_LOST_REPAIR ((NTSTATUS) 0x80000803L) -#endif - -#ifndef STATUS_CONTENT_BLOCKED -# define STATUS_CONTENT_BLOCKED ((NTSTATUS) 0xC0000804L) -#endif - -#ifndef STATUS_BAD_CLUSTERS -# define STATUS_BAD_CLUSTERS ((NTSTATUS) 0xC0000805L) -#endif - -#ifndef STATUS_VOLUME_DIRTY -# define STATUS_VOLUME_DIRTY ((NTSTATUS) 0xC0000806L) -#endif - -#ifndef STATUS_FILE_CHECKED_OUT -# define STATUS_FILE_CHECKED_OUT ((NTSTATUS) 0xC0000901L) -#endif - -#ifndef STATUS_CHECKOUT_REQUIRED -# define STATUS_CHECKOUT_REQUIRED ((NTSTATUS) 0xC0000902L) -#endif - -#ifndef STATUS_BAD_FILE_TYPE -# define STATUS_BAD_FILE_TYPE ((NTSTATUS) 0xC0000903L) -#endif - -#ifndef STATUS_FILE_TOO_LARGE -# define STATUS_FILE_TOO_LARGE ((NTSTATUS) 0xC0000904L) -#endif - -#ifndef STATUS_FORMS_AUTH_REQUIRED -# define STATUS_FORMS_AUTH_REQUIRED ((NTSTATUS) 0xC0000905L) -#endif - -#ifndef STATUS_VIRUS_INFECTED -# define STATUS_VIRUS_INFECTED ((NTSTATUS) 0xC0000906L) -#endif - -#ifndef STATUS_VIRUS_DELETED -# define STATUS_VIRUS_DELETED ((NTSTATUS) 0xC0000907L) -#endif - -#ifndef STATUS_BAD_MCFG_TABLE -# define STATUS_BAD_MCFG_TABLE ((NTSTATUS) 0xC0000908L) -#endif - -#ifndef STATUS_CANNOT_BREAK_OPLOCK -# define STATUS_CANNOT_BREAK_OPLOCK ((NTSTATUS) 0xC0000909L) -#endif - -#ifndef STATUS_WOW_ASSERTION -# define STATUS_WOW_ASSERTION ((NTSTATUS) 0xC0009898L) -#endif - -#ifndef STATUS_INVALID_SIGNATURE -# define STATUS_INVALID_SIGNATURE ((NTSTATUS) 0xC000A000L) -#endif - -#ifndef STATUS_HMAC_NOT_SUPPORTED -# define STATUS_HMAC_NOT_SUPPORTED ((NTSTATUS) 0xC000A001L) -#endif - -#ifndef STATUS_AUTH_TAG_MISMATCH -# define STATUS_AUTH_TAG_MISMATCH ((NTSTATUS) 0xC000A002L) -#endif - -#ifndef STATUS_IPSEC_QUEUE_OVERFLOW -# define STATUS_IPSEC_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A010L) -#endif - -#ifndef STATUS_ND_QUEUE_OVERFLOW -# define STATUS_ND_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A011L) -#endif - -#ifndef STATUS_HOPLIMIT_EXCEEDED -# define STATUS_HOPLIMIT_EXCEEDED ((NTSTATUS) 0xC000A012L) -#endif - -#ifndef STATUS_PROTOCOL_NOT_SUPPORTED -# define STATUS_PROTOCOL_NOT_SUPPORTED ((NTSTATUS) 0xC000A013L) -#endif - -#ifndef STATUS_FASTPATH_REJECTED -# define STATUS_FASTPATH_REJECTED ((NTSTATUS) 0xC000A014L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED -# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED ((NTSTATUS) 0xC000A080L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR -# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR ((NTSTATUS) 0xC000A081L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR -# define STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR ((NTSTATUS) 0xC000A082L) -#endif - -#ifndef STATUS_XML_PARSE_ERROR -# define STATUS_XML_PARSE_ERROR ((NTSTATUS) 0xC000A083L) -#endif - -#ifndef STATUS_XMLDSIG_ERROR -# define STATUS_XMLDSIG_ERROR ((NTSTATUS) 0xC000A084L) -#endif - -#ifndef STATUS_WRONG_COMPARTMENT -# define STATUS_WRONG_COMPARTMENT ((NTSTATUS) 0xC000A085L) -#endif - -#ifndef STATUS_AUTHIP_FAILURE -# define STATUS_AUTHIP_FAILURE ((NTSTATUS) 0xC000A086L) -#endif - -#ifndef STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS -# define STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS ((NTSTATUS) 0xC000A087L) -#endif - -#ifndef STATUS_DS_OID_NOT_FOUND -# define STATUS_DS_OID_NOT_FOUND ((NTSTATUS) 0xC000A088L) -#endif - -#ifndef STATUS_HASH_NOT_SUPPORTED -# define STATUS_HASH_NOT_SUPPORTED ((NTSTATUS) 0xC000A100L) -#endif - -#ifndef STATUS_HASH_NOT_PRESENT -# define STATUS_HASH_NOT_PRESENT ((NTSTATUS) 0xC000A101L) -#endif - -/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the */ -/* DDK got it wrong! */ -#ifdef NTSTATUS_FROM_WIN32 -# undef NTSTATUS_FROM_WIN32 -#endif -#define NTSTATUS_FROM_WIN32(error) ((NTSTATUS) (error) <= 0 ? \ - ((NTSTATUS) (error)) : ((NTSTATUS) (((error) & 0x0000FFFF) | \ - (FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING))) - -#ifndef JOB_OBJECT_LIMIT_PROCESS_MEMORY -# define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100 -#endif -#ifndef JOB_OBJECT_LIMIT_JOB_MEMORY -# define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200 -#endif -#ifndef JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION -# define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400 -#endif -#ifndef JOB_OBJECT_LIMIT_BREAKAWAY_OK -# define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800 -#endif -#ifndef JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK -# define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000 -#endif -#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE -# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000 -#endif - -/* from winternl.h */ -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING, *PUNICODE_STRING; - -typedef const UNICODE_STRING *PCUNICODE_STRING; - -/* from ntifs.h */ -#ifndef DEVICE_TYPE -# define DEVICE_TYPE DWORD -#endif - -/* MinGW already has a definition for REPARSE_DATA_BUFFER, but mingw-w64 does - * not. - */ -#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) - typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; - } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; -#endif - -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - } DUMMYUNIONNAME; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -typedef enum _FILE_INFORMATION_CLASS { - FileDirectoryInformation = 1, - FileFullDirectoryInformation, - FileBothDirectoryInformation, - FileBasicInformation, - FileStandardInformation, - FileInternalInformation, - FileEaInformation, - FileAccessInformation, - FileNameInformation, - FileRenameInformation, - FileLinkInformation, - FileNamesInformation, - FileDispositionInformation, - FilePositionInformation, - FileFullEaInformation, - FileModeInformation, - FileAlignmentInformation, - FileAllInformation, - FileAllocationInformation, - FileEndOfFileInformation, - FileAlternateNameInformation, - FileStreamInformation, - FilePipeInformation, - FilePipeLocalInformation, - FilePipeRemoteInformation, - FileMailslotQueryInformation, - FileMailslotSetInformation, - FileCompressionInformation, - FileObjectIdInformation, - FileCompletionInformation, - FileMoveClusterInformation, - FileQuotaInformation, - FileReparsePointInformation, - FileNetworkOpenInformation, - FileAttributeTagInformation, - FileTrackingInformation, - FileIdBothDirectoryInformation, - FileIdFullDirectoryInformation, - FileValidDataLengthInformation, - FileShortNameInformation, - FileIoCompletionNotificationInformation, - FileIoStatusBlockRangeInformation, - FileIoPriorityHintInformation, - FileSfioReserveInformation, - FileSfioVolumeInformation, - FileHardLinkInformation, - FileProcessIdsUsingFileInformation, - FileNormalizedNameInformation, - FileNetworkPhysicalNameInformation, - FileIdGlobalTxDirectoryInformation, - FileIsRemoteDeviceInformation, - FileAttributeCacheInformation, - FileNumaNodeInformation, - FileStandardLinkInformation, - FileRemoteProtocolInformation, - FileMaximumInformation -} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; - -typedef struct _FILE_DIRECTORY_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION; - -typedef struct _FILE_BOTH_DIR_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - CCHAR ShortNameLength; - WCHAR ShortName[12]; - WCHAR FileName[1]; -} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; - -typedef struct _FILE_BASIC_INFORMATION { - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - DWORD FileAttributes; -} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; - -typedef struct _FILE_STANDARD_INFORMATION { - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; - -typedef struct _FILE_INTERNAL_INFORMATION { - LARGE_INTEGER IndexNumber; -} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; - -typedef struct _FILE_EA_INFORMATION { - ULONG EaSize; -} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; - -typedef struct _FILE_ACCESS_INFORMATION { - ACCESS_MASK AccessFlags; -} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; - -typedef struct _FILE_POSITION_INFORMATION { - LARGE_INTEGER CurrentByteOffset; -} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; - -typedef struct _FILE_MODE_INFORMATION { - ULONG Mode; -} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; - -typedef struct _FILE_ALIGNMENT_INFORMATION { - ULONG AlignmentRequirement; -} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; - -typedef struct _FILE_NAME_INFORMATION { - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - -typedef struct _FILE_END_OF_FILE_INFORMATION { - LARGE_INTEGER EndOfFile; -} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; - -typedef struct _FILE_ALL_INFORMATION { - FILE_BASIC_INFORMATION BasicInformation; - FILE_STANDARD_INFORMATION StandardInformation; - FILE_INTERNAL_INFORMATION InternalInformation; - FILE_EA_INFORMATION EaInformation; - FILE_ACCESS_INFORMATION AccessInformation; - FILE_POSITION_INFORMATION PositionInformation; - FILE_MODE_INFORMATION ModeInformation; - FILE_ALIGNMENT_INFORMATION AlignmentInformation; - FILE_NAME_INFORMATION NameInformation; -} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; - -typedef struct _FILE_DISPOSITION_INFORMATION { - BOOLEAN DeleteFile; -} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; - -typedef struct _FILE_PIPE_LOCAL_INFORMATION { - ULONG NamedPipeType; - ULONG NamedPipeConfiguration; - ULONG MaximumInstances; - ULONG CurrentInstances; - ULONG InboundQuota; - ULONG ReadDataAvailable; - ULONG OutboundQuota; - ULONG WriteQuotaAvailable; - ULONG NamedPipeState; - ULONG NamedPipeEnd; -} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; - -#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 - -typedef enum _FS_INFORMATION_CLASS { - FileFsVolumeInformation = 1, - FileFsLabelInformation = 2, - FileFsSizeInformation = 3, - FileFsDeviceInformation = 4, - FileFsAttributeInformation = 5, - FileFsControlInformation = 6, - FileFsFullSizeInformation = 7, - FileFsObjectIdInformation = 8, - FileFsDriverPathInformation = 9, - FileFsVolumeFlagsInformation = 10, - FileFsSectorSizeInformation = 11 -} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; - -typedef struct _FILE_FS_VOLUME_INFORMATION { - LARGE_INTEGER VolumeCreationTime; - ULONG VolumeSerialNumber; - ULONG VolumeLabelLength; - BOOLEAN SupportsObjects; - WCHAR VolumeLabel[1]; -} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; - -typedef struct _FILE_FS_LABEL_INFORMATION { - ULONG VolumeLabelLength; - WCHAR VolumeLabel[1]; -} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; - -typedef struct _FILE_FS_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER AvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; - -typedef struct _FILE_FS_DEVICE_INFORMATION { - DEVICE_TYPE DeviceType; - ULONG Characteristics; -} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; - -typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { - ULONG FileSystemAttributes; - LONG MaximumComponentNameLength; - ULONG FileSystemNameLength; - WCHAR FileSystemName[1]; -} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; - -typedef struct _FILE_FS_CONTROL_INFORMATION { - LARGE_INTEGER FreeSpaceStartFiltering; - LARGE_INTEGER FreeSpaceThreshold; - LARGE_INTEGER FreeSpaceStopFiltering; - LARGE_INTEGER DefaultQuotaThreshold; - LARGE_INTEGER DefaultQuotaLimit; - ULONG FileSystemControlFlags; -} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION; - -typedef struct _FILE_FS_FULL_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER CallerAvailableAllocationUnits; - LARGE_INTEGER ActualAvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; - -typedef struct _FILE_FS_OBJECTID_INFORMATION { - UCHAR ObjectId[16]; - UCHAR ExtendedInfo[48]; -} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; - -typedef struct _FILE_FS_DRIVER_PATH_INFORMATION { - BOOLEAN DriverInPath; - ULONG DriverNameLength; - WCHAR DriverName[1]; -} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION; - -typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION { - ULONG Flags; -} FILE_FS_VOLUME_FLAGS_INFORMATION, *PFILE_FS_VOLUME_FLAGS_INFORMATION; - -typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION { - ULONG LogicalBytesPerSector; - ULONG PhysicalBytesPerSectorForAtomicity; - ULONG PhysicalBytesPerSectorForPerformance; - ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity; - ULONG Flags; - ULONG ByteOffsetForSectorAlignment; - ULONG ByteOffsetForPartitionAlignment; -} FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION; - -typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { - LARGE_INTEGER IdleTime; - LARGE_INTEGER KernelTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER DpcTime; - LARGE_INTEGER InterruptTime; - ULONG InterruptCount; -} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; - -#ifndef SystemProcessorPerformanceInformation -# define SystemProcessorPerformanceInformation 8 -#endif - -#ifndef FILE_DEVICE_FILE_SYSTEM -# define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#endif - -#ifndef FILE_DEVICE_NETWORK -# define FILE_DEVICE_NETWORK 0x00000012 -#endif - -#ifndef METHOD_BUFFERED -# define METHOD_BUFFERED 0 -#endif - -#ifndef METHOD_IN_DIRECT -# define METHOD_IN_DIRECT 1 -#endif - -#ifndef METHOD_OUT_DIRECT -# define METHOD_OUT_DIRECT 2 -#endif - -#ifndef METHOD_NEITHER -#define METHOD_NEITHER 3 -#endif - -#ifndef METHOD_DIRECT_TO_HARDWARE -# define METHOD_DIRECT_TO_HARDWARE METHOD_IN_DIRECT -#endif - -#ifndef METHOD_DIRECT_FROM_HARDWARE -# define METHOD_DIRECT_FROM_HARDWARE METHOD_OUT_DIRECT -#endif - -#ifndef FILE_ANY_ACCESS -# define FILE_ANY_ACCESS 0 -#endif - -#ifndef FILE_SPECIAL_ACCESS -# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) -#endif - -#ifndef FILE_READ_ACCESS -# define FILE_READ_ACCESS 0x0001 -#endif - -#ifndef FILE_WRITE_ACCESS -# define FILE_WRITE_ACCESS 0x0002 -#endif - -#ifndef CTL_CODE -# define CTL_CODE(device_type, function, method, access) \ - (((device_type) << 16) | ((access) << 14) | ((function) << 2) | (method)) -#endif - -#ifndef FSCTL_SET_REPARSE_POINT -# define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 41, \ - METHOD_BUFFERED, \ - FILE_SPECIAL_ACCESS) -#endif - -#ifndef FSCTL_GET_REPARSE_POINT -# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 42, \ - METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#endif - -#ifndef FSCTL_DELETE_REPARSE_POINT -# define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 43, \ - METHOD_BUFFERED, \ - FILE_SPECIAL_ACCESS) -#endif - -#ifndef IO_REPARSE_TAG_SYMLINK -# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) -#endif - -typedef VOID (NTAPI *PIO_APC_ROUTINE) - (PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG Reserved); - -typedef ULONG (NTAPI *sRtlNtStatusToDosError) - (NTSTATUS Status); - -typedef NTSTATUS (NTAPI *sNtDeviceIoControlFile) - (HANDLE FileHandle, - HANDLE Event, - PIO_APC_ROUTINE ApcRoutine, - PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG IoControlCode, - PVOID InputBuffer, - ULONG InputBufferLength, - PVOID OutputBuffer, - ULONG OutputBufferLength); - -typedef NTSTATUS (NTAPI *sNtQueryInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass); - -typedef NTSTATUS (NTAPI *sNtSetInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass); - -typedef NTSTATUS (NTAPI *sNtQueryVolumeInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FsInformation, - ULONG Length, - FS_INFORMATION_CLASS FsInformationClass); - -typedef NTSTATUS (NTAPI *sNtQuerySystemInformation) - (UINT SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength); - -typedef NTSTATUS (NTAPI *sNtQueryDirectoryFile) - (HANDLE FileHandle, - HANDLE Event, - PIO_APC_ROUTINE ApcRoutine, - PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass, - BOOLEAN ReturnSingleEntry, - PUNICODE_STRING FileName, - BOOLEAN RestartScan - ); - -/* - * Kernel32 headers - */ -#ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS -# define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1 -#endif - -#ifndef FILE_SKIP_SET_EVENT_ON_HANDLE -# define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2 -#endif - -#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY -# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 -#endif - -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) - typedef struct _OVERLAPPED_ENTRY { - ULONG_PTR lpCompletionKey; - LPOVERLAPPED lpOverlapped; - ULONG_PTR Internal; - DWORD dwNumberOfBytesTransferred; - } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY; -#endif - -/* from wincon.h */ -#ifndef ENABLE_INSERT_MODE -# define ENABLE_INSERT_MODE 0x20 -#endif - -#ifndef ENABLE_QUICK_EDIT_MODE -# define ENABLE_QUICK_EDIT_MODE 0x40 -#endif - -#ifndef ENABLE_EXTENDED_FLAGS -# define ENABLE_EXTENDED_FLAGS 0x80 -#endif - -/* from winerror.h */ -#ifndef ERROR_SYMLINK_NOT_SUPPORTED -# define ERROR_SYMLINK_NOT_SUPPORTED 1464 -#endif - -#ifndef ERROR_MUI_FILE_NOT_FOUND -# define ERROR_MUI_FILE_NOT_FOUND 15100 -#endif - -#ifndef ERROR_MUI_INVALID_FILE -# define ERROR_MUI_INVALID_FILE 15101 -#endif - -#ifndef ERROR_MUI_INVALID_RC_CONFIG -# define ERROR_MUI_INVALID_RC_CONFIG 15102 -#endif - -#ifndef ERROR_MUI_INVALID_LOCALE_NAME -# define ERROR_MUI_INVALID_LOCALE_NAME 15103 -#endif - -#ifndef ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME -# define ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME 15104 -#endif - -#ifndef ERROR_MUI_FILE_NOT_LOADED -# define ERROR_MUI_FILE_NOT_LOADED 15105 -#endif - -typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx) - (HANDLE CompletionPort, - LPOVERLAPPED_ENTRY lpCompletionPortEntries, - ULONG ulCount, - PULONG ulNumEntriesRemoved, - DWORD dwMilliseconds, - BOOL fAlertable); - -typedef BOOL (WINAPI* sSetFileCompletionNotificationModes) - (HANDLE FileHandle, - UCHAR Flags); - -typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW) - (LPCWSTR lpSymlinkFileName, - LPCWSTR lpTargetFileName, - DWORD dwFlags); - -typedef BOOL (WINAPI* sCancelIoEx) - (HANDLE hFile, - LPOVERLAPPED lpOverlapped); - -typedef VOID (WINAPI* sInitializeConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef BOOL (WINAPI* sSleepConditionVariableCS) - (PCONDITION_VARIABLE ConditionVariable, - PCRITICAL_SECTION CriticalSection, - DWORD dwMilliseconds); - -typedef BOOL (WINAPI* sSleepConditionVariableSRW) - (PCONDITION_VARIABLE ConditionVariable, - PSRWLOCK SRWLock, - DWORD dwMilliseconds, - ULONG Flags); - -typedef VOID (WINAPI* sWakeAllConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef VOID (WINAPI* sWakeConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef BOOL (WINAPI* sCancelSynchronousIo) - (HANDLE hThread); - -/* Ntdll function pointers */ -extern sRtlNtStatusToDosError pRtlNtStatusToDosError; -extern sNtDeviceIoControlFile pNtDeviceIoControlFile; -extern sNtQueryInformationFile pNtQueryInformationFile; -extern sNtSetInformationFile pNtSetInformationFile; -extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; -extern sNtQueryDirectoryFile pNtQueryDirectoryFile; -extern sNtQuerySystemInformation pNtQuerySystemInformation; - - -/* Kernel32 function pointers */ -extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; -extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; -extern sCreateSymbolicLinkW pCreateSymbolicLinkW; -extern sCancelIoEx pCancelIoEx; -extern sInitializeConditionVariable pInitializeConditionVariable; -extern sSleepConditionVariableCS pSleepConditionVariableCS; -extern sSleepConditionVariableSRW pSleepConditionVariableSRW; -extern sWakeAllConditionVariable pWakeAllConditionVariable; -extern sWakeConditionVariable pWakeConditionVariable; -extern sCancelSynchronousIo pCancelSynchronousIo; - -#endif /* UV_WIN_WINAPI_H_ */ diff --git a/outside/libuv-v1.7.5/src/win/winsock.c b/outside/libuv-v1.7.5/src/win/winsock.c deleted file mode 100644 index d2e667e9f7..0000000000 --- a/outside/libuv-v1.7.5/src/win/winsock.c +++ /dev/null @@ -1,561 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "uv.h" -#include "internal.h" - - -/* Whether there are any non-IFS LSPs stacked on TCP */ -int uv_tcp_non_ifs_lsp_ipv4; -int uv_tcp_non_ifs_lsp_ipv6; - -/* Ip address used to bind to any port at any interface */ -struct sockaddr_in uv_addr_ip4_any_; -struct sockaddr_in6 uv_addr_ip6_any_; - - -/* - * Retrieves the pointer to a winsock extension function. - */ -static BOOL uv_get_extension_function(SOCKET socket, GUID guid, - void **target) { - int result; - DWORD bytes; - - result = WSAIoctl(socket, - SIO_GET_EXTENSION_FUNCTION_POINTER, - &guid, - sizeof(guid), - (void*)target, - sizeof(*target), - &bytes, - NULL, - NULL); - - if (result == SOCKET_ERROR) { - *target = NULL; - return FALSE; - } else { - return TRUE; - } -} - - -BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target) { - const GUID wsaid_acceptex = WSAID_ACCEPTEX; - return uv_get_extension_function(socket, wsaid_acceptex, (void**)target); -} - - -BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) { - const GUID wsaid_connectex = WSAID_CONNECTEX; - return uv_get_extension_function(socket, wsaid_connectex, (void**)target); -} - - -static int error_means_no_support(DWORD error) { - return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT || - error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT; -} - - -void uv_winsock_init() { - WSADATA wsa_data; - int errorno; - SOCKET dummy; - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - - /* Initialize winsock */ - errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data); - if (errorno != 0) { - uv_fatal_error(errorno, "WSAStartup"); - } - - /* Set implicit binding address used by connectEx */ - if (uv_ip4_addr("0.0.0.0", 0, &uv_addr_ip4_any_)) { - abort(); - } - - if (uv_ip6_addr("::", 0, &uv_addr_ip6_any_)) { - abort(); - } - - /* Detect non-IFS LSPs */ - dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); - - if (dummy != INVALID_SOCKET) { - opt_len = (int) sizeof protocol_info; - if (getsockopt(dummy, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "getsockopt"); - - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) - uv_tcp_non_ifs_lsp_ipv4 = 1; - - if (closesocket(dummy) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "closesocket"); - - } else if (!error_means_no_support(WSAGetLastError())) { - /* Any error other than "socket type not supported" is fatal. */ - uv_fatal_error(WSAGetLastError(), "socket"); - } - - /* Detect IPV6 support and non-IFS LSPs */ - dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); - - if (dummy != INVALID_SOCKET) { - opt_len = (int) sizeof protocol_info; - if (getsockopt(dummy, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "getsockopt"); - - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) - uv_tcp_non_ifs_lsp_ipv6 = 1; - - if (closesocket(dummy) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "closesocket"); - - } else if (!error_means_no_support(WSAGetLastError())) { - /* Any error other than "socket type not supported" is fatal. */ - uv_fatal_error(WSAGetLastError(), "socket"); - } -} - - -int uv_ntstatus_to_winsock_error(NTSTATUS status) { - switch (status) { - case STATUS_SUCCESS: - return ERROR_SUCCESS; - - case STATUS_PENDING: - return ERROR_IO_PENDING; - - case STATUS_INVALID_HANDLE: - case STATUS_OBJECT_TYPE_MISMATCH: - return WSAENOTSOCK; - - case STATUS_INSUFFICIENT_RESOURCES: - case STATUS_PAGEFILE_QUOTA: - case STATUS_COMMITMENT_LIMIT: - case STATUS_WORKING_SET_QUOTA: - case STATUS_NO_MEMORY: - case STATUS_QUOTA_EXCEEDED: - case STATUS_TOO_MANY_PAGING_FILES: - case STATUS_REMOTE_RESOURCES: - return WSAENOBUFS; - - case STATUS_TOO_MANY_ADDRESSES: - case STATUS_SHARING_VIOLATION: - case STATUS_ADDRESS_ALREADY_EXISTS: - return WSAEADDRINUSE; - - case STATUS_LINK_TIMEOUT: - case STATUS_IO_TIMEOUT: - case STATUS_TIMEOUT: - return WSAETIMEDOUT; - - case STATUS_GRACEFUL_DISCONNECT: - return WSAEDISCON; - - case STATUS_REMOTE_DISCONNECT: - case STATUS_CONNECTION_RESET: - case STATUS_LINK_FAILED: - case STATUS_CONNECTION_DISCONNECTED: - case STATUS_PORT_UNREACHABLE: - case STATUS_HOPLIMIT_EXCEEDED: - return WSAECONNRESET; - - case STATUS_LOCAL_DISCONNECT: - case STATUS_TRANSACTION_ABORTED: - case STATUS_CONNECTION_ABORTED: - return WSAECONNABORTED; - - case STATUS_BAD_NETWORK_PATH: - case STATUS_NETWORK_UNREACHABLE: - case STATUS_PROTOCOL_UNREACHABLE: - return WSAENETUNREACH; - - case STATUS_HOST_UNREACHABLE: - return WSAEHOSTUNREACH; - - case STATUS_CANCELLED: - case STATUS_REQUEST_ABORTED: - return WSAEINTR; - - case STATUS_BUFFER_OVERFLOW: - case STATUS_INVALID_BUFFER_SIZE: - return WSAEMSGSIZE; - - case STATUS_BUFFER_TOO_SMALL: - case STATUS_ACCESS_VIOLATION: - return WSAEFAULT; - - case STATUS_DEVICE_NOT_READY: - case STATUS_REQUEST_NOT_ACCEPTED: - return WSAEWOULDBLOCK; - - case STATUS_INVALID_NETWORK_RESPONSE: - case STATUS_NETWORK_BUSY: - case STATUS_NO_SUCH_DEVICE: - case STATUS_NO_SUCH_FILE: - case STATUS_OBJECT_PATH_NOT_FOUND: - case STATUS_OBJECT_NAME_NOT_FOUND: - case STATUS_UNEXPECTED_NETWORK_ERROR: - return WSAENETDOWN; - - case STATUS_INVALID_CONNECTION: - return WSAENOTCONN; - - case STATUS_REMOTE_NOT_LISTENING: - case STATUS_CONNECTION_REFUSED: - return WSAECONNREFUSED; - - case STATUS_PIPE_DISCONNECTED: - return WSAESHUTDOWN; - - case STATUS_CONFLICTING_ADDRESSES: - case STATUS_INVALID_ADDRESS: - case STATUS_INVALID_ADDRESS_COMPONENT: - return WSAEADDRNOTAVAIL; - - case STATUS_NOT_SUPPORTED: - case STATUS_NOT_IMPLEMENTED: - return WSAEOPNOTSUPP; - - case STATUS_ACCESS_DENIED: - return WSAEACCES; - - default: - if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) && - (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) { - /* It's a windows error that has been previously mapped to an */ - /* ntstatus code. */ - return (DWORD) (status & 0xffff); - } else { - /* The default fallback for unmappable ntstatus codes. */ - return WSAEINVAL; - } - } -} - - -/* - * This function provides a workaround for a bug in the winsock implementation - * of WSARecv. The problem is that when SetFileCompletionNotificationModes is - * used to avoid IOCP notifications of completed reads, WSARecv does not - * reliably indicate whether we can expect a completion package to be posted - * when the receive buffer is smaller than the received datagram. - * - * However it is desirable to use SetFileCompletionNotificationModes because - * it yields a massive performance increase. - * - * This function provides a workaround for that bug, but it only works for the - * specific case that we need it for. E.g. it assumes that the "avoid iocp" - * bit has been set, and supports only overlapped operation. It also requires - * the user to use the default msafd driver, doesn't work when other LSPs are - * stacked on top of it. - */ -int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { - NTSTATUS status; - void* apc_context; - IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; - AFD_RECV_INFO info; - DWORD error; - - if (overlapped == NULL || completion_routine != NULL) { - WSASetLastError(WSAEINVAL); - return SOCKET_ERROR; - } - - info.BufferArray = buffers; - info.BufferCount = buffer_count; - info.AfdFlags = AFD_OVERLAPPED; - info.TdiFlags = TDI_RECEIVE_NORMAL; - - if (*flags & MSG_PEEK) { - info.TdiFlags |= TDI_RECEIVE_PEEK; - } - - if (*flags & MSG_PARTIAL) { - info.TdiFlags |= TDI_RECEIVE_PARTIAL; - } - - if (!((intptr_t) overlapped->hEvent & 1)) { - apc_context = (void*) overlapped; - } else { - apc_context = NULL; - } - - iosb->Status = STATUS_PENDING; - iosb->Pointer = 0; - - status = pNtDeviceIoControlFile((HANDLE) socket, - overlapped->hEvent, - NULL, - apc_context, - iosb, - IOCTL_AFD_RECEIVE, - &info, - sizeof(info), - NULL, - 0); - - *flags = 0; - *bytes = (DWORD) iosb->Information; - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - case STATUS_BUFFER_OVERFLOW: - error = WSAEMSGSIZE; - break; - - case STATUS_RECEIVE_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} - - -/* See description of uv_wsarecv_workaround. */ -int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, - int* addr_len, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { - NTSTATUS status; - void* apc_context; - IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; - AFD_RECV_DATAGRAM_INFO info; - DWORD error; - - if (overlapped == NULL || addr == NULL || addr_len == NULL || - completion_routine != NULL) { - WSASetLastError(WSAEINVAL); - return SOCKET_ERROR; - } - - info.BufferArray = buffers; - info.BufferCount = buffer_count; - info.AfdFlags = AFD_OVERLAPPED; - info.TdiFlags = TDI_RECEIVE_NORMAL; - info.Address = addr; - info.AddressLength = addr_len; - - if (*flags & MSG_PEEK) { - info.TdiFlags |= TDI_RECEIVE_PEEK; - } - - if (*flags & MSG_PARTIAL) { - info.TdiFlags |= TDI_RECEIVE_PARTIAL; - } - - if (!((intptr_t) overlapped->hEvent & 1)) { - apc_context = (void*) overlapped; - } else { - apc_context = NULL; - } - - iosb->Status = STATUS_PENDING; - iosb->Pointer = 0; - - status = pNtDeviceIoControlFile((HANDLE) socket, - overlapped->hEvent, - NULL, - apc_context, - iosb, - IOCTL_AFD_RECEIVE_DATAGRAM, - &info, - sizeof(info), - NULL, - 0); - - *flags = 0; - *bytes = (DWORD) iosb->Information; - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - case STATUS_BUFFER_OVERFLOW: - error = WSAEMSGSIZE; - break; - - case STATUS_RECEIVE_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} - - -int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, - AFD_POLL_INFO* info_out, OVERLAPPED* overlapped) { - IO_STATUS_BLOCK iosb; - IO_STATUS_BLOCK* iosb_ptr; - HANDLE event = NULL; - void* apc_context; - NTSTATUS status; - DWORD error; - - if (overlapped != NULL) { - /* Overlapped operation. */ - iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal; - event = overlapped->hEvent; - - /* Do not report iocp completion if hEvent is tagged. */ - if ((uintptr_t) event & 1) { - event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1); - apc_context = NULL; - } else { - apc_context = overlapped; - } - - } else { - /* Blocking operation. */ - iosb_ptr = &iosb; - event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (event == NULL) { - return SOCKET_ERROR; - } - apc_context = NULL; - } - - iosb_ptr->Status = STATUS_PENDING; - status = pNtDeviceIoControlFile((HANDLE) socket, - event, - NULL, - apc_context, - iosb_ptr, - IOCTL_AFD_POLL, - info_in, - sizeof *info_in, - info_out, - sizeof *info_out); - - if (overlapped == NULL) { - /* If this is a blocking operation, wait for the event to become */ - /* signaled, and then grab the real status from the io status block. */ - if (status == STATUS_PENDING) { - DWORD r = WaitForSingleObject(event, INFINITE); - - if (r == WAIT_FAILED) { - DWORD saved_error = GetLastError(); - CloseHandle(event); - WSASetLastError(saved_error); - return SOCKET_ERROR; - } - - status = iosb.Status; - } - - CloseHandle(event); - } - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} diff --git a/outside/libuv-v1.7.5/src/win/winsock.h b/outside/libuv-v1.7.5/src/win/winsock.h deleted file mode 100644 index 7c007ab493..0000000000 --- a/outside/libuv-v1.7.5/src/win/winsock.h +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_WINSOCK_H_ -#define UV_WIN_WINSOCK_H_ - -#include -#include -#include -#include -#include - -#include "winapi.h" - - -/* - * MinGW is missing these too - */ -#ifndef SO_UPDATE_CONNECT_CONTEXT -# define SO_UPDATE_CONNECT_CONTEXT 0x7010 -#endif - -#ifndef TCP_KEEPALIVE -# define TCP_KEEPALIVE 3 -#endif - -#ifndef IPV6_V6ONLY -# define IPV6_V6ONLY 27 -#endif - -#ifndef IPV6_HOPLIMIT -# define IPV6_HOPLIMIT 21 -#endif - -#ifndef SIO_BASE_HANDLE -# define SIO_BASE_HANDLE 0x48000022 -#endif - -/* - * TDI defines that are only in the DDK. - * We only need receive flags so far. - */ -#ifndef TDI_RECEIVE_NORMAL - #define TDI_RECEIVE_BROADCAST 0x00000004 - #define TDI_RECEIVE_MULTICAST 0x00000008 - #define TDI_RECEIVE_PARTIAL 0x00000010 - #define TDI_RECEIVE_NORMAL 0x00000020 - #define TDI_RECEIVE_EXPEDITED 0x00000040 - #define TDI_RECEIVE_PEEK 0x00000080 - #define TDI_RECEIVE_NO_RESPONSE_EXP 0x00000100 - #define TDI_RECEIVE_COPY_LOOKAHEAD 0x00000200 - #define TDI_RECEIVE_ENTIRE_MESSAGE 0x00000400 - #define TDI_RECEIVE_AT_DISPATCH_LEVEL 0x00000800 - #define TDI_RECEIVE_CONTROL_INFO 0x00001000 - #define TDI_RECEIVE_FORCE_INDICATION 0x00002000 - #define TDI_RECEIVE_NO_PUSH 0x00004000 -#endif - -/* - * The "Auxiliary Function Driver" is the windows kernel-mode driver that does - * TCP, UDP etc. Winsock is just a layer that dispatches requests to it. - * Having these definitions allows us to bypass winsock and make an AFD kernel - * call directly, avoiding a bug in winsock's recvfrom implementation. - */ - -#define AFD_NO_FAST_IO 0x00000001 -#define AFD_OVERLAPPED 0x00000002 -#define AFD_IMMEDIATE 0x00000004 - -#define AFD_POLL_RECEIVE_BIT 0 -#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT) -#define AFD_POLL_RECEIVE_EXPEDITED_BIT 1 -#define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT) -#define AFD_POLL_SEND_BIT 2 -#define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT) -#define AFD_POLL_DISCONNECT_BIT 3 -#define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT) -#define AFD_POLL_ABORT_BIT 4 -#define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT) -#define AFD_POLL_LOCAL_CLOSE_BIT 5 -#define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT) -#define AFD_POLL_CONNECT_BIT 6 -#define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT) -#define AFD_POLL_ACCEPT_BIT 7 -#define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT) -#define AFD_POLL_CONNECT_FAIL_BIT 8 -#define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT) -#define AFD_POLL_QOS_BIT 9 -#define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT) -#define AFD_POLL_GROUP_QOS_BIT 10 -#define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT) - -#define AFD_NUM_POLL_EVENTS 11 -#define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1) - -typedef struct _AFD_RECV_DATAGRAM_INFO { - LPWSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; - struct sockaddr* Address; - int* AddressLength; -} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO; - -typedef struct _AFD_RECV_INFO { - LPWSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; -} AFD_RECV_INFO, *PAFD_RECV_INFO; - - -#define _AFD_CONTROL_CODE(operation, method) \ - ((FSCTL_AFD_BASE) << 12 | (operation << 2) | method) - -#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK - -#define AFD_RECEIVE 5 -#define AFD_RECEIVE_DATAGRAM 6 -#define AFD_POLL 9 - -#define IOCTL_AFD_RECEIVE \ - _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER) - -#define IOCTL_AFD_RECEIVE_DATAGRAM \ - _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER) - -#define IOCTL_AFD_POLL \ - _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED) - -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) -typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP { - /* FIXME: __C89_NAMELESS was removed */ - /* __C89_NAMELESS */ union { - ULONGLONG Alignment; - /* __C89_NAMELESS */ struct { - ULONG Length; - DWORD Flags; - }; - }; - struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next; - SOCKET_ADDRESS Address; - IP_PREFIX_ORIGIN PrefixOrigin; - IP_SUFFIX_ORIGIN SuffixOrigin; - IP_DAD_STATE DadState; - ULONG ValidLifetime; - ULONG PreferredLifetime; - ULONG LeaseLifetime; -} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP; - -typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH { - union { - ULONGLONG Alignment; - struct { - ULONG Length; - DWORD Flags; - }; - }; - struct _IP_ADAPTER_UNICAST_ADDRESS_LH *Next; - SOCKET_ADDRESS Address; - IP_PREFIX_ORIGIN PrefixOrigin; - IP_SUFFIX_ORIGIN SuffixOrigin; - IP_DAD_STATE DadState; - ULONG ValidLifetime; - ULONG PreferredLifetime; - ULONG LeaseLifetime; - UINT8 OnLinkPrefixLength; -} IP_ADAPTER_UNICAST_ADDRESS_LH,*PIP_ADAPTER_UNICAST_ADDRESS_LH; - -#endif - -#endif /* UV_WIN_WINSOCK_H_ */ diff --git a/outside/libuv-v1.7.5/test/benchmark-async-pummel.c b/outside/libuv-v1.7.5/test/benchmark-async-pummel.c deleted file mode 100644 index cca3de1062..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-async-pummel.c +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#include -#include - -#define NUM_PINGS (1000 * 1000) -#define ACCESS_ONCE(type, var) (*(volatile type*) &(var)) - -static unsigned int callbacks; -static volatile int done; - -static const char running[] = "running"; -static const char stop[] = "stop"; -static const char stopped[] = "stopped"; - - -static void async_cb(uv_async_t* handle) { - if (++callbacks == NUM_PINGS) { - /* Tell the pummel thread to stop. */ - ACCESS_ONCE(const char*, handle->data) = stop; - - /* Wait for for the pummel thread to acknowledge that it has stoppped. */ - while (ACCESS_ONCE(const char*, handle->data) != stopped) - uv_sleep(0); - - uv_close((uv_handle_t*) handle, NULL); - } -} - - -static void pummel(void* arg) { - uv_async_t* handle = (uv_async_t*) arg; - - while (ACCESS_ONCE(const char*, handle->data) == running) - uv_async_send(handle); - - /* Acknowledge that we've seen handle->data change. */ - ACCESS_ONCE(const char*, handle->data) = stopped; -} - - -static int test_async_pummel(int nthreads) { - uv_thread_t* tids; - uv_async_t handle; - uint64_t time; - int i; - - tids = calloc(nthreads, sizeof(tids[0])); - ASSERT(tids != NULL); - - ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb)); - ACCESS_ONCE(const char*, handle.data) = running; - - for (i = 0; i < nthreads; i++) - ASSERT(0 == uv_thread_create(tids + i, pummel, &handle)); - - time = uv_hrtime(); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - time = uv_hrtime() - time; - done = 1; - - for (i = 0; i < nthreads; i++) - ASSERT(0 == uv_thread_join(tids + i)); - - printf("async_pummel_%d: %s callbacks in %.2f seconds (%s/sec)\n", - nthreads, - fmt(callbacks), - time / 1e9, - fmt(callbacks / (time / 1e9))); - - free(tids); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -BENCHMARK_IMPL(async_pummel_1) { - return test_async_pummel(1); -} - - -BENCHMARK_IMPL(async_pummel_2) { - return test_async_pummel(2); -} - - -BENCHMARK_IMPL(async_pummel_4) { - return test_async_pummel(4); -} - - -BENCHMARK_IMPL(async_pummel_8) { - return test_async_pummel(8); -} diff --git a/outside/libuv-v1.7.5/test/benchmark-async.c b/outside/libuv-v1.7.5/test/benchmark-async.c deleted file mode 100644 index e44165f2b8..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-async.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#include -#include - -#define NUM_PINGS (1000 * 1000) - -struct ctx { - uv_loop_t loop; - uv_thread_t thread; - uv_async_t main_async; /* wake up main thread */ - uv_async_t worker_async; /* wake up worker */ - unsigned int nthreads; - unsigned int main_sent; - unsigned int main_seen; - unsigned int worker_sent; - unsigned int worker_seen; -}; - - -static void worker_async_cb(uv_async_t* handle) { - struct ctx* ctx = container_of(handle, struct ctx, worker_async); - - ASSERT(0 == uv_async_send(&ctx->main_async)); - ctx->worker_sent++; - ctx->worker_seen++; - - if (ctx->worker_sent >= NUM_PINGS) - uv_close((uv_handle_t*) &ctx->worker_async, NULL); -} - - -static void main_async_cb(uv_async_t* handle) { - struct ctx* ctx = container_of(handle, struct ctx, main_async); - - ASSERT(0 == uv_async_send(&ctx->worker_async)); - ctx->main_sent++; - ctx->main_seen++; - - if (ctx->main_sent >= NUM_PINGS) - uv_close((uv_handle_t*) &ctx->main_async, NULL); -} - - -static void worker(void* arg) { - struct ctx* ctx = arg; - ASSERT(0 == uv_async_send(&ctx->main_async)); - ASSERT(0 == uv_run(&ctx->loop, UV_RUN_DEFAULT)); - uv_loop_close(&ctx->loop); -} - - -static int test_async(int nthreads) { - struct ctx* threads; - struct ctx* ctx; - uint64_t time; - int i; - - threads = calloc(nthreads, sizeof(threads[0])); - ASSERT(threads != NULL); - - for (i = 0; i < nthreads; i++) { - ctx = threads + i; - ctx->nthreads = nthreads; - ASSERT(0 == uv_loop_init(&ctx->loop)); - ASSERT(0 == uv_async_init(&ctx->loop, &ctx->worker_async, worker_async_cb)); - ASSERT(0 == uv_async_init(uv_default_loop(), - &ctx->main_async, - main_async_cb)); - ASSERT(0 == uv_thread_create(&ctx->thread, worker, ctx)); - } - - time = uv_hrtime(); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - for (i = 0; i < nthreads; i++) - ASSERT(0 == uv_thread_join(&threads[i].thread)); - - time = uv_hrtime() - time; - - for (i = 0; i < nthreads; i++) { - ctx = threads + i; - ASSERT(ctx->worker_sent == NUM_PINGS); - ASSERT(ctx->worker_seen == NUM_PINGS); - ASSERT(ctx->main_sent == (unsigned int) NUM_PINGS); - ASSERT(ctx->main_seen == (unsigned int) NUM_PINGS); - } - - printf("async%d: %.2f sec (%s/sec)\n", - nthreads, - time / 1e9, - fmt(NUM_PINGS / (time / 1e9))); - - free(threads); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -BENCHMARK_IMPL(async1) { - return test_async(1); -} - - -BENCHMARK_IMPL(async2) { - return test_async(2); -} - - -BENCHMARK_IMPL(async4) { - return test_async(4); -} - - -BENCHMARK_IMPL(async8) { - return test_async(8); -} diff --git a/outside/libuv-v1.7.5/test/benchmark-fs-stat.c b/outside/libuv-v1.7.5/test/benchmark-fs-stat.c deleted file mode 100644 index 32d2589586..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-fs-stat.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#include -#include - -#define NUM_SYNC_REQS (10 * 1e5) -#define NUM_ASYNC_REQS (1 * (int) 1e5) -#define MAX_CONCURRENT_REQS 32 - -#define sync_stat(req, path) \ - do { \ - uv_fs_stat(NULL, (req), (path), NULL); \ - uv_fs_req_cleanup((req)); \ - } \ - while (0) - -struct async_req { - const char* path; - uv_fs_t fs_req; - int* count; -}; - - -static void warmup(const char* path) { - uv_fs_t reqs[MAX_CONCURRENT_REQS]; - unsigned int i; - - /* warm up the thread pool */ - for (i = 0; i < ARRAY_SIZE(reqs); i++) - uv_fs_stat(uv_default_loop(), reqs + i, path, uv_fs_req_cleanup); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - /* warm up the OS dirent cache */ - for (i = 0; i < 16; i++) - sync_stat(reqs + 0, path); -} - - -static void sync_bench(const char* path) { - uint64_t before; - uint64_t after; - uv_fs_t req; - int i; - - /* do the sync benchmark */ - before = uv_hrtime(); - - for (i = 0; i < NUM_SYNC_REQS; i++) - sync_stat(&req, path); - - after = uv_hrtime(); - - printf("%s stats (sync): %.2fs (%s/s)\n", - fmt(1.0 * NUM_SYNC_REQS), - (after - before) / 1e9, - fmt((1.0 * NUM_SYNC_REQS) / ((after - before) / 1e9))); - fflush(stdout); -} - - -static void stat_cb(uv_fs_t* fs_req) { - struct async_req* req = container_of(fs_req, struct async_req, fs_req); - uv_fs_req_cleanup(&req->fs_req); - if (*req->count == 0) return; - uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb); - (*req->count)--; -} - - -static void async_bench(const char* path) { - struct async_req reqs[MAX_CONCURRENT_REQS]; - struct async_req* req; - uint64_t before; - uint64_t after; - int count; - int i; - - for (i = 1; i <= MAX_CONCURRENT_REQS; i++) { - count = NUM_ASYNC_REQS; - - for (req = reqs; req < reqs + i; req++) { - req->path = path; - req->count = &count; - uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb); - } - - before = uv_hrtime(); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - after = uv_hrtime(); - - printf("%s stats (%d concurrent): %.2fs (%s/s)\n", - fmt(1.0 * NUM_ASYNC_REQS), - i, - (after - before) / 1e9, - fmt((1.0 * NUM_ASYNC_REQS) / ((after - before) / 1e9))); - fflush(stdout); - } -} - - -/* This benchmark aims to measure the overhead of doing I/O syscalls from - * the thread pool. The stat() syscall was chosen because its results are - * easy for the operating system to cache, taking the actual I/O overhead - * out of the equation. - */ -BENCHMARK_IMPL(fs_stat) { - const char path[] = "."; - warmup(path); - sync_bench(path); - async_bench(path); - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-getaddrinfo.c b/outside/libuv-v1.7.5/test/benchmark-getaddrinfo.c deleted file mode 100644 index 1dbc23ddba..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-getaddrinfo.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - -#define CONCURRENT_CALLS 10 -#define TOTAL_CALLS 10000 - -static const char* name = "localhost"; - -static uv_loop_t* loop; - -static uv_getaddrinfo_t handles[CONCURRENT_CALLS]; - -static int calls_initiated = 0; -static int calls_completed = 0; -static int64_t start_time; -static int64_t end_time; - - -static void getaddrinfo_initiate(uv_getaddrinfo_t* handle); - - -static void getaddrinfo_cb(uv_getaddrinfo_t* handle, int status, - struct addrinfo* res) { - ASSERT(status == 0); - calls_completed++; - if (calls_initiated < TOTAL_CALLS) { - getaddrinfo_initiate(handle); - } - - uv_freeaddrinfo(res); -} - - -static void getaddrinfo_initiate(uv_getaddrinfo_t* handle) { - int r; - - calls_initiated++; - - r = uv_getaddrinfo(loop, handle, &getaddrinfo_cb, name, NULL, NULL); - ASSERT(r == 0); -} - - -BENCHMARK_IMPL(getaddrinfo) { - int i; - - loop = uv_default_loop(); - - uv_update_time(loop); - start_time = uv_now(loop); - - for (i = 0; i < CONCURRENT_CALLS; i++) { - getaddrinfo_initiate(&handles[i]); - } - - uv_run(loop, UV_RUN_DEFAULT); - - uv_update_time(loop); - end_time = uv_now(loop); - - ASSERT(calls_initiated == TOTAL_CALLS); - ASSERT(calls_completed == TOTAL_CALLS); - - fprintf(stderr, "getaddrinfo: %.0f req/s\n", - (double) calls_completed / (double) (end_time - start_time) * 1000.0); - fflush(stderr); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-list.h b/outside/libuv-v1.7.5/test/benchmark-list.h deleted file mode 100644 index 1e843071c0..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-list.h +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -BENCHMARK_DECLARE (sizes) -BENCHMARK_DECLARE (loop_count) -BENCHMARK_DECLARE (loop_count_timed) -BENCHMARK_DECLARE (ping_pongs) -BENCHMARK_DECLARE (tcp_write_batch) -BENCHMARK_DECLARE (tcp4_pound_100) -BENCHMARK_DECLARE (tcp4_pound_1000) -BENCHMARK_DECLARE (pipe_pound_100) -BENCHMARK_DECLARE (pipe_pound_1000) -BENCHMARK_DECLARE (tcp_pump100_client) -BENCHMARK_DECLARE (tcp_pump1_client) -BENCHMARK_DECLARE (pipe_pump100_client) -BENCHMARK_DECLARE (pipe_pump1_client) - -BENCHMARK_DECLARE (tcp_multi_accept2) -BENCHMARK_DECLARE (tcp_multi_accept4) -BENCHMARK_DECLARE (tcp_multi_accept8) - -/* Run until X packets have been sent/received. */ -BENCHMARK_DECLARE (udp_pummel_1v1) -BENCHMARK_DECLARE (udp_pummel_1v10) -BENCHMARK_DECLARE (udp_pummel_1v100) -BENCHMARK_DECLARE (udp_pummel_1v1000) -BENCHMARK_DECLARE (udp_pummel_10v10) -BENCHMARK_DECLARE (udp_pummel_10v100) -BENCHMARK_DECLARE (udp_pummel_10v1000) -BENCHMARK_DECLARE (udp_pummel_100v100) -BENCHMARK_DECLARE (udp_pummel_100v1000) -BENCHMARK_DECLARE (udp_pummel_1000v1000) - -/* Run until X seconds have elapsed. */ -BENCHMARK_DECLARE (udp_timed_pummel_1v1) -BENCHMARK_DECLARE (udp_timed_pummel_1v10) -BENCHMARK_DECLARE (udp_timed_pummel_1v100) -BENCHMARK_DECLARE (udp_timed_pummel_1v1000) -BENCHMARK_DECLARE (udp_timed_pummel_10v10) -BENCHMARK_DECLARE (udp_timed_pummel_10v100) -BENCHMARK_DECLARE (udp_timed_pummel_10v1000) -BENCHMARK_DECLARE (udp_timed_pummel_100v100) -BENCHMARK_DECLARE (udp_timed_pummel_100v1000) -BENCHMARK_DECLARE (udp_timed_pummel_1000v1000) - -BENCHMARK_DECLARE (getaddrinfo) -BENCHMARK_DECLARE (fs_stat) -BENCHMARK_DECLARE (async1) -BENCHMARK_DECLARE (async2) -BENCHMARK_DECLARE (async4) -BENCHMARK_DECLARE (async8) -BENCHMARK_DECLARE (async_pummel_1) -BENCHMARK_DECLARE (async_pummel_2) -BENCHMARK_DECLARE (async_pummel_4) -BENCHMARK_DECLARE (async_pummel_8) -BENCHMARK_DECLARE (spawn) -BENCHMARK_DECLARE (thread_create) -BENCHMARK_DECLARE (million_async) -BENCHMARK_DECLARE (million_timers) -HELPER_DECLARE (tcp4_blackhole_server) -HELPER_DECLARE (tcp_pump_server) -HELPER_DECLARE (pipe_pump_server) -HELPER_DECLARE (tcp4_echo_server) -HELPER_DECLARE (pipe_echo_server) -HELPER_DECLARE (dns_server) - -TASK_LIST_START - BENCHMARK_ENTRY (sizes) - BENCHMARK_ENTRY (loop_count) - BENCHMARK_ENTRY (loop_count_timed) - - BENCHMARK_ENTRY (ping_pongs) - BENCHMARK_HELPER (ping_pongs, tcp4_echo_server) - - BENCHMARK_ENTRY (tcp_write_batch) - BENCHMARK_HELPER (tcp_write_batch, tcp4_blackhole_server) - - BENCHMARK_ENTRY (tcp_pump100_client) - BENCHMARK_HELPER (tcp_pump100_client, tcp_pump_server) - - BENCHMARK_ENTRY (tcp_pump1_client) - BENCHMARK_HELPER (tcp_pump1_client, tcp_pump_server) - - BENCHMARK_ENTRY (tcp4_pound_100) - BENCHMARK_HELPER (tcp4_pound_100, tcp4_echo_server) - - BENCHMARK_ENTRY (tcp4_pound_1000) - BENCHMARK_HELPER (tcp4_pound_1000, tcp4_echo_server) - - BENCHMARK_ENTRY (pipe_pump100_client) - BENCHMARK_HELPER (pipe_pump100_client, pipe_pump_server) - - BENCHMARK_ENTRY (pipe_pump1_client) - BENCHMARK_HELPER (pipe_pump1_client, pipe_pump_server) - - BENCHMARK_ENTRY (pipe_pound_100) - BENCHMARK_HELPER (pipe_pound_100, pipe_echo_server) - - BENCHMARK_ENTRY (pipe_pound_1000) - BENCHMARK_HELPER (pipe_pound_1000, pipe_echo_server) - - BENCHMARK_ENTRY (tcp_multi_accept2) - BENCHMARK_ENTRY (tcp_multi_accept4) - BENCHMARK_ENTRY (tcp_multi_accept8) - - BENCHMARK_ENTRY (udp_pummel_1v1) - BENCHMARK_ENTRY (udp_pummel_1v10) - BENCHMARK_ENTRY (udp_pummel_1v100) - BENCHMARK_ENTRY (udp_pummel_1v1000) - BENCHMARK_ENTRY (udp_pummel_10v10) - BENCHMARK_ENTRY (udp_pummel_10v100) - BENCHMARK_ENTRY (udp_pummel_10v1000) - BENCHMARK_ENTRY (udp_pummel_100v100) - BENCHMARK_ENTRY (udp_pummel_100v1000) - BENCHMARK_ENTRY (udp_pummel_1000v1000) - - BENCHMARK_ENTRY (udp_timed_pummel_1v1) - BENCHMARK_ENTRY (udp_timed_pummel_1v10) - BENCHMARK_ENTRY (udp_timed_pummel_1v100) - BENCHMARK_ENTRY (udp_timed_pummel_1v1000) - BENCHMARK_ENTRY (udp_timed_pummel_10v10) - BENCHMARK_ENTRY (udp_timed_pummel_10v100) - BENCHMARK_ENTRY (udp_timed_pummel_10v1000) - BENCHMARK_ENTRY (udp_timed_pummel_100v100) - BENCHMARK_ENTRY (udp_timed_pummel_100v1000) - BENCHMARK_ENTRY (udp_timed_pummel_1000v1000) - - BENCHMARK_ENTRY (getaddrinfo) - - BENCHMARK_ENTRY (fs_stat) - - BENCHMARK_ENTRY (async1) - BENCHMARK_ENTRY (async2) - BENCHMARK_ENTRY (async4) - BENCHMARK_ENTRY (async8) - BENCHMARK_ENTRY (async_pummel_1) - BENCHMARK_ENTRY (async_pummel_2) - BENCHMARK_ENTRY (async_pummel_4) - BENCHMARK_ENTRY (async_pummel_8) - - BENCHMARK_ENTRY (spawn) - BENCHMARK_ENTRY (thread_create) - BENCHMARK_ENTRY (million_async) - BENCHMARK_ENTRY (million_timers) -TASK_LIST_END diff --git a/outside/libuv-v1.7.5/test/benchmark-loop-count.c b/outside/libuv-v1.7.5/test/benchmark-loop-count.c deleted file mode 100644 index 970a94c2fe..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-loop-count.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#include -#include - -#define NUM_TICKS (2 * 1000 * 1000) - -static unsigned long ticks; -static uv_idle_t idle_handle; -static uv_timer_t timer_handle; - - -static void idle_cb(uv_idle_t* handle) { - if (++ticks == NUM_TICKS) - uv_idle_stop(handle); -} - - -static void idle2_cb(uv_idle_t* handle) { - ticks++; -} - - -static void timer_cb(uv_timer_t* handle) { - uv_idle_stop(&idle_handle); - uv_timer_stop(&timer_handle); -} - - -BENCHMARK_IMPL(loop_count) { - uv_loop_t* loop = uv_default_loop(); - uint64_t ns; - - uv_idle_init(loop, &idle_handle); - uv_idle_start(&idle_handle, idle_cb); - - ns = uv_hrtime(); - uv_run(loop, UV_RUN_DEFAULT); - ns = uv_hrtime() - ns; - - ASSERT(ticks == NUM_TICKS); - - fprintf(stderr, "loop_count: %d ticks in %.2fs (%.0f/s)\n", - NUM_TICKS, - ns / 1e9, - NUM_TICKS / (ns / 1e9)); - fflush(stderr); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -BENCHMARK_IMPL(loop_count_timed) { - uv_loop_t* loop = uv_default_loop(); - - uv_idle_init(loop, &idle_handle); - uv_idle_start(&idle_handle, idle2_cb); - - uv_timer_init(loop, &timer_handle); - uv_timer_start(&timer_handle, timer_cb, 5000, 0); - - uv_run(loop, UV_RUN_DEFAULT); - - fprintf(stderr, "loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0); - fflush(stderr); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-million-async.c b/outside/libuv-v1.7.5/test/benchmark-million-async.c deleted file mode 100644 index 5395ed54ba..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-million-async.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -struct async_container { - unsigned async_events; - unsigned handles_seen; - uv_async_t async_handles[1024 * 1024]; -}; - -static volatile int done; -static uv_thread_t thread_id; -static struct async_container* container; - - -static unsigned fastrand(void) { - static unsigned g = 0; - g = g * 214013 + 2531011; - return g; -} - - -static void thread_cb(void* arg) { - unsigned i; - - while (done == 0) { - i = fastrand() % ARRAY_SIZE(container->async_handles); - uv_async_send(container->async_handles + i); - } -} - - -static void async_cb(uv_async_t* handle) { - container->async_events++; - handle->data = handle; -} - - -static void timer_cb(uv_timer_t* handle) { - unsigned i; - - done = 1; - ASSERT(0 == uv_thread_join(&thread_id)); - - for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) { - uv_async_t* handle = container->async_handles + i; - - if (handle->data != NULL) - container->handles_seen++; - - uv_close((uv_handle_t*) handle, NULL); - } - - uv_close((uv_handle_t*) handle, NULL); -} - - -BENCHMARK_IMPL(million_async) { - uv_timer_t timer_handle; - uv_async_t* handle; - uv_loop_t* loop; - int timeout; - unsigned i; - - loop = uv_default_loop(); - timeout = 5000; - - container = malloc(sizeof(*container)); - ASSERT(container != NULL); - container->async_events = 0; - container->handles_seen = 0; - - for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) { - handle = container->async_handles + i; - ASSERT(0 == uv_async_init(loop, handle, async_cb)); - handle->data = NULL; - } - - ASSERT(0 == uv_timer_init(loop, &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, timeout, 0)); - ASSERT(0 == uv_thread_create(&thread_id, thread_cb, NULL)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - printf("%s async events in %.1f seconds (%s/s, %s unique handles seen)\n", - fmt(container->async_events), - timeout / 1000., - fmt(container->async_events / (timeout / 1000.)), - fmt(container->handles_seen)); - free(container); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-million-timers.c b/outside/libuv-v1.7.5/test/benchmark-million-timers.c deleted file mode 100644 index 60a308bef1..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-million-timers.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#define NUM_TIMERS (10 * 1000 * 1000) - -static int timer_cb_called; -static int close_cb_called; - - -static void timer_cb(uv_timer_t* handle) { - timer_cb_called++; -} - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -BENCHMARK_IMPL(million_timers) { - uv_timer_t* timers; - uv_loop_t* loop; - uint64_t before_all; - uint64_t before_run; - uint64_t after_run; - uint64_t after_all; - int timeout; - int i; - - timers = malloc(NUM_TIMERS * sizeof(timers[0])); - ASSERT(timers != NULL); - - loop = uv_default_loop(); - timeout = 0; - - before_all = uv_hrtime(); - for (i = 0; i < NUM_TIMERS; i++) { - if (i % 1000 == 0) timeout++; - ASSERT(0 == uv_timer_init(loop, timers + i)); - ASSERT(0 == uv_timer_start(timers + i, timer_cb, timeout, 0)); - } - - before_run = uv_hrtime(); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - after_run = uv_hrtime(); - - for (i = 0; i < NUM_TIMERS; i++) - uv_close((uv_handle_t*) (timers + i), close_cb); - - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - after_all = uv_hrtime(); - - ASSERT(timer_cb_called == NUM_TIMERS); - ASSERT(close_cb_called == NUM_TIMERS); - free(timers); - - fprintf(stderr, "%.2f seconds total\n", (after_all - before_all) / 1e9); - fprintf(stderr, "%.2f seconds init\n", (before_run - before_all) / 1e9); - fprintf(stderr, "%.2f seconds dispatch\n", (after_run - before_run) / 1e9); - fprintf(stderr, "%.2f seconds cleanup\n", (after_all - after_run) / 1e9); - fflush(stderr); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-multi-accept.c b/outside/libuv-v1.7.5/test/benchmark-multi-accept.c deleted file mode 100644 index 2f32c0caf4..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-multi-accept.c +++ /dev/null @@ -1,447 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#define IPC_PIPE_NAME TEST_PIPENAME -#define NUM_CONNECTS (250 * 1000) - -union stream_handle { - uv_pipe_t pipe; - uv_tcp_t tcp; -}; - -/* Use as (uv_stream_t *) &handle_storage -- it's kind of clunky but it - * avoids aliasing warnings. - */ -typedef unsigned char handle_storage_t[sizeof(union stream_handle)]; - -/* Used for passing around the listen handle, not part of the benchmark proper. - * We have an overabundance of server types here. It works like this: - * - * 1. The main thread starts an IPC pipe server. - * 2. The worker threads connect to the IPC server and obtain a listen handle. - * 3. The worker threads start accepting requests on the listen handle. - * 4. The main thread starts connecting repeatedly. - * - * Step #4 should perhaps be farmed out over several threads. - */ -struct ipc_server_ctx { - handle_storage_t server_handle; - unsigned int num_connects; - uv_pipe_t ipc_pipe; -}; - -struct ipc_peer_ctx { - handle_storage_t peer_handle; - uv_write_t write_req; -}; - -struct ipc_client_ctx { - uv_connect_t connect_req; - uv_stream_t* server_handle; - uv_pipe_t ipc_pipe; - char scratch[16]; -}; - -/* Used in the actual benchmark. */ -struct server_ctx { - handle_storage_t server_handle; - unsigned int num_connects; - uv_async_t async_handle; - uv_thread_t thread_id; - uv_sem_t semaphore; -}; - -struct client_ctx { - handle_storage_t client_handle; - unsigned int num_connects; - uv_connect_t connect_req; - uv_idle_t idle_handle; -}; - -static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status); -static void ipc_write_cb(uv_write_t* req, int status); -static void ipc_close_cb(uv_handle_t* handle); -static void ipc_connect_cb(uv_connect_t* req, int status); -static void ipc_read_cb(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf); -static void ipc_alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf); - -static void sv_async_cb(uv_async_t* handle); -static void sv_connection_cb(uv_stream_t* server_handle, int status); -static void sv_read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf); -static void sv_alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf); - -static void cl_connect_cb(uv_connect_t* req, int status); -static void cl_idle_cb(uv_idle_t* handle); -static void cl_close_cb(uv_handle_t* handle); - -static struct sockaddr_in listen_addr; - - -static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) { - struct ipc_server_ctx* sc; - struct ipc_peer_ctx* pc; - uv_loop_t* loop; - uv_buf_t buf; - - loop = ipc_pipe->loop; - buf = uv_buf_init("PING", 4); - sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe); - pc = calloc(1, sizeof(*pc)); - ASSERT(pc != NULL); - - if (ipc_pipe->type == UV_TCP) - ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle)); - else if (ipc_pipe->type == UV_NAMED_PIPE) - ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) &pc->peer_handle, 1)); - else - ASSERT(0); - - ASSERT(0 == uv_accept(ipc_pipe, (uv_stream_t*) &pc->peer_handle)); - ASSERT(0 == uv_write2(&pc->write_req, - (uv_stream_t*) &pc->peer_handle, - &buf, - 1, - (uv_stream_t*) &sc->server_handle, - ipc_write_cb)); - - if (--sc->num_connects == 0) - uv_close((uv_handle_t*) ipc_pipe, NULL); -} - - -static void ipc_write_cb(uv_write_t* req, int status) { - struct ipc_peer_ctx* ctx; - ctx = container_of(req, struct ipc_peer_ctx, write_req); - uv_close((uv_handle_t*) &ctx->peer_handle, ipc_close_cb); -} - - -static void ipc_close_cb(uv_handle_t* handle) { - struct ipc_peer_ctx* ctx; - ctx = container_of(handle, struct ipc_peer_ctx, peer_handle); - free(ctx); -} - - -static void ipc_connect_cb(uv_connect_t* req, int status) { - struct ipc_client_ctx* ctx; - ctx = container_of(req, struct ipc_client_ctx, connect_req); - ASSERT(0 == status); - ASSERT(0 == uv_read_start((uv_stream_t*) &ctx->ipc_pipe, - ipc_alloc_cb, - ipc_read_cb)); -} - - -static void ipc_alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - struct ipc_client_ctx* ctx; - ctx = container_of(handle, struct ipc_client_ctx, ipc_pipe); - buf->base = ctx->scratch; - buf->len = sizeof(ctx->scratch); -} - - -static void ipc_read_cb(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - struct ipc_client_ctx* ctx; - uv_loop_t* loop; - uv_handle_type type; - uv_pipe_t* ipc_pipe; - - ipc_pipe = (uv_pipe_t*) handle; - ctx = container_of(ipc_pipe, struct ipc_client_ctx, ipc_pipe); - loop = ipc_pipe->loop; - - ASSERT(1 == uv_pipe_pending_count(ipc_pipe)); - type = uv_pipe_pending_type(ipc_pipe); - if (type == UV_TCP) - ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) ctx->server_handle)); - else if (type == UV_NAMED_PIPE) - ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) ctx->server_handle, 0)); - else - ASSERT(0); - - ASSERT(0 == uv_accept(handle, ctx->server_handle)); - uv_close((uv_handle_t*) &ctx->ipc_pipe, NULL); -} - - -/* Set up an IPC pipe server that hands out listen sockets to the worker - * threads. It's kind of cumbersome for such a simple operation, maybe we - * should revive uv_import() and uv_export(). - */ -static void send_listen_handles(uv_handle_type type, - unsigned int num_servers, - struct server_ctx* servers) { - struct ipc_server_ctx ctx; - uv_loop_t* loop; - unsigned int i; - - loop = uv_default_loop(); - ctx.num_connects = num_servers; - - if (type == UV_TCP) { - ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &ctx.server_handle)); - ASSERT(0 == uv_tcp_bind((uv_tcp_t*) &ctx.server_handle, - (const struct sockaddr*) &listen_addr, - 0)); - } - else - ASSERT(0); - - ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 1)); - ASSERT(0 == uv_pipe_bind(&ctx.ipc_pipe, IPC_PIPE_NAME)); - ASSERT(0 == uv_listen((uv_stream_t*) &ctx.ipc_pipe, 128, ipc_connection_cb)); - - for (i = 0; i < num_servers; i++) - uv_sem_post(&servers[i].semaphore); - - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - uv_close((uv_handle_t*) &ctx.server_handle, NULL); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - for (i = 0; i < num_servers; i++) - uv_sem_wait(&servers[i].semaphore); -} - - -static void get_listen_handle(uv_loop_t* loop, uv_stream_t* server_handle) { - struct ipc_client_ctx ctx; - - ctx.server_handle = server_handle; - ctx.server_handle->data = "server handle"; - - ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 1)); - uv_pipe_connect(&ctx.connect_req, - &ctx.ipc_pipe, - IPC_PIPE_NAME, - ipc_connect_cb); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); -} - - -static void server_cb(void *arg) { - struct server_ctx *ctx; - uv_loop_t loop; - - ctx = arg; - ASSERT(0 == uv_loop_init(&loop)); - - ASSERT(0 == uv_async_init(&loop, &ctx->async_handle, sv_async_cb)); - uv_unref((uv_handle_t*) &ctx->async_handle); - - /* Wait until the main thread is ready. */ - uv_sem_wait(&ctx->semaphore); - get_listen_handle(&loop, (uv_stream_t*) &ctx->server_handle); - uv_sem_post(&ctx->semaphore); - - /* Now start the actual benchmark. */ - ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle, - 128, - sv_connection_cb)); - ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); - - uv_loop_close(&loop); -} - - -static void sv_async_cb(uv_async_t* handle) { - struct server_ctx* ctx; - ctx = container_of(handle, struct server_ctx, async_handle); - uv_close((uv_handle_t*) &ctx->server_handle, NULL); - uv_close((uv_handle_t*) &ctx->async_handle, NULL); -} - - -static void sv_connection_cb(uv_stream_t* server_handle, int status) { - handle_storage_t* storage; - struct server_ctx* ctx; - - ctx = container_of(server_handle, struct server_ctx, server_handle); - ASSERT(status == 0); - - storage = malloc(sizeof(*storage)); - ASSERT(storage != NULL); - - if (server_handle->type == UV_TCP) - ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage)); - else if (server_handle->type == UV_NAMED_PIPE) - ASSERT(0 == uv_pipe_init(server_handle->loop, (uv_pipe_t*) storage, 0)); - else - ASSERT(0); - - ASSERT(0 == uv_accept(server_handle, (uv_stream_t*) storage)); - ASSERT(0 == uv_read_start((uv_stream_t*) storage, sv_alloc_cb, sv_read_cb)); - ctx->num_connects++; -} - - -static void sv_alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[32]; - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void sv_read_cb(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - ASSERT(nread == UV_EOF); - uv_close((uv_handle_t*) handle, (uv_close_cb) free); -} - - -static void cl_connect_cb(uv_connect_t* req, int status) { - struct client_ctx* ctx = container_of(req, struct client_ctx, connect_req); - uv_idle_start(&ctx->idle_handle, cl_idle_cb); - ASSERT(0 == status); -} - - -static void cl_idle_cb(uv_idle_t* handle) { - struct client_ctx* ctx = container_of(handle, struct client_ctx, idle_handle); - uv_close((uv_handle_t*) &ctx->client_handle, cl_close_cb); - uv_idle_stop(&ctx->idle_handle); -} - - -static void cl_close_cb(uv_handle_t* handle) { - struct client_ctx* ctx; - - ctx = container_of(handle, struct client_ctx, client_handle); - - if (--ctx->num_connects == 0) { - uv_close((uv_handle_t*) &ctx->idle_handle, NULL); - return; - } - - ASSERT(0 == uv_tcp_init(handle->loop, (uv_tcp_t*) &ctx->client_handle)); - ASSERT(0 == uv_tcp_connect(&ctx->connect_req, - (uv_tcp_t*) &ctx->client_handle, - (const struct sockaddr*) &listen_addr, - cl_connect_cb)); -} - - -static int test_tcp(unsigned int num_servers, unsigned int num_clients) { - struct server_ctx* servers; - struct client_ctx* clients; - uv_loop_t* loop; - uv_tcp_t* handle; - unsigned int i; - double time; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &listen_addr)); - loop = uv_default_loop(); - - servers = calloc(num_servers, sizeof(servers[0])); - clients = calloc(num_clients, sizeof(clients[0])); - ASSERT(servers != NULL); - ASSERT(clients != NULL); - - /* We're making the assumption here that from the perspective of the - * OS scheduler, threads are functionally equivalent to and interchangeable - * with full-blown processes. - */ - for (i = 0; i < num_servers; i++) { - struct server_ctx* ctx = servers + i; - ASSERT(0 == uv_sem_init(&ctx->semaphore, 0)); - ASSERT(0 == uv_thread_create(&ctx->thread_id, server_cb, ctx)); - } - - send_listen_handles(UV_TCP, num_servers, servers); - - for (i = 0; i < num_clients; i++) { - struct client_ctx* ctx = clients + i; - ctx->num_connects = NUM_CONNECTS / num_clients; - handle = (uv_tcp_t*) &ctx->client_handle; - handle->data = "client handle"; - ASSERT(0 == uv_tcp_init(loop, handle)); - ASSERT(0 == uv_tcp_connect(&ctx->connect_req, - handle, - (const struct sockaddr*) &listen_addr, - cl_connect_cb)); - ASSERT(0 == uv_idle_init(loop, &ctx->idle_handle)); - } - - { - uint64_t t = uv_hrtime(); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - t = uv_hrtime() - t; - time = t / 1e9; - } - - for (i = 0; i < num_servers; i++) { - struct server_ctx* ctx = servers + i; - uv_async_send(&ctx->async_handle); - ASSERT(0 == uv_thread_join(&ctx->thread_id)); - uv_sem_destroy(&ctx->semaphore); - } - - printf("accept%u: %.0f accepts/sec (%u total)\n", - num_servers, - NUM_CONNECTS / time, - NUM_CONNECTS); - - for (i = 0; i < num_servers; i++) { - struct server_ctx* ctx = servers + i; - printf(" thread #%u: %.0f accepts/sec (%u total, %.1f%%)\n", - i, - ctx->num_connects / time, - ctx->num_connects, - ctx->num_connects * 100.0 / NUM_CONNECTS); - } - - free(clients); - free(servers); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -BENCHMARK_IMPL(tcp_multi_accept2) { - return test_tcp(2, 40); -} - - -BENCHMARK_IMPL(tcp_multi_accept4) { - return test_tcp(4, 40); -} - - -BENCHMARK_IMPL(tcp_multi_accept8) { - return test_tcp(8, 40); -} diff --git a/outside/libuv-v1.7.5/test/benchmark-ping-pongs.c b/outside/libuv-v1.7.5/test/benchmark-ping-pongs.c deleted file mode 100644 index 646a7df944..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-ping-pongs.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -/* Run the benchmark for this many ms */ -#define TIME 5000 - - -typedef struct { - int pongs; - int state; - uv_tcp_t tcp; - uv_connect_t connect_req; - uv_shutdown_t shutdown_req; -} pinger_t; - -typedef struct buf_s { - uv_buf_t uv_buf_t; - struct buf_s* next; -} buf_t; - - -static char PING[] = "PING\n"; - -static uv_loop_t* loop; - -static buf_t* buf_freelist = NULL; -static int pinger_shutdown_cb_called; -static int completed_pingers = 0; -static int64_t start_time; - - -static void buf_alloc(uv_handle_t* tcp, size_t size, uv_buf_t* buf) { - buf_t* ab; - - ab = buf_freelist; - if (ab != NULL) - buf_freelist = ab->next; - else { - ab = malloc(size + sizeof(*ab)); - ab->uv_buf_t.len = size; - ab->uv_buf_t.base = (char*) (ab + 1); - } - - *buf = ab->uv_buf_t; -} - - -static void buf_free(const uv_buf_t* buf) { - buf_t* ab = (buf_t*) buf->base - 1; - ab->next = buf_freelist; - buf_freelist = ab; -} - - -static void pinger_close_cb(uv_handle_t* handle) { - pinger_t* pinger; - - pinger = (pinger_t*)handle->data; - fprintf(stderr, "ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME); - fflush(stderr); - - free(pinger); - - completed_pingers++; -} - - -static void pinger_write_cb(uv_write_t* req, int status) { - ASSERT(status == 0); - - free(req); -} - - -static void pinger_write_ping(pinger_t* pinger) { - uv_write_t* req; - uv_buf_t buf; - - buf = uv_buf_init(PING, sizeof(PING) - 1); - - req = malloc(sizeof *req); - if (uv_write(req, (uv_stream_t*) &pinger->tcp, &buf, 1, pinger_write_cb)) { - FATAL("uv_write failed"); - } -} - - -static void pinger_shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(status == 0); - pinger_shutdown_cb_called++; - - /* - * The close callback has not been triggered yet. We must wait for EOF - * until we close the connection. - */ - ASSERT(completed_pingers == 0); -} - - -static void pinger_read_cb(uv_stream_t* tcp, - ssize_t nread, - const uv_buf_t* buf) { - ssize_t i; - pinger_t* pinger; - - pinger = (pinger_t*)tcp->data; - - if (nread < 0) { - ASSERT(nread == UV_EOF); - - if (buf->base) { - buf_free(buf); - } - - ASSERT(pinger_shutdown_cb_called == 1); - uv_close((uv_handle_t*)tcp, pinger_close_cb); - - return; - } - - /* Now we count the pings */ - for (i = 0; i < nread; i++) { - ASSERT(buf->base[i] == PING[pinger->state]); - pinger->state = (pinger->state + 1) % (sizeof(PING) - 1); - if (pinger->state == 0) { - pinger->pongs++; - if (uv_now(loop) - start_time > TIME) { - uv_shutdown(&pinger->shutdown_req, - (uv_stream_t*) tcp, - pinger_shutdown_cb); - break; - } else { - pinger_write_ping(pinger); - } - } - } - - buf_free(buf); -} - - -static void pinger_connect_cb(uv_connect_t* req, int status) { - pinger_t *pinger = (pinger_t*)req->handle->data; - - ASSERT(status == 0); - - pinger_write_ping(pinger); - - if (uv_read_start(req->handle, buf_alloc, pinger_read_cb)) { - FATAL("uv_read_start failed"); - } -} - - -static void pinger_new(void) { - struct sockaddr_in client_addr; - struct sockaddr_in server_addr; - pinger_t *pinger; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr)); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); - pinger = malloc(sizeof(*pinger)); - pinger->state = 0; - pinger->pongs = 0; - - /* Try to connect to the server and do NUM_PINGS ping-pongs. */ - r = uv_tcp_init(loop, &pinger->tcp); - ASSERT(!r); - - pinger->tcp.data = pinger; - - ASSERT(0 == uv_tcp_bind(&pinger->tcp, - (const struct sockaddr*) &client_addr, - 0)); - - r = uv_tcp_connect(&pinger->connect_req, - &pinger->tcp, - (const struct sockaddr*) &server_addr, - pinger_connect_cb); - ASSERT(!r); -} - - -BENCHMARK_IMPL(ping_pongs) { - loop = uv_default_loop(); - - start_time = uv_now(loop); - - pinger_new(); - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(completed_pingers == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-pound.c b/outside/libuv-v1.7.5/test/benchmark-pound.c deleted file mode 100644 index 79f3634503..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-pound.c +++ /dev/null @@ -1,351 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -/* Update this is you're going to run > 1000 concurrent requests. */ -#define MAX_CONNS 1000 - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - -#undef DEBUG -#define DEBUG 0 - -struct conn_rec_s; - -typedef void (*setup_fn)(int num, void* arg); -typedef void (*make_connect_fn)(struct conn_rec_s* conn); -typedef int (*connect_fn)(int num, make_connect_fn make_connect, void* arg); - -/* Base class for tcp_conn_rec and pipe_conn_rec. - * The ordering of fields matters! - */ -typedef struct conn_rec_s { - int i; - uv_connect_t conn_req; - uv_write_t write_req; - make_connect_fn make_connect; - uv_stream_t stream; -} conn_rec; - -typedef struct { - int i; - uv_connect_t conn_req; - uv_write_t write_req; - make_connect_fn make_connect; - uv_tcp_t stream; -} tcp_conn_rec; - -typedef struct { - int i; - uv_connect_t conn_req; - uv_write_t write_req; - make_connect_fn make_connect; - uv_pipe_t stream; -} pipe_conn_rec; - -static char buffer[] = "QS"; - -static uv_loop_t* loop; - -static tcp_conn_rec tcp_conns[MAX_CONNS]; -static pipe_conn_rec pipe_conns[MAX_CONNS]; - -static uint64_t start; /* in ms */ -static int closed_streams; -static int conns_failed; - -static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); -static void connect_cb(uv_connect_t* conn_req, int status); -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); -static void close_cb(uv_handle_t* handle); - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void after_write(uv_write_t* req, int status) { - if (status != 0) { - fprintf(stderr, "write error %s\n", uv_err_name(status)); - uv_close((uv_handle_t*)req->handle, close_cb); - conns_failed++; - return; - } -} - - -static void connect_cb(uv_connect_t* req, int status) { - conn_rec* conn; - uv_buf_t buf; - int r; - - if (status != 0) { -#if DEBUG - fprintf(stderr, "connect error %s\n", uv_err_name(status)); -#endif - uv_close((uv_handle_t*)req->handle, close_cb); - conns_failed++; - return; - } - - ASSERT(req != NULL); - ASSERT(status == 0); - - conn = (conn_rec*)req->data; - ASSERT(conn != NULL); - -#if DEBUG - printf("connect_cb %d\n", conn->i); -#endif - - r = uv_read_start(&conn->stream, alloc_cb, read_cb); - ASSERT(r == 0); - - buf.base = buffer; - buf.len = sizeof(buffer) - 1; - - r = uv_write(&conn->write_req, &conn->stream, &buf, 1, after_write); - ASSERT(r == 0); -} - - -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { - - ASSERT(stream != NULL); - -#if DEBUG - printf("read_cb %d\n", p->i); -#endif - - uv_close((uv_handle_t*)stream, close_cb); - - if (nread < 0) { - if (nread == UV_EOF) { - ; - } else if (nread == UV_ECONNRESET) { - conns_failed++; - } else { - fprintf(stderr, "read error %s\n", uv_err_name(nread)); - ASSERT(0); - } - } -} - - -static void close_cb(uv_handle_t* handle) { - conn_rec* p = (conn_rec*)handle->data; - - ASSERT(handle != NULL); - closed_streams++; - -#if DEBUG - printf("close_cb %d\n", p->i); -#endif - - if (uv_now(loop) - start < 10000) { - p->make_connect(p); - } -} - - -static void tcp_do_setup(int num, void* arg) { - int i; - - for (i = 0; i < num; i++) { - tcp_conns[i].i = i; - } -} - - -static void pipe_do_setup(int num, void* arg) { - int i; - - for (i = 0; i < num; i++) { - pipe_conns[i].i = i; - } -} - - -static void tcp_make_connect(conn_rec* p) { - struct sockaddr_in addr; - tcp_conn_rec* tp; - int r; - - tp = (tcp_conn_rec*) p; - - r = uv_tcp_init(loop, (uv_tcp_t*)&p->stream); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_connect(&tp->conn_req, - (uv_tcp_t*) &p->stream, - (const struct sockaddr*) &addr, - connect_cb); - if (r) { - fprintf(stderr, "uv_tcp_connect error %s\n", uv_err_name(r)); - ASSERT(0); - } - -#if DEBUG - printf("make connect %d\n", p->i); -#endif - - p->conn_req.data = p; - p->write_req.data = p; - p->stream.data = p; -} - - -static void pipe_make_connect(conn_rec* p) { - int r; - - r = uv_pipe_init(loop, (uv_pipe_t*)&p->stream, 0); - ASSERT(r == 0); - - uv_pipe_connect(&((pipe_conn_rec*) p)->conn_req, - (uv_pipe_t*) &p->stream, - TEST_PIPENAME, - connect_cb); - -#if DEBUG - printf("make connect %d\n", p->i); -#endif - - p->conn_req.data = p; - p->write_req.data = p; - p->stream.data = p; -} - - -static int tcp_do_connect(int num, make_connect_fn make_connect, void* arg) { - int i; - - for (i = 0; i < num; i++) { - tcp_make_connect((conn_rec*)&tcp_conns[i]); - tcp_conns[i].make_connect = make_connect; - } - - return 0; -} - - -static int pipe_do_connect(int num, make_connect_fn make_connect, void* arg) { - int i; - - for (i = 0; i < num; i++) { - pipe_make_connect((conn_rec*)&pipe_conns[i]); - pipe_conns[i].make_connect = make_connect; - } - - return 0; -} - - -static int pound_it(int concurrency, - const char* type, - setup_fn do_setup, - connect_fn do_connect, - make_connect_fn make_connect, - void* arg) { - double secs; - int r; - uint64_t start_time; /* in ns */ - uint64_t end_time; - - loop = uv_default_loop(); - - uv_update_time(loop); - start = uv_now(loop); - - /* Run benchmark for at least five seconds. */ - start_time = uv_hrtime(); - - do_setup(concurrency, arg); - - r = do_connect(concurrency, make_connect, arg); - ASSERT(!r); - - uv_run(loop, UV_RUN_DEFAULT); - - end_time = uv_hrtime(); - - /* Number of fractional seconds it took to run the benchmark. */ - secs = (double)(end_time - start_time) / NANOSEC; - - fprintf(stderr, "%s-conn-pound-%d: %.0f accepts/s (%d failed)\n", - type, - concurrency, - closed_streams / secs, - conns_failed); - fflush(stderr); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -BENCHMARK_IMPL(tcp4_pound_100) { - return pound_it(100, - "tcp", - tcp_do_setup, - tcp_do_connect, - tcp_make_connect, - NULL); -} - - -BENCHMARK_IMPL(tcp4_pound_1000) { - return pound_it(1000, - "tcp", - tcp_do_setup, - tcp_do_connect, - tcp_make_connect, - NULL); -} - - -BENCHMARK_IMPL(pipe_pound_100) { - return pound_it(100, - "pipe", - pipe_do_setup, - pipe_do_connect, - pipe_make_connect, - NULL); -} - - -BENCHMARK_IMPL(pipe_pound_1000) { - return pound_it(1000, - "pipe", - pipe_do_setup, - pipe_do_connect, - pipe_make_connect, - NULL); -} diff --git a/outside/libuv-v1.7.5/test/benchmark-pump.c b/outside/libuv-v1.7.5/test/benchmark-pump.c deleted file mode 100644 index 88f2dc5c65..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-pump.c +++ /dev/null @@ -1,476 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#include -#include - - -static int TARGET_CONNECTIONS; -#define WRITE_BUFFER_SIZE 8192 -#define MAX_SIMULTANEOUS_CONNECTS 100 - -#define PRINT_STATS 0 -#define STATS_INTERVAL 1000 /* msec */ -#define STATS_COUNT 5 - - -static void do_write(uv_stream_t*); -static void maybe_connect_some(); - -static uv_req_t* req_alloc(); -static void req_free(uv_req_t* uv_req); - -static void buf_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf); -static void buf_free(const uv_buf_t* buf); - -static uv_loop_t* loop; - -static uv_tcp_t tcpServer; -static uv_pipe_t pipeServer; -static uv_stream_t* server; -static struct sockaddr_in listen_addr; -static struct sockaddr_in connect_addr; - -static int64_t start_time; - -static int max_connect_socket = 0; -static int max_read_sockets = 0; -static int read_sockets = 0; -static int write_sockets = 0; - -static int64_t nrecv = 0; -static int64_t nrecv_total = 0; -static int64_t nsent = 0; -static int64_t nsent_total = 0; - -static int stats_left = 0; - -static char write_buffer[WRITE_BUFFER_SIZE]; - -/* Make this as large as you need. */ -#define MAX_WRITE_HANDLES 1000 - -static stream_type type; - -static uv_tcp_t tcp_write_handles[MAX_WRITE_HANDLES]; -static uv_pipe_t pipe_write_handles[MAX_WRITE_HANDLES]; - -static uv_timer_t timer_handle; - - -static double gbit(int64_t bytes, int64_t passed_ms) { - double gbits = ((double)bytes / (1024 * 1024 * 1024)) * 8; - return gbits / ((double)passed_ms / 1000); -} - - -static void show_stats(uv_timer_t* handle) { - int64_t diff; - int i; - -#if PRINT_STATS - fprintf(stderr, "connections: %d, write: %.1f gbit/s\n", - write_sockets, - gbit(nsent, STATS_INTERVAL)); - fflush(stderr); -#endif - - /* Exit if the show is over */ - if (!--stats_left) { - - uv_update_time(loop); - diff = uv_now(loop) - start_time; - - fprintf(stderr, "%s_pump%d_client: %.1f gbit/s\n", - type == TCP ? "tcp" : "pipe", - write_sockets, - gbit(nsent_total, diff)); - fflush(stderr); - - for (i = 0; i < write_sockets; i++) { - if (type == TCP) - uv_close((uv_handle_t*) &tcp_write_handles[i], NULL); - else - uv_close((uv_handle_t*) &pipe_write_handles[i], NULL); - } - - exit(0); - } - - /* Reset read and write counters */ - nrecv = 0; - nsent = 0; -} - - -static void read_show_stats(void) { - int64_t diff; - - uv_update_time(loop); - diff = uv_now(loop) - start_time; - - fprintf(stderr, "%s_pump%d_server: %.1f gbit/s\n", - type == TCP ? "tcp" : "pipe", - max_read_sockets, - gbit(nrecv_total, diff)); - fflush(stderr); -} - - - -static void read_sockets_close_cb(uv_handle_t* handle) { - free(handle); - read_sockets--; - - /* If it's past the first second and everyone has closed their connection - * Then print stats. - */ - if (uv_now(loop) - start_time > 1000 && read_sockets == 0) { - read_show_stats(); - uv_close((uv_handle_t*)server, NULL); - } -} - - -static void start_stats_collection(void) { - int r; - - /* Show-stats timer */ - stats_left = STATS_COUNT; - r = uv_timer_init(loop, &timer_handle); - ASSERT(r == 0); - r = uv_timer_start(&timer_handle, show_stats, STATS_INTERVAL, STATS_INTERVAL); - ASSERT(r == 0); - - uv_update_time(loop); - start_time = uv_now(loop); -} - - -static void read_cb(uv_stream_t* stream, ssize_t bytes, const uv_buf_t* buf) { - if (nrecv_total == 0) { - ASSERT(start_time == 0); - uv_update_time(loop); - start_time = uv_now(loop); - } - - if (bytes < 0) { - uv_close((uv_handle_t*)stream, read_sockets_close_cb); - return; - } - - buf_free(buf); - - nrecv += bytes; - nrecv_total += bytes; -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(status == 0); - - req_free((uv_req_t*) req); - - nsent += sizeof write_buffer; - nsent_total += sizeof write_buffer; - - do_write((uv_stream_t*) req->handle); -} - - -static void do_write(uv_stream_t* stream) { - uv_write_t* req; - uv_buf_t buf; - int r; - - buf.base = (char*) &write_buffer; - buf.len = sizeof write_buffer; - - req = (uv_write_t*) req_alloc(); - r = uv_write(req, stream, &buf, 1, write_cb); - ASSERT(r == 0); -} - - -static void connect_cb(uv_connect_t* req, int status) { - int i; - - if (status) { - fprintf(stderr, "%s", uv_strerror(status)); - fflush(stderr); - } - ASSERT(status == 0); - - write_sockets++; - req_free((uv_req_t*) req); - - maybe_connect_some(); - - if (write_sockets == TARGET_CONNECTIONS) { - start_stats_collection(); - - /* Yay! start writing */ - for (i = 0; i < write_sockets; i++) { - if (type == TCP) - do_write((uv_stream_t*) &tcp_write_handles[i]); - else - do_write((uv_stream_t*) &pipe_write_handles[i]); - } - } -} - - -static void maybe_connect_some(void) { - uv_connect_t* req; - uv_tcp_t* tcp; - uv_pipe_t* pipe; - int r; - - while (max_connect_socket < TARGET_CONNECTIONS && - max_connect_socket < write_sockets + MAX_SIMULTANEOUS_CONNECTS) { - if (type == TCP) { - tcp = &tcp_write_handles[max_connect_socket++]; - - r = uv_tcp_init(loop, tcp); - ASSERT(r == 0); - - req = (uv_connect_t*) req_alloc(); - r = uv_tcp_connect(req, - tcp, - (const struct sockaddr*) &connect_addr, - connect_cb); - ASSERT(r == 0); - } else { - pipe = &pipe_write_handles[max_connect_socket++]; - - r = uv_pipe_init(loop, pipe, 0); - ASSERT(r == 0); - - req = (uv_connect_t*) req_alloc(); - uv_pipe_connect(req, pipe, TEST_PIPENAME, connect_cb); - } - } -} - - -static void connection_cb(uv_stream_t* s, int status) { - uv_stream_t* stream; - int r; - - ASSERT(server == s); - ASSERT(status == 0); - - if (type == TCP) { - stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t)); - r = uv_tcp_init(loop, (uv_tcp_t*)stream); - ASSERT(r == 0); - } else { - stream = (uv_stream_t*)malloc(sizeof(uv_pipe_t)); - r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0); - ASSERT(r == 0); - } - - r = uv_accept(s, stream); - ASSERT(r == 0); - - r = uv_read_start(stream, buf_alloc, read_cb); - ASSERT(r == 0); - - read_sockets++; - max_read_sockets++; -} - - -/* - * Request allocator - */ - -typedef struct req_list_s { - union uv_any_req uv_req; - struct req_list_s* next; -} req_list_t; - - -static req_list_t* req_freelist = NULL; - - -static uv_req_t* req_alloc(void) { - req_list_t* req; - - req = req_freelist; - if (req != NULL) { - req_freelist = req->next; - return (uv_req_t*) req; - } - - req = (req_list_t*) malloc(sizeof *req); - return (uv_req_t*) req; -} - - -static void req_free(uv_req_t* uv_req) { - req_list_t* req = (req_list_t*) uv_req; - - req->next = req_freelist; - req_freelist = req; -} - - -/* - * Buffer allocator - */ - -typedef struct buf_list_s { - uv_buf_t uv_buf_t; - struct buf_list_s* next; -} buf_list_t; - - -static buf_list_t* buf_freelist = NULL; - - -static void buf_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf_list_t* ab; - - ab = buf_freelist; - if (ab != NULL) - buf_freelist = ab->next; - else { - ab = malloc(size + sizeof(*ab)); - ab->uv_buf_t.len = size; - ab->uv_buf_t.base = (char*) (ab + 1); - } - - *buf = ab->uv_buf_t; -} - - -static void buf_free(const uv_buf_t* buf) { - buf_list_t* ab = (buf_list_t*) buf->base - 1; - ab->next = buf_freelist; - buf_freelist = ab; -} - - -HELPER_IMPL(tcp_pump_server) { - int r; - - type = TCP; - loop = uv_default_loop(); - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &listen_addr)); - - /* Server */ - server = (uv_stream_t*)&tcpServer; - r = uv_tcp_init(loop, &tcpServer); - ASSERT(r == 0); - r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &listen_addr, 0); - ASSERT(r == 0); - r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - return 0; -} - - -HELPER_IMPL(pipe_pump_server) { - int r; - type = PIPE; - - loop = uv_default_loop(); - - /* Server */ - server = (uv_stream_t*)&pipeServer; - r = uv_pipe_init(loop, &pipeServer, 0); - ASSERT(r == 0); - r = uv_pipe_bind(&pipeServer, TEST_PIPENAME); - ASSERT(r == 0); - r = uv_listen((uv_stream_t*)&pipeServer, MAX_WRITE_HANDLES, connection_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static void tcp_pump(int n) { - ASSERT(n <= MAX_WRITE_HANDLES); - TARGET_CONNECTIONS = n; - type = TCP; - - loop = uv_default_loop(); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &connect_addr)); - - /* Start making connections */ - maybe_connect_some(); - - uv_run(loop, UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); -} - - -static void pipe_pump(int n) { - ASSERT(n <= MAX_WRITE_HANDLES); - TARGET_CONNECTIONS = n; - type = PIPE; - - loop = uv_default_loop(); - - /* Start making connections */ - maybe_connect_some(); - - uv_run(loop, UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); -} - - -BENCHMARK_IMPL(tcp_pump100_client) { - tcp_pump(100); - return 0; -} - - -BENCHMARK_IMPL(tcp_pump1_client) { - tcp_pump(1); - return 0; -} - - -BENCHMARK_IMPL(pipe_pump100_client) { - pipe_pump(100); - return 0; -} - - -BENCHMARK_IMPL(pipe_pump1_client) { - pipe_pump(1); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-sizes.c b/outside/libuv-v1.7.5/test/benchmark-sizes.c deleted file mode 100644 index 9bf42f9153..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-sizes.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - - -BENCHMARK_IMPL(sizes) { - fprintf(stderr, "uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t)); - fprintf(stderr, "uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t)); - fprintf(stderr, "uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t)); - fprintf(stderr, "uv_udp_send_t: %u bytes\n", (unsigned int) sizeof(uv_udp_send_t)); - fprintf(stderr, "uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t)); - fprintf(stderr, "uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t)); - fprintf(stderr, "uv_tty_t: %u bytes\n", (unsigned int) sizeof(uv_tty_t)); - fprintf(stderr, "uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t)); - fprintf(stderr, "uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t)); - fprintf(stderr, "uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t)); - fprintf(stderr, "uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t)); - fprintf(stderr, "uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t)); - fprintf(stderr, "uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t)); - fprintf(stderr, "uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t)); - fprintf(stderr, "uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t)); - fprintf(stderr, "uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t)); - fprintf(stderr, "uv_loop_t: %u bytes\n", (unsigned int) sizeof(uv_loop_t)); - fflush(stderr); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-spawn.c b/outside/libuv-v1.7.5/test/benchmark-spawn.c deleted file mode 100644 index ed9ad608f3..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-spawn.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* This benchmark spawns itself 1000 times. */ - -#include "task.h" -#include "uv.h" - -static uv_loop_t* loop; - -static int N = 1000; -static int done; - -static uv_process_t process; -static uv_process_options_t options; -static char exepath[1024]; -static size_t exepath_size = 1024; -static char* args[3]; -static uv_pipe_t out; - -#define OUTPUT_SIZE 1024 -static char output[OUTPUT_SIZE]; -static int output_used; - -static int process_open; -static int pipe_open; - - -static void spawn(void); - - -static void maybe_spawn(void) { - if (process_open == 0 && pipe_open == 0) { - done++; - if (done < N) { - spawn(); - } - } -} - - -static void process_close_cb(uv_handle_t* handle) { - ASSERT(process_open == 1); - process_open = 0; - maybe_spawn(); -} - - -static void exit_cb(uv_process_t* process, - int64_t exit_status, - int term_signal) { - ASSERT(exit_status == 42); - ASSERT(term_signal == 0); - uv_close((uv_handle_t*)process, process_close_cb); -} - - -static void on_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = output + output_used; - buf->len = OUTPUT_SIZE - output_used; -} - - -static void pipe_close_cb(uv_handle_t* pipe) { - ASSERT(pipe_open == 1); - pipe_open = 0; - maybe_spawn(); -} - - -static void on_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* buf) { - if (nread > 0) { - ASSERT(pipe_open == 1); - output_used += nread; - } else if (nread < 0) { - if (nread == UV_EOF) { - uv_close((uv_handle_t*)pipe, pipe_close_cb); - } - } -} - - -static void spawn(void) { - uv_stdio_container_t stdio[2]; - int r; - - ASSERT(process_open == 0); - ASSERT(pipe_open == 0); - - args[0] = exepath; - args[1] = "spawn_helper"; - args[2] = NULL; - options.file = exepath; - options.args = args; - options.exit_cb = exit_cb; - - uv_pipe_init(loop, &out, 0); - - options.stdio = stdio; - options.stdio_count = 2; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - - r = uv_spawn(loop, &process, &options); - ASSERT(r == 0); - - process_open = 1; - pipe_open = 1; - output_used = 0; - - r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); - ASSERT(r == 0); -} - - -BENCHMARK_IMPL(spawn) { - int r; - static int64_t start_time, end_time; - - loop = uv_default_loop(); - - r = uv_exepath(exepath, &exepath_size); - ASSERT(r == 0); - exepath[exepath_size] = '\0'; - - uv_update_time(loop); - start_time = uv_now(loop); - - spawn(); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - uv_update_time(loop); - end_time = uv_now(loop); - - fprintf(stderr, "spawn: %.0f spawns/s\n", - (double) N / (double) (end_time - start_time) * 1000.0); - fflush(stderr); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-tcp-write-batch.c b/outside/libuv-v1.7.5/test/benchmark-tcp-write-batch.c deleted file mode 100644 index 96921b70db..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-tcp-write-batch.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -#define WRITE_REQ_DATA "Hello, world." -#define NUM_WRITE_REQS (1000 * 1000) - -typedef struct { - uv_write_t req; - uv_buf_t buf; -} write_req; - - -static write_req* write_reqs; -static uv_tcp_t tcp_client; -static uv_connect_t connect_req; -static uv_shutdown_t shutdown_req; - -static int shutdown_cb_called = 0; -static int connect_cb_called = 0; -static int write_cb_called = 0; -static int close_cb_called = 0; - -static void connect_cb(uv_connect_t* req, int status); -static void write_cb(uv_write_t* req, int status); -static void shutdown_cb(uv_shutdown_t* req, int status); -static void close_cb(uv_handle_t* handle); - - -static void connect_cb(uv_connect_t* req, int status) { - write_req* w; - int i; - int r; - - ASSERT(req->handle == (uv_stream_t*)&tcp_client); - - for (i = 0; i < NUM_WRITE_REQS; i++) { - w = &write_reqs[i]; - r = uv_write(&w->req, req->handle, &w->buf, 1, write_cb); - ASSERT(r == 0); - } - - r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb); - ASSERT(r == 0); - - connect_cb_called++; -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - write_cb_called++; -} - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(req->handle == (uv_stream_t*)&tcp_client); - ASSERT(req->handle->write_queue_size == 0); - - uv_close((uv_handle_t*)req->handle, close_cb); - free(write_reqs); - - shutdown_cb_called++; -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*)&tcp_client); - close_cb_called++; -} - - -BENCHMARK_IMPL(tcp_write_batch) { - struct sockaddr_in addr; - uv_loop_t* loop; - uint64_t start; - uint64_t stop; - int i; - int r; - - write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS); - ASSERT(write_reqs != NULL); - - /* Prepare the data to write out. */ - for (i = 0; i < NUM_WRITE_REQS; i++) { - write_reqs[i].buf = uv_buf_init(WRITE_REQ_DATA, - sizeof(WRITE_REQ_DATA) - 1); - } - - loop = uv_default_loop(); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init(loop, &tcp_client); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &tcp_client, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - start = uv_hrtime(); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - stop = uv_hrtime(); - - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == NUM_WRITE_REQS); - ASSERT(shutdown_cb_called == 1); - ASSERT(close_cb_called == 1); - - printf("%ld write requests in %.2fs.\n", - (long)NUM_WRITE_REQS, - (stop - start) / 1e9); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-thread.c b/outside/libuv-v1.7.5/test/benchmark-thread.c deleted file mode 100644 index b37a7fd6d0..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-thread.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -#define NUM_THREADS (20 * 1000) - -static volatile int num_threads; - - -static void thread_entry(void* arg) { - ASSERT(arg == (void *) 42); - num_threads++; - /* FIXME write barrier? */ -} - - -BENCHMARK_IMPL(thread_create) { - uint64_t start_time; - double duration; - uv_thread_t tid; - int i, r; - - start_time = uv_hrtime(); - - for (i = 0; i < NUM_THREADS; i++) { - r = uv_thread_create(&tid, thread_entry, (void *) 42); - ASSERT(r == 0); - - r = uv_thread_join(&tid); - ASSERT(r == 0); - } - - duration = (uv_hrtime() - start_time) / 1e9; - - ASSERT(num_threads == NUM_THREADS); - - printf("%d threads created in %.2f seconds (%.0f/s)\n", - NUM_THREADS, duration, NUM_THREADS / duration); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/benchmark-udp-pummel.c b/outside/libuv-v1.7.5/test/benchmark-udp-pummel.c deleted file mode 100644 index 68a2373d78..0000000000 --- a/outside/libuv-v1.7.5/test/benchmark-udp-pummel.c +++ /dev/null @@ -1,243 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" -#include "uv.h" - -#include -#include -#include - -#define EXPECTED "RANG TANG DING DONG I AM THE JAPANESE SANDMAN" - -#define TEST_DURATION 5000 /* ms */ - -#define BASE_PORT 12345 - -struct sender_state { - struct sockaddr_in addr; - uv_udp_send_t send_req; - uv_udp_t udp_handle; -}; - -struct receiver_state { - struct sockaddr_in addr; - uv_udp_t udp_handle; -}; - -/* not used in timed mode */ -static unsigned int packet_counter = (unsigned int) 1e6; - -static int n_senders_; -static int n_receivers_; -static uv_buf_t bufs[5]; -static struct sender_state senders[1024]; -static struct receiver_state receivers[1024]; - -static unsigned int send_cb_called; -static unsigned int recv_cb_called; -static unsigned int close_cb_called; -static int timed; -static int exiting; - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void send_cb(uv_udp_send_t* req, int status) { - struct sender_state* s; - - ASSERT(req != NULL); - - if (status != 0) { - ASSERT(status == UV_ECANCELED); - return; - } - - if (exiting) - return; - - s = container_of(req, struct sender_state, send_req); - ASSERT(req->handle == &s->udp_handle); - - if (timed) - goto send; - - if (packet_counter == 0) { - uv_close((uv_handle_t*)&s->udp_handle, NULL); - return; - } - - packet_counter--; - -send: - ASSERT(0 == uv_udp_send(&s->send_req, - &s->udp_handle, - bufs, - ARRAY_SIZE(bufs), - (const struct sockaddr*) &s->addr, - send_cb)); - send_cb_called++; -} - - -static void recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - if (nread == 0) - return; - - if (nread < 0) { - ASSERT(nread == UV_ECANCELED); - return; - } - - ASSERT(addr->sa_family == AF_INET); - ASSERT(!memcmp(buf->base, EXPECTED, nread)); - - recv_cb_called++; -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void timeout_cb(uv_timer_t* timer) { - int i; - - exiting = 1; - - for (i = 0; i < n_senders_; i++) - uv_close((uv_handle_t*)&senders[i].udp_handle, close_cb); - - for (i = 0; i < n_receivers_; i++) - uv_close((uv_handle_t*)&receivers[i].udp_handle, close_cb); -} - - -static int pummel(unsigned int n_senders, - unsigned int n_receivers, - unsigned long timeout) { - uv_timer_t timer_handle; - uint64_t duration; - uv_loop_t* loop; - unsigned int i; - - ASSERT(n_senders <= ARRAY_SIZE(senders)); - ASSERT(n_receivers <= ARRAY_SIZE(receivers)); - - loop = uv_default_loop(); - - n_senders_ = n_senders; - n_receivers_ = n_receivers; - - if (timeout) { - ASSERT(0 == uv_timer_init(loop, &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timeout_cb, timeout, 0)); - /* Timer should not keep loop alive. */ - uv_unref((uv_handle_t*)&timer_handle); - timed = 1; - } - - for (i = 0; i < n_receivers; i++) { - struct receiver_state* s = receivers + i; - struct sockaddr_in addr; - ASSERT(0 == uv_ip4_addr("0.0.0.0", BASE_PORT + i, &addr)); - ASSERT(0 == uv_udp_init(loop, &s->udp_handle)); - ASSERT(0 == uv_udp_bind(&s->udp_handle, (const struct sockaddr*) &addr, 0)); - ASSERT(0 == uv_udp_recv_start(&s->udp_handle, alloc_cb, recv_cb)); - uv_unref((uv_handle_t*)&s->udp_handle); - } - - bufs[0] = uv_buf_init(EXPECTED + 0, 10); - bufs[1] = uv_buf_init(EXPECTED + 10, 10); - bufs[2] = uv_buf_init(EXPECTED + 20, 10); - bufs[3] = uv_buf_init(EXPECTED + 30, 10); - bufs[4] = uv_buf_init(EXPECTED + 40, 5); - - for (i = 0; i < n_senders; i++) { - struct sender_state* s = senders + i; - ASSERT(0 == uv_ip4_addr("127.0.0.1", - BASE_PORT + (i % n_receivers), - &s->addr)); - ASSERT(0 == uv_udp_init(loop, &s->udp_handle)); - ASSERT(0 == uv_udp_send(&s->send_req, - &s->udp_handle, - bufs, - ARRAY_SIZE(bufs), - (const struct sockaddr*) &s->addr, - send_cb)); - } - - duration = uv_hrtime(); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - duration = uv_hrtime() - duration; - /* convert from nanoseconds to milliseconds */ - duration = duration / (uint64_t) 1e6; - - printf("udp_pummel_%dv%d: %.0f/s received, %.0f/s sent. " - "%u received, %u sent in %.1f seconds.\n", - n_receivers, - n_senders, - recv_cb_called / (duration / 1000.0), - send_cb_called / (duration / 1000.0), - recv_cb_called, - send_cb_called, - duration / 1000.0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -#define X(a, b) \ - BENCHMARK_IMPL(udp_pummel_##a##v##b) { \ - return pummel(a, b, 0); \ - } \ - BENCHMARK_IMPL(udp_timed_pummel_##a##v##b) { \ - return pummel(a, b, TEST_DURATION); \ - } - -X(1, 1) -X(1, 10) -X(1, 100) -X(1, 1000) -X(10, 10) -X(10, 100) -X(10, 1000) -X(100, 10) -X(100, 100) -X(100, 1000) -X(1000, 1000) - -#undef X diff --git a/outside/libuv-v1.7.5/test/blackhole-server.c b/outside/libuv-v1.7.5/test/blackhole-server.c deleted file mode 100644 index ad878b35c6..0000000000 --- a/outside/libuv-v1.7.5/test/blackhole-server.c +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -typedef struct { - uv_tcp_t handle; - uv_shutdown_t shutdown_req; -} conn_rec; - -static uv_tcp_t tcp_server; - -static void connection_cb(uv_stream_t* stream, int status); -static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); -static void shutdown_cb(uv_shutdown_t* req, int status); -static void close_cb(uv_handle_t* handle); - - -static void connection_cb(uv_stream_t* stream, int status) { - conn_rec* conn; - int r; - - ASSERT(status == 0); - ASSERT(stream == (uv_stream_t*)&tcp_server); - - conn = malloc(sizeof *conn); - ASSERT(conn != NULL); - - r = uv_tcp_init(stream->loop, &conn->handle); - ASSERT(r == 0); - - r = uv_accept(stream, (uv_stream_t*)&conn->handle); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)&conn->handle, alloc_cb, read_cb); - ASSERT(r == 0); -} - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { - conn_rec* conn; - int r; - - if (nread >= 0) - return; - - ASSERT(nread == UV_EOF); - - conn = container_of(stream, conn_rec, handle); - - r = uv_shutdown(&conn->shutdown_req, stream, shutdown_cb); - ASSERT(r == 0); -} - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - conn_rec* conn = container_of(req, conn_rec, shutdown_req); - uv_close((uv_handle_t*)&conn->handle, close_cb); -} - - -static void close_cb(uv_handle_t* handle) { - conn_rec* conn = container_of(handle, conn_rec, handle); - free(conn); -} - - -HELPER_IMPL(tcp4_blackhole_server) { - struct sockaddr_in addr; - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init(loop, &tcp_server); - ASSERT(r == 0); - - r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb); - ASSERT(r == 0); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(0 && "Blackhole server dropped out of event loop."); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/dns-server.c b/outside/libuv-v1.7.5/test/dns-server.c deleted file mode 100644 index 80052c7039..0000000000 --- a/outside/libuv-v1.7.5/test/dns-server.c +++ /dev/null @@ -1,340 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#include - - -typedef struct { - uv_write_t req; - uv_buf_t buf; -} write_req_t; - - -/* used to track multiple DNS requests received */ -typedef struct { - char* prevbuf_ptr; - int prevbuf_pos; - int prevbuf_rem; -} dnsstate; - - -/* modify handle to append dnsstate */ -typedef struct { - uv_tcp_t handle; - dnsstate state; -} dnshandle; - - -static uv_loop_t* loop; - - -static uv_tcp_t server; - - -static void after_write(uv_write_t* req, int status); -static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf); -static void on_close(uv_handle_t* peer); -static void on_connection(uv_stream_t*, int status); - -#define WRITE_BUF_LEN (64*1024) -#define DNSREC_LEN (4) - -#define LEN_OFFSET 0 -#define QUERYID_OFFSET 2 - -static unsigned char DNSRsp[] = { - 0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0 -}; - -static unsigned char qrecord[] = { - 5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1 -}; - -static unsigned char arecord[] = { - 0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 -}; - - -static void after_write(uv_write_t* req, int status) { - write_req_t* wr; - - if (status) { - fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); - ASSERT(0); - } - - wr = (write_req_t*) req; - - /* Free the read/write buffer and the request */ - free(wr->buf.base); - free(wr); -} - - -static void after_shutdown(uv_shutdown_t* req, int status) { - uv_close((uv_handle_t*) req->handle, on_close); - free(req); -} - - -static void addrsp(write_req_t* wr, char* hdr) { - char * dnsrsp; - short int rsplen; - short int* reclen; - - rsplen = sizeof(DNSRsp) + sizeof(qrecord) + sizeof(arecord); - - ASSERT (rsplen + wr->buf.len < WRITE_BUF_LEN); - - dnsrsp = wr->buf.base + wr->buf.len; - - /* copy stock response */ - memcpy(dnsrsp, DNSRsp, sizeof(DNSRsp)); - memcpy(dnsrsp + sizeof(DNSRsp), qrecord, sizeof(qrecord)); - memcpy(dnsrsp + sizeof(DNSRsp) + sizeof(qrecord), arecord, sizeof(arecord)); - - /* overwrite with network order length and id from request header */ - reclen = (short int*)dnsrsp; - *reclen = htons(rsplen-2); - dnsrsp[QUERYID_OFFSET] = hdr[QUERYID_OFFSET]; - dnsrsp[QUERYID_OFFSET+1] = hdr[QUERYID_OFFSET+1]; - - wr->buf.len += rsplen; -} - -static void process_req(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - write_req_t* wr; - dnshandle* dns = (dnshandle*)handle; - char hdrbuf[DNSREC_LEN]; - int hdrbuf_remaining = DNSREC_LEN; - int rec_remaining = 0; - int readbuf_remaining; - char* dnsreq; - char* hdrstart; - int usingprev = 0; - - wr = (write_req_t*) malloc(sizeof *wr); - wr->buf.base = (char*)malloc(WRITE_BUF_LEN); - wr->buf.len = 0; - - if (dns->state.prevbuf_ptr != NULL) { - dnsreq = dns->state.prevbuf_ptr + dns->state.prevbuf_pos; - readbuf_remaining = dns->state.prevbuf_rem; - usingprev = 1; - } else { - dnsreq = buf->base; - readbuf_remaining = nread; - } - hdrstart = dnsreq; - - while (dnsreq != NULL) { - /* something to process */ - while (readbuf_remaining > 0) { - /* something to process in current buffer */ - if (hdrbuf_remaining > 0) { - /* process len and id */ - if (readbuf_remaining < hdrbuf_remaining) { - /* too little to get request header. save for next buffer */ - memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], - dnsreq, - readbuf_remaining); - hdrbuf_remaining = DNSREC_LEN - readbuf_remaining; - break; - } else { - /* save header */ - memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], - dnsreq, - hdrbuf_remaining); - dnsreq += hdrbuf_remaining; - readbuf_remaining -= hdrbuf_remaining; - hdrbuf_remaining = 0; - - /* get record length */ - rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1]; - rec_remaining -= (DNSREC_LEN - 2); - } - } - - if (rec_remaining <= readbuf_remaining) { - /* prepare reply */ - addrsp(wr, hdrbuf); - - /* move to next record */ - dnsreq += rec_remaining; - hdrstart = dnsreq; - readbuf_remaining -= rec_remaining; - rec_remaining = 0; - hdrbuf_remaining = DNSREC_LEN; - } else { - /* otherwise this buffer is done. */ - rec_remaining -= readbuf_remaining; - break; - } - } - - /* If we had to use bytes from prev buffer, start processing the current - * one. - */ - if (usingprev == 1) { - /* free previous buffer */ - free(dns->state.prevbuf_ptr); - dnsreq = buf->base; - readbuf_remaining = nread; - usingprev = 0; - } else { - dnsreq = NULL; - } - } - - /* send write buffer */ - if (wr->buf.len > 0) { - if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) { - FATAL("uv_write failed"); - } - } - - if (readbuf_remaining > 0) { - /* save start of record position, so we can continue on next read */ - dns->state.prevbuf_ptr = buf->base; - dns->state.prevbuf_pos = hdrstart - buf->base; - dns->state.prevbuf_rem = nread - dns->state.prevbuf_pos; - } else { - /* nothing left in this buffer */ - dns->state.prevbuf_ptr = NULL; - dns->state.prevbuf_pos = 0; - dns->state.prevbuf_rem = 0; - free(buf->base); - } -} - -static void after_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - uv_shutdown_t* req; - - if (nread < 0) { - /* Error or EOF */ - ASSERT(nread == UV_EOF); - - if (buf->base) { - free(buf->base); - } - - req = malloc(sizeof *req); - uv_shutdown(req, handle, after_shutdown); - - return; - } - - if (nread == 0) { - /* Everything OK, but nothing read. */ - free(buf->base); - return; - } - /* process requests and send responses */ - process_req(handle, nread, buf); -} - - -static void on_close(uv_handle_t* peer) { - free(peer); -} - - -static void buf_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -static void on_connection(uv_stream_t* server, int status) { - dnshandle* handle; - int r; - - ASSERT(status == 0); - - handle = (dnshandle*) malloc(sizeof *handle); - ASSERT(handle != NULL); - - /* initialize read buffer state */ - handle->state.prevbuf_ptr = 0; - handle->state.prevbuf_pos = 0; - handle->state.prevbuf_rem = 0; - - r = uv_tcp_init(loop, (uv_tcp_t*)handle); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)handle); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)handle, buf_alloc, after_read); - ASSERT(r == 0); -} - - -static int dns_start(int port) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr)); - - r = uv_tcp_init(loop, &server); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Socket creation error\n"); - return 1; - } - - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Bind error\n"); - return 1; - } - - r = uv_listen((uv_stream_t*)&server, 128, on_connection); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Listen error\n"); - return 1; - } - - return 0; -} - - -HELPER_IMPL(dns_server) { - loop = uv_default_loop(); - - if (dns_start(TEST_PORT_2)) - return 1; - - uv_run(loop, UV_RUN_DEFAULT); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/echo-server.c b/outside/libuv-v1.7.5/test/echo-server.c deleted file mode 100644 index bfed67675d..0000000000 --- a/outside/libuv-v1.7.5/test/echo-server.c +++ /dev/null @@ -1,378 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - -typedef struct { - uv_write_t req; - uv_buf_t buf; -} write_req_t; - -static uv_loop_t* loop; - -static int server_closed; -static stream_type serverType; -static uv_tcp_t tcpServer; -static uv_udp_t udpServer; -static uv_pipe_t pipeServer; -static uv_handle_t* server; - -static void after_write(uv_write_t* req, int status); -static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf); -static void on_close(uv_handle_t* peer); -static void on_server_close(uv_handle_t* handle); -static void on_connection(uv_stream_t*, int status); - - -static void after_write(uv_write_t* req, int status) { - write_req_t* wr; - - /* Free the read/write buffer and the request */ - wr = (write_req_t*) req; - free(wr->buf.base); - free(wr); - - if (status == 0) - return; - - fprintf(stderr, - "uv_write error: %s - %s\n", - uv_err_name(status), - uv_strerror(status)); -} - - -static void after_shutdown(uv_shutdown_t* req, int status) { - uv_close((uv_handle_t*) req->handle, on_close); - free(req); -} - - -static void after_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - int i; - write_req_t *wr; - uv_shutdown_t* sreq; - - if (nread < 0) { - /* Error or EOF */ - ASSERT(nread == UV_EOF); - - free(buf->base); - sreq = malloc(sizeof* sreq); - ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown)); - return; - } - - if (nread == 0) { - /* Everything OK, but nothing read. */ - free(buf->base); - return; - } - - /* - * Scan for the letter Q which signals that we should quit the server. - * If we get QS it means close the stream. - */ - if (!server_closed) { - for (i = 0; i < nread; i++) { - if (buf->base[i] == 'Q') { - if (i + 1 < nread && buf->base[i + 1] == 'S') { - free(buf->base); - uv_close((uv_handle_t*)handle, on_close); - return; - } else { - uv_close(server, on_server_close); - server_closed = 1; - } - } - } - } - - wr = (write_req_t*) malloc(sizeof *wr); - ASSERT(wr != NULL); - wr->buf = uv_buf_init(buf->base, nread); - - if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) { - FATAL("uv_write failed"); - } -} - - -static void on_close(uv_handle_t* peer) { - free(peer); -} - - -static void echo_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -static void on_connection(uv_stream_t* server, int status) { - uv_stream_t* stream; - int r; - - if (status != 0) { - fprintf(stderr, "Connect error %s\n", uv_err_name(status)); - } - ASSERT(status == 0); - - switch (serverType) { - case TCP: - stream = malloc(sizeof(uv_tcp_t)); - ASSERT(stream != NULL); - r = uv_tcp_init(loop, (uv_tcp_t*)stream); - ASSERT(r == 0); - break; - - case PIPE: - stream = malloc(sizeof(uv_pipe_t)); - ASSERT(stream != NULL); - r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0); - ASSERT(r == 0); - break; - - default: - ASSERT(0 && "Bad serverType"); - abort(); - } - - /* associate server with stream */ - stream->data = server; - - r = uv_accept(server, stream); - ASSERT(r == 0); - - r = uv_read_start(stream, echo_alloc, after_read); - ASSERT(r == 0); -} - - -static void on_server_close(uv_handle_t* handle) { - ASSERT(handle == server); -} - - -static void on_send(uv_udp_send_t* req, int status); - - -static void on_recv(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* rcvbuf, - const struct sockaddr* addr, - unsigned flags) { - uv_udp_send_t* req; - uv_buf_t sndbuf; - - ASSERT(nread > 0); - ASSERT(addr->sa_family == AF_INET); - - req = malloc(sizeof(*req)); - ASSERT(req != NULL); - - sndbuf = *rcvbuf; - ASSERT(0 == uv_udp_send(req, handle, &sndbuf, 1, addr, on_send)); -} - - -static void on_send(uv_udp_send_t* req, int status) { - ASSERT(status == 0); - free(req); -} - - -static int tcp4_echo_start(int port) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr)); - - server = (uv_handle_t*)&tcpServer; - serverType = TCP; - - r = uv_tcp_init(loop, &tcpServer); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Socket creation error\n"); - return 1; - } - - r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Bind error\n"); - return 1; - } - - r = uv_listen((uv_stream_t*)&tcpServer, SOMAXCONN, on_connection); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Listen error %s\n", uv_err_name(r)); - return 1; - } - - return 0; -} - - -static int tcp6_echo_start(int port) { - struct sockaddr_in6 addr6; - int r; - - ASSERT(0 == uv_ip6_addr("::1", port, &addr6)); - - server = (uv_handle_t*)&tcpServer; - serverType = TCP; - - r = uv_tcp_init(loop, &tcpServer); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Socket creation error\n"); - return 1; - } - - /* IPv6 is optional as not all platforms support it */ - r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr6, 0); - if (r) { - /* show message but return OK */ - fprintf(stderr, "IPv6 not supported\n"); - return 0; - } - - r = uv_listen((uv_stream_t*)&tcpServer, SOMAXCONN, on_connection); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Listen error\n"); - return 1; - } - - return 0; -} - - -static int udp4_echo_start(int port) { - int r; - - server = (uv_handle_t*)&udpServer; - serverType = UDP; - - r = uv_udp_init(loop, &udpServer); - if (r) { - fprintf(stderr, "uv_udp_init: %s\n", uv_strerror(r)); - return 1; - } - - r = uv_udp_recv_start(&udpServer, echo_alloc, on_recv); - if (r) { - fprintf(stderr, "uv_udp_recv_start: %s\n", uv_strerror(r)); - return 1; - } - - return 0; -} - - -static int pipe_echo_start(char* pipeName) { - int r; - -#ifndef _WIN32 - { - uv_fs_t req; - uv_fs_unlink(NULL, &req, pipeName, NULL); - uv_fs_req_cleanup(&req); - } -#endif - - server = (uv_handle_t*)&pipeServer; - serverType = PIPE; - - r = uv_pipe_init(loop, &pipeServer, 0); - if (r) { - fprintf(stderr, "uv_pipe_init: %s\n", uv_strerror(r)); - return 1; - } - - r = uv_pipe_bind(&pipeServer, pipeName); - if (r) { - fprintf(stderr, "uv_pipe_bind: %s\n", uv_strerror(r)); - return 1; - } - - r = uv_listen((uv_stream_t*)&pipeServer, SOMAXCONN, on_connection); - if (r) { - fprintf(stderr, "uv_pipe_listen: %s\n", uv_strerror(r)); - return 1; - } - - return 0; -} - - -HELPER_IMPL(tcp4_echo_server) { - loop = uv_default_loop(); - - if (tcp4_echo_start(TEST_PORT)) - return 1; - - uv_run(loop, UV_RUN_DEFAULT); - return 0; -} - - -HELPER_IMPL(tcp6_echo_server) { - loop = uv_default_loop(); - - if (tcp6_echo_start(TEST_PORT)) - return 1; - - uv_run(loop, UV_RUN_DEFAULT); - return 0; -} - - -HELPER_IMPL(pipe_echo_server) { - loop = uv_default_loop(); - - if (pipe_echo_start(TEST_PIPENAME)) - return 1; - - uv_run(loop, UV_RUN_DEFAULT); - return 0; -} - - -HELPER_IMPL(udp4_echo_server) { - loop = uv_default_loop(); - - if (udp4_echo_start(TEST_PORT)) - return 1; - - uv_run(loop, UV_RUN_DEFAULT); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/fixtures/empty_file b/outside/libuv-v1.7.5/test/fixtures/empty_file deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/outside/libuv-v1.7.5/test/fixtures/load_error.node b/outside/libuv-v1.7.5/test/fixtures/load_error.node deleted file mode 100644 index 323fae03f4..0000000000 --- a/outside/libuv-v1.7.5/test/fixtures/load_error.node +++ /dev/null @@ -1 +0,0 @@ -foobar diff --git a/outside/libuv-v1.7.5/test/run-benchmarks.c b/outside/libuv-v1.7.5/test/run-benchmarks.c deleted file mode 100644 index 6e42623d54..0000000000 --- a/outside/libuv-v1.7.5/test/run-benchmarks.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "runner.h" -#include "task.h" - -/* Actual benchmarks and helpers are defined in benchmark-list.h */ -#include "benchmark-list.h" - - -static int maybe_run_test(int argc, char **argv); - - -int main(int argc, char **argv) { - if (platform_init(argc, argv)) - return EXIT_FAILURE; - - switch (argc) { - case 1: return run_tests(1); - case 2: return maybe_run_test(argc, argv); - case 3: return run_test_part(argv[1], argv[2]); - default: - fprintf(stderr, "Too many arguments.\n"); - fflush(stderr); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - - -static int maybe_run_test(int argc, char **argv) { - if (strcmp(argv[1], "--list") == 0) { - print_tests(stdout); - return 0; - } - - if (strcmp(argv[1], "spawn_helper") == 0) { - printf("hello world\n"); - return 42; - } - - return run_test(argv[1], 1, 1); -} diff --git a/outside/libuv-v1.7.5/test/run-tests.c b/outside/libuv-v1.7.5/test/run-tests.c deleted file mode 100644 index b4be01f6f9..0000000000 --- a/outside/libuv-v1.7.5/test/run-tests.c +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include - -#ifdef _WIN32 -# include -#else -# include -#endif - -#include "uv.h" -#include "runner.h" -#include "task.h" - -/* Actual tests and helpers are defined in test-list.h */ -#include "test-list.h" - -int ipc_helper(int listen_after_write); -int ipc_helper_tcp_connection(void); -int ipc_send_recv_helper(void); -int ipc_helper_bind_twice(void); -int stdio_over_pipes_helper(void); -int spawn_stdin_stdout(void); - -static int maybe_run_test(int argc, char **argv); - - -int main(int argc, char **argv) { - if (platform_init(argc, argv)) - return EXIT_FAILURE; - - argv = uv_setup_args(argc, argv); - - switch (argc) { - case 1: return run_tests(0); - case 2: return maybe_run_test(argc, argv); - case 3: return run_test_part(argv[1], argv[2]); - default: - fprintf(stderr, "Too many arguments.\n"); - fflush(stderr); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - - -static int maybe_run_test(int argc, char **argv) { - if (strcmp(argv[1], "--list") == 0) { - print_tests(stdout); - return 0; - } - - if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) { - return ipc_helper(0); - } - - if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) { - return ipc_helper(1); - } - - if (strcmp(argv[1], "ipc_send_recv_helper") == 0) { - return ipc_send_recv_helper(); - } - - if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) { - return ipc_helper_tcp_connection(); - } - - if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) { - return ipc_helper_bind_twice(); - } - - if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) { - return stdio_over_pipes_helper(); - } - - if (strcmp(argv[1], "spawn_helper1") == 0) { - return 1; - } - - if (strcmp(argv[1], "spawn_helper2") == 0) { - printf("hello world\n"); - return 1; - } - - if (strcmp(argv[1], "spawn_helper3") == 0) { - char buffer[256]; - ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin)); - buffer[sizeof(buffer) - 1] = '\0'; - fputs(buffer, stdout); - return 1; - } - - if (strcmp(argv[1], "spawn_helper4") == 0) { - /* Never surrender, never return! */ - while (1) uv_sleep(10000); - } - - if (strcmp(argv[1], "spawn_helper5") == 0) { - const char out[] = "fourth stdio!\n"; -#ifdef _WIN32 - DWORD bytes; - WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL); -#else - { - ssize_t r; - - do - r = write(3, out, sizeof(out) - 1); - while (r == -1 && errno == EINTR); - - fsync(3); - } -#endif - return 1; - } - - if (strcmp(argv[1], "spawn_helper6") == 0) { - int r; - - r = fprintf(stdout, "hello world\n"); - ASSERT(r > 0); - - r = fprintf(stderr, "hello errworld\n"); - ASSERT(r > 0); - - return 1; - } - - if (strcmp(argv[1], "spawn_helper7") == 0) { - int r; - char *test; - /* Test if the test value from the parent is still set */ - test = getenv("ENV_TEST"); - ASSERT(test != NULL); - - r = fprintf(stdout, "%s", test); - ASSERT(r > 0); - - return 1; - } - -#ifndef _WIN32 - if (strcmp(argv[1], "spawn_helper8") == 0) { - int fd; - ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd))); - ASSERT(fd > 2); - ASSERT(-1 == write(fd, "x", 1)); - - return 1; - } -#endif /* !_WIN32 */ - - if (strcmp(argv[1], "spawn_helper9") == 0) { - return spawn_stdin_stdout(); - } - - return run_test(argv[1], 0, 1); -} diff --git a/outside/libuv-v1.7.5/test/runner-unix.c b/outside/libuv-v1.7.5/test/runner-unix.c deleted file mode 100644 index 2264d1e89d..0000000000 --- a/outside/libuv-v1.7.5/test/runner-unix.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "runner-unix.h" -#include "runner.h" - -#include -#include /* uintptr_t */ - -#include -#include /* readlink, usleep */ -#include /* strdup */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -/* Do platform-specific initialization. */ -int platform_init(int argc, char **argv) { - const char* tap; - - tap = getenv("UV_TAP_OUTPUT"); - tap_output = (tap != NULL && atoi(tap) > 0); - - /* Disable stdio output buffering. */ - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - signal(SIGPIPE, SIG_IGN); - - if (realpath(argv[0], executable_path) == NULL) { - perror("realpath"); - return -1; - } - - return 0; -} - - -/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */ -/* Make sure that all stdio output of the processes is buffered up. */ -int process_start(char* name, char* part, process_info_t* p, int is_helper) { - FILE* stdout_file; - const char* arg; - char* args[16]; - int n; - pid_t pid; - - stdout_file = tmpfile(); - if (!stdout_file) { - perror("tmpfile"); - return -1; - } - - p->terminated = 0; - p->status = 0; - - pid = fork(); - - if (pid < 0) { - perror("fork"); - return -1; - } - - if (pid == 0) { - /* child */ - arg = getenv("UV_USE_VALGRIND"); - n = 0; - - /* Disable valgrind for helpers, it complains about helpers leaking memory. - * They're killed after the test and as such never get a chance to clean up. - */ - if (is_helper == 0 && arg != NULL && atoi(arg) != 0) { - args[n++] = "valgrind"; - args[n++] = "--quiet"; - args[n++] = "--leak-check=full"; - args[n++] = "--show-reachable=yes"; - args[n++] = "--error-exitcode=125"; - } - - args[n++] = executable_path; - args[n++] = name; - args[n++] = part; - args[n++] = NULL; - - dup2(fileno(stdout_file), STDOUT_FILENO); - dup2(fileno(stdout_file), STDERR_FILENO); - execvp(args[0], args); - perror("execvp()"); - _exit(127); - } - - /* parent */ - p->pid = pid; - p->name = strdup(name); - p->stdout_file = stdout_file; - - return 0; -} - - -typedef struct { - int pipe[2]; - process_info_t* vec; - int n; -} dowait_args; - - -/* This function is run inside a pthread. We do this so that we can possibly - * timeout. - */ -static void* dowait(void* data) { - dowait_args* args = data; - - int i, r; - process_info_t* p; - - for (i = 0; i < args->n; i++) { - p = (process_info_t*)(args->vec + i * sizeof(process_info_t)); - if (p->terminated) continue; - r = waitpid(p->pid, &p->status, 0); - if (r < 0) { - perror("waitpid"); - return NULL; - } - p->terminated = 1; - } - - if (args->pipe[1] >= 0) { - /* Write a character to the main thread to notify it about this. */ - ssize_t r; - - do - r = write(args->pipe[1], "", 1); - while (r == -1 && errno == EINTR); - } - - return NULL; -} - - -/* Wait for all `n` processes in `vec` to terminate. */ -/* Time out after `timeout` msec, or never if timeout == -1 */ -/* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */ -int process_wait(process_info_t* vec, int n, int timeout) { - int i; - int r; - int retval; - process_info_t* p; - dowait_args args; - pthread_t tid; - pthread_attr_t attr; - unsigned int elapsed_ms; - struct timeval timebase; - struct timeval tv; - fd_set fds; - - args.vec = vec; - args.n = n; - args.pipe[0] = -1; - args.pipe[1] = -1; - - /* The simple case is where there is no timeout */ - if (timeout == -1) { - dowait(&args); - return 0; - } - - /* Hard case. Do the wait with a timeout. - * - * Assumption: we are the only ones making this call right now. Otherwise - * we'd need to lock vec. - */ - - r = pipe((int*)&(args.pipe)); - if (r) { - perror("pipe()"); - return -1; - } - - if (pthread_attr_init(&attr)) - abort(); - - if (pthread_attr_setstacksize(&attr, 256 * 1024)) - abort(); - - r = pthread_create(&tid, &attr, dowait, &args); - - if (pthread_attr_destroy(&attr)) - abort(); - - if (r) { - perror("pthread_create()"); - retval = -1; - goto terminate; - } - - if (gettimeofday(&timebase, NULL)) - abort(); - - tv = timebase; - for (;;) { - /* Check that gettimeofday() doesn't jump back in time. */ - assert(tv.tv_sec == timebase.tv_sec || - (tv.tv_sec == timebase.tv_sec && tv.tv_usec >= timebase.tv_usec)); - - elapsed_ms = - (tv.tv_sec - timebase.tv_sec) * 1000 + - (tv.tv_usec / 1000) - - (timebase.tv_usec / 1000); - - r = 0; /* Timeout. */ - if (elapsed_ms >= (unsigned) timeout) - break; - - tv.tv_sec = (timeout - elapsed_ms) / 1000; - tv.tv_usec = (timeout - elapsed_ms) % 1000 * 1000; - - FD_ZERO(&fds); - FD_SET(args.pipe[0], &fds); - - r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv); - if (!(r == -1 && errno == EINTR)) - break; - - if (gettimeofday(&tv, NULL)) - abort(); - } - - if (r == -1) { - perror("select()"); - retval = -1; - - } else if (r) { - /* The thread completed successfully. */ - retval = 0; - - } else { - /* Timeout. Kill all the children. */ - for (i = 0; i < n; i++) { - p = (process_info_t*)(vec + i * sizeof(process_info_t)); - kill(p->pid, SIGTERM); - } - retval = -2; - } - - if (pthread_join(tid, NULL)) - abort(); - -terminate: - close(args.pipe[0]); - close(args.pipe[1]); - return retval; -} - - -/* Returns the number of bytes in the stdio output buffer for process `p`. */ -long int process_output_size(process_info_t *p) { - /* Size of the p->stdout_file */ - struct stat buf; - - int r = fstat(fileno(p->stdout_file), &buf); - if (r < 0) { - return -1; - } - - return (long)buf.st_size; -} - - -/* Copy the contents of the stdio output buffer to `fd`. */ -int process_copy_output(process_info_t *p, int fd) { - ssize_t nwritten; - char buf[1024]; - int r; - - r = fseek(p->stdout_file, 0, SEEK_SET); - if (r < 0) { - perror("fseek"); - return -1; - } - - /* TODO: what if the line is longer than buf */ - while (fgets(buf, sizeof(buf), p->stdout_file) != NULL) { - /* TODO: what if write doesn't write the whole buffer... */ - nwritten = 0; - - if (tap_output) - nwritten += write(fd, "#", 1); - - nwritten += write(fd, buf, strlen(buf)); - - if (nwritten < 0) { - perror("write"); - return -1; - } - } - - if (ferror(p->stdout_file)) { - perror("read"); - return -1; - } - - return 0; -} - - -/* Copy the last line of the stdio output buffer to `buffer` */ -int process_read_last_line(process_info_t *p, - char* buffer, - size_t buffer_len) { - char* ptr; - - int r = fseek(p->stdout_file, 0, SEEK_SET); - if (r < 0) { - perror("fseek"); - return -1; - } - - buffer[0] = '\0'; - - while (fgets(buffer, buffer_len, p->stdout_file) != NULL) { - for (ptr = buffer; *ptr && *ptr != '\r' && *ptr != '\n'; ptr++); - *ptr = '\0'; - } - - if (ferror(p->stdout_file)) { - perror("read"); - buffer[0] = '\0'; - return -1; - } - return 0; -} - - -/* Return the name that was specified when `p` was started by process_start */ -char* process_get_name(process_info_t *p) { - return p->name; -} - - -/* Terminate process `p`. */ -int process_terminate(process_info_t *p) { - return kill(p->pid, SIGTERM); -} - - -/* Return the exit code of process p. */ -/* On error, return -1. */ -int process_reap(process_info_t *p) { - if (WIFEXITED(p->status)) { - return WEXITSTATUS(p->status); - } else { - return p->status; /* ? */ - } -} - - -/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */ -void process_cleanup(process_info_t *p) { - fclose(p->stdout_file); - free(p->name); -} - - -/* Move the console cursor one line up and back to the first column. */ -void rewind_cursor(void) { - fprintf(stderr, "\033[2K\r"); -} - - -/* Pause the calling thread for a number of milliseconds. */ -void uv_sleep(int msec) { - usleep(msec * 1000); -} diff --git a/outside/libuv-v1.7.5/test/runner-unix.h b/outside/libuv-v1.7.5/test/runner-unix.h deleted file mode 100644 index e21847f92c..0000000000 --- a/outside/libuv-v1.7.5/test/runner-unix.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef TEST_RUNNER_UNIX_H -#define TEST_RUNNER_UNIX_H - -#include -#include /* FILE */ - -typedef struct { - FILE* stdout_file; - pid_t pid; - char* name; - int status; - int terminated; -} process_info_t; - -#endif /* TEST_RUNNER_UNIX_H */ diff --git a/outside/libuv-v1.7.5/test/runner-win.c b/outside/libuv-v1.7.5/test/runner-win.c deleted file mode 100644 index 97ef7599eb..0000000000 --- a/outside/libuv-v1.7.5/test/runner-win.c +++ /dev/null @@ -1,371 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#if !defined(__MINGW32__) -# include -#endif - - -#include "task.h" -#include "runner.h" - - -/* - * Define the stuff that MinGW doesn't have - */ -#ifndef GetFileSizeEx - WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, - PLARGE_INTEGER lpFileSize); -#endif - - -/* Do platform-specific initialization. */ -int platform_init(int argc, char **argv) { - const char* tap; - - tap = getenv("UV_TAP_OUTPUT"); - tap_output = (tap != NULL && atoi(tap) > 0); - - /* Disable the "application crashed" popup. */ - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); -#if !defined(__MINGW32__) - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); -#endif - - _setmode(0, _O_BINARY); - _setmode(1, _O_BINARY); - _setmode(2, _O_BINARY); - - /* Disable stdio output buffering. */ - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - - strcpy(executable_path, argv[0]); - - return 0; -} - - -int process_start(char *name, char *part, process_info_t *p, int is_helper) { - HANDLE file = INVALID_HANDLE_VALUE; - HANDLE nul = INVALID_HANDLE_VALUE; - WCHAR path[MAX_PATH], filename[MAX_PATH]; - WCHAR image[MAX_PATH + 1]; - WCHAR args[MAX_PATH * 2]; - STARTUPINFOW si; - PROCESS_INFORMATION pi; - DWORD result; - - if (GetTempPathW(sizeof(path) / sizeof(WCHAR), (WCHAR*)&path) == 0) - goto error; - if (GetTempFileNameW((WCHAR*)&path, L"uv", 0, (WCHAR*)&filename) == 0) - goto error; - - file = CreateFileW((WCHAR*)filename, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - NULL); - if (file == INVALID_HANDLE_VALUE) - goto error; - - if (!SetHandleInformation(file, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) - goto error; - - nul = CreateFileA("nul", - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (nul == INVALID_HANDLE_VALUE) - goto error; - - if (!SetHandleInformation(nul, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) - goto error; - - result = GetModuleFileNameW(NULL, - (WCHAR*) &image, - sizeof(image) / sizeof(WCHAR)); - if (result == 0 || result == sizeof(image)) - goto error; - - if (part) { - if (_snwprintf((WCHAR*)args, - sizeof(args) / sizeof(WCHAR), - L"\"%s\" %S %S", - image, - name, - part) < 0) { - goto error; - } - } else { - if (_snwprintf((WCHAR*)args, - sizeof(args) / sizeof(WCHAR), - L"\"%s\" %S", - image, - name) < 0) { - goto error; - } - } - - memset((void*)&si, 0, sizeof(si)); - si.cb = sizeof(si); - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = nul; - si.hStdOutput = file; - si.hStdError = file; - - if (!CreateProcessW(image, args, NULL, NULL, TRUE, - 0, NULL, NULL, &si, &pi)) - goto error; - - CloseHandle(pi.hThread); - - SetHandleInformation(nul, HANDLE_FLAG_INHERIT, 0); - SetHandleInformation(file, HANDLE_FLAG_INHERIT, 0); - - p->stdio_in = nul; - p->stdio_out = file; - p->process = pi.hProcess; - p->name = part; - - return 0; - -error: - if (file != INVALID_HANDLE_VALUE) - CloseHandle(file); - if (nul != INVALID_HANDLE_VALUE) - CloseHandle(nul); - - return -1; -} - - -/* Timeout is is msecs. Set timeout < 0 to never time out. */ -/* Returns 0 when all processes are terminated, -2 on timeout. */ -int process_wait(process_info_t *vec, int n, int timeout) { - int i; - HANDLE handles[MAXIMUM_WAIT_OBJECTS]; - DWORD timeout_api, result; - - /* If there's nothing to wait for, return immediately. */ - if (n == 0) - return 0; - - ASSERT(n <= MAXIMUM_WAIT_OBJECTS); - - for (i = 0; i < n; i++) - handles[i] = vec[i].process; - - if (timeout >= 0) { - timeout_api = (DWORD)timeout; - } else { - timeout_api = INFINITE; - } - - result = WaitForMultipleObjects(n, handles, TRUE, timeout_api); - - if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + n) { - /* All processes are terminated. */ - return 0; - } - if (result == WAIT_TIMEOUT) { - return -2; - } - return -1; -} - - -long int process_output_size(process_info_t *p) { - LARGE_INTEGER size; - if (!GetFileSizeEx(p->stdio_out, &size)) - return -1; - return (long int)size.QuadPart; -} - - -int process_copy_output(process_info_t *p, int fd) { - DWORD read; - char buf[1024]; - char *line, *start; - - if (SetFilePointer(p->stdio_out, - 0, - 0, - FILE_BEGIN) == INVALID_SET_FILE_POINTER) { - return -1; - } - - if (tap_output) - write(fd, "#", 1); - - while (ReadFile(p->stdio_out, (void*)&buf, sizeof(buf), &read, NULL) && - read > 0) { - if (tap_output) { - start = buf; - - while ((line = strchr(start, '\n')) != NULL) { - write(fd, start, line - start + 1); - write(fd, "#", 1); - start = line + 1; - } - - if (start < buf + read) - write(fd, start, buf + read - start); - } else { - write(fd, buf, read); - } - } - - if (tap_output) - write(fd, "\n", 1); - - if (GetLastError() != ERROR_HANDLE_EOF) - return -1; - - return 0; -} - - -int process_read_last_line(process_info_t *p, - char * buffer, - size_t buffer_len) { - DWORD size; - DWORD read; - DWORD start; - OVERLAPPED overlapped; - - ASSERT(buffer_len > 0); - - size = GetFileSize(p->stdio_out, NULL); - if (size == INVALID_FILE_SIZE) - return -1; - - if (size == 0) { - buffer[0] = '\0'; - return 1; - } - - memset(&overlapped, 0, sizeof overlapped); - if (size >= buffer_len) - overlapped.Offset = size - buffer_len - 1; - - if (!ReadFile(p->stdio_out, buffer, buffer_len - 1, &read, &overlapped)) - return -1; - - for (start = read - 1; start >= 0; start--) { - if (buffer[start] == '\n' || buffer[start] == '\r') - break; - } - - if (start > 0) - memmove(buffer, buffer + start, read - start); - - buffer[read - start] = '\0'; - - return 0; -} - - -char* process_get_name(process_info_t *p) { - return p->name; -} - - -int process_terminate(process_info_t *p) { - if (!TerminateProcess(p->process, 1)) - return -1; - return 0; -} - - -int process_reap(process_info_t *p) { - DWORD exitCode; - if (!GetExitCodeProcess(p->process, &exitCode)) - return -1; - return (int)exitCode; -} - - -void process_cleanup(process_info_t *p) { - CloseHandle(p->process); - CloseHandle(p->stdio_in); - CloseHandle(p->stdio_out); -} - - -static int clear_line() { - HANDLE handle; - CONSOLE_SCREEN_BUFFER_INFO info; - COORD coord; - DWORD written; - - handle = (HANDLE)_get_osfhandle(fileno(stderr)); - if (handle == INVALID_HANDLE_VALUE) - return -1; - - if (!GetConsoleScreenBufferInfo(handle, &info)) - return -1; - - coord = info.dwCursorPosition; - if (coord.Y <= 0) - return -1; - - coord.X = 0; - - if (!SetConsoleCursorPosition(handle, coord)) - return -1; - - if (!FillConsoleOutputCharacterW(handle, - 0x20, - info.dwSize.X, - coord, - &written)) { - return -1; - } - - return 0; -} - - -void rewind_cursor() { - if (clear_line() == -1) { - /* If clear_line fails (stdout is not a console), print a newline. */ - fprintf(stderr, "\n"); - } -} - - -/* Pause the calling thread for a number of milliseconds. */ -void uv_sleep(int msec) { - Sleep(msec); -} diff --git a/outside/libuv-v1.7.5/test/runner-win.h b/outside/libuv-v1.7.5/test/runner-win.h deleted file mode 100644 index c94b89bd5e..0000000000 --- a/outside/libuv-v1.7.5/test/runner-win.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* Don't complain about _snprintf being insecure. */ -#define _CRT_SECURE_NO_WARNINGS - -/* Don't complain about write(), fileno() etc. being deprecated. */ -#pragma warning(disable : 4996) - - -#include -#include -#include - - -/* Windows has no snprintf, only _snprintf. */ -#define snprintf _snprintf - - -typedef struct { - HANDLE process; - HANDLE stdio_in; - HANDLE stdio_out; - char *name; -} process_info_t; diff --git a/outside/libuv-v1.7.5/test/runner.c b/outside/libuv-v1.7.5/test/runner.c deleted file mode 100644 index e094defc7e..0000000000 --- a/outside/libuv-v1.7.5/test/runner.c +++ /dev/null @@ -1,464 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include - -#include "runner.h" -#include "task.h" -#include "uv.h" - -char executable_path[sizeof(executable_path)]; - -int tap_output = 0; - - -static void log_progress(int total, - int passed, - int failed, - int todos, - int skipped, - const char* name) { - int progress; - - if (total == 0) - total = 1; - - progress = 100 * (passed + failed + skipped + todos) / total; - fprintf(stderr, "[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s", - progress, - passed, - failed, - todos, - skipped, - name); - fflush(stderr); -} - - -const char* fmt(double d) { - static char buf[1024]; - static char* p; - uint64_t v; - - if (p == NULL) - p = buf; - - p += 31; - - if (p >= buf + sizeof(buf)) - return ""; - - v = (uint64_t) d; - -#if 0 /* works but we don't care about fractional precision */ - if (d - v >= 0.01) { - *--p = '0' + (uint64_t) (d * 100) % 10; - *--p = '0' + (uint64_t) (d * 10) % 10; - *--p = '.'; - } -#endif - - if (v == 0) - *--p = '0'; - - while (v) { - if (v) *--p = '0' + (v % 10), v /= 10; - if (v) *--p = '0' + (v % 10), v /= 10; - if (v) *--p = '0' + (v % 10), v /= 10; - if (v) *--p = ','; - } - - return p; -} - - -int run_tests(int benchmark_output) { - int total; - int passed; - int failed; - int todos; - int skipped; - int current; - int test_result; - task_entry_t* task; - - /* Count the number of tests. */ - total = 0; - for (task = TASKS; task->main; task++) { - if (!task->is_helper) { - total++; - } - } - - if (tap_output) { - fprintf(stderr, "1..%d\n", total); - fflush(stderr); - } - - /* Run all tests. */ - passed = 0; - failed = 0; - todos = 0; - skipped = 0; - current = 1; - for (task = TASKS; task->main; task++) { - if (task->is_helper) { - continue; - } - - if (!tap_output) - rewind_cursor(); - - if (!benchmark_output && !tap_output) { - log_progress(total, passed, failed, todos, skipped, task->task_name); - } - - test_result = run_test(task->task_name, benchmark_output, current); - switch (test_result) { - case TEST_OK: passed++; break; - case TEST_TODO: todos++; break; - case TEST_SKIP: skipped++; break; - default: failed++; - } - current++; - } - - if (!tap_output) - rewind_cursor(); - - if (!benchmark_output && !tap_output) { - log_progress(total, passed, failed, todos, skipped, "Done.\n"); - } - - return failed; -} - - -void log_tap_result(int test_count, - const char* test, - int status, - process_info_t* process) { - const char* result; - const char* directive; - char reason[1024]; - - switch (status) { - case TEST_OK: - result = "ok"; - directive = ""; - break; - case TEST_TODO: - result = "not ok"; - directive = " # TODO "; - break; - case TEST_SKIP: - result = "ok"; - directive = " # SKIP "; - break; - default: - result = "not ok"; - directive = ""; - } - - if ((status == TEST_SKIP || status == TEST_TODO) && - process_output_size(process) > 0) { - process_read_last_line(process, reason, sizeof reason); - } else { - reason[0] = '\0'; - } - - fprintf(stderr, "%s %d - %s%s%s\n", result, test_count, test, directive, reason); - fflush(stderr); -} - - -int run_test(const char* test, - int benchmark_output, - int test_count) { - char errmsg[1024] = "no error"; - process_info_t processes[1024]; - process_info_t *main_proc; - task_entry_t* task; - int process_count; - int result; - int status; - int i; - - status = 255; - main_proc = NULL; - process_count = 0; - -#ifndef _WIN32 - /* Clean up stale socket from previous run. */ - remove(TEST_PIPENAME); -#endif - - /* If it's a helper the user asks for, start it directly. */ - for (task = TASKS; task->main; task++) { - if (task->is_helper && strcmp(test, task->process_name) == 0) { - return task->main(); - } - } - - /* Start the helpers first. */ - for (task = TASKS; task->main; task++) { - if (strcmp(test, task->task_name) != 0) { - continue; - } - - /* Skip the test itself. */ - if (!task->is_helper) { - continue; - } - - if (process_start(task->task_name, - task->process_name, - &processes[process_count], - 1 /* is_helper */) == -1) { - snprintf(errmsg, - sizeof errmsg, - "Process `%s` failed to start.", - task->process_name); - goto out; - } - - process_count++; - } - - /* Give the helpers time to settle. Race-y, fix this. */ - uv_sleep(250); - - /* Now start the test itself. */ - for (task = TASKS; task->main; task++) { - if (strcmp(test, task->task_name) != 0) { - continue; - } - - if (task->is_helper) { - continue; - } - - if (process_start(task->task_name, - task->process_name, - &processes[process_count], - 0 /* !is_helper */) == -1) { - snprintf(errmsg, - sizeof errmsg, - "Process `%s` failed to start.", - task->process_name); - goto out; - } - - main_proc = &processes[process_count]; - process_count++; - break; - } - - if (main_proc == NULL) { - snprintf(errmsg, - sizeof errmsg, - "No test with that name: %s", - test); - goto out; - } - - result = process_wait(main_proc, 1, task->timeout); - if (result == -1) { - FATAL("process_wait failed"); - } else if (result == -2) { - /* Don't have to clean up the process, process_wait() has killed it. */ - snprintf(errmsg, - sizeof errmsg, - "timeout"); - goto out; - } - - status = process_reap(main_proc); - if (status != TEST_OK) { - snprintf(errmsg, - sizeof errmsg, - "exit code %d", - status); - goto out; - } - - if (benchmark_output) { - /* Give the helpers time to clean up their act. */ - uv_sleep(1000); - } - -out: - /* Reap running processes except the main process, it's already dead. */ - for (i = 0; i < process_count - 1; i++) { - process_terminate(&processes[i]); - } - - if (process_count > 0 && - process_wait(processes, process_count - 1, -1) < 0) { - FATAL("process_wait failed"); - } - - if (tap_output) - log_tap_result(test_count, test, status, &processes[i]); - - /* Show error and output from processes if the test failed. */ - if (status != 0 || task->show_output) { - if (tap_output) { - fprintf(stderr, "#"); - } else if (status == TEST_TODO) { - fprintf(stderr, "\n`%s` todo\n", test); - } else if (status == TEST_SKIP) { - fprintf(stderr, "\n`%s` skipped\n", test); - } else if (status != 0) { - fprintf(stderr, "\n`%s` failed: %s\n", test, errmsg); - } else { - fprintf(stderr, "\n"); - } - fflush(stderr); - - for (i = 0; i < process_count; i++) { - switch (process_output_size(&processes[i])) { - case -1: - fprintf(stderr, "Output from process `%s`: (unavailable)\n", - process_get_name(&processes[i])); - fflush(stderr); - break; - - case 0: - fprintf(stderr, "Output from process `%s`: (no output)\n", - process_get_name(&processes[i])); - fflush(stderr); - break; - - default: - fprintf(stderr, "Output from process `%s`:\n", process_get_name(&processes[i])); - fflush(stderr); - process_copy_output(&processes[i], fileno(stderr)); - break; - } - } - - if (!tap_output) { - fprintf(stderr, "=============================================================\n"); - } - - /* In benchmark mode show concise output from the main process. */ - } else if (benchmark_output) { - switch (process_output_size(main_proc)) { - case -1: - fprintf(stderr, "%s: (unavailable)\n", test); - fflush(stderr); - break; - - case 0: - fprintf(stderr, "%s: (no output)\n", test); - fflush(stderr); - break; - - default: - for (i = 0; i < process_count; i++) { - process_copy_output(&processes[i], fileno(stderr)); - } - break; - } - } - - /* Clean up all process handles. */ - for (i = 0; i < process_count; i++) { - process_cleanup(&processes[i]); - } - - return status; -} - - -/* Returns the status code of the task part - * or 255 if no matching task was not found. - */ -int run_test_part(const char* test, const char* part) { - task_entry_t* task; - int r; - - for (task = TASKS; task->main; task++) { - if (strcmp(test, task->task_name) == 0 && - strcmp(part, task->process_name) == 0) { - r = task->main(); - return r; - } - } - - fprintf(stderr, "No test part with that name: %s:%s\n", test, part); - fflush(stderr); - return 255; -} - - -static int compare_task(const void* va, const void* vb) { - const task_entry_t* a = va; - const task_entry_t* b = vb; - return strcmp(a->task_name, b->task_name); -} - - -static int find_helpers(const task_entry_t* task, - const task_entry_t** helpers) { - const task_entry_t* helper; - int n_helpers; - - for (n_helpers = 0, helper = TASKS; helper->main; helper++) { - if (helper->is_helper && strcmp(helper->task_name, task->task_name) == 0) { - *helpers++ = helper; - n_helpers++; - } - } - - return n_helpers; -} - - -void print_tests(FILE* stream) { - const task_entry_t* helpers[1024]; - const task_entry_t* task; - int n_helpers; - int n_tasks; - int i; - - for (n_tasks = 0, task = TASKS; task->main; n_tasks++, task++); - qsort(TASKS, n_tasks, sizeof(TASKS[0]), compare_task); - - for (task = TASKS; task->main; task++) { - if (task->is_helper) { - continue; - } - - n_helpers = find_helpers(task, helpers); - if (n_helpers) { - printf("%-25s (helpers:", task->task_name); - for (i = 0; i < n_helpers; i++) { - printf(" %s", helpers[i]->process_name); - } - printf(")\n"); - } else { - printf("%s\n", task->task_name); - } - } -} diff --git a/outside/libuv-v1.7.5/test/runner.h b/outside/libuv-v1.7.5/test/runner.h deleted file mode 100644 index 78f3c880a9..0000000000 --- a/outside/libuv-v1.7.5/test/runner.h +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef RUNNER_H_ -#define RUNNER_H_ - -#include /* PATH_MAX */ -#include /* FILE */ - - -/* - * The maximum number of processes (main + helpers) that a test / benchmark - * can have. - */ -#define MAX_PROCESSES 8 - - -/* - * Struct to store both tests and to define helper processes for tasks. - */ -typedef struct { - char *task_name; - char *process_name; - int (*main)(void); - int is_helper; - int show_output; - - /* - * The time in milliseconds after which a single test or benchmark times out. - */ - int timeout; -} task_entry_t, bench_entry_t; - - -/* - * Macros used by test-list.h and benchmark-list.h. - */ -#define TASK_LIST_START \ - task_entry_t TASKS[] = { - -#define TASK_LIST_END \ - { 0, 0, 0, 0, 0, 0 } \ - }; - -#define TEST_DECLARE(name) \ - int run_test_##name(void); - -#define TEST_ENTRY(name) \ - { #name, #name, &run_test_##name, 0, 0, 5000 }, - -#define TEST_ENTRY_CUSTOM(name, is_helper, show_output, timeout) \ - { #name, #name, &run_test_##name, is_helper, show_output, timeout }, - -#define BENCHMARK_DECLARE(name) \ - int run_benchmark_##name(void); - -#define BENCHMARK_ENTRY(name) \ - { #name, #name, &run_benchmark_##name, 0, 0, 60000 }, - -#define HELPER_DECLARE(name) \ - int run_helper_##name(void); - -#define HELPER_ENTRY(task_name, name) \ - { #task_name, #name, &run_helper_##name, 1, 0, 0 }, - -#define TEST_HELPER HELPER_ENTRY -#define BENCHMARK_HELPER HELPER_ENTRY - -#ifdef PATH_MAX -extern char executable_path[PATH_MAX]; -#else -extern char executable_path[4096]; -#endif - -/* - * Include platform-dependent definitions - */ -#ifdef _WIN32 -# include "runner-win.h" -#else -# include "runner-unix.h" -#endif - - -/* The array that is filled by test-list.h or benchmark-list.h */ -extern task_entry_t TASKS[]; - -/* - * Run all tests. - */ -int run_tests(int benchmark_output); - -/* - * Run a single test. Starts up any helpers. - */ -int run_test(const char* test, - int benchmark_output, - int test_count); - -/* - * Run a test part, i.e. the test or one of its helpers. - */ -int run_test_part(const char* test, const char* part); - - -/* - * Print tests in sorted order to `stream`. Used by `./run-tests --list`. - */ -void print_tests(FILE* stream); - - -/* - * Stuff that should be implemented by test-runner-.h - * All functions return 0 on success, -1 on failure, unless specified - * otherwise. - */ - -/* Do platform-specific initialization. */ -int platform_init(int argc, char** argv); - -/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */ -/* Make sure that all stdio output of the processes is buffered up. */ -int process_start(char *name, char* part, process_info_t *p, int is_helper); - -/* Wait for all `n` processes in `vec` to terminate. */ -/* Time out after `timeout` msec, or never if timeout == -1 */ -/* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */ -int process_wait(process_info_t *vec, int n, int timeout); - -/* Returns the number of bytes in the stdio output buffer for process `p`. */ -long int process_output_size(process_info_t *p); - -/* Copy the contents of the stdio output buffer to `fd`. */ -int process_copy_output(process_info_t *p, int fd); - -/* Copy the last line of the stdio output buffer to `buffer` */ -int process_read_last_line(process_info_t *p, - char * buffer, - size_t buffer_len); - -/* Return the name that was specified when `p` was started by process_start */ -char* process_get_name(process_info_t *p); - -/* Terminate process `p`. */ -int process_terminate(process_info_t *p); - -/* Return the exit code of process p. */ -/* On error, return -1. */ -int process_reap(process_info_t *p); - -/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */ -void process_cleanup(process_info_t *p); - -/* Move the console cursor one line up and back to the first column. */ -void rewind_cursor(void); - -/* trigger output as tap */ -extern int tap_output; - -#endif /* RUNNER_H_ */ diff --git a/outside/libuv-v1.7.5/test/task.h b/outside/libuv-v1.7.5/test/task.h deleted file mode 100644 index e736763802..0000000000 --- a/outside/libuv-v1.7.5/test/task.h +++ /dev/null @@ -1,250 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef TASK_H_ -#define TASK_H_ - -#include "uv.h" - -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include -#endif - -#if !defined(_WIN32) -# include -# include /* setrlimit() */ -#endif - -#ifdef __clang__ -# pragma clang diagnostic ignored "-Wvariadic-macros" -# pragma clang diagnostic ignored "-Wc99-extensions" -#endif - -#define TEST_PORT 9123 -#define TEST_PORT_2 9124 - -#ifdef _WIN32 -# define TEST_PIPENAME "\\\\?\\pipe\\uv-test" -# define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2" -#else -# define TEST_PIPENAME "/tmp/uv-test-sock" -# define TEST_PIPENAME_2 "/tmp/uv-test-sock2" -#endif - -#ifdef _WIN32 -# include -# ifndef S_IRUSR -# define S_IRUSR _S_IREAD -# endif -# ifndef S_IWUSR -# define S_IWUSR _S_IWRITE -# endif -#endif - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -#define container_of(ptr, type, member) \ - ((type *) ((char *) (ptr) - offsetof(type, member))) - -typedef enum { - TCP = 0, - UDP, - PIPE -} stream_type; - -/* Die with fatal error. */ -#define FATAL(msg) \ - do { \ - fprintf(stderr, \ - "Fatal error in %s on line %d: %s\n", \ - __FILE__, \ - __LINE__, \ - msg); \ - fflush(stderr); \ - abort(); \ - } while (0) - -/* Have our own assert, so we are sure it does not get optimized away in - * a release build. - */ -#define ASSERT(expr) \ - do { \ - if (!(expr)) { \ - fprintf(stderr, \ - "Assertion failed in %s on line %d: %s\n", \ - __FILE__, \ - __LINE__, \ - #expr); \ - abort(); \ - } \ - } while (0) - -/* This macro cleans up the main loop. This is used to avoid valgrind - * warnings about memory being "leaked" by the main event loop. - */ -#define MAKE_VALGRIND_HAPPY() \ - do { \ - close_loop(uv_default_loop()); \ - uv_loop_delete(uv_default_loop()); \ - } while (0) - -/* Just sugar for wrapping the main() for a task or helper. */ -#define TEST_IMPL(name) \ - int run_test_##name(void); \ - int run_test_##name(void) - -#define BENCHMARK_IMPL(name) \ - int run_benchmark_##name(void); \ - int run_benchmark_##name(void) - -#define HELPER_IMPL(name) \ - int run_helper_##name(void); \ - int run_helper_##name(void) - -/* Pause the calling thread for a number of milliseconds. */ -void uv_sleep(int msec); - -/* Format big numbers nicely. WARNING: leaks memory. */ -const char* fmt(double d); - -/* Reserved test exit codes. */ -enum test_status { - TEST_OK = 0, - TEST_TODO, - TEST_SKIP -}; - -#define RETURN_OK() \ - do { \ - return TEST_OK; \ - } while (0) - -#define RETURN_TODO(explanation) \ - do { \ - fprintf(stderr, "%s\n", explanation); \ - fflush(stderr); \ - return TEST_TODO; \ - } while (0) - -#define RETURN_SKIP(explanation) \ - do { \ - fprintf(stderr, "%s\n", explanation); \ - fflush(stderr); \ - return TEST_SKIP; \ - } while (0) - -#if !defined(_WIN32) - -# define TEST_FILE_LIMIT(num) \ - do { \ - struct rlimit lim; \ - lim.rlim_cur = (num); \ - lim.rlim_max = lim.rlim_cur; \ - if (setrlimit(RLIMIT_NOFILE, &lim)) \ - RETURN_SKIP("File descriptor limit too low."); \ - } while (0) - -#else /* defined(_WIN32) */ - -# define TEST_FILE_LIMIT(num) do {} while (0) - -#endif - - -#if defined _WIN32 && ! defined __GNUC__ - -#include - -/* Define inline for MSVC<2015 */ -# if defined(_MSC_VER) && _MSC_VER < 1900 -# define inline __inline -# endif - -# if defined(_MSC_VER) && _MSC_VER < 1900 -/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer - * on overflow... - */ -inline int snprintf(char* buf, size_t len, const char* fmt, ...) { - va_list ap; - int n; - - va_start(ap, fmt); - n = _vsprintf_p(buf, len, fmt, ap); - va_end(ap); - - /* It's a sad fact of life that no one ever checks the return value of - * snprintf(). Zero-terminating the buffer hopefully reduces the risk - * of gaping security holes. - */ - if (n < 0) - if (len > 0) - buf[0] = '\0'; - - return n; -} -# endif - -#endif - -#if defined(__clang__) || \ - defined(__GNUC__) || \ - defined(__INTEL_COMPILER) || \ - defined(__SUNPRO_C) -# define UNUSED __attribute__((unused)) -#else -# define UNUSED -#endif - -/* Fully close a loop */ -static void close_walk_cb(uv_handle_t* handle, void* arg) { - if (!uv_is_closing(handle)) - uv_close(handle, NULL); -} - -UNUSED static void close_loop(uv_loop_t* loop) { - uv_walk(loop, close_walk_cb, NULL); - uv_run(loop, UV_RUN_DEFAULT); -} - -UNUSED static int can_ipv6(void) { - uv_interface_address_t* addr; - int supported; - int count; - int i; - - if (uv_interface_addresses(&addr, &count)) - return 1; /* Assume IPv6 support on failure. */ - - supported = 0; - for (i = 0; supported == 0 && i < count; i += 1) - supported = (AF_INET6 == addr[i].address.address6.sin6_family); - - uv_free_interface_addresses(addr, count); - return supported; -} - -#endif /* TASK_H_ */ diff --git a/outside/libuv-v1.7.5/test/test-active.c b/outside/libuv-v1.7.5/test/test-active.c deleted file mode 100644 index b17bd17601..0000000000 --- a/outside/libuv-v1.7.5/test/test-active.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(0 && "timer_cb should not have been called"); -} - - -TEST_IMPL(active) { - int r; - uv_timer_t timer; - - r = uv_timer_init(uv_default_loop(), &timer); - ASSERT(r == 0); - - /* uv_is_active() and uv_is_closing() should always return either 0 or 1. */ - ASSERT(0 == uv_is_active((uv_handle_t*) &timer)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); - - r = uv_timer_start(&timer, timer_cb, 1000, 0); - ASSERT(r == 0); - - ASSERT(1 == uv_is_active((uv_handle_t*) &timer)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); - - r = uv_timer_stop(&timer); - ASSERT(r == 0); - - ASSERT(0 == uv_is_active((uv_handle_t*) &timer)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); - - r = uv_timer_start(&timer, timer_cb, 1000, 0); - ASSERT(r == 0); - - ASSERT(1 == uv_is_active((uv_handle_t*) &timer)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); - - uv_close((uv_handle_t*) &timer, close_cb); - - ASSERT(0 == uv_is_active((uv_handle_t*) &timer)); - ASSERT(1 == uv_is_closing((uv_handle_t*) &timer)); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-async-null-cb.c b/outside/libuv-v1.7.5/test/test-async-null-cb.c deleted file mode 100644 index 757944a276..0000000000 --- a/outside/libuv-v1.7.5/test/test-async-null-cb.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_async_t async_handle; -static uv_check_t check_handle; -static int check_cb_called; -static uv_thread_t thread; - - -static void thread_cb(void* dummy) { - (void) &dummy; - uv_async_send(&async_handle); -} - - -static void check_cb(uv_check_t* handle) { - ASSERT(check_cb_called == 0); - uv_close((uv_handle_t*) &async_handle, NULL); - uv_close((uv_handle_t*) &check_handle, NULL); - check_cb_called++; -} - - -TEST_IMPL(async_null_cb) { - ASSERT(0 == uv_async_init(uv_default_loop(), &async_handle, NULL)); - ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle)); - ASSERT(0 == uv_check_start(&check_handle, check_cb)); - ASSERT(0 == uv_thread_create(&thread, thread_cb, NULL)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(0 == uv_thread_join(&thread)); - ASSERT(1 == check_cb_called); - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-async.c b/outside/libuv-v1.7.5/test/test-async.c deleted file mode 100644 index 6f5351bf15..0000000000 --- a/outside/libuv-v1.7.5/test/test-async.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - -static uv_thread_t thread; -static uv_mutex_t mutex; - -static uv_prepare_t prepare; -static uv_async_t async; - -static volatile int async_cb_called; -static int prepare_cb_called; -static int close_cb_called; - - -static void thread_cb(void *arg) { - int n; - int r; - - for (;;) { - uv_mutex_lock(&mutex); - n = async_cb_called; - uv_mutex_unlock(&mutex); - - if (n == 3) { - break; - } - - r = uv_async_send(&async); - ASSERT(r == 0); - - /* Work around a bug in Valgrind. - * - * Valgrind runs threads not in parallel but sequentially, i.e. one after - * the other. It also doesn't preempt them, instead it depends on threads - * yielding voluntarily by making a syscall. - * - * That never happens here: the pipe that is associated with the async - * handle is written to once but that's too early for Valgrind's scheduler - * to kick in. Afterwards, the thread busy-loops, starving the main thread. - * Therefore, we yield. - * - * This behavior has been observed with Valgrind 3.7.0 and 3.9.0. - */ - uv_sleep(0); - } -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void async_cb(uv_async_t* handle) { - int n; - - ASSERT(handle == &async); - - uv_mutex_lock(&mutex); - n = ++async_cb_called; - uv_mutex_unlock(&mutex); - - if (n == 3) { - uv_close((uv_handle_t*)&async, close_cb); - uv_close((uv_handle_t*)&prepare, close_cb); - } -} - - -static void prepare_cb(uv_prepare_t* handle) { - int r; - - ASSERT(handle == &prepare); - - if (prepare_cb_called++) - return; - - r = uv_thread_create(&thread, thread_cb, NULL); - ASSERT(r == 0); - uv_mutex_unlock(&mutex); -} - - -TEST_IMPL(async) { - int r; - - r = uv_mutex_init(&mutex); - ASSERT(r == 0); - uv_mutex_lock(&mutex); - - r = uv_prepare_init(uv_default_loop(), &prepare); - ASSERT(r == 0); - r = uv_prepare_start(&prepare, prepare_cb); - ASSERT(r == 0); - - r = uv_async_init(uv_default_loop(), &async, async_cb); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(prepare_cb_called > 0); - ASSERT(async_cb_called == 3); - ASSERT(close_cb_called == 2); - - ASSERT(0 == uv_thread_join(&thread)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-barrier.c b/outside/libuv-v1.7.5/test/test-barrier.c deleted file mode 100644 index dfd2dbdef1..0000000000 --- a/outside/libuv-v1.7.5/test/test-barrier.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -typedef struct { - uv_barrier_t barrier; - int delay; - volatile int posted; - int main_barrier_wait_rval; - int worker_barrier_wait_rval; -} worker_config; - - -static void worker(void* arg) { - worker_config* c = arg; - - if (c->delay) - uv_sleep(c->delay); - - c->worker_barrier_wait_rval = uv_barrier_wait(&c->barrier); -} - - -TEST_IMPL(barrier_1) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - - ASSERT(0 == uv_barrier_init(&wc.barrier, 2)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_sleep(100); - wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier); - - ASSERT(0 == uv_thread_join(&thread)); - uv_barrier_destroy(&wc.barrier); - - ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval)); - - return 0; -} - - -TEST_IMPL(barrier_2) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - wc.delay = 100; - - ASSERT(0 == uv_barrier_init(&wc.barrier, 2)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier); - - ASSERT(0 == uv_thread_join(&thread)); - uv_barrier_destroy(&wc.barrier); - - ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval)); - - return 0; -} - - -TEST_IMPL(barrier_3) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - - ASSERT(0 == uv_barrier_init(&wc.barrier, 2)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier); - - ASSERT(0 == uv_thread_join(&thread)); - uv_barrier_destroy(&wc.barrier); - - ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval)); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-callback-order.c b/outside/libuv-v1.7.5/test/test-callback-order.c deleted file mode 100644 index 8bc2c4f75d..0000000000 --- a/outside/libuv-v1.7.5/test/test-callback-order.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static int idle_cb_called; -static int timer_cb_called; - -static uv_idle_t idle_handle; -static uv_timer_t timer_handle; - - -/* idle_cb should run before timer_cb */ -static void idle_cb(uv_idle_t* handle) { - ASSERT(idle_cb_called == 0); - ASSERT(timer_cb_called == 0); - uv_idle_stop(handle); - idle_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(idle_cb_called == 1); - ASSERT(timer_cb_called == 0); - uv_timer_stop(handle); - timer_cb_called++; -} - - -static void next_tick(uv_idle_t* handle) { - uv_loop_t* loop = handle->loop; - uv_idle_stop(handle); - uv_idle_init(loop, &idle_handle); - uv_idle_start(&idle_handle, idle_cb); - uv_timer_init(loop, &timer_handle); - uv_timer_start(&timer_handle, timer_cb, 0, 0); -} - - -TEST_IMPL(callback_order) { - uv_loop_t* loop; - uv_idle_t idle; - - loop = uv_default_loop(); - uv_idle_init(loop, &idle); - uv_idle_start(&idle, next_tick); - - ASSERT(idle_cb_called == 0); - ASSERT(timer_cb_called == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(idle_cb_called == 1); - ASSERT(timer_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-callback-stack.c b/outside/libuv-v1.7.5/test/test-callback-stack.c deleted file mode 100644 index 8855c0841b..0000000000 --- a/outside/libuv-v1.7.5/test/test-callback-stack.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* - * TODO: Add explanation of why we want on_close to be called from fresh - * stack. - */ - -#include "uv.h" -#include "task.h" - - -static const char MESSAGE[] = "Failure is for the weak. Everyone dies alone."; - -static uv_tcp_t client; -static uv_timer_t timer; -static uv_connect_t connect_req; -static uv_write_t write_req; -static uv_shutdown_t shutdown_req; - -static int nested = 0; -static int close_cb_called = 0; -static int connect_cb_called = 0; -static int write_cb_called = 0; -static int timer_cb_called = 0; -static int bytes_received = 0; -static int shutdown_cb_called = 0; - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf->len = size; - buf->base = malloc(size); - ASSERT(buf->base != NULL); -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(nested == 0 && "close_cb must be called from a fresh stack"); - - close_cb_called++; -} - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(status == 0); - ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack"); - - shutdown_cb_called++; -} - - -static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - ASSERT(nested == 0 && "read_cb must be called from a fresh stack"); - - printf("Read. nread == %d\n", (int)nread); - free(buf->base); - - if (nread == 0) { - return; - - } else if (nread < 0) { - ASSERT(nread == UV_EOF); - - nested++; - uv_close((uv_handle_t*)tcp, close_cb); - nested--; - - return; - } - - bytes_received += nread; - - /* We call shutdown here because when bytes_received == sizeof MESSAGE */ - /* there will be no more data sent nor received, so here it would be */ - /* possible for a backend to to call shutdown_cb immediately and *not* */ - /* from a fresh stack. */ - if (bytes_received == sizeof MESSAGE) { - nested++; - - puts("Shutdown"); - - if (uv_shutdown(&shutdown_req, (uv_stream_t*)tcp, shutdown_cb)) { - FATAL("uv_shutdown failed"); - } - nested--; - } -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer); - ASSERT(nested == 0 && "timer_cb must be called from a fresh stack"); - - puts("Timeout complete. Now read data..."); - - nested++; - if (uv_read_start((uv_stream_t*)&client, alloc_cb, read_cb)) { - FATAL("uv_read_start failed"); - } - nested--; - - timer_cb_called++; - - uv_close((uv_handle_t*)handle, close_cb); -} - - -static void write_cb(uv_write_t* req, int status) { - int r; - - ASSERT(status == 0); - ASSERT(nested == 0 && "write_cb must be called from a fresh stack"); - - puts("Data written. 500ms timeout..."); - - /* After the data has been sent, we're going to wait for a while, then */ - /* start reading. This makes us certain that the message has been echoed */ - /* back to our receive buffer when we start reading. This maximizes the */ - /* temptation for the backend to use dirty stack for calling read_cb. */ - nested++; - r = uv_timer_init(uv_default_loop(), &timer); - ASSERT(r == 0); - r = uv_timer_start(&timer, timer_cb, 500, 0); - ASSERT(r == 0); - nested--; - - write_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - uv_buf_t buf; - - puts("Connected. Write some data to echo server..."); - - ASSERT(status == 0); - ASSERT(nested == 0 && "connect_cb must be called from a fresh stack"); - - nested++; - - buf.base = (char*) &MESSAGE; - buf.len = sizeof MESSAGE; - - if (uv_write(&write_req, (uv_stream_t*)req->handle, &buf, 1, write_cb)) { - FATAL("uv_write failed"); - } - - nested--; - - connect_cb_called++; -} - - -TEST_IMPL(callback_stack) { - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - if (uv_tcp_init(uv_default_loop(), &client)) { - FATAL("uv_tcp_init failed"); - } - - puts("Connecting..."); - - nested++; - - if (uv_tcp_connect(&connect_req, - &client, - (const struct sockaddr*) &addr, - connect_cb)) { - FATAL("uv_tcp_connect failed"); - } - nested--; - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(nested == 0); - ASSERT(connect_cb_called == 1 && "connect_cb must be called exactly once"); - ASSERT(write_cb_called == 1 && "write_cb must be called exactly once"); - ASSERT(timer_cb_called == 1 && "timer_cb must be called exactly once"); - ASSERT(bytes_received == sizeof MESSAGE); - ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once"); - ASSERT(close_cb_called == 2 && "close_cb must be called exactly twice"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-close-fd.c b/outside/libuv-v1.7.5/test/test-close-fd.c deleted file mode 100644 index 93a7bd7c02..0000000000 --- a/outside/libuv-v1.7.5/test/test-close-fd.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#if !defined(_WIN32) - -#include "uv.h" -#include "task.h" -#include -#include - -static unsigned int read_cb_called; - -static void alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) { - static char slab[1]; - buf->base = slab; - buf->len = sizeof(slab); -} - -static void read_cb(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) { - switch (++read_cb_called) { - case 1: - ASSERT(nread == 1); - uv_read_stop(handle); - break; - case 2: - ASSERT(nread == UV_EOF); - uv_close((uv_handle_t *) handle, NULL); - break; - default: - ASSERT(!"read_cb_called > 2"); - } -} - -TEST_IMPL(close_fd) { - uv_pipe_t pipe_handle; - int fd[2]; - - ASSERT(0 == pipe(fd)); - ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0)); - ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0])); - fd[0] = -1; /* uv_pipe_open() takes ownership of the file descriptor. */ - ASSERT(1 == write(fd[1], "", 1)); - ASSERT(0 == close(fd[1])); - fd[1] = -1; - ASSERT(0 == uv_read_start((uv_stream_t *) &pipe_handle, alloc_cb, read_cb)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(1 == read_cb_called); - ASSERT(0 == uv_is_active((const uv_handle_t *) &pipe_handle)); - ASSERT(0 == uv_read_start((uv_stream_t *) &pipe_handle, alloc_cb, read_cb)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(2 == read_cb_called); - ASSERT(0 != uv_is_closing((const uv_handle_t *) &pipe_handle)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* !defined(_WIN32) */ diff --git a/outside/libuv-v1.7.5/test/test-close-order.c b/outside/libuv-v1.7.5/test/test-close-order.c deleted file mode 100644 index 2b24f6d657..0000000000 --- a/outside/libuv-v1.7.5/test/test-close-order.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static int check_cb_called; -static int timer_cb_called; -static int close_cb_called; - -static uv_check_t check_handle; -static uv_timer_t timer_handle1; -static uv_timer_t timer_handle2; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -/* check_cb should run before any close_cb */ -static void check_cb(uv_check_t* handle) { - ASSERT(check_cb_called == 0); - ASSERT(timer_cb_called == 1); - ASSERT(close_cb_called == 0); - uv_close((uv_handle_t*) handle, close_cb); - uv_close((uv_handle_t*) &timer_handle2, close_cb); - check_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - uv_close((uv_handle_t*) handle, close_cb); - timer_cb_called++; -} - - -TEST_IMPL(close_order) { - uv_loop_t* loop; - loop = uv_default_loop(); - - uv_check_init(loop, &check_handle); - uv_check_start(&check_handle, check_cb); - uv_timer_init(loop, &timer_handle1); - uv_timer_start(&timer_handle1, timer_cb, 0, 0); - uv_timer_init(loop, &timer_handle2); - uv_timer_start(&timer_handle2, timer_cb, 100000, 0); - - ASSERT(check_cb_called == 0); - ASSERT(close_cb_called == 0); - ASSERT(timer_cb_called == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(check_cb_called == 1); - ASSERT(close_cb_called == 3); - ASSERT(timer_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-condvar.c b/outside/libuv-v1.7.5/test/test-condvar.c deleted file mode 100644 index dbacdba384..0000000000 --- a/outside/libuv-v1.7.5/test/test-condvar.c +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -typedef struct { - uv_mutex_t mutex; - uv_cond_t cond; - int delay; - int use_broadcast; - volatile int posted; -} worker_config; - - -static void worker(void* arg) { - worker_config* c = arg; - - if (c->delay) - uv_sleep(c->delay); - - uv_mutex_lock(&c->mutex); - ASSERT(c->posted == 0); - c->posted = 1; - if (c->use_broadcast) - uv_cond_broadcast(&c->cond); - else - uv_cond_signal(&c->cond); - uv_mutex_unlock(&c->mutex); -} - - -TEST_IMPL(condvar_1) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - - ASSERT(0 == uv_cond_init(&wc.cond)); - ASSERT(0 == uv_mutex_init(&wc.mutex)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_mutex_lock(&wc.mutex); - uv_sleep(100); - uv_cond_wait(&wc.cond, &wc.mutex); - ASSERT(wc.posted == 1); - uv_mutex_unlock(&wc.mutex); - - ASSERT(0 == uv_thread_join(&thread)); - uv_mutex_destroy(&wc.mutex); - uv_cond_destroy(&wc.cond); - - return 0; -} - - -TEST_IMPL(condvar_2) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - wc.delay = 100; - - ASSERT(0 == uv_cond_init(&wc.cond)); - ASSERT(0 == uv_mutex_init(&wc.mutex)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_mutex_lock(&wc.mutex); - uv_cond_wait(&wc.cond, &wc.mutex); - uv_mutex_unlock(&wc.mutex); - - ASSERT(0 == uv_thread_join(&thread)); - uv_mutex_destroy(&wc.mutex); - uv_cond_destroy(&wc.cond); - - return 0; -} - - -TEST_IMPL(condvar_3) { - uv_thread_t thread; - worker_config wc; - int r; - - memset(&wc, 0, sizeof(wc)); - wc.delay = 100; - - ASSERT(0 == uv_cond_init(&wc.cond)); - ASSERT(0 == uv_mutex_init(&wc.mutex)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_mutex_lock(&wc.mutex); - r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(50 * 1e6)); - ASSERT(r == UV_ETIMEDOUT); - uv_mutex_unlock(&wc.mutex); - - ASSERT(0 == uv_thread_join(&thread)); - uv_mutex_destroy(&wc.mutex); - uv_cond_destroy(&wc.cond); - - return 0; -} - - -TEST_IMPL(condvar_4) { - uv_thread_t thread; - worker_config wc; - int r; - - memset(&wc, 0, sizeof(wc)); - wc.delay = 100; - - ASSERT(0 == uv_cond_init(&wc.cond)); - ASSERT(0 == uv_mutex_init(&wc.mutex)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_mutex_lock(&wc.mutex); - r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(150 * 1e6)); - ASSERT(r == 0); - uv_mutex_unlock(&wc.mutex); - - ASSERT(0 == uv_thread_join(&thread)); - uv_mutex_destroy(&wc.mutex); - uv_cond_destroy(&wc.cond); - - return 0; -} - - -TEST_IMPL(condvar_5) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - wc.use_broadcast = 1; - - ASSERT(0 == uv_cond_init(&wc.cond)); - ASSERT(0 == uv_mutex_init(&wc.mutex)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_mutex_lock(&wc.mutex); - uv_sleep(100); - uv_cond_wait(&wc.cond, &wc.mutex); - ASSERT(wc.posted == 1); - uv_mutex_unlock(&wc.mutex); - - ASSERT(0 == uv_thread_join(&thread)); - uv_mutex_destroy(&wc.mutex); - uv_cond_destroy(&wc.cond); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-connection-fail.c b/outside/libuv-v1.7.5/test/test-connection-fail.c deleted file mode 100644 index 328bff46e7..0000000000 --- a/outside/libuv-v1.7.5/test/test-connection-fail.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -static uv_tcp_t tcp; -static uv_connect_t req; -static int connect_cb_calls; -static int close_cb_calls; - -static uv_timer_t timer; -static int timer_close_cb_calls; -static int timer_cb_calls; - - -static void on_close(uv_handle_t* handle) { - close_cb_calls++; -} - - -static void timer_close_cb(uv_handle_t* handle) { - timer_close_cb_calls++; -} - - -static void timer_cb(uv_timer_t* handle) { - timer_cb_calls++; - - /* - * These are the important asserts. The connection callback has been made, - * but libuv hasn't automatically closed the socket. The user must - * uv_close the handle manually. - */ - ASSERT(close_cb_calls == 0); - ASSERT(connect_cb_calls == 1); - - /* Close the tcp handle. */ - uv_close((uv_handle_t*)&tcp, on_close); - - /* Close the timer. */ - uv_close((uv_handle_t*)handle, timer_close_cb); -} - - -static void on_connect_with_close(uv_connect_t *req, int status) { - ASSERT((uv_stream_t*) &tcp == req->handle); - ASSERT(status == UV_ECONNREFUSED); - connect_cb_calls++; - - ASSERT(close_cb_calls == 0); - uv_close((uv_handle_t*)req->handle, on_close); -} - - -static void on_connect_without_close(uv_connect_t *req, int status) { - ASSERT(status == UV_ECONNREFUSED); - connect_cb_calls++; - - uv_timer_start(&timer, timer_cb, 100, 0); - - ASSERT(close_cb_calls == 0); -} - - -static void connection_fail(uv_connect_cb connect_cb) { - struct sockaddr_in client_addr, server_addr; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr)); - - /* There should be no servers listening on this port. */ - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); - - /* Try to connect to the server and do NUM_PINGS ping-pongs. */ - r = uv_tcp_init(uv_default_loop(), &tcp); - ASSERT(!r); - - /* We are never doing multiple reads/connects at a time anyway. */ - /* so these handles can be pre-initialized. */ - ASSERT(0 == uv_tcp_bind(&tcp, (const struct sockaddr*) &client_addr, 0)); - - r = uv_tcp_connect(&req, - &tcp, - (const struct sockaddr*) &server_addr, - connect_cb); - ASSERT(!r); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(connect_cb_calls == 1); - ASSERT(close_cb_calls == 1); -} - - -/* - * This test attempts to connect to a port where no server is running. We - * expect an error. - */ -TEST_IMPL(connection_fail) { - connection_fail(on_connect_with_close); - - ASSERT(timer_close_cb_calls == 0); - ASSERT(timer_cb_calls == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -/* - * This test is the same as the first except it check that the close - * callback of the tcp handle hasn't been made after the failed connection - * attempt. - */ -TEST_IMPL(connection_fail_doesnt_auto_close) { - int r; - - r = uv_timer_init(uv_default_loop(), &timer); - ASSERT(r == 0); - - connection_fail(on_connect_without_close); - - ASSERT(timer_close_cb_calls == 1); - ASSERT(timer_cb_calls == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-cwd-and-chdir.c b/outside/libuv-v1.7.5/test/test-cwd-and-chdir.c deleted file mode 100644 index 1e95043c17..0000000000 --- a/outside/libuv-v1.7.5/test/test-cwd-and-chdir.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - -#define PATHMAX 1024 -extern char executable_path[]; - -TEST_IMPL(cwd_and_chdir) { - char buffer_orig[PATHMAX]; - char buffer_new[PATHMAX]; - size_t size1; - size_t size2; - int err; - - size1 = sizeof buffer_orig; - err = uv_cwd(buffer_orig, &size1); - ASSERT(err == 0); - - err = uv_chdir(buffer_orig); - ASSERT(err == 0); - - size2 = sizeof buffer_new; - err = uv_cwd(buffer_new, &size2); - ASSERT(err == 0); - - ASSERT(size1 == size2); - ASSERT(strcmp(buffer_orig, buffer_new) == 0); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-default-loop-close.c b/outside/libuv-v1.7.5/test/test-default-loop-close.c deleted file mode 100644 index fd11cfa8c1..0000000000 --- a/outside/libuv-v1.7.5/test/test-default-loop-close.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -static int timer_cb_called; - - -static void timer_cb(uv_timer_t* timer) { - timer_cb_called++; - uv_close((uv_handle_t*) timer, NULL); -} - - -TEST_IMPL(default_loop_close) { - uv_loop_t* loop; - uv_timer_t timer_handle; - - loop = uv_default_loop(); - ASSERT(loop != NULL); - - ASSERT(0 == uv_timer_init(loop, &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(1 == timer_cb_called); - ASSERT(0 == uv_loop_close(loop)); - - loop = uv_default_loop(); - ASSERT(loop != NULL); - - ASSERT(0 == uv_timer_init(loop, &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(2 == timer_cb_called); - ASSERT(0 == uv_loop_close(loop)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-delayed-accept.c b/outside/libuv-v1.7.5/test/test-delayed-accept.c deleted file mode 100644 index 4a7998909c..0000000000 --- a/outside/libuv-v1.7.5/test/test-delayed-accept.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - -static int connection_cb_called = 0; -static int do_accept_called = 0; -static int close_cb_called = 0; -static int connect_cb_called = 0; - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf->base = malloc(size); - buf->len = size; -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - - free(handle); - - close_cb_called++; -} - - -static void do_accept(uv_timer_t* timer_handle) { - uv_tcp_t* server; - uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle); - int r; - - ASSERT(timer_handle != NULL); - ASSERT(accepted_handle != NULL); - - r = uv_tcp_init(uv_default_loop(), accepted_handle); - ASSERT(r == 0); - - server = (uv_tcp_t*)timer_handle->data; - r = uv_accept((uv_stream_t*)server, (uv_stream_t*)accepted_handle); - ASSERT(r == 0); - - do_accept_called++; - - /* Immediately close the accepted handle. */ - uv_close((uv_handle_t*)accepted_handle, close_cb); - - /* After accepting the two clients close the server handle */ - if (do_accept_called == 2) { - uv_close((uv_handle_t*)server, close_cb); - } - - /* Dispose the timer. */ - uv_close((uv_handle_t*)timer_handle, close_cb); -} - - -static void connection_cb(uv_stream_t* tcp, int status) { - int r; - uv_timer_t* timer_handle; - - ASSERT(status == 0); - - timer_handle = (uv_timer_t*)malloc(sizeof *timer_handle); - ASSERT(timer_handle != NULL); - - /* Accept the client after 1 second */ - r = uv_timer_init(uv_default_loop(), timer_handle); - ASSERT(r == 0); - - timer_handle->data = tcp; - - r = uv_timer_start(timer_handle, do_accept, 1000, 0); - ASSERT(r == 0); - - connection_cb_called++; -} - - -static void start_server(void) { - struct sockaddr_in addr; - uv_tcp_t* server = (uv_tcp_t*)malloc(sizeof *server); - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - ASSERT(server != NULL); - - r = uv_tcp_init(uv_default_loop(), server); - ASSERT(r == 0); - r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)server, 128, connection_cb); - ASSERT(r == 0); -} - - -static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - /* The server will not send anything, it should close gracefully. */ - - if (buf->base) { - free(buf->base); - } - - if (nread >= 0) { - ASSERT(nread == 0); - } else { - ASSERT(tcp != NULL); - ASSERT(nread == UV_EOF); - uv_close((uv_handle_t*)tcp, close_cb); - } -} - - -static void connect_cb(uv_connect_t* req, int status) { - int r; - - ASSERT(req != NULL); - ASSERT(status == 0); - - /* Not that the server will send anything, but otherwise we'll never know */ - /* when the server closes the connection. */ - r = uv_read_start((uv_stream_t*)(req->handle), alloc_cb, read_cb); - ASSERT(r == 0); - - connect_cb_called++; - - free(req); -} - - -static void client_connect(void) { - struct sockaddr_in addr; - uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client); - uv_connect_t* connect_req = malloc(sizeof *connect_req); - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(client != NULL); - ASSERT(connect_req != NULL); - - r = uv_tcp_init(uv_default_loop(), client); - ASSERT(r == 0); - - r = uv_tcp_connect(connect_req, - client, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); -} - - - -TEST_IMPL(delayed_accept) { - start_server(); - - client_connect(); - client_connect(); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(connection_cb_called == 2); - ASSERT(do_accept_called == 2); - ASSERT(connect_cb_called == 2); - ASSERT(close_cb_called == 7); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-dlerror.c b/outside/libuv-v1.7.5/test/test-dlerror.c deleted file mode 100644 index 091200edbe..0000000000 --- a/outside/libuv-v1.7.5/test/test-dlerror.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - - -TEST_IMPL(dlerror) { - const char* path = "test/fixtures/load_error.node"; - const char* dlerror_no_error = "no error"; - const char* msg; - uv_lib_t lib; - int r; - - lib.errmsg = NULL; - lib.handle = NULL; - msg = uv_dlerror(&lib); - ASSERT(msg != NULL); - ASSERT(strstr(msg, dlerror_no_error) != NULL); - - r = uv_dlopen(path, &lib); - ASSERT(r == -1); - - msg = uv_dlerror(&lib); - ASSERT(msg != NULL); - ASSERT(strstr(msg, dlerror_no_error) == NULL); - - /* Should return the same error twice in a row. */ - msg = uv_dlerror(&lib); - ASSERT(msg != NULL); - ASSERT(strstr(msg, dlerror_no_error) == NULL); - - uv_dlclose(&lib); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-embed.c b/outside/libuv-v1.7.5/test/test-embed.c deleted file mode 100644 index 06137456f8..0000000000 --- a/outside/libuv-v1.7.5/test/test-embed.c +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#include - -#ifndef HAVE_KQUEUE -# if defined(__APPLE__) || \ - defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) -# define HAVE_KQUEUE 1 -# endif -#endif - -#ifndef HAVE_EPOLL -# if defined(__linux__) -# define HAVE_EPOLL 1 -# endif -#endif - -#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) - -#if defined(HAVE_KQUEUE) -# include -# include -# include -#endif - -#if defined(HAVE_EPOLL) -# include -#endif - -static uv_thread_t embed_thread; -static uv_sem_t embed_sem; -static uv_timer_t embed_timer; -static uv_async_t embed_async; -static volatile int embed_closed; - -static int embed_timer_called; - - -static void embed_thread_runner(void* arg) { - int r; - int fd; - int timeout; - - while (!embed_closed) { - fd = uv_backend_fd(uv_default_loop()); - timeout = uv_backend_timeout(uv_default_loop()); - - do { -#if defined(HAVE_KQUEUE) - struct timespec ts; - ts.tv_sec = timeout / 1000; - ts.tv_nsec = (timeout % 1000) * 1000000; - r = kevent(fd, NULL, 0, NULL, 0, &ts); -#elif defined(HAVE_EPOLL) - { - struct epoll_event ev; - r = epoll_wait(fd, &ev, 1, timeout); - } -#endif - } while (r == -1 && errno == EINTR); - uv_async_send(&embed_async); - uv_sem_wait(&embed_sem); - } -} - - -static void embed_cb(uv_async_t* async) { - uv_run(uv_default_loop(), UV_RUN_ONCE); - - uv_sem_post(&embed_sem); -} - - -static void embed_timer_cb(uv_timer_t* timer) { - embed_timer_called++; - embed_closed = 1; - - uv_close((uv_handle_t*) &embed_async, NULL); -} -#endif - - -TEST_IMPL(embed) { -#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) - uv_loop_t external; - - ASSERT(0 == uv_loop_init(&external)); - - embed_timer_called = 0; - embed_closed = 0; - - uv_async_init(&external, &embed_async, embed_cb); - - /* Start timer in default loop */ - uv_timer_init(uv_default_loop(), &embed_timer); - uv_timer_start(&embed_timer, embed_timer_cb, 250, 0); - - /* Start worker that will interrupt external loop */ - uv_sem_init(&embed_sem, 0); - uv_thread_create(&embed_thread, embed_thread_runner, NULL); - - /* But run external loop */ - uv_run(&external, UV_RUN_DEFAULT); - - uv_thread_join(&embed_thread); - uv_loop_close(&external); - - ASSERT(embed_timer_called == 1); -#endif - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-emfile.c b/outside/libuv-v1.7.5/test/test-emfile.c deleted file mode 100644 index 453bfe4cf5..0000000000 --- a/outside/libuv-v1.7.5/test/test-emfile.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#if !defined(_WIN32) - -#include "uv.h" -#include "task.h" - -#include -#include -#include -#include - -static void connection_cb(uv_stream_t* server_handle, int status); -static void connect_cb(uv_connect_t* req, int status); - -static const int maxfd = 31; -static unsigned connect_cb_called; -static uv_tcp_t server_handle; -static uv_tcp_t client_handle; - - -TEST_IMPL(emfile) { - struct sockaddr_in addr; - struct rlimit limits; - uv_connect_t connect_req; - uv_loop_t* loop; - int first_fd; - - loop = uv_default_loop(); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(0 == uv_tcp_init(loop, &server_handle)); - ASSERT(0 == uv_tcp_init(loop, &client_handle)); - ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); - ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb)); - - /* Lower the file descriptor limit and use up all fds save one. */ - limits.rlim_cur = limits.rlim_max = maxfd + 1; - if (setrlimit(RLIMIT_NOFILE, &limits)) { - perror("setrlimit(RLIMIT_NOFILE)"); - ASSERT(0); - } - - /* Remember the first one so we can clean up afterwards. */ - do - first_fd = dup(0); - while (first_fd == -1 && errno == EINTR); - ASSERT(first_fd > 0); - - while (dup(0) != -1 || errno == EINTR); - ASSERT(errno == EMFILE); - close(maxfd); - - /* Now connect and use up the last available file descriptor. The EMFILE - * handling logic in src/unix/stream.c should ensure that connect_cb() runs - * whereas connection_cb() should *not* run. - */ - ASSERT(0 == uv_tcp_connect(&connect_req, - &client_handle, - (const struct sockaddr*) &addr, - connect_cb)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(1 == connect_cb_called); - - /* Close the dups again. Ignore errors in the unlikely event that the - * file descriptors were not contiguous. - */ - while (first_fd < maxfd) { - close(first_fd); - first_fd += 1; - } - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static void connection_cb(uv_stream_t* server_handle, int status) { - ASSERT(0 && "connection_cb should not be called."); -} - - -static void connect_cb(uv_connect_t* req, int status) { - /* |status| should equal 0 because the connection should have been accepted, - * it's just that the server immediately closes it again. - */ - ASSERT(0 == status); - connect_cb_called += 1; - uv_close((uv_handle_t*) &server_handle, NULL); - uv_close((uv_handle_t*) &client_handle, NULL); -} - -#endif /* !defined(_WIN32) */ diff --git a/outside/libuv-v1.7.5/test/test-error.c b/outside/libuv-v1.7.5/test/test-error.c deleted file mode 100644 index eb337e66f3..0000000000 --- a/outside/libuv-v1.7.5/test/test-error.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - - -/* - * Synthetic errors (errors that originate from within libuv, not the system) - * should produce sensible error messages when run through uv_strerror(). - * - * See https://github.com/joyent/libuv/issues/210 - */ -TEST_IMPL(error_message) { - /* Cop out. Can't do proper checks on systems with - * i18n-ized error messages... - */ - if (strcmp(uv_strerror(0), "Success") != 0) { - printf("i18n error messages detected, skipping test.\n"); - return 0; - } - - ASSERT(strstr(uv_strerror(UV_EINVAL), "Success") == NULL); - ASSERT(strcmp(uv_strerror(1337), "Unknown error") == 0); - ASSERT(strcmp(uv_strerror(-1337), "Unknown error") == 0); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-fail-always.c b/outside/libuv-v1.7.5/test/test-fail-always.c deleted file mode 100644 index 0008459eac..0000000000 --- a/outside/libuv-v1.7.5/test/test-fail-always.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" - - -TEST_IMPL(fail_always) { - /* This test always fails. It is used to test the test runner. */ - FATAL("Yes, it always fails"); - return 2; -} diff --git a/outside/libuv-v1.7.5/test/test-fs-event.c b/outside/libuv-v1.7.5/test/test-fs-event.c deleted file mode 100644 index a0908ce575..0000000000 --- a/outside/libuv-v1.7.5/test/test-fs-event.c +++ /dev/null @@ -1,883 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -#ifndef HAVE_KQUEUE -# if defined(__APPLE__) || \ - defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) -# define HAVE_KQUEUE 1 -# endif -#endif - -static uv_fs_event_t fs_event; -static const char file_prefix[] = "fsevent-"; -static const int fs_event_file_count = 16; -#if defined(__APPLE__) || defined(_WIN32) -static const char file_prefix_in_subdir[] = "subdir"; -#endif -static uv_timer_t timer; -static int timer_cb_called; -static int close_cb_called; -static int fs_event_created; -static int fs_event_removed; -static int fs_event_cb_called; -#if defined(PATH_MAX) -static char fs_event_filename[PATH_MAX]; -#else -static char fs_event_filename[1024]; -#endif /* defined(PATH_MAX) */ -static int timer_cb_touch_called; - -static void create_dir(const char* name) { - int r; - uv_fs_t req; - r = uv_fs_mkdir(NULL, &req, name, 0755, NULL); - ASSERT(r == 0 || r == UV_EEXIST); - uv_fs_req_cleanup(&req); -} - -static void create_file(const char* name) { - int r; - uv_file file; - uv_fs_t req; - - r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - file = r; - uv_fs_req_cleanup(&req); - r = uv_fs_close(NULL, &req, file, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&req); -} - -static void touch_file(const char* name) { - int r; - uv_file file; - uv_fs_t req; - uv_buf_t buf; - - r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL); - ASSERT(r >= 0); - file = r; - uv_fs_req_cleanup(&req); - - buf = uv_buf_init("foo", 4); - r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL); - ASSERT(r >= 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_close(NULL, &req, file, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&req); -} - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - -static void fail_cb(uv_fs_event_t* handle, - const char* path, - int events, - int status) { - ASSERT(0 && "fail_cb called"); -} - -static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename, - int events, int status) { - ++fs_event_cb_called; - ASSERT(handle == &fs_event); - ASSERT(status == 0); - ASSERT(events == UV_RENAME); - ASSERT(filename == NULL || strcmp(filename, "file1") == 0); - ASSERT(0 == uv_fs_event_stop(handle)); - uv_close((uv_handle_t*)handle, close_cb); -} - -static const char* fs_event_get_filename(int i) { - snprintf(fs_event_filename, - sizeof(fs_event_filename), - "watch_dir/%s%d", - file_prefix, - i); - return fs_event_filename; -} - -static void fs_event_create_files(uv_timer_t* handle) { - /* Make sure we're not attempting to create files we do not intend */ - ASSERT(fs_event_created < fs_event_file_count); - - /* Create the file */ - create_file(fs_event_get_filename(fs_event_created)); - - if (++fs_event_created < fs_event_file_count) { - /* Create another file on a different event loop tick. We do it this way - * to avoid fs events coalescing into one fs event. */ - ASSERT(0 == uv_timer_start(&timer, fs_event_create_files, 1, 0)); - } -} - -static void fs_event_unlink_files(uv_timer_t* handle) { - int r; - int i; - - /* NOTE: handle might be NULL if invoked not as timer callback */ - if (handle == NULL) { - /* Unlink all files */ - for (i = 0; i < 16; i++) { - r = remove(fs_event_get_filename(i)); - if (handle != NULL) - ASSERT(r == 0); - } - } else { - /* Make sure we're not attempting to remove files we do not intend */ - ASSERT(fs_event_removed < fs_event_file_count); - - /* Remove the file */ - ASSERT(0 == remove(fs_event_get_filename(fs_event_removed))); - - if (++fs_event_removed < fs_event_file_count) { - /* Remove another file on a different event loop tick. We do it this way - * to avoid fs events coalescing into one fs event. */ - ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 1, 0)); - } - } -} - -static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle, - const char* filename, - int events, - int status) { - fs_event_cb_called++; - ASSERT(handle == &fs_event); - ASSERT(status == 0); - ASSERT(events == UV_CHANGE || UV_RENAME); - ASSERT(filename == NULL || - strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0); - - if (fs_event_created + fs_event_removed == fs_event_file_count) { - /* Once we've processed all create events, delete all files */ - ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 1, 0)); - } else if (fs_event_cb_called == 2 * fs_event_file_count) { - /* Once we've processed all create and delete events, stop watching */ - uv_close((uv_handle_t*) &timer, close_cb); - uv_close((uv_handle_t*) handle, close_cb); - } -} - -#if defined(__APPLE__) || defined(_WIN32) -static const char* fs_event_get_filename_in_subdir(int i) { - snprintf(fs_event_filename, - sizeof(fs_event_filename), - "watch_dir/subdir/%s%d", - file_prefix, - i); - return fs_event_filename; -} - -static void fs_event_create_files_in_subdir(uv_timer_t* handle) { - /* Make sure we're not attempting to create files we do not intend */ - ASSERT(fs_event_created < fs_event_file_count); - - /* Create the file */ - create_file(fs_event_get_filename_in_subdir(fs_event_created)); - - if (++fs_event_created < fs_event_file_count) { - /* Create another file on a different event loop tick. We do it this way - * to avoid fs events coalescing into one fs event. */ - ASSERT(0 == uv_timer_start(&timer, fs_event_create_files_in_subdir, 1, 0)); - } -} - -static void fs_event_unlink_files_in_subdir(uv_timer_t* handle) { - int r; - int i; - - /* NOTE: handle might be NULL if invoked not as timer callback */ - if (handle == NULL) { - /* Unlink all files */ - for (i = 0; i < 16; i++) { - r = remove(fs_event_get_filename_in_subdir(i)); - if (handle != NULL) - ASSERT(r == 0); - } - } else { - /* Make sure we're not attempting to remove files we do not intend */ - ASSERT(fs_event_removed < fs_event_file_count); - - /* Remove the file */ - ASSERT(0 == remove(fs_event_get_filename_in_subdir(fs_event_removed))); - - if (++fs_event_removed < fs_event_file_count) { - /* Remove another file on a different event loop tick. We do it this way - * to avoid fs events coalescing into one fs event. */ - ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0)); - } - } -} - -static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, - const char* filename, - int events, - int status) { - fs_event_cb_called++; - ASSERT(handle == &fs_event); - ASSERT(status == 0); - ASSERT(events == UV_CHANGE || UV_RENAME); - ASSERT(filename == NULL || - strncmp(filename, file_prefix_in_subdir, sizeof(file_prefix_in_subdir) - 1) == 0); - - if (fs_event_created + fs_event_removed == fs_event_file_count) { - /* Once we've processed all create events, delete all files */ - ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0)); - } else if (fs_event_cb_called == 2 * fs_event_file_count) { - /* Once we've processed all create and delete events, stop watching */ - uv_close((uv_handle_t*) &timer, close_cb); - uv_close((uv_handle_t*) handle, close_cb); - } -} -#endif - -static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename, - int events, int status) { - ++fs_event_cb_called; - ASSERT(handle == &fs_event); - ASSERT(status == 0); - ASSERT(events == UV_CHANGE); - ASSERT(filename == NULL || strcmp(filename, "file2") == 0); - ASSERT(0 == uv_fs_event_stop(handle)); - uv_close((uv_handle_t*)handle, close_cb); -} - -static void timer_cb_close_handle(uv_timer_t* timer) { - uv_handle_t* handle; - - ASSERT(timer != NULL); - handle = timer->data; - - uv_close((uv_handle_t*)timer, NULL); - uv_close((uv_handle_t*)handle, close_cb); -} - -static void fs_event_cb_file_current_dir(uv_fs_event_t* handle, - const char* filename, int events, int status) { - ASSERT(fs_event_cb_called == 0); - ++fs_event_cb_called; - - ASSERT(handle == &fs_event); - ASSERT(status == 0); - ASSERT(events == UV_CHANGE); - ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0); - - /* Regression test for SunOS: touch should generate just one event. */ - { - static uv_timer_t timer; - uv_timer_init(handle->loop, &timer); - timer.data = handle; - uv_timer_start(&timer, timer_cb_close_handle, 250, 0); - } -} - -static void timer_cb_file(uv_timer_t* handle) { - ++timer_cb_called; - - if (timer_cb_called == 1) { - touch_file("watch_dir/file1"); - } else { - touch_file("watch_dir/file2"); - uv_close((uv_handle_t*)handle, close_cb); - } -} - -static void timer_cb_touch(uv_timer_t* timer) { - uv_close((uv_handle_t*)timer, NULL); - touch_file("watch_file"); - timer_cb_touch_called++; -} - -static void timer_cb_watch_twice(uv_timer_t* handle) { - uv_fs_event_t* handles = handle->data; - uv_close((uv_handle_t*) (handles + 0), NULL); - uv_close((uv_handle_t*) (handles + 1), NULL); - uv_close((uv_handle_t*) handle, NULL); -} - -TEST_IMPL(fs_event_watch_dir) { - uv_loop_t* loop = uv_default_loop(); - int r; - - /* Setup */ - fs_event_unlink_files(NULL); - remove("watch_dir/file2"); - remove("watch_dir/file1"); - remove("watch_dir/"); - create_dir("watch_dir"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file, "watch_dir", 0); - ASSERT(r == 0); - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - r = uv_timer_start(&timer, fs_event_create_files, 100, 0); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed); - ASSERT(close_cb_called == 2); - - /* Cleanup */ - fs_event_unlink_files(NULL); - remove("watch_dir/file2"); - remove("watch_dir/file1"); - remove("watch_dir/"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_event_watch_dir_recursive) { -#if defined(__APPLE__) || defined(_WIN32) - uv_loop_t* loop; - int r; - - /* Setup */ - loop = uv_default_loop(); - fs_event_unlink_files(NULL); - remove("watch_dir/file2"); - remove("watch_dir/file1"); - remove("watch_dir/subdir"); - remove("watch_dir/"); - create_dir("watch_dir"); - create_dir("watch_dir/subdir"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file_in_subdir, "watch_dir", UV_FS_EVENT_RECURSIVE); - ASSERT(r == 0); - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - r = uv_timer_start(&timer, fs_event_create_files_in_subdir, 100, 0); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed); - ASSERT(close_cb_called == 2); - - /* Cleanup */ - fs_event_unlink_files_in_subdir(NULL); - remove("watch_dir/file2"); - remove("watch_dir/file1"); - remove("watch_dir/subdir"); - remove("watch_dir/"); - - MAKE_VALGRIND_HAPPY(); - return 0; -#else - RETURN_SKIP("Recursive directory watching not supported on this platform."); -#endif -} - - -TEST_IMPL(fs_event_watch_file) { - uv_loop_t* loop = uv_default_loop(); - int r; - - /* Setup */ - remove("watch_dir/file2"); - remove("watch_dir/file1"); - remove("watch_dir/"); - create_dir("watch_dir"); - create_file("watch_dir/file1"); - create_file("watch_dir/file2"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_cb_file, "watch_dir/file2", 0); - ASSERT(r == 0); - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - r = uv_timer_start(&timer, timer_cb_file, 100, 100); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(fs_event_cb_called == 1); - ASSERT(timer_cb_called == 2); - ASSERT(close_cb_called == 2); - - /* Cleanup */ - remove("watch_dir/file2"); - remove("watch_dir/file1"); - remove("watch_dir/"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_event_watch_file_twice) { - const char path[] = "test/fixtures/empty_file"; - uv_fs_event_t watchers[2]; - uv_timer_t timer; - uv_loop_t* loop; - - loop = uv_default_loop(); - timer.data = watchers; - - ASSERT(0 == uv_fs_event_init(loop, watchers + 0)); - ASSERT(0 == uv_fs_event_start(watchers + 0, fail_cb, path, 0)); - ASSERT(0 == uv_fs_event_init(loop, watchers + 1)); - ASSERT(0 == uv_fs_event_start(watchers + 1, fail_cb, path, 0)); - ASSERT(0 == uv_timer_init(loop, &timer)); - ASSERT(0 == uv_timer_start(&timer, timer_cb_watch_twice, 10, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_event_watch_file_current_dir) { - uv_timer_t timer; - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - - /* Setup */ - remove("watch_file"); - create_file("watch_file"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, - fs_event_cb_file_current_dir, - "watch_file", - 0); - ASSERT(r == 0); - - - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - - r = uv_timer_start(&timer, timer_cb_touch, 1, 0); - ASSERT(r == 0); - - ASSERT(timer_cb_touch_called == 0); - ASSERT(fs_event_cb_called == 0); - ASSERT(close_cb_called == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(timer_cb_touch_called == 1); - ASSERT(fs_event_cb_called == 1); - ASSERT(close_cb_called == 1); - - /* Cleanup */ - remove("watch_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_event_no_callback_after_close) { - uv_loop_t* loop = uv_default_loop(); - int r; - - /* Setup */ - remove("watch_dir/file1"); - remove("watch_dir/"); - create_dir("watch_dir"); - create_file("watch_dir/file1"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, - fs_event_cb_file, - "watch_dir/file1", - 0); - ASSERT(r == 0); - - - uv_close((uv_handle_t*)&fs_event, close_cb); - touch_file("watch_dir/file1"); - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(fs_event_cb_called == 0); - ASSERT(close_cb_called == 1); - - /* Cleanup */ - remove("watch_dir/file1"); - remove("watch_dir/"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_event_no_callback_on_close) { - uv_loop_t* loop = uv_default_loop(); - int r; - - /* Setup */ - remove("watch_dir/file1"); - remove("watch_dir/"); - create_dir("watch_dir"); - create_file("watch_dir/file1"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, - fs_event_cb_file, - "watch_dir/file1", - 0); - ASSERT(r == 0); - - uv_close((uv_handle_t*)&fs_event, close_cb); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(fs_event_cb_called == 0); - ASSERT(close_cb_called == 1); - - /* Cleanup */ - remove("watch_dir/file1"); - remove("watch_dir/"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static void fs_event_fail(uv_fs_event_t* handle, const char* filename, - int events, int status) { - ASSERT(0 && "should never be called"); -} - - -static void timer_cb(uv_timer_t* handle) { - int r; - - r = uv_fs_event_init(handle->loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_fail, ".", 0); - ASSERT(r == 0); - - uv_close((uv_handle_t*)&fs_event, close_cb); - uv_close((uv_handle_t*)handle, close_cb); -} - - -TEST_IMPL(fs_event_immediate_close) { - uv_timer_t timer; - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - - r = uv_timer_start(&timer, timer_cb, 1, 0); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_event_close_with_pending_event) { - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - - create_dir("watch_dir"); - create_file("watch_dir/file"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_fail, "watch_dir", 0); - ASSERT(r == 0); - - /* Generate an fs event. */ - touch_file("watch_dir/file"); - - uv_close((uv_handle_t*)&fs_event, close_cb); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - /* Clean up */ - remove("watch_dir/file"); - remove("watch_dir/"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#if defined(HAVE_KQUEUE) - -/* kqueue doesn't register fs events if you don't have an active watcher. - * The file descriptor needs to be part of the kqueue set of interest and - * that's not the case until we actually enter the event loop. - */ -TEST_IMPL(fs_event_close_in_callback) { - fprintf(stderr, "Skipping test, doesn't work with kqueue.\n"); - return 0; -} - -#else /* !HAVE_KQUEUE */ - -static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename, - int events, int status) { - ASSERT(status == 0); - - ASSERT(fs_event_cb_called < 3); - ++fs_event_cb_called; - - if (fs_event_cb_called == 3) { - uv_close((uv_handle_t*) handle, close_cb); - } -} - - -TEST_IMPL(fs_event_close_in_callback) { - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - - create_dir("watch_dir"); - create_file("watch_dir/file1"); - create_file("watch_dir/file2"); - create_file("watch_dir/file3"); - create_file("watch_dir/file4"); - create_file("watch_dir/file5"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_cb_close, "watch_dir", 0); - ASSERT(r == 0); - - /* Generate a couple of fs events. */ - touch_file("watch_dir/file1"); - touch_file("watch_dir/file2"); - touch_file("watch_dir/file3"); - touch_file("watch_dir/file4"); - touch_file("watch_dir/file5"); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - ASSERT(fs_event_cb_called == 3); - - /* Clean up */ - remove("watch_dir/file1"); - remove("watch_dir/file2"); - remove("watch_dir/file3"); - remove("watch_dir/file4"); - remove("watch_dir/file5"); - remove("watch_dir/"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* HAVE_KQUEUE */ - -TEST_IMPL(fs_event_start_and_close) { - uv_loop_t* loop; - uv_fs_event_t fs_event1; - uv_fs_event_t fs_event2; - int r; - - loop = uv_default_loop(); - - create_dir("watch_dir"); - - r = uv_fs_event_init(loop, &fs_event1); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event1, fs_event_cb_dir, "watch_dir", 0); - ASSERT(r == 0); - - r = uv_fs_event_init(loop, &fs_event2); - ASSERT(r == 0); - r = uv_fs_event_start(&fs_event2, fs_event_cb_dir, "watch_dir", 0); - ASSERT(r == 0); - - uv_close((uv_handle_t*) &fs_event2, close_cb); - uv_close((uv_handle_t*) &fs_event1, close_cb); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 2); - - remove("watch_dir/"); - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_event_getpath) { - uv_loop_t* loop = uv_default_loop(); - int r; - char buf[1024]; - size_t len; - - create_dir("watch_dir"); - - r = uv_fs_event_init(loop, &fs_event); - ASSERT(r == 0); - len = sizeof buf; - r = uv_fs_event_getpath(&fs_event, buf, &len); - ASSERT(r == UV_EINVAL); - r = uv_fs_event_start(&fs_event, fail_cb, "watch_dir", 0); - ASSERT(r == 0); - len = sizeof buf; - r = uv_fs_event_getpath(&fs_event, buf, &len); - ASSERT(r == 0); - ASSERT(buf[len - 1] != 0); - ASSERT(memcmp(buf, "watch_dir", len) == 0); - r = uv_fs_event_stop(&fs_event); - ASSERT(r == 0); - uv_close((uv_handle_t*) &fs_event, close_cb); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - remove("watch_dir/"); - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#if defined(__APPLE__) - -static int fs_event_error_reported; - -static void fs_event_error_report_cb(uv_fs_event_t* handle, - const char* filename, - int events, - int status) { - if (status != 0) - fs_event_error_reported = status; -} - -static void timer_cb_nop(uv_timer_t* handle) { - ++timer_cb_called; - uv_close((uv_handle_t*) handle, close_cb); -} - -static void fs_event_error_report_close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; - - /* handle is allocated on-stack, no need to free it */ -} - - -TEST_IMPL(fs_event_error_reporting) { - unsigned int i; - uv_loop_t loops[1024]; - uv_fs_event_t events[ARRAY_SIZE(loops)]; - uv_loop_t* loop; - uv_fs_event_t* event; - - TEST_FILE_LIMIT(ARRAY_SIZE(loops) * 3); - - remove("watch_dir/"); - create_dir("watch_dir"); - - /* Create a lot of loops, and start FSEventStream in each of them. - * Eventually, this should create enough streams to make FSEventStreamStart() - * fail. - */ - for (i = 0; i < ARRAY_SIZE(loops); i++) { - loop = &loops[i]; - ASSERT(0 == uv_loop_init(loop)); - event = &events[i]; - - timer_cb_called = 0; - close_cb_called = 0; - ASSERT(0 == uv_fs_event_init(loop, event)); - ASSERT(0 == uv_fs_event_start(event, - fs_event_error_report_cb, - "watch_dir", - 0)); - uv_unref((uv_handle_t*) event); - - /* Let loop run for some time */ - ASSERT(0 == uv_timer_init(loop, &timer)); - ASSERT(0 == uv_timer_start(&timer, timer_cb_nop, 2, 0)); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(1 == timer_cb_called); - ASSERT(1 == close_cb_called); - if (fs_event_error_reported != 0) - break; - } - - /* At least one loop should fail */ - ASSERT(fs_event_error_reported == UV_EMFILE); - - /* Stop and close all events, and destroy loops */ - do { - loop = &loops[i]; - event = &events[i]; - - ASSERT(0 == uv_fs_event_stop(event)); - uv_ref((uv_handle_t*) event); - uv_close((uv_handle_t*) event, fs_event_error_report_close_cb); - - close_cb_called = 0; - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(close_cb_called == 1); - - uv_loop_close(loop); - } while (i-- != 0); - - remove("watch_dir/"); - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#else /* !defined(__APPLE__) */ - -TEST_IMPL(fs_event_error_reporting) { - /* No-op, needed only for FSEvents backend */ - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* defined(__APPLE__) */ diff --git a/outside/libuv-v1.7.5/test/test-fs-poll.c b/outside/libuv-v1.7.5/test/test-fs-poll.c deleted file mode 100644 index dbc1515b0b..0000000000 --- a/outside/libuv-v1.7.5/test/test-fs-poll.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include - -#define FIXTURE "testfile" - -static void timer_cb(uv_timer_t* handle); -static void close_cb(uv_handle_t* handle); -static void poll_cb(uv_fs_poll_t* handle, - int status, - const uv_stat_t* prev, - const uv_stat_t* curr); - -static void poll_cb_fail(uv_fs_poll_t* handle, - int status, - const uv_stat_t* prev, - const uv_stat_t* curr); - -static uv_fs_poll_t poll_handle; -static uv_timer_t timer_handle; -static uv_loop_t* loop; - -static int poll_cb_called; -static int timer_cb_called; -static int close_cb_called; - - -static void touch_file(const char* path) { - static int count; - FILE* fp; - int i; - - ASSERT((fp = fopen(FIXTURE, "w+"))); - - /* Need to change the file size because the poller may not pick up - * sub-second mtime changes. - */ - i = ++count; - - while (i--) - fputc('*', fp); - - fclose(fp); -} - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - touch_file(FIXTURE); - timer_cb_called++; -} - - -static void poll_cb_fail(uv_fs_poll_t* handle, - int status, - const uv_stat_t* prev, - const uv_stat_t* curr) { - ASSERT(0 && "fail_cb called"); -} - - -static void poll_cb(uv_fs_poll_t* handle, - int status, - const uv_stat_t* prev, - const uv_stat_t* curr) { - uv_stat_t zero_statbuf; - - memset(&zero_statbuf, 0, sizeof(zero_statbuf)); - - ASSERT(handle == &poll_handle); - ASSERT(1 == uv_is_active((uv_handle_t*) handle)); - ASSERT(prev != NULL); - ASSERT(curr != NULL); - - switch (poll_cb_called++) { - case 0: - ASSERT(status == UV_ENOENT); - ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); - ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); - touch_file(FIXTURE); - break; - - case 1: - ASSERT(status == 0); - ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); - ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 20, 0)); - break; - - case 2: - ASSERT(status == 0); - ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); - ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 200, 0)); - break; - - case 3: - ASSERT(status == 0); - ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); - ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); - remove(FIXTURE); - break; - - case 4: - ASSERT(status == UV_ENOENT); - ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); - ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); - uv_close((uv_handle_t*)handle, close_cb); - break; - - default: - ASSERT(0); - } -} - - -TEST_IMPL(fs_poll) { - loop = uv_default_loop(); - - remove(FIXTURE); - - ASSERT(0 == uv_timer_init(loop, &timer_handle)); - ASSERT(0 == uv_fs_poll_init(loop, &poll_handle)); - ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb, FIXTURE, 100)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - ASSERT(poll_cb_called == 5); - ASSERT(timer_cb_called == 2); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_poll_getpath) { - char buf[1024]; - size_t len; - loop = uv_default_loop(); - - remove(FIXTURE); - - ASSERT(0 == uv_fs_poll_init(loop, &poll_handle)); - len = sizeof buf; - ASSERT(UV_EINVAL == uv_fs_poll_getpath(&poll_handle, buf, &len)); - ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100)); - len = sizeof buf; - ASSERT(0 == uv_fs_poll_getpath(&poll_handle, buf, &len)); - ASSERT(buf[len - 1] != 0); - ASSERT(0 == memcmp(buf, FIXTURE, len)); - - uv_close((uv_handle_t*) &poll_handle, close_cb); - - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-fs.c b/outside/libuv-v1.7.5/test/test-fs.c deleted file mode 100644 index 90572ca614..0000000000 --- a/outside/libuv-v1.7.5/test/test-fs.c +++ /dev/null @@ -1,2540 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include /* memset */ -#include -#include - -/* FIXME we shouldn't need to branch in this file */ -#if defined(__unix__) || defined(__POSIX__) || \ - defined(__APPLE__) || defined(_AIX) -#include /* unlink, rmdir, etc. */ -#else -# include -# include -# define unlink _unlink -# define rmdir _rmdir -# define open _open -# define write _write -# define close _close -# ifndef stat -# define stat _stati64 -# endif -# ifndef lseek -# define lseek _lseek -# endif -#endif - -#define TOO_LONG_NAME_LENGTH 65536 -#define PATHMAX 1024 - -typedef struct { - const char* path; - double atime; - double mtime; -} utime_check_t; - - -static int dummy_cb_count; -static int close_cb_count; -static int create_cb_count; -static int open_cb_count; -static int read_cb_count; -static int write_cb_count; -static int unlink_cb_count; -static int mkdir_cb_count; -static int mkdtemp_cb_count; -static int rmdir_cb_count; -static int scandir_cb_count; -static int stat_cb_count; -static int rename_cb_count; -static int fsync_cb_count; -static int fdatasync_cb_count; -static int ftruncate_cb_count; -static int sendfile_cb_count; -static int fstat_cb_count; -static int access_cb_count; -static int chmod_cb_count; -static int fchmod_cb_count; -static int chown_cb_count; -static int fchown_cb_count; -static int link_cb_count; -static int symlink_cb_count; -static int readlink_cb_count; -static int utime_cb_count; -static int futime_cb_count; - -static uv_loop_t* loop; - -static uv_fs_t open_req1; -static uv_fs_t open_req2; -static uv_fs_t read_req; -static uv_fs_t write_req; -static uv_fs_t unlink_req; -static uv_fs_t close_req; -static uv_fs_t mkdir_req; -static uv_fs_t mkdtemp_req1; -static uv_fs_t mkdtemp_req2; -static uv_fs_t rmdir_req; -static uv_fs_t scandir_req; -static uv_fs_t stat_req; -static uv_fs_t rename_req; -static uv_fs_t fsync_req; -static uv_fs_t fdatasync_req; -static uv_fs_t ftruncate_req; -static uv_fs_t sendfile_req; -static uv_fs_t utime_req; -static uv_fs_t futime_req; - -static char buf[32]; -static char buf2[32]; -static char test_buf[] = "test-buffer\n"; -static char test_buf2[] = "second-buffer\n"; -static uv_buf_t iov; - -static void check_permission(const char* filename, unsigned int mode) { - int r; - uv_fs_t req; - uv_stat_t* s; - - r = uv_fs_stat(NULL, &req, filename, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - - s = &req.statbuf; -#ifdef _WIN32 - /* - * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit, - * so only testing for the specified flags. - */ - ASSERT((s->st_mode & 0777) & mode); -#else - ASSERT((s->st_mode & 0777) == mode); -#endif - - uv_fs_req_cleanup(&req); -} - - -static void dummy_cb(uv_fs_t* req) { - (void) req; - dummy_cb_count++; -} - - -static void link_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_LINK); - ASSERT(req->result == 0); - link_cb_count++; - uv_fs_req_cleanup(req); -} - - -static void symlink_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_SYMLINK); - ASSERT(req->result == 0); - symlink_cb_count++; - uv_fs_req_cleanup(req); -} - -static void readlink_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_READLINK); - ASSERT(req->result == 0); - ASSERT(strcmp(req->ptr, "test_file_symlink2") == 0); - readlink_cb_count++; - uv_fs_req_cleanup(req); -} - - -static void access_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_ACCESS); - access_cb_count++; - uv_fs_req_cleanup(req); -} - - -static void fchmod_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_FCHMOD); - ASSERT(req->result == 0); - fchmod_cb_count++; - uv_fs_req_cleanup(req); - check_permission("test_file", *(int*)req->data); -} - - -static void chmod_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_CHMOD); - ASSERT(req->result == 0); - chmod_cb_count++; - uv_fs_req_cleanup(req); - check_permission("test_file", *(int*)req->data); -} - - -static void fchown_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_FCHOWN); - ASSERT(req->result == 0); - fchown_cb_count++; - uv_fs_req_cleanup(req); -} - - -static void chown_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_CHOWN); - ASSERT(req->result == 0); - chown_cb_count++; - uv_fs_req_cleanup(req); -} - -static void chown_root_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_CHOWN); -#ifdef _WIN32 - /* On windows, chown is a no-op and always succeeds. */ - ASSERT(req->result == 0); -#else - /* On unix, chown'ing the root directory is not allowed - - * unless you're root, of course. - */ - if (geteuid() == 0) - ASSERT(req->result == 0); - else - ASSERT(req->result == UV_EPERM); -#endif - chown_cb_count++; - uv_fs_req_cleanup(req); -} - -static void unlink_cb(uv_fs_t* req) { - ASSERT(req == &unlink_req); - ASSERT(req->fs_type == UV_FS_UNLINK); - ASSERT(req->result == 0); - unlink_cb_count++; - uv_fs_req_cleanup(req); -} - -static void fstat_cb(uv_fs_t* req) { - uv_stat_t* s = req->ptr; - ASSERT(req->fs_type == UV_FS_FSTAT); - ASSERT(req->result == 0); - ASSERT(s->st_size == sizeof(test_buf)); - uv_fs_req_cleanup(req); - fstat_cb_count++; -} - - -static void close_cb(uv_fs_t* req) { - int r; - ASSERT(req == &close_req); - ASSERT(req->fs_type == UV_FS_CLOSE); - ASSERT(req->result == 0); - close_cb_count++; - uv_fs_req_cleanup(req); - if (close_cb_count == 3) { - r = uv_fs_unlink(loop, &unlink_req, "test_file2", unlink_cb); - ASSERT(r == 0); - } -} - - -static void ftruncate_cb(uv_fs_t* req) { - int r; - ASSERT(req == &ftruncate_req); - ASSERT(req->fs_type == UV_FS_FTRUNCATE); - ASSERT(req->result == 0); - ftruncate_cb_count++; - uv_fs_req_cleanup(req); - r = uv_fs_close(loop, &close_req, open_req1.result, close_cb); - ASSERT(r == 0); -} - - -static void read_cb(uv_fs_t* req) { - int r; - ASSERT(req == &read_req); - ASSERT(req->fs_type == UV_FS_READ); - ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */ - read_cb_count++; - uv_fs_req_cleanup(req); - if (read_cb_count == 1) { - ASSERT(strcmp(buf, test_buf) == 0); - r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7, - ftruncate_cb); - } else { - ASSERT(strcmp(buf, "test-bu") == 0); - r = uv_fs_close(loop, &close_req, open_req1.result, close_cb); - } - ASSERT(r == 0); -} - - -static void open_cb(uv_fs_t* req) { - int r; - ASSERT(req == &open_req1); - ASSERT(req->fs_type == UV_FS_OPEN); - if (req->result < 0) { - fprintf(stderr, "async open error: %d\n", (int) req->result); - ASSERT(0); - } - open_cb_count++; - ASSERT(req->path); - ASSERT(memcmp(req->path, "test_file2\0", 11) == 0); - uv_fs_req_cleanup(req); - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1, - read_cb); - ASSERT(r == 0); -} - - -static void open_cb_simple(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_OPEN); - if (req->result < 0) { - fprintf(stderr, "async open error: %d\n", (int) req->result); - ASSERT(0); - } - open_cb_count++; - ASSERT(req->path); - uv_fs_req_cleanup(req); -} - - -static void fsync_cb(uv_fs_t* req) { - int r; - ASSERT(req == &fsync_req); - ASSERT(req->fs_type == UV_FS_FSYNC); - ASSERT(req->result == 0); - fsync_cb_count++; - uv_fs_req_cleanup(req); - r = uv_fs_close(loop, &close_req, open_req1.result, close_cb); - ASSERT(r == 0); -} - - -static void fdatasync_cb(uv_fs_t* req) { - int r; - ASSERT(req == &fdatasync_req); - ASSERT(req->fs_type == UV_FS_FDATASYNC); - ASSERT(req->result == 0); - fdatasync_cb_count++; - uv_fs_req_cleanup(req); - r = uv_fs_fsync(loop, &fsync_req, open_req1.result, fsync_cb); - ASSERT(r == 0); -} - - -static void write_cb(uv_fs_t* req) { - int r; - ASSERT(req == &write_req); - ASSERT(req->fs_type == UV_FS_WRITE); - ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */ - write_cb_count++; - uv_fs_req_cleanup(req); - r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb); - ASSERT(r == 0); -} - - -static void create_cb(uv_fs_t* req) { - int r; - ASSERT(req == &open_req1); - ASSERT(req->fs_type == UV_FS_OPEN); - ASSERT(req->result >= 0); - create_cb_count++; - uv_fs_req_cleanup(req); - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(loop, &write_req, req->result, &iov, 1, -1, write_cb); - ASSERT(r == 0); -} - - -static void rename_cb(uv_fs_t* req) { - ASSERT(req == &rename_req); - ASSERT(req->fs_type == UV_FS_RENAME); - ASSERT(req->result == 0); - rename_cb_count++; - uv_fs_req_cleanup(req); -} - - -static void mkdir_cb(uv_fs_t* req) { - ASSERT(req == &mkdir_req); - ASSERT(req->fs_type == UV_FS_MKDIR); - ASSERT(req->result == 0); - mkdir_cb_count++; - ASSERT(req->path); - ASSERT(memcmp(req->path, "test_dir\0", 9) == 0); - uv_fs_req_cleanup(req); -} - - -static void check_mkdtemp_result(uv_fs_t* req) { - int r; - - ASSERT(req->fs_type == UV_FS_MKDTEMP); - ASSERT(req->result == 0); - ASSERT(req->path); - ASSERT(strlen(req->path) == 15); - ASSERT(memcmp(req->path, "test_dir_", 9) == 0); - ASSERT(memcmp(req->path + 9, "XXXXXX", 6) != 0); - check_permission(req->path, 0700); - - /* Check if req->path is actually a directory */ - r = uv_fs_stat(NULL, &stat_req, req->path, NULL); - ASSERT(r == 0); - ASSERT(((uv_stat_t*)stat_req.ptr)->st_mode & S_IFDIR); - uv_fs_req_cleanup(&stat_req); -} - - -static void mkdtemp_cb(uv_fs_t* req) { - ASSERT(req == &mkdtemp_req1); - check_mkdtemp_result(req); - mkdtemp_cb_count++; -} - - -static void rmdir_cb(uv_fs_t* req) { - ASSERT(req == &rmdir_req); - ASSERT(req->fs_type == UV_FS_RMDIR); - ASSERT(req->result == 0); - rmdir_cb_count++; - ASSERT(req->path); - ASSERT(memcmp(req->path, "test_dir\0", 9) == 0); - uv_fs_req_cleanup(req); -} - - -static void assert_is_file_type(uv_dirent_t dent) { -#ifdef HAVE_DIRENT_TYPES - /* - * For Apple and Windows, we know getdents is expected to work but for other - * environments, the filesystem dictates whether or not getdents supports - * returning the file type. - * - * See: - * http://man7.org/linux/man-pages/man2/getdents.2.html - * https://github.com/libuv/libuv/issues/501 - */ - #if defined(__APPLE__) || defined(_WIN32) - ASSERT(dent.type == UV_DIRENT_FILE); - #else - ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); - #endif -#else - ASSERT(dent.type == UV_DIRENT_UNKNOWN); -#endif -} - - -static void scandir_cb(uv_fs_t* req) { - uv_dirent_t dent; - ASSERT(req == &scandir_req); - ASSERT(req->fs_type == UV_FS_SCANDIR); - ASSERT(req->result == 2); - ASSERT(req->ptr); - - while (UV_EOF != uv_fs_scandir_next(req, &dent)) { - ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - assert_is_file_type(dent); - } - scandir_cb_count++; - ASSERT(req->path); - ASSERT(memcmp(req->path, "test_dir\0", 9) == 0); - uv_fs_req_cleanup(req); - ASSERT(!req->ptr); -} - - -static void empty_scandir_cb(uv_fs_t* req) { - uv_dirent_t dent; - - ASSERT(req == &scandir_req); - ASSERT(req->fs_type == UV_FS_SCANDIR); - ASSERT(req->result == 0); - ASSERT(req->ptr == NULL); - ASSERT(UV_EOF == uv_fs_scandir_next(req, &dent)); - uv_fs_req_cleanup(req); - scandir_cb_count++; -} - - -static void file_scandir_cb(uv_fs_t* req) { - ASSERT(req == &scandir_req); - ASSERT(req->fs_type == UV_FS_SCANDIR); - ASSERT(req->result == UV_ENOTDIR); - ASSERT(req->ptr == NULL); - uv_fs_req_cleanup(req); - scandir_cb_count++; -} - - -static void stat_cb(uv_fs_t* req) { - ASSERT(req == &stat_req); - ASSERT(req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT); - ASSERT(req->result == 0); - ASSERT(req->ptr); - stat_cb_count++; - uv_fs_req_cleanup(req); - ASSERT(!req->ptr); -} - - -static void sendfile_cb(uv_fs_t* req) { - ASSERT(req == &sendfile_req); - ASSERT(req->fs_type == UV_FS_SENDFILE); - ASSERT(req->result == 65546); - sendfile_cb_count++; - uv_fs_req_cleanup(req); -} - - -static void open_noent_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_OPEN); - ASSERT(req->result == UV_ENOENT); - open_cb_count++; - uv_fs_req_cleanup(req); -} - -static void open_nametoolong_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_OPEN); - ASSERT(req->result == UV_ENAMETOOLONG); - open_cb_count++; - uv_fs_req_cleanup(req); -} - -static void open_loop_cb(uv_fs_t* req) { - ASSERT(req->fs_type == UV_FS_OPEN); - ASSERT(req->result == UV_ELOOP); - open_cb_count++; - uv_fs_req_cleanup(req); -} - - -TEST_IMPL(fs_file_noent) { - uv_fs_t req; - int r; - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &req, "does_not_exist", O_RDONLY, 0, NULL); - ASSERT(r == UV_ENOENT); - ASSERT(req.result == UV_ENOENT); - uv_fs_req_cleanup(&req); - - r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, open_noent_cb); - ASSERT(r == 0); - - ASSERT(open_cb_count == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(open_cb_count == 1); - - /* TODO add EACCES test */ - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_file_nametoolong) { - uv_fs_t req; - int r; - char name[TOO_LONG_NAME_LENGTH + 1]; - - loop = uv_default_loop(); - - memset(name, 'a', TOO_LONG_NAME_LENGTH); - name[TOO_LONG_NAME_LENGTH] = 0; - - r = uv_fs_open(NULL, &req, name, O_RDONLY, 0, NULL); - ASSERT(r == UV_ENAMETOOLONG); - ASSERT(req.result == UV_ENAMETOOLONG); - uv_fs_req_cleanup(&req); - - r = uv_fs_open(loop, &req, name, O_RDONLY, 0, open_nametoolong_cb); - ASSERT(r == 0); - - ASSERT(open_cb_count == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(open_cb_count == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(fs_file_loop) { - uv_fs_t req; - int r; - - loop = uv_default_loop(); - - unlink("test_symlink"); - r = uv_fs_symlink(NULL, &req, "test_symlink", "test_symlink", 0, NULL); -#ifdef _WIN32 - /* - * Windows XP and Server 2003 don't support symlinks; we'll get UV_ENOTSUP. - * Starting with vista they are supported, but only when elevated, otherwise - * we'll see UV_EPERM. - */ - if (r == UV_ENOTSUP || r == UV_EPERM) - return 0; -#endif - ASSERT(r == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_open(NULL, &req, "test_symlink", O_RDONLY, 0, NULL); - ASSERT(r == UV_ELOOP); - ASSERT(req.result == UV_ELOOP); - uv_fs_req_cleanup(&req); - - r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, open_loop_cb); - ASSERT(r == 0); - - ASSERT(open_cb_count == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(open_cb_count == 1); - - unlink("test_symlink"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -static void check_utime(const char* path, double atime, double mtime) { - uv_stat_t* s; - uv_fs_t req; - int r; - - r = uv_fs_stat(loop, &req, path, NULL); - ASSERT(r == 0); - - ASSERT(req.result == 0); - s = &req.statbuf; - - ASSERT(s->st_atim.tv_sec == atime); - ASSERT(s->st_mtim.tv_sec == mtime); - - uv_fs_req_cleanup(&req); -} - - -static void utime_cb(uv_fs_t* req) { - utime_check_t* c; - - ASSERT(req == &utime_req); - ASSERT(req->result == 0); - ASSERT(req->fs_type == UV_FS_UTIME); - - c = req->data; - check_utime(c->path, c->atime, c->mtime); - - uv_fs_req_cleanup(req); - utime_cb_count++; -} - - -static void futime_cb(uv_fs_t* req) { - utime_check_t* c; - - ASSERT(req == &futime_req); - ASSERT(req->result == 0); - ASSERT(req->fs_type == UV_FS_FUTIME); - - c = req->data; - check_utime(c->path, c->atime, c->mtime); - - uv_fs_req_cleanup(req); - futime_cb_count++; -} - - -TEST_IMPL(fs_file_async) { - int r; - - /* Setup. */ - unlink("test_file"); - unlink("test_file2"); - - loop = uv_default_loop(); - - r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT, - S_IRUSR | S_IWUSR, create_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); - ASSERT(fsync_cb_count == 1); - ASSERT(fdatasync_cb_count == 1); - ASSERT(close_cb_count == 1); - - r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", rename_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); - ASSERT(close_cb_count == 1); - ASSERT(rename_cb_count == 1); - - r = uv_fs_open(loop, &open_req1, "test_file2", O_RDWR, 0, open_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(open_cb_count == 1); - ASSERT(read_cb_count == 1); - ASSERT(close_cb_count == 2); - ASSERT(rename_cb_count == 1); - ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); - ASSERT(ftruncate_cb_count == 1); - - r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, open_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(open_cb_count == 2); - ASSERT(read_cb_count == 2); - ASSERT(close_cb_count == 3); - ASSERT(rename_cb_count == 1); - ASSERT(unlink_cb_count == 1); - ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); - ASSERT(ftruncate_cb_count == 1); - - /* Cleanup. */ - unlink("test_file"); - unlink("test_file2"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_file_sync) { - int r; - - /* Setup. */ - unlink("test_file"); - unlink("test_file2"); - - loop = uv_default_loop(); - - r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(write_req.result >= 0); - uv_fs_req_cleanup(&write_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR, 0, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(read_req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_ftruncate(NULL, &ftruncate_req, open_req1.result, 7, NULL); - ASSERT(r == 0); - ASSERT(ftruncate_req.result == 0); - uv_fs_req_cleanup(&ftruncate_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL); - ASSERT(r == 0); - ASSERT(rename_req.result == 0); - uv_fs_req_cleanup(&rename_req); - - r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY, 0, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(read_req.result >= 0); - ASSERT(strcmp(buf, "test-bu") == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_unlink(NULL, &unlink_req, "test_file2", NULL); - ASSERT(r == 0); - ASSERT(unlink_req.result == 0); - uv_fs_req_cleanup(&unlink_req); - - /* Cleanup */ - unlink("test_file"); - unlink("test_file2"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_file_write_null_buffer) { - int r; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(NULL, 0); - r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r == 0); - ASSERT(write_req.result == 0); - uv_fs_req_cleanup(&write_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_async_dir) { - int r; - uv_dirent_t dent; - - /* Setup */ - unlink("test_dir/file1"); - unlink("test_dir/file2"); - rmdir("test_dir"); - - loop = uv_default_loop(); - - r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(mkdir_cb_count == 1); - - /* Create 2 files synchronously. */ - r = uv_fs_open(NULL, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - uv_fs_req_cleanup(&open_req1); - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - uv_fs_req_cleanup(&open_req1); - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_scandir(loop, &scandir_req, "test_dir", 0, scandir_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(scandir_cb_count == 1); - - /* sync uv_fs_scandir */ - r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL); - ASSERT(r == 2); - ASSERT(scandir_req.result == 2); - ASSERT(scandir_req.ptr); - while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { - ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - assert_is_file_type(dent); - } - uv_fs_req_cleanup(&scandir_req); - ASSERT(!scandir_req.ptr); - - r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - - r = uv_fs_stat(loop, &stat_req, "test_dir/", stat_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - - r = uv_fs_lstat(loop, &stat_req, "test_dir", stat_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - - r = uv_fs_lstat(loop, &stat_req, "test_dir/", stat_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(stat_cb_count == 4); - - r = uv_fs_unlink(loop, &unlink_req, "test_dir/file1", unlink_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(unlink_cb_count == 1); - - r = uv_fs_unlink(loop, &unlink_req, "test_dir/file2", unlink_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(unlink_cb_count == 2); - - r = uv_fs_rmdir(loop, &rmdir_req, "test_dir", rmdir_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(rmdir_cb_count == 1); - - /* Cleanup */ - unlink("test_dir/file1"); - unlink("test_dir/file2"); - rmdir("test_dir"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_async_sendfile) { - int f, r; - struct stat s1, s2; - - loop = uv_default_loop(); - - /* Setup. */ - unlink("test_file"); - unlink("test_file2"); - - f = open("test_file", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR); - ASSERT(f != -1); - - r = write(f, "begin\n", 6); - ASSERT(r == 6); - - r = lseek(f, 65536, SEEK_CUR); - ASSERT(r == 65542); - - r = write(f, "end\n", 4); - ASSERT(r != -1); - - r = close(f); - ASSERT(r == 0); - - /* Test starts here. */ - r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR, 0, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - r = uv_fs_open(NULL, &open_req2, "test_file2", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req2.result >= 0); - uv_fs_req_cleanup(&open_req2); - - r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result, - 0, 131072, sendfile_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(sendfile_cb_count == 1); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&close_req); - r = uv_fs_close(NULL, &close_req, open_req2.result, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&close_req); - - stat("test_file", &s1); - stat("test_file2", &s2); - ASSERT(65546 == s2.st_size && s1.st_size == s2.st_size); - - /* Cleanup. */ - unlink("test_file"); - unlink("test_file2"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_mkdtemp) { - int r; - const char* path_template = "test_dir_XXXXXX"; - - loop = uv_default_loop(); - - r = uv_fs_mkdtemp(loop, &mkdtemp_req1, path_template, mkdtemp_cb); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(mkdtemp_cb_count == 1); - - /* sync mkdtemp */ - r = uv_fs_mkdtemp(NULL, &mkdtemp_req2, path_template, NULL); - ASSERT(r == 0); - check_mkdtemp_result(&mkdtemp_req2); - - /* mkdtemp return different values on subsequent calls */ - ASSERT(strcmp(mkdtemp_req1.path, mkdtemp_req2.path) != 0); - - /* Cleanup */ - rmdir(mkdtemp_req1.path); - rmdir(mkdtemp_req2.path); - uv_fs_req_cleanup(&mkdtemp_req1); - uv_fs_req_cleanup(&mkdtemp_req2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_fstat) { - int r; - uv_fs_t req; - uv_file file; - uv_stat_t* s; -#ifndef _WIN32 - struct stat t; -#endif - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; - uv_fs_req_cleanup(&req); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); - ASSERT(r == sizeof(test_buf)); - ASSERT(req.result == sizeof(test_buf)); - uv_fs_req_cleanup(&req); - - r = uv_fs_fstat(NULL, &req, file, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - s = req.ptr; - ASSERT(s->st_size == sizeof(test_buf)); - -#ifndef _WIN32 - r = fstat(file, &t); - ASSERT(r == 0); - - ASSERT(s->st_dev == (uint64_t) t.st_dev); - ASSERT(s->st_mode == (uint64_t) t.st_mode); - ASSERT(s->st_nlink == (uint64_t) t.st_nlink); - ASSERT(s->st_uid == (uint64_t) t.st_uid); - ASSERT(s->st_gid == (uint64_t) t.st_gid); - ASSERT(s->st_rdev == (uint64_t) t.st_rdev); - ASSERT(s->st_ino == (uint64_t) t.st_ino); - ASSERT(s->st_size == (uint64_t) t.st_size); - ASSERT(s->st_blksize == (uint64_t) t.st_blksize); - ASSERT(s->st_blocks == (uint64_t) t.st_blocks); -#if defined(__APPLE__) - ASSERT(s->st_atim.tv_sec == t.st_atimespec.tv_sec); - ASSERT(s->st_atim.tv_nsec == t.st_atimespec.tv_nsec); - ASSERT(s->st_mtim.tv_sec == t.st_mtimespec.tv_sec); - ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec); - ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec); - ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec); - ASSERT(s->st_birthtim.tv_sec == t.st_birthtimespec.tv_sec); - ASSERT(s->st_birthtim.tv_nsec == t.st_birthtimespec.tv_nsec); - ASSERT(s->st_flags == t.st_flags); - ASSERT(s->st_gen == t.st_gen); -#elif defined(_AIX) - ASSERT(s->st_atim.tv_sec == t.st_atime); - ASSERT(s->st_atim.tv_nsec == 0); - ASSERT(s->st_mtim.tv_sec == t.st_mtime); - ASSERT(s->st_mtim.tv_nsec == 0); - ASSERT(s->st_ctim.tv_sec == t.st_ctime); - ASSERT(s->st_ctim.tv_nsec == 0); -#elif defined(__sun) || \ - defined(_BSD_SOURCE) || \ - defined(_SVID_SOURCE) || \ - defined(_XOPEN_SOURCE) || \ - defined(_DEFAULT_SOURCE) - ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec); - ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec); - ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec); - ASSERT(s->st_mtim.tv_nsec == t.st_mtim.tv_nsec); - ASSERT(s->st_ctim.tv_sec == t.st_ctim.tv_sec); - ASSERT(s->st_ctim.tv_nsec == t.st_ctim.tv_nsec); -# if defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) - ASSERT(s->st_birthtim.tv_sec == t.st_birthtim.tv_sec); - ASSERT(s->st_birthtim.tv_nsec == t.st_birthtim.tv_nsec); - ASSERT(s->st_flags == t.st_flags); - ASSERT(s->st_gen == t.st_gen); -# endif -#else - ASSERT(s->st_atim.tv_sec == t.st_atime); - ASSERT(s->st_atim.tv_nsec == 0); - ASSERT(s->st_mtim.tv_sec == t.st_mtime); - ASSERT(s->st_mtim.tv_nsec == 0); - ASSERT(s->st_ctim.tv_sec == t.st_ctime); - ASSERT(s->st_ctim.tv_nsec == 0); -#endif -#endif - - uv_fs_req_cleanup(&req); - - /* Now do the uv_fs_fstat call asynchronously */ - r = uv_fs_fstat(loop, &req, file, fstat_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(fstat_cb_count == 1); - - - r = uv_fs_close(NULL, &req, file, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - /* - * Run the loop just to check we don't have make any extraneous uv_ref() - * calls. This should drop out immediately. - */ - uv_run(loop, UV_RUN_DEFAULT); - - /* Cleanup. */ - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_access) { - int r; - uv_fs_t req; - uv_file file; - - /* Setup. */ - unlink("test_file"); - rmdir("test_dir"); - - loop = uv_default_loop(); - - /* File should not exist */ - r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL); - ASSERT(r < 0); - ASSERT(req.result < 0); - uv_fs_req_cleanup(&req); - - /* File should not exist */ - r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(access_cb_count == 1); - access_cb_count = 0; /* reset for the next test */ - - /* Create file */ - r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; - uv_fs_req_cleanup(&req); - - /* File should exist */ - r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - /* File should exist */ - r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(access_cb_count == 1); - access_cb_count = 0; /* reset for the next test */ - - /* Close file */ - r = uv_fs_close(NULL, &req, file, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - /* Directory access */ - r = uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_access(NULL, &req, "test_dir", W_OK, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - /* - * Run the loop just to check we don't have make any extraneous uv_ref() - * calls. This should drop out immediately. - */ - uv_run(loop, UV_RUN_DEFAULT); - - /* Cleanup. */ - unlink("test_file"); - rmdir("test_dir"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_chmod) { - int r; - uv_fs_t req; - uv_file file; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; - uv_fs_req_cleanup(&req); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); - ASSERT(r == sizeof(test_buf)); - ASSERT(req.result == sizeof(test_buf)); - uv_fs_req_cleanup(&req); - -#ifndef _WIN32 - /* Make the file write-only */ - r = uv_fs_chmod(NULL, &req, "test_file", 0200, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - check_permission("test_file", 0200); -#endif - - /* Make the file read-only */ - r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - check_permission("test_file", 0400); - - /* Make the file read+write with sync uv_fs_fchmod */ - r = uv_fs_fchmod(NULL, &req, file, 0600, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - check_permission("test_file", 0600); - -#ifndef _WIN32 - /* async chmod */ - { - static int mode = 0200; - req.data = &mode; - } - r = uv_fs_chmod(loop, &req, "test_file", 0200, chmod_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(chmod_cb_count == 1); - chmod_cb_count = 0; /* reset for the next test */ -#endif - - /* async chmod */ - { - static int mode = 0400; - req.data = &mode; - } - r = uv_fs_chmod(loop, &req, "test_file", 0400, chmod_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(chmod_cb_count == 1); - - /* async fchmod */ - { - static int mode = 0600; - req.data = &mode; - } - r = uv_fs_fchmod(loop, &req, file, 0600, fchmod_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(fchmod_cb_count == 1); - - close(file); - - /* - * Run the loop just to check we don't have make any extraneous uv_ref() - * calls. This should drop out immediately. - */ - uv_run(loop, UV_RUN_DEFAULT); - - /* Cleanup. */ - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_unlink_readonly) { - int r; - uv_fs_t req; - uv_file file; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, - &req, - "test_file", - O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, - NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; - uv_fs_req_cleanup(&req); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); - ASSERT(r == sizeof(test_buf)); - ASSERT(req.result == sizeof(test_buf)); - uv_fs_req_cleanup(&req); - - close(file); - - /* Make the file read-only */ - r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - check_permission("test_file", 0400); - - /* Try to unlink the file */ - r = uv_fs_unlink(NULL, &req, "test_file", NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - /* - * Run the loop just to check we don't have make any extraneous uv_ref() - * calls. This should drop out immediately. - */ - uv_run(loop, UV_RUN_DEFAULT); - - /* Cleanup. */ - uv_fs_chmod(NULL, &req, "test_file", 0600, NULL); - uv_fs_req_cleanup(&req); - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_chown) { - int r; - uv_fs_t req; - uv_file file; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; - uv_fs_req_cleanup(&req); - - /* sync chown */ - r = uv_fs_chown(NULL, &req, "test_file", -1, -1, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - /* sync fchown */ - r = uv_fs_fchown(NULL, &req, file, -1, -1, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - /* async chown */ - r = uv_fs_chown(loop, &req, "test_file", -1, -1, chown_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(chown_cb_count == 1); - - /* chown to root (fail) */ - chown_cb_count = 0; - r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(chown_cb_count == 1); - - /* async fchown */ - r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(fchown_cb_count == 1); - - close(file); - - /* - * Run the loop just to check we don't have make any extraneous uv_ref() - * calls. This should drop out immediately. - */ - uv_run(loop, UV_RUN_DEFAULT); - - /* Cleanup. */ - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_link) { - int r; - uv_fs_t req; - uv_file file; - uv_file link; - - /* Setup. */ - unlink("test_file"); - unlink("test_file_link"); - unlink("test_file_link2"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; - uv_fs_req_cleanup(&req); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); - ASSERT(r == sizeof(test_buf)); - ASSERT(req.result == sizeof(test_buf)); - uv_fs_req_cleanup(&req); - - close(file); - - /* sync link */ - r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_open(NULL, &req, "test_file_link", O_RDWR, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - link = req.result; - uv_fs_req_cleanup(&req); - - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - - close(link); - - /* async link */ - r = uv_fs_link(loop, &req, "test_file", "test_file_link2", link_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(link_cb_count == 1); - - r = uv_fs_open(NULL, &req, "test_file_link2", O_RDWR, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - link = req.result; - uv_fs_req_cleanup(&req); - - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - - close(link); - - /* - * Run the loop just to check we don't have make any extraneous uv_ref() - * calls. This should drop out immediately. - */ - uv_run(loop, UV_RUN_DEFAULT); - - /* Cleanup. */ - unlink("test_file"); - unlink("test_file_link"); - unlink("test_file_link2"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_readlink) { - uv_fs_t req; - - loop = uv_default_loop(); - ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(dummy_cb_count == 1); - ASSERT(req.ptr == NULL); - ASSERT(req.result == UV_ENOENT); - uv_fs_req_cleanup(&req); - - ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL)); - ASSERT(req.ptr == NULL); - ASSERT(req.result == UV_ENOENT); - uv_fs_req_cleanup(&req); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_symlink) { - int r; - uv_fs_t req; - uv_file file; - uv_file link; - - /* Setup. */ - unlink("test_file"); - unlink("test_file_symlink"); - unlink("test_file_symlink2"); - unlink("test_file_symlink_symlink"); - unlink("test_file_symlink2_symlink"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; - uv_fs_req_cleanup(&req); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); - ASSERT(r == sizeof(test_buf)); - ASSERT(req.result == sizeof(test_buf)); - uv_fs_req_cleanup(&req); - - close(file); - - /* sync symlink */ - r = uv_fs_symlink(NULL, &req, "test_file", "test_file_symlink", 0, NULL); -#ifdef _WIN32 - if (r < 0) { - if (r == UV_ENOTSUP) { - /* - * Windows doesn't support symlinks on older versions. - * We just pass the test and bail out early if we get ENOTSUP. - */ - return 0; - } else if (r == UV_EPERM) { - /* - * Creating a symlink is only allowed when running elevated. - * We pass the test and bail out early if we get UV_EPERM. - */ - return 0; - } - } -#endif - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_open(NULL, &req, "test_file_symlink", O_RDWR, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - link = req.result; - uv_fs_req_cleanup(&req); - - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - - close(link); - - r = uv_fs_symlink(NULL, - &req, - "test_file_symlink", - "test_file_symlink_symlink", - 0, - NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_readlink(NULL, &req, "test_file_symlink_symlink", NULL); - ASSERT(r == 0); - ASSERT(strcmp(req.ptr, "test_file_symlink") == 0); - uv_fs_req_cleanup(&req); - - /* async link */ - r = uv_fs_symlink(loop, - &req, - "test_file", - "test_file_symlink2", - 0, - symlink_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(symlink_cb_count == 1); - - r = uv_fs_open(NULL, &req, "test_file_symlink2", O_RDWR, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - link = req.result; - uv_fs_req_cleanup(&req); - - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - - close(link); - - r = uv_fs_symlink(NULL, - &req, - "test_file_symlink2", - "test_file_symlink2_symlink", - 0, - NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(readlink_cb_count == 1); - - /* - * Run the loop just to check we don't have make any extraneous uv_ref() - * calls. This should drop out immediately. - */ - uv_run(loop, UV_RUN_DEFAULT); - - /* Cleanup. */ - unlink("test_file"); - unlink("test_file_symlink"); - unlink("test_file_symlink_symlink"); - unlink("test_file_symlink2"); - unlink("test_file_symlink2_symlink"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_symlink_dir) { - uv_fs_t req; - int r; - char* test_dir; - uv_dirent_t dent; - - /* set-up */ - unlink("test_dir/file1"); - unlink("test_dir/file2"); - rmdir("test_dir"); - rmdir("test_dir_symlink"); - - loop = uv_default_loop(); - - uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL); - uv_fs_req_cleanup(&req); - -#ifdef _WIN32 - { - static char src_path_buf[PATHMAX]; - size_t size; - size = sizeof(src_path_buf); - strcpy(src_path_buf, "\\\\?\\"); - uv_cwd(src_path_buf + 4, &size); - strcat(src_path_buf, "\\test_dir\\"); - test_dir = src_path_buf; - } -#else - test_dir = "test_dir"; -#endif - - r = uv_fs_symlink(NULL, &req, test_dir, "test_dir_symlink", - UV_FS_SYMLINK_JUNCTION, NULL); - fprintf(stderr, "r == %i\n", r); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_stat(NULL, &req, "test_dir_symlink", NULL); - ASSERT(r == 0); - ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFDIR); - uv_fs_req_cleanup(&req); - - r = uv_fs_lstat(NULL, &req, "test_dir_symlink", NULL); - ASSERT(r == 0); - ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK); -#ifdef _WIN32 - ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4)); -#else - ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir)); -#endif - uv_fs_req_cleanup(&req); - - r = uv_fs_readlink(NULL, &req, "test_dir_symlink", NULL); - ASSERT(r == 0); -#ifdef _WIN32 - ASSERT(strcmp(req.ptr, test_dir + 4) == 0); -#else - ASSERT(strcmp(req.ptr, test_dir) == 0); -#endif - uv_fs_req_cleanup(&req); - - r = uv_fs_open(NULL, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - uv_fs_req_cleanup(&open_req1); - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - uv_fs_req_cleanup(&open_req1); - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL); - ASSERT(r == 2); - ASSERT(scandir_req.result == 2); - ASSERT(scandir_req.ptr); - while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { - ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - assert_is_file_type(dent); - } - uv_fs_req_cleanup(&scandir_req); - ASSERT(!scandir_req.ptr); - - /* unlink will remove the directory symlink */ - r = uv_fs_unlink(NULL, &req, "test_dir_symlink", NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL); - ASSERT(r == UV_ENOENT); - uv_fs_req_cleanup(&scandir_req); - - r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL); - ASSERT(r == 2); - ASSERT(scandir_req.result == 2); - ASSERT(scandir_req.ptr); - while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { - ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - assert_is_file_type(dent); - } - uv_fs_req_cleanup(&scandir_req); - ASSERT(!scandir_req.ptr); - - /* clean-up */ - unlink("test_dir/file1"); - unlink("test_dir/file2"); - rmdir("test_dir"); - rmdir("test_dir_symlink"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_utime) { - utime_check_t checkme; - const char* path = "test_file"; - double atime; - double mtime; - uv_fs_t req; - int r; - - /* Setup. */ - loop = uv_default_loop(); - unlink(path); - r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - uv_fs_req_cleanup(&req); - close(r); - - atime = mtime = 400497753; /* 1982-09-10 11:22:33 */ - - r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_stat(NULL, &req, path, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - check_utime(path, atime, mtime); - uv_fs_req_cleanup(&req); - - atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */ - checkme.path = path; - checkme.atime = atime; - checkme.mtime = mtime; - - /* async utime */ - utime_req.data = &checkme; - r = uv_fs_utime(loop, &utime_req, path, atime, mtime, utime_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(utime_cb_count == 1); - - /* Cleanup. */ - unlink(path); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -#ifdef _WIN32 -TEST_IMPL(fs_stat_root) { - int r; - uv_loop_t* loop = uv_default_loop(); - - r = uv_fs_stat(NULL, &stat_req, "\\", NULL); - ASSERT(r == 0); - - r = uv_fs_stat(NULL, &stat_req, "..\\..\\..\\..\\..\\..\\..", NULL); - ASSERT(r == 0); - - r = uv_fs_stat(NULL, &stat_req, "..", NULL); - ASSERT(r == 0); - - r = uv_fs_stat(NULL, &stat_req, "..\\", NULL); - ASSERT(r == 0); - - /* stats the current directory on c: */ - r = uv_fs_stat(NULL, &stat_req, "c:", NULL); - ASSERT(r == 0); - - r = uv_fs_stat(NULL, &stat_req, "c:\\", NULL); - ASSERT(r == 0); - - r = uv_fs_stat(NULL, &stat_req, "\\\\?\\C:\\", NULL); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif - - -TEST_IMPL(fs_futime) { - utime_check_t checkme; - const char* path = "test_file"; - double atime; - double mtime; - uv_file file; - uv_fs_t req; - int r; - - /* Setup. */ - loop = uv_default_loop(); - unlink(path); - r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - uv_fs_req_cleanup(&req); - close(r); - - atime = mtime = 400497753; /* 1982-09-10 11:22:33 */ - - r = uv_fs_open(NULL, &req, path, O_RDWR, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - file = req.result; /* FIXME probably not how it's supposed to be used */ - uv_fs_req_cleanup(&req); - - r = uv_fs_futime(NULL, &req, file, atime, mtime, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - uv_fs_req_cleanup(&req); - - r = uv_fs_stat(NULL, &req, path, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - check_utime(path, atime, mtime); - uv_fs_req_cleanup(&req); - - atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */ - - checkme.atime = atime; - checkme.mtime = mtime; - checkme.path = path; - - /* async futime */ - futime_req.data = &checkme; - r = uv_fs_futime(loop, &futime_req, file, atime, mtime, futime_cb); - ASSERT(r == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(futime_cb_count == 1); - - /* Cleanup. */ - unlink(path); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_stat_missing_path) { - uv_fs_t req; - int r; - - loop = uv_default_loop(); - - r = uv_fs_stat(NULL, &req, "non_existent_file", NULL); - ASSERT(r == UV_ENOENT); - ASSERT(req.result == UV_ENOENT); - uv_fs_req_cleanup(&req); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_scandir_empty_dir) { - const char* path; - uv_fs_t req; - uv_dirent_t dent; - int r; - - path = "./empty_dir/"; - loop = uv_default_loop(); - - uv_fs_mkdir(NULL, &req, path, 0777, NULL); - uv_fs_req_cleanup(&req); - - /* Fill the req to ensure that required fields are cleaned up */ - memset(&req, 0xdb, sizeof(req)); - - r = uv_fs_scandir(NULL, &req, path, 0, NULL); - ASSERT(r == 0); - ASSERT(req.result == 0); - ASSERT(req.ptr == NULL); - ASSERT(UV_EOF == uv_fs_scandir_next(&req, &dent)); - uv_fs_req_cleanup(&req); - - r = uv_fs_scandir(loop, &scandir_req, path, 0, empty_scandir_cb); - ASSERT(r == 0); - - ASSERT(scandir_cb_count == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(scandir_cb_count == 1); - - uv_fs_rmdir(NULL, &req, path, NULL); - uv_fs_req_cleanup(&req); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_scandir_file) { - const char* path; - int r; - - path = "test/fixtures/empty_file"; - loop = uv_default_loop(); - - r = uv_fs_scandir(NULL, &scandir_req, path, 0, NULL); - ASSERT(r == UV_ENOTDIR); - uv_fs_req_cleanup(&scandir_req); - - r = uv_fs_scandir(loop, &scandir_req, path, 0, file_scandir_cb); - ASSERT(r == 0); - - ASSERT(scandir_cb_count == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(scandir_cb_count == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_open_dir) { - const char* path; - uv_fs_t req; - int r, file; - - path = "."; - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &req, path, O_RDONLY, 0, NULL); - ASSERT(r >= 0); - ASSERT(req.result >= 0); - ASSERT(req.ptr == NULL); - file = r; - uv_fs_req_cleanup(&req); - - r = uv_fs_close(NULL, &req, file, NULL); - ASSERT(r == 0); - - r = uv_fs_open(loop, &req, path, O_RDONLY, 0, open_cb_simple); - ASSERT(r == 0); - - ASSERT(open_cb_count == 0); - uv_run(loop, UV_RUN_DEFAULT); - ASSERT(open_cb_count == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_file_open_append) { - int r; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(write_req.result >= 0); - uv_fs_req_cleanup(&write_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR | O_APPEND, 0, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(write_req.result >= 0); - uv_fs_req_cleanup(&write_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); - printf("read = %d\n", r); - ASSERT(r == 26); - ASSERT(read_req.result == 26); - ASSERT(memcmp(buf, - "test-buffer\n\0test-buffer\n\0", - sizeof("test-buffer\n\0test-buffer\n\0") - 1) == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - /* Cleanup */ - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_rename_to_existing_file) { - int r; - - /* Setup. */ - unlink("test_file"); - unlink("test_file2"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(write_req.result >= 0); - uv_fs_req_cleanup(&write_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_file2", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL); - ASSERT(r == 0); - ASSERT(rename_req.result == 0); - uv_fs_req_cleanup(&rename_req); - - r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY, 0, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(read_req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - /* Cleanup */ - unlink("test_file"); - unlink("test_file2"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_read_file_eof) { - int r; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(test_buf, sizeof(test_buf)); - r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(write_req.result >= 0); - uv_fs_req_cleanup(&write_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - memset(buf, 0, sizeof(buf)); - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r >= 0); - ASSERT(read_req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - uv_fs_req_cleanup(&read_req); - - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, - read_req.result, NULL); - ASSERT(r == 0); - ASSERT(read_req.result == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - /* Cleanup */ - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_write_multiple_bufs) { - uv_buf_t iovs[2]; - int r; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT, - S_IWUSR | S_IRUSR, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iovs[0] = uv_buf_init(test_buf, sizeof(test_buf)); - iovs[1] = uv_buf_init(test_buf2, sizeof(test_buf2)); - r = uv_fs_write(NULL, &write_req, open_req1.result, iovs, 2, 0, NULL); - ASSERT(r >= 0); - ASSERT(write_req.result >= 0); - uv_fs_req_cleanup(&write_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - memset(buf, 0, sizeof(buf)); - memset(buf2, 0, sizeof(buf2)); - /* Read the strings back to separate buffers. */ - iovs[0] = uv_buf_init(buf, sizeof(test_buf)); - iovs[1] = uv_buf_init(buf2, sizeof(test_buf2)); - r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, 2, 0, NULL); - ASSERT(r >= 0); - ASSERT(read_req.result >= 0); - ASSERT(strcmp(buf, test_buf) == 0); - ASSERT(strcmp(buf2, test_buf2) == 0); - uv_fs_req_cleanup(&read_req); - - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, - read_req.result, NULL); - ASSERT(r == 0); - ASSERT(read_req.result == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - /* Cleanup */ - unlink("test_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_write_alotof_bufs) { - const size_t iovcount = 54321; - uv_buf_t* iovs; - char* buffer; - size_t index; - int r; - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - iovs = malloc(sizeof(*iovs) * iovcount); - ASSERT(iovs != NULL); - - r = uv_fs_open(NULL, - &open_req1, - "test_file", - O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, - NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - for (index = 0; index < iovcount; ++index) - iovs[index] = uv_buf_init(test_buf, sizeof(test_buf)); - - r = uv_fs_write(NULL, - &write_req, - open_req1.result, - iovs, - iovcount, - -1, - NULL); - ASSERT(r >= 0); - ASSERT((size_t)write_req.result == sizeof(test_buf) * iovcount); - uv_fs_req_cleanup(&write_req); - - /* Read the strings back to separate buffers. */ - buffer = malloc(sizeof(test_buf) * iovcount); - ASSERT(buffer != NULL); - - for (index = 0; index < iovcount; ++index) - iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), - sizeof(test_buf)); - - r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, iovcount, 0, NULL); - ASSERT(r >= 0); - ASSERT((size_t)read_req.result == sizeof(test_buf) * iovcount); - - for (index = 0; index < iovcount; ++index) - ASSERT(strncmp(buffer + index * sizeof(test_buf), - test_buf, - sizeof(test_buf)) == 0); - - uv_fs_req_cleanup(&read_req); - free(buffer); - - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, - &read_req, - open_req1.result, - &iov, - 1, - read_req.result, - NULL); - ASSERT(r == 0); - ASSERT(read_req.result == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - /* Cleanup */ - unlink("test_file"); - free(iovs); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_write_alotof_bufs_with_offset) { - const size_t iovcount = 54321; - uv_buf_t* iovs; - char* buffer; - size_t index; - int r; - int64_t offset; - char* filler = "0123456789"; - int filler_len = strlen(filler); - - /* Setup. */ - unlink("test_file"); - - loop = uv_default_loop(); - - iovs = malloc(sizeof(*iovs) * iovcount); - ASSERT(iovs != NULL); - - r = uv_fs_open(NULL, - &open_req1, - "test_file", - O_RDWR | O_CREAT, - S_IWUSR | S_IRUSR, - NULL); - ASSERT(r >= 0); - ASSERT(open_req1.result >= 0); - uv_fs_req_cleanup(&open_req1); - - iov = uv_buf_init(filler, filler_len); - r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); - ASSERT(r == filler_len); - ASSERT(write_req.result == filler_len); - uv_fs_req_cleanup(&write_req); - offset = (int64_t)r; - - for (index = 0; index < iovcount; ++index) - iovs[index] = uv_buf_init(test_buf, sizeof(test_buf)); - - r = uv_fs_write(NULL, - &write_req, - open_req1.result, - iovs, - iovcount, - offset, - NULL); - ASSERT(r >= 0); - ASSERT((size_t)write_req.result == sizeof(test_buf) * iovcount); - uv_fs_req_cleanup(&write_req); - - /* Read the strings back to separate buffers. */ - buffer = malloc(sizeof(test_buf) * iovcount); - ASSERT(buffer != NULL); - - for (index = 0; index < iovcount; ++index) - iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), - sizeof(test_buf)); - - r = uv_fs_read(NULL, &read_req, open_req1.result, - iovs, iovcount, offset, NULL); - ASSERT(r >= 0); - ASSERT(read_req.result == sizeof(test_buf) * iovcount); - - for (index = 0; index < iovcount; ++index) - ASSERT(strncmp(buffer + index * sizeof(test_buf), - test_buf, - sizeof(test_buf)) == 0); - - uv_fs_req_cleanup(&read_req); - free(buffer); - - r = uv_fs_stat(NULL, &stat_req, "test_file", NULL); - ASSERT(r == 0); - ASSERT((int64_t)((uv_stat_t*)stat_req.ptr)->st_size == - offset + (int64_t)(iovcount * sizeof(test_buf))); - uv_fs_req_cleanup(&stat_req); - - iov = uv_buf_init(buf, sizeof(buf)); - r = uv_fs_read(NULL, - &read_req, - open_req1.result, - &iov, - 1, - read_req.result + offset, - NULL); - ASSERT(r == 0); - ASSERT(read_req.result == 0); - uv_fs_req_cleanup(&read_req); - - r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); - ASSERT(r == 0); - ASSERT(close_req.result == 0); - uv_fs_req_cleanup(&close_req); - - /* Cleanup */ - unlink("test_file"); - free(iovs); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_read_write_null_arguments) { - int r; - - r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL); - ASSERT(r == UV_EINVAL); - - r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL); - ASSERT(r == UV_EINVAL); - - iov = uv_buf_init(NULL, 0); - r = uv_fs_read(NULL, NULL, 0, &iov, 0, -1, NULL); - ASSERT(r == UV_EINVAL); - - iov = uv_buf_init(NULL, 0); - r = uv_fs_write(NULL, NULL, 0, &iov, 0, -1, NULL); - ASSERT(r == UV_EINVAL); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-get-currentexe.c b/outside/libuv-v1.7.5/test/test-get-currentexe.c deleted file mode 100644 index 0e9d696540..0000000000 --- a/outside/libuv-v1.7.5/test/test-get-currentexe.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - -#define PATHMAX 1024 -extern char executable_path[]; - -TEST_IMPL(get_currentexe) { - char buffer[PATHMAX]; - size_t size; - char* match; - char* path; - int r; - - size = sizeof(buffer) / sizeof(buffer[0]); - r = uv_exepath(buffer, &size); - ASSERT(!r); - - /* uv_exepath can return an absolute path on darwin, so if the test runner - * was run with a relative prefix of "./", we need to strip that prefix off - * executable_path or we'll fail. */ - if (executable_path[0] == '.' && executable_path[1] == '/') { - path = executable_path + 2; - } else { - path = executable_path; - } - - match = strstr(buffer, path); - /* Verify that the path returned from uv_exepath is a subdirectory of - * executable_path. - */ - ASSERT(match && !strcmp(match, path)); - ASSERT(size == strlen(buffer)); - - /* Negative tests */ - size = sizeof(buffer) / sizeof(buffer[0]); - r = uv_exepath(NULL, &size); - ASSERT(r == UV_EINVAL); - - r = uv_exepath(buffer, NULL); - ASSERT(r == UV_EINVAL); - - size = 0; - r = uv_exepath(buffer, &size); - ASSERT(r == UV_EINVAL); - - memset(buffer, -1, sizeof(buffer)); - - size = 1; - r = uv_exepath(buffer, &size); - ASSERT(r == 0); - ASSERT(size == 0); - ASSERT(buffer[0] == '\0'); - - memset(buffer, -1, sizeof(buffer)); - - size = 2; - r = uv_exepath(buffer, &size); - ASSERT(r == 0); - ASSERT(size == 1); - ASSERT(buffer[0] != '\0'); - ASSERT(buffer[1] == '\0'); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-get-loadavg.c b/outside/libuv-v1.7.5/test/test-get-loadavg.c deleted file mode 100644 index 7465e18b91..0000000000 --- a/outside/libuv-v1.7.5/test/test-get-loadavg.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -TEST_IMPL(get_loadavg) { - - double avg[3]; - uv_loadavg(avg); - - ASSERT(avg != NULL); - ASSERT(avg[0] >= 0); - ASSERT(avg[1] >= 0); - ASSERT(avg[2] >= 0); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-get-memory.c b/outside/libuv-v1.7.5/test/test-get-memory.c deleted file mode 100644 index 2396939bcb..0000000000 --- a/outside/libuv-v1.7.5/test/test-get-memory.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -TEST_IMPL(get_memory) { - uint64_t free_mem = uv_get_free_memory(); - uint64_t total_mem = uv_get_total_memory(); - - printf("free_mem=%llu, total_mem=%llu\n", - (unsigned long long) free_mem, - (unsigned long long) total_mem); - - ASSERT(free_mem > 0); - ASSERT(total_mem > 0); - ASSERT(total_mem > free_mem); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-getaddrinfo.c b/outside/libuv-v1.7.5/test/test-getaddrinfo.c deleted file mode 100644 index 45813c313a..0000000000 --- a/outside/libuv-v1.7.5/test/test-getaddrinfo.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - -#define CONCURRENT_COUNT 10 - -static const char* name = "localhost"; - -static int getaddrinfo_cbs = 0; - -/* data used for running multiple calls concurrently */ -static uv_getaddrinfo_t* getaddrinfo_handle; -static uv_getaddrinfo_t getaddrinfo_handles[CONCURRENT_COUNT]; -static int callback_counts[CONCURRENT_COUNT]; -static int fail_cb_called; - - -static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req, - int status, - struct addrinfo* res) { - ASSERT(fail_cb_called == 0); - ASSERT(status < 0); - ASSERT(res == NULL); - uv_freeaddrinfo(res); /* Should not crash. */ - fail_cb_called++; -} - - -static void getaddrinfo_basic_cb(uv_getaddrinfo_t* handle, - int status, - struct addrinfo* res) { - ASSERT(handle == getaddrinfo_handle); - getaddrinfo_cbs++; - free(handle); - uv_freeaddrinfo(res); -} - - -static void getaddrinfo_cuncurrent_cb(uv_getaddrinfo_t* handle, - int status, - struct addrinfo* res) { - int i; - int* data = (int*)handle->data; - - for (i = 0; i < CONCURRENT_COUNT; i++) { - if (&getaddrinfo_handles[i] == handle) { - ASSERT(i == *data); - - callback_counts[i]++; - break; - } - } - ASSERT (i < CONCURRENT_COUNT); - - free(data); - uv_freeaddrinfo(res); - - getaddrinfo_cbs++; -} - - -TEST_IMPL(getaddrinfo_fail) { - uv_getaddrinfo_t req; - - ASSERT(0 == uv_getaddrinfo(uv_default_loop(), - &req, - getaddrinfo_fail_cb, - "xyzzy.xyzzy.xyzzy", - NULL, - NULL)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(fail_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(getaddrinfo_fail_sync) { - uv_getaddrinfo_t req; - - ASSERT(0 > uv_getaddrinfo(uv_default_loop(), - &req, - NULL, - "xyzzy.xyzzy.xyzzy", - NULL, - NULL)); - uv_freeaddrinfo(req.addrinfo); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(getaddrinfo_basic) { - int r; - getaddrinfo_handle = (uv_getaddrinfo_t*)malloc(sizeof(uv_getaddrinfo_t)); - - r = uv_getaddrinfo(uv_default_loop(), - getaddrinfo_handle, - &getaddrinfo_basic_cb, - name, - NULL, - NULL); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(getaddrinfo_cbs == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(getaddrinfo_basic_sync) { - uv_getaddrinfo_t req; - - ASSERT(0 == uv_getaddrinfo(uv_default_loop(), - &req, - NULL, - name, - NULL, - NULL)); - uv_freeaddrinfo(req.addrinfo); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(getaddrinfo_concurrent) { - int i, r; - int* data; - - for (i = 0; i < CONCURRENT_COUNT; i++) { - callback_counts[i] = 0; - - data = (int*)malloc(sizeof(int)); - ASSERT(data != NULL); - *data = i; - getaddrinfo_handles[i].data = data; - - r = uv_getaddrinfo(uv_default_loop(), - &getaddrinfo_handles[i], - &getaddrinfo_cuncurrent_cb, - name, - NULL, - NULL); - ASSERT(r == 0); - } - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - for (i = 0; i < CONCURRENT_COUNT; i++) { - ASSERT(callback_counts[i] == 1); - } - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-getnameinfo.c b/outside/libuv-v1.7.5/test/test-getnameinfo.c deleted file mode 100644 index ebe9246699..0000000000 --- a/outside/libuv-v1.7.5/test/test-getnameinfo.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to -* deal in the Software without restriction, including without limitation the -* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -* sell copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -* IN THE SOFTWARE. -*/ - -#include "uv.h" -#include "task.h" -#include -#include -#include - - -static const char* address_ip4 = "127.0.0.1"; -static const char* address_ip6 = "::1"; -static const int port = 80; - -static struct sockaddr_in addr4; -static struct sockaddr_in6 addr6; -static uv_getnameinfo_t req; - -static void getnameinfo_req(uv_getnameinfo_t* handle, - int status, - const char* hostname, - const char* service) { - ASSERT(handle != NULL); - ASSERT(status == 0); - ASSERT(hostname != NULL); - ASSERT(service != NULL); -} - - -TEST_IMPL(getnameinfo_basic_ip4) { - int r; - - r = uv_ip4_addr(address_ip4, port, &addr4); - ASSERT(r == 0); - - r = uv_getnameinfo(uv_default_loop(), - &req, - &getnameinfo_req, - (const struct sockaddr*)&addr4, - 0); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(getnameinfo_basic_ip4_sync) { - ASSERT(0 == uv_ip4_addr(address_ip4, port, &addr4)); - - ASSERT(0 == uv_getnameinfo(uv_default_loop(), - &req, - NULL, - (const struct sockaddr*)&addr4, - 0)); - ASSERT(req.host != NULL); - ASSERT(req.service != NULL); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(getnameinfo_basic_ip6) { - int r; - - r = uv_ip6_addr(address_ip6, port, &addr6); - ASSERT(r == 0); - - r = uv_getnameinfo(uv_default_loop(), - &req, - &getnameinfo_req, - (const struct sockaddr*)&addr6, - 0); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-getsockname.c b/outside/libuv-v1.7.5/test/test-getsockname.c deleted file mode 100644 index 565c17fe50..0000000000 --- a/outside/libuv-v1.7.5/test/test-getsockname.c +++ /dev/null @@ -1,361 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -static const int server_port = TEST_PORT; -/* Will be updated right after making the uv_connect_call */ -static int connect_port = -1; - -static int getsocknamecount = 0; -static int getpeernamecount = 0; - -static uv_loop_t* loop; -static uv_tcp_t tcp; -static uv_udp_t udp; -static uv_connect_t connect_req; -static uv_tcp_t tcpServer; -static uv_udp_t udpServer; -static uv_udp_send_t send_req; - - -static void alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -static void on_close(uv_handle_t* peer) { - free(peer); - uv_close((uv_handle_t*)&tcpServer, NULL); -} - - -static void after_shutdown(uv_shutdown_t* req, int status) { - uv_close((uv_handle_t*) req->handle, on_close); - free(req); -} - - -static void after_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - uv_shutdown_t* req; - int r; - - if (buf->base) { - free(buf->base); - } - - req = (uv_shutdown_t*) malloc(sizeof *req); - r = uv_shutdown(req, handle, after_shutdown); - ASSERT(r == 0); -} - - -static void check_sockname(struct sockaddr* addr, const char* compare_ip, - int compare_port, const char* context) { - struct sockaddr_in check_addr = *(struct sockaddr_in*) addr; - struct sockaddr_in compare_addr; - char check_ip[17]; - int r; - - ASSERT(0 == uv_ip4_addr(compare_ip, compare_port, &compare_addr)); - - /* Both addresses should be ipv4 */ - ASSERT(check_addr.sin_family == AF_INET); - ASSERT(compare_addr.sin_family == AF_INET); - - /* Check if the ip matches */ - ASSERT(memcmp(&check_addr.sin_addr, - &compare_addr.sin_addr, - sizeof compare_addr.sin_addr) == 0); - - /* Check if the port matches. If port == 0 anything goes. */ - ASSERT(compare_port == 0 || check_addr.sin_port == compare_addr.sin_port); - - r = uv_ip4_name(&check_addr, (char*) check_ip, sizeof check_ip); - ASSERT(r == 0); - - printf("%s: %s:%d\n", context, check_ip, ntohs(check_addr.sin_port)); -} - - -static void on_connection(uv_stream_t* server, int status) { - struct sockaddr sockname, peername; - int namelen; - uv_tcp_t* handle; - int r; - - if (status != 0) { - fprintf(stderr, "Connect error %s\n", uv_err_name(status)); - } - ASSERT(status == 0); - - handle = malloc(sizeof(*handle)); - ASSERT(handle != NULL); - - r = uv_tcp_init(loop, handle); - ASSERT(r == 0); - - /* associate server with stream */ - handle->data = server; - - r = uv_accept(server, (uv_stream_t*)handle); - ASSERT(r == 0); - - namelen = sizeof sockname; - r = uv_tcp_getsockname(handle, &sockname, &namelen); - ASSERT(r == 0); - check_sockname(&sockname, "127.0.0.1", server_port, "accepted socket"); - getsocknamecount++; - - namelen = sizeof peername; - r = uv_tcp_getpeername(handle, &peername, &namelen); - ASSERT(r == 0); - check_sockname(&peername, "127.0.0.1", connect_port, "accepted socket peer"); - getpeernamecount++; - - r = uv_read_start((uv_stream_t*)handle, alloc, after_read); - ASSERT(r == 0); -} - - -static void on_connect(uv_connect_t* req, int status) { - struct sockaddr sockname, peername; - int r, namelen; - - ASSERT(status == 0); - - namelen = sizeof sockname; - r = uv_tcp_getsockname((uv_tcp_t*) req->handle, &sockname, &namelen); - ASSERT(r == 0); - check_sockname(&sockname, "127.0.0.1", 0, "connected socket"); - getsocknamecount++; - - namelen = sizeof peername; - r = uv_tcp_getpeername((uv_tcp_t*) req->handle, &peername, &namelen); - ASSERT(r == 0); - check_sockname(&peername, "127.0.0.1", server_port, "connected socket peer"); - getpeernamecount++; - - uv_close((uv_handle_t*)&tcp, NULL); -} - - -static int tcp_listener(void) { - struct sockaddr_in addr; - struct sockaddr sockname, peername; - int namelen; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr)); - - r = uv_tcp_init(loop, &tcpServer); - if (r) { - fprintf(stderr, "Socket creation error\n"); - return 1; - } - - r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0); - if (r) { - fprintf(stderr, "Bind error\n"); - return 1; - } - - r = uv_listen((uv_stream_t*)&tcpServer, 128, on_connection); - if (r) { - fprintf(stderr, "Listen error\n"); - return 1; - } - - memset(&sockname, -1, sizeof sockname); - namelen = sizeof sockname; - r = uv_tcp_getsockname(&tcpServer, &sockname, &namelen); - ASSERT(r == 0); - check_sockname(&sockname, "0.0.0.0", server_port, "server socket"); - getsocknamecount++; - - namelen = sizeof sockname; - r = uv_tcp_getpeername(&tcpServer, &peername, &namelen); - ASSERT(r == UV_ENOTCONN); - getpeernamecount++; - - return 0; -} - - -static void tcp_connector(void) { - struct sockaddr_in server_addr; - struct sockaddr sockname; - int r, namelen; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr)); - - r = uv_tcp_init(loop, &tcp); - tcp.data = &connect_req; - ASSERT(!r); - - r = uv_tcp_connect(&connect_req, - &tcp, - (const struct sockaddr*) &server_addr, - on_connect); - ASSERT(!r); - - /* Fetch the actual port used by the connecting socket. */ - namelen = sizeof sockname; - r = uv_tcp_getsockname(&tcp, &sockname, &namelen); - ASSERT(!r); - ASSERT(sockname.sa_family == AF_INET); - connect_port = ntohs(((struct sockaddr_in*) &sockname)->sin_port); - ASSERT(connect_port > 0); -} - - -static void udp_recv(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - struct sockaddr sockname; - int namelen; - int r; - - ASSERT(nread >= 0); - free(buf->base); - - if (nread == 0) { - return; - } - - memset(&sockname, -1, sizeof sockname); - namelen = sizeof(sockname); - r = uv_udp_getsockname(&udp, &sockname, &namelen); - ASSERT(r == 0); - check_sockname(&sockname, "0.0.0.0", 0, "udp receiving socket"); - getsocknamecount++; - - uv_close((uv_handle_t*) &udp, NULL); - uv_close((uv_handle_t*) handle, NULL); -} - - -static void udp_send(uv_udp_send_t* req, int status) { - -} - - -static int udp_listener(void) { - struct sockaddr_in addr; - struct sockaddr sockname; - int namelen; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr)); - - r = uv_udp_init(loop, &udpServer); - if (r) { - fprintf(stderr, "Socket creation error\n"); - return 1; - } - - r = uv_udp_bind(&udpServer, (const struct sockaddr*) &addr, 0); - if (r) { - fprintf(stderr, "Bind error\n"); - return 1; - } - - memset(&sockname, -1, sizeof sockname); - namelen = sizeof sockname; - r = uv_udp_getsockname(&udpServer, &sockname, &namelen); - ASSERT(r == 0); - check_sockname(&sockname, "0.0.0.0", server_port, "udp listener socket"); - getsocknamecount++; - - r = uv_udp_recv_start(&udpServer, alloc, udp_recv); - ASSERT(r == 0); - - return 0; -} - - -static void udp_sender(void) { - struct sockaddr_in server_addr; - uv_buf_t buf; - int r; - - r = uv_udp_init(loop, &udp); - ASSERT(!r); - - buf = uv_buf_init("PING", 4); - ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr)); - - r = uv_udp_send(&send_req, - &udp, - &buf, - 1, - (const struct sockaddr*) &server_addr, - udp_send); - ASSERT(!r); -} - - -TEST_IMPL(getsockname_tcp) { - loop = uv_default_loop(); - - if (tcp_listener()) - return 1; - - tcp_connector(); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(getsocknamecount == 3); - ASSERT(getpeernamecount == 3); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(getsockname_udp) { - loop = uv_default_loop(); - - if (udp_listener()) - return 1; - - udp_sender(); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(getsocknamecount == 2); - - ASSERT(udp.send_queue_size == 0); - ASSERT(udpServer.send_queue_size == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-handle-fileno.c b/outside/libuv-v1.7.5/test/test-handle-fileno.c deleted file mode 100644 index 3fe933adeb..0000000000 --- a/outside/libuv-v1.7.5/test/test-handle-fileno.c +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -static int get_tty_fd(void) { - /* Make sure we have an FD that refers to a tty */ -#ifdef _WIN32 - HANDLE handle; - handle = CreateFileA("conout$", - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (handle == INVALID_HANDLE_VALUE) - return -1; - return _open_osfhandle((intptr_t) handle, 0); -#else /* unix */ - return open("/dev/tty", O_RDONLY, 0); -#endif -} - - -TEST_IMPL(handle_fileno) { - int r; - int tty_fd; - struct sockaddr_in addr; - uv_os_fd_t fd; - uv_tcp_t tcp; - uv_udp_t udp; - uv_pipe_t pipe; - uv_tty_t tty; - uv_idle_t idle; - uv_loop_t* loop; - - loop = uv_default_loop(); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_idle_init(loop, &idle); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &idle, &fd); - ASSERT(r == UV_EINVAL); - uv_close((uv_handle_t*) &idle, NULL); - - r = uv_tcp_init(loop, &tcp); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &tcp, &fd); - ASSERT(r == UV_EBADF); - r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &tcp, &fd); - ASSERT(r == 0); - uv_close((uv_handle_t*) &tcp, NULL); - r = uv_fileno((uv_handle_t*) &tcp, &fd); - ASSERT(r == UV_EBADF); - - r = uv_udp_init(loop, &udp); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &udp, &fd); - ASSERT(r == UV_EBADF); - r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &udp, &fd); - ASSERT(r == 0); - uv_close((uv_handle_t*) &udp, NULL); - r = uv_fileno((uv_handle_t*) &udp, &fd); - ASSERT(r == UV_EBADF); - - r = uv_pipe_init(loop, &pipe, 0); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &pipe, &fd); - ASSERT(r == UV_EBADF); - r = uv_pipe_bind(&pipe, TEST_PIPENAME); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &pipe, &fd); - ASSERT(r == 0); - uv_close((uv_handle_t*) &pipe, NULL); - r = uv_fileno((uv_handle_t*) &pipe, &fd); - ASSERT(r == UV_EBADF); - - tty_fd = get_tty_fd(); - if (tty_fd < 0) { - fprintf(stderr, "Cannot open a TTY fd"); - fflush(stderr); - } else { - r = uv_tty_init(loop, &tty, tty_fd, 0); - ASSERT(r == 0); - r = uv_fileno((uv_handle_t*) &tty, &fd); - ASSERT(r == 0); - uv_close((uv_handle_t*) &tty, NULL); - r = uv_fileno((uv_handle_t*) &tty, &fd); - ASSERT(r == UV_EBADF); - } - - uv_run(loop, UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-homedir.c b/outside/libuv-v1.7.5/test/test-homedir.c deleted file mode 100644 index cbc47566c5..0000000000 --- a/outside/libuv-v1.7.5/test/test-homedir.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "uv.h" -#include "task.h" -#include - -#define PATHMAX 1024 -#define SMALLPATH 1 - -TEST_IMPL(homedir) { - char homedir[PATHMAX]; - size_t len; - char last; - int r; - - /* Test the normal case */ - len = sizeof homedir; - homedir[0] = '\0'; - ASSERT(strlen(homedir) == 0); - r = uv_os_homedir(homedir, &len); - ASSERT(r == 0); - ASSERT(strlen(homedir) == len); - ASSERT(len > 0); - ASSERT(homedir[len] == '\0'); - - if (len > 1) { - last = homedir[len - 1]; -#ifdef _WIN32 - ASSERT(last != '\\'); -#else - ASSERT(last != '/'); -#endif - } - - /* Test the case where the buffer is too small */ - len = SMALLPATH; - r = uv_os_homedir(homedir, &len); - ASSERT(r == UV_ENOBUFS); - ASSERT(len > SMALLPATH); - - /* Test invalid inputs */ - r = uv_os_homedir(NULL, &len); - ASSERT(r == UV_EINVAL); - r = uv_os_homedir(homedir, NULL); - ASSERT(r == UV_EINVAL); - len = 0; - r = uv_os_homedir(homedir, &len); - ASSERT(r == UV_EINVAL); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-hrtime.c b/outside/libuv-v1.7.5/test/test-hrtime.c deleted file mode 100644 index 72a4d4b181..0000000000 --- a/outside/libuv-v1.7.5/test/test-hrtime.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#ifndef MILLISEC -# define MILLISEC 1000 -#endif - -#ifndef NANOSEC -# define NANOSEC ((uint64_t) 1e9) -#endif - - -TEST_IMPL(hrtime) { - uint64_t a, b, diff; - int i = 75; - while (i > 0) { - a = uv_hrtime(); - uv_sleep(45); - b = uv_hrtime(); - - diff = b - a; - - /* printf("i= %d diff = %llu\n", i, (unsigned long long int) diff); */ - - /* The windows Sleep() function has only a resolution of 10-20 ms. */ - /* Check that the difference between the two hrtime values is somewhat in */ - /* the range we expect it to be. */ - ASSERT(diff > (uint64_t) 25 * NANOSEC / MILLISEC); - ASSERT(diff < (uint64_t) 80 * NANOSEC / MILLISEC); - --i; - } - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-idle.c b/outside/libuv-v1.7.5/test/test-idle.c deleted file mode 100644 index f49d196482..0000000000 --- a/outside/libuv-v1.7.5/test/test-idle.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -static uv_idle_t idle_handle; -static uv_check_t check_handle; -static uv_timer_t timer_handle; - -static int idle_cb_called = 0; -static int check_cb_called = 0; -static int timer_cb_called = 0; -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer_handle); - - uv_close((uv_handle_t*) &idle_handle, close_cb); - uv_close((uv_handle_t*) &check_handle, close_cb); - uv_close((uv_handle_t*) &timer_handle, close_cb); - - timer_cb_called++; - fprintf(stderr, "timer_cb %d\n", timer_cb_called); - fflush(stderr); -} - - -static void idle_cb(uv_idle_t* handle) { - ASSERT(handle == &idle_handle); - - idle_cb_called++; - fprintf(stderr, "idle_cb %d\n", idle_cb_called); - fflush(stderr); -} - - -static void check_cb(uv_check_t* handle) { - ASSERT(handle == &check_handle); - - check_cb_called++; - fprintf(stderr, "check_cb %d\n", check_cb_called); - fflush(stderr); -} - - -TEST_IMPL(idle_starvation) { - int r; - - r = uv_idle_init(uv_default_loop(), &idle_handle); - ASSERT(r == 0); - r = uv_idle_start(&idle_handle, idle_cb); - ASSERT(r == 0); - - r = uv_check_init(uv_default_loop(), &check_handle); - ASSERT(r == 0); - r = uv_check_start(&check_handle, check_cb); - ASSERT(r == 0); - - r = uv_timer_init(uv_default_loop(), &timer_handle); - ASSERT(r == 0); - r = uv_timer_start(&timer_handle, timer_cb, 50, 0); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(idle_cb_called > 0); - ASSERT(timer_cb_called == 1); - ASSERT(close_cb_called == 3); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-ip4-addr.c b/outside/libuv-v1.7.5/test/test-ip4-addr.c deleted file mode 100644 index 3d6e0cf286..0000000000 --- a/outside/libuv-v1.7.5/test/test-ip4-addr.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -TEST_IMPL(ip4_addr) { - - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(0 == uv_ip4_addr("255.255.255.255", TEST_PORT, &addr)); - ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255*000", TEST_PORT, &addr)); - ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255.256", TEST_PORT, &addr)); - ASSERT(UV_EINVAL == uv_ip4_addr("2555.0.0.0", TEST_PORT, &addr)); - ASSERT(UV_EINVAL == uv_ip4_addr("255", TEST_PORT, &addr)); - - /* for broken address family */ - ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1", - &addr.sin_addr.s_addr)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-ip6-addr.c b/outside/libuv-v1.7.5/test/test-ip6-addr.c deleted file mode 100644 index 869b099e0f..0000000000 --- a/outside/libuv-v1.7.5/test/test-ip6-addr.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -#ifdef __linux__ -# include -# include -#endif - - -TEST_IMPL(ip6_addr_link_local) { - char string_address[INET6_ADDRSTRLEN]; - uv_interface_address_t* addresses; - uv_interface_address_t* address; - struct sockaddr_in6 addr; - unsigned int iface_index; - const char* device_name; - /* 40 bytes address, 16 bytes device name, plus reserve. */ - char scoped_addr[128]; - int count; - int ix; - - ASSERT(0 == uv_interface_addresses(&addresses, &count)); - - for (ix = 0; ix < count; ix++) { - address = addresses + ix; - - if (address->address.address6.sin6_family != AF_INET6) - continue; - - ASSERT(0 == uv_inet_ntop(AF_INET6, - &address->address.address6.sin6_addr, - string_address, - sizeof(string_address))); - - /* Skip addresses that are not link-local. */ - if (strncmp(string_address, "fe80::", 6) != 0) - continue; - - iface_index = address->address.address6.sin6_scope_id; - device_name = address->name; - -#ifdef _WIN32 - snprintf(scoped_addr, - sizeof(scoped_addr), - "%s%%%d", - string_address, - iface_index); -#else - snprintf(scoped_addr, - sizeof(scoped_addr), - "%s%%%s", - string_address, - device_name); -#endif - - fprintf(stderr, "Testing link-local address %s " - "(iface_index: 0x%02x, device_name: %s)\n", - scoped_addr, - iface_index, - device_name); - fflush(stderr); - - ASSERT(0 == uv_ip6_addr(scoped_addr, TEST_PORT, &addr)); - fprintf(stderr, "Got scope_id 0x%02x\n", addr.sin6_scope_id); - fflush(stderr); - ASSERT(iface_index == addr.sin6_scope_id); - } - - uv_free_interface_addresses(addresses, count); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -#define GOOD_ADDR_LIST(X) \ - X("::") \ - X("::1") \ - X("fe80::1") \ - X("fe80::") \ - X("fe80::2acf:daff:fedd:342a") \ - X("fe80:0:0:0:2acf:daff:fedd:342a") \ - X("fe80:0:0:0:2acf:daff:1.2.3.4") \ - X("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") \ - -#define BAD_ADDR_LIST(X) \ - X(":::1") \ - X("abcde::1") \ - X("fe80:0:0:0:2acf:daff:fedd:342a:5678") \ - X("fe80:0:0:0:2acf:daff:abcd:1.2.3.4") \ - X("fe80:0:0:2acf:daff:1.2.3.4.5") \ - X("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255.255") \ - -#define TEST_GOOD(ADDR) \ - ASSERT(0 == uv_inet_pton(AF_INET6, ADDR, &addr)); \ - ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1", &addr)); \ - ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%%%%", &addr)); \ - ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr)); \ - -#define TEST_BAD(ADDR) \ - ASSERT(0 != uv_inet_pton(AF_INET6, ADDR, &addr)); \ - ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1", &addr)); \ - ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%%%%", &addr)); \ - ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr)); \ - -TEST_IMPL(ip6_pton) { - struct in6_addr addr; - - GOOD_ADDR_LIST(TEST_GOOD) - BAD_ADDR_LIST(TEST_BAD) - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#undef GOOD_ADDR_LIST -#undef BAD_ADDR_LIST diff --git a/outside/libuv-v1.7.5/test/test-ipc-send-recv.c b/outside/libuv-v1.7.5/test/test-ipc-send-recv.c deleted file mode 100644 index d9b913339d..0000000000 --- a/outside/libuv-v1.7.5/test/test-ipc-send-recv.c +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -/* See test-ipc.ctx */ -void spawn_helper(uv_pipe_t* channel, - uv_process_t* process, - const char* helper); - -union handles { - uv_handle_t handle; - uv_stream_t stream; - uv_pipe_t pipe; - uv_tcp_t tcp; - uv_tty_t tty; -}; - -struct echo_ctx { - uv_pipe_t channel; - uv_write_t write_req; - uv_handle_type expected_type; - union handles send; - union handles recv; -}; - -static struct echo_ctx ctx; -static int num_recv_handles; - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - /* we're not actually reading anything so a small buffer is okay */ - static char slab[8]; - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void recv_cb(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - uv_handle_type pending; - uv_pipe_t* pipe; - int r; - - pipe = (uv_pipe_t*) handle; - ASSERT(pipe == &ctx.channel); - ASSERT(nread >= 0); - ASSERT(1 == uv_pipe_pending_count(pipe)); - - pending = uv_pipe_pending_type(pipe); - ASSERT(pending == ctx.expected_type); - - if (pending == UV_NAMED_PIPE) - r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0); - else if (pending == UV_TCP) - r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp); - else - abort(); - ASSERT(r == 0); - - r = uv_accept(handle, &ctx.recv.stream); - ASSERT(r == 0); - - uv_close((uv_handle_t*)&ctx.channel, NULL); - uv_close(&ctx.send.handle, NULL); - uv_close(&ctx.recv.handle, NULL); - num_recv_handles++; -} - - -static int run_test(void) { - uv_process_t process; - uv_buf_t buf; - int r; - - spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper"); - - buf = uv_buf_init(".", 1); - r = uv_write2(&ctx.write_req, - (uv_stream_t*)&ctx.channel, - &buf, 1, - &ctx.send.stream, - NULL); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(num_recv_handles == 1); - - return 0; -} - - -TEST_IMPL(ipc_send_recv_pipe) { - int r; - - ctx.expected_type = UV_NAMED_PIPE; - - r = uv_pipe_init(uv_default_loop(), &ctx.send.pipe, 1); - ASSERT(r == 0); - - r = uv_pipe_bind(&ctx.send.pipe, TEST_PIPENAME); - ASSERT(r == 0); - - r = run_test(); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(ipc_send_recv_tcp) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - ctx.expected_type = UV_TCP; - - r = uv_tcp_init(uv_default_loop(), &ctx.send.tcp); - ASSERT(r == 0); - - r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = run_test(); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -/* Everything here runs in a child process. */ - -static void write2_cb(uv_write_t* req, int status) { - ASSERT(status == 0); - uv_close(&ctx.recv.handle, NULL); - uv_close((uv_handle_t*)&ctx.channel, NULL); -} - - -static void read_cb(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* rdbuf) { - uv_buf_t wrbuf; - uv_pipe_t* pipe; - uv_handle_type pending; - int r; - - pipe = (uv_pipe_t*) handle; - ASSERT(pipe == &ctx.channel); - ASSERT(nread >= 0); - ASSERT(1 == uv_pipe_pending_count(pipe)); - - pending = uv_pipe_pending_type(pipe); - ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP); - - wrbuf = uv_buf_init(".", 1); - - if (pending == UV_NAMED_PIPE) - r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0); - else if (pending == UV_TCP) - r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp); - else - abort(); - ASSERT(r == 0); - - r = uv_accept(handle, &ctx.recv.stream); - ASSERT(r == 0); - - r = uv_write2(&ctx.write_req, - (uv_stream_t*)&ctx.channel, - &wrbuf, - 1, - &ctx.recv.stream, - write2_cb); - ASSERT(r == 0); -} - - -/* stdin is a duplex channel over which a handle is sent. - * We receive it and send it back where it came from. - */ -int ipc_send_recv_helper(void) { - int r; - - memset(&ctx, 0, sizeof(ctx)); - - r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1); - ASSERT(r == 0); - - uv_pipe_open(&ctx.channel, 0); - ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx.channel)); - ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx.channel)); - ASSERT(0 == uv_is_closing((uv_handle_t*)&ctx.channel)); - - r = uv_read_start((uv_stream_t*)&ctx.channel, alloc_cb, read_cb); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-ipc.c b/outside/libuv-v1.7.5/test/test-ipc.c deleted file mode 100644 index f018c2d4d4..0000000000 --- a/outside/libuv-v1.7.5/test/test-ipc.c +++ /dev/null @@ -1,779 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -static uv_pipe_t channel; -static uv_tcp_t tcp_server; -static uv_tcp_t tcp_server2; -static uv_tcp_t tcp_connection; - -static int exit_cb_called; -static int read_cb_called; -static int tcp_write_cb_called; -static int tcp_read_cb_called; -static int on_pipe_read_called; -static int local_conn_accepted; -static int remote_conn_accepted; -static int tcp_server_listening; -static uv_write_t write_req; -static uv_write_t conn_notify_req; -static int close_cb_called; -static int connection_accepted; -static int tcp_conn_read_cb_called; -static int tcp_conn_write_cb_called; - -typedef struct { - uv_connect_t conn_req; - uv_write_t tcp_write_req; - uv_tcp_t conn; -} tcp_conn; - -#define CONN_COUNT 100 -#define BACKLOG 128 - - -static void close_server_conn_cb(uv_handle_t* handle) { - free(handle); -} - - -static void on_connection(uv_stream_t* server, int status) { - uv_tcp_t* conn; - int r; - - if (!local_conn_accepted) { - /* Accept the connection and close it. Also and close the server. */ - ASSERT(status == 0); - ASSERT((uv_stream_t*)&tcp_server == server); - - conn = malloc(sizeof(*conn)); - ASSERT(conn); - r = uv_tcp_init(server->loop, conn); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)conn); - ASSERT(r == 0); - - uv_close((uv_handle_t*)conn, close_server_conn_cb); - uv_close((uv_handle_t*)server, NULL); - local_conn_accepted = 1; - } -} - - -static void exit_cb(uv_process_t* process, - int64_t exit_status, - int term_signal) { - printf("exit_cb\n"); - exit_cb_called++; - ASSERT(exit_status == 0); - uv_close((uv_handle_t*)process, NULL); -} - - -static void on_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -static void close_client_conn_cb(uv_handle_t* handle) { - tcp_conn* p = (tcp_conn*)handle->data; - free(p); -} - - -static void connect_cb(uv_connect_t* req, int status) { - uv_close((uv_handle_t*)req->handle, close_client_conn_cb); -} - - -static void make_many_connections(void) { - tcp_conn* conn; - struct sockaddr_in addr; - int r, i; - - for (i = 0; i < CONN_COUNT; i++) { - conn = malloc(sizeof(*conn)); - ASSERT(conn); - - r = uv_tcp_init(uv_default_loop(), &conn->conn); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_connect(&conn->conn_req, - (uv_tcp_t*) &conn->conn, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - conn->conn.data = conn; - } -} - - -static void on_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - int r; - uv_pipe_t* pipe; - uv_handle_type pending; - uv_buf_t outbuf; - - pipe = (uv_pipe_t*) handle; - - if (nread == 0) { - /* Everything OK, but nothing read. */ - free(buf->base); - return; - } - - if (nread < 0) { - if (nread == UV_EOF) { - free(buf->base); - return; - } - - printf("error recving on channel: %s\n", uv_strerror(nread)); - abort(); - } - - fprintf(stderr, "got %d bytes\n", (int)nread); - - pending = uv_pipe_pending_type(pipe); - if (!tcp_server_listening) { - ASSERT(1 == uv_pipe_pending_count(pipe)); - ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE); - read_cb_called++; - - /* Accept the pending TCP server, and start listening on it. */ - ASSERT(pending == UV_TCP); - r = uv_tcp_init(uv_default_loop(), &tcp_server); - ASSERT(r == 0); - - r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, on_connection); - ASSERT(r == 0); - - tcp_server_listening = 1; - - /* Make sure that the expected data is correctly multiplexed. */ - ASSERT(memcmp("hello\n", buf->base, nread) == 0); - - outbuf = uv_buf_init("world\n", 6); - r = uv_write(&write_req, (uv_stream_t*)pipe, &outbuf, 1, NULL); - ASSERT(r == 0); - - /* Create a bunch of connections to get both servers to accept. */ - make_many_connections(); - } else if (memcmp("accepted_connection\n", buf->base, nread) == 0) { - /* Remote server has accepted a connection. Close the channel. */ - ASSERT(0 == uv_pipe_pending_count(pipe)); - ASSERT(pending == UV_UNKNOWN_HANDLE); - remote_conn_accepted = 1; - uv_close((uv_handle_t*)&channel, NULL); - } - - free(buf->base); -} - -#ifdef _WIN32 -static void on_read_listen_after_bound_twice(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - int r; - uv_pipe_t* pipe; - uv_handle_type pending; - - pipe = (uv_pipe_t*) handle; - - if (nread == 0) { - /* Everything OK, but nothing read. */ - free(buf->base); - return; - } - - if (nread < 0) { - if (nread == UV_EOF) { - free(buf->base); - return; - } - - printf("error recving on channel: %s\n", uv_strerror(nread)); - abort(); - } - - fprintf(stderr, "got %d bytes\n", (int)nread); - - ASSERT(uv_pipe_pending_count(pipe) > 0); - pending = uv_pipe_pending_type(pipe); - ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE); - read_cb_called++; - - if (read_cb_called == 1) { - /* Accept the first TCP server, and start listening on it. */ - ASSERT(pending == UV_TCP); - r = uv_tcp_init(uv_default_loop(), &tcp_server); - ASSERT(r == 0); - - r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, on_connection); - ASSERT(r == 0); - } else if (read_cb_called == 2) { - /* Accept the second TCP server, and start listening on it. */ - ASSERT(pending == UV_TCP); - r = uv_tcp_init(uv_default_loop(), &tcp_server2); - ASSERT(r == 0); - - r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server2); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&tcp_server2, BACKLOG, on_connection); - ASSERT(r == UV_EADDRINUSE); - - uv_close((uv_handle_t*)&tcp_server, NULL); - uv_close((uv_handle_t*)&tcp_server2, NULL); - ASSERT(0 == uv_pipe_pending_count(pipe)); - uv_close((uv_handle_t*)&channel, NULL); - } - - free(buf->base); -} -#endif - -void spawn_helper(uv_pipe_t* channel, - uv_process_t* process, - const char* helper) { - uv_process_options_t options; - size_t exepath_size; - char exepath[1024]; - char* args[3]; - int r; - uv_stdio_container_t stdio[1]; - - r = uv_pipe_init(uv_default_loop(), channel, 1); - ASSERT(r == 0); - ASSERT(channel->ipc); - - exepath_size = sizeof(exepath); - r = uv_exepath(exepath, &exepath_size); - ASSERT(r == 0); - - exepath[exepath_size] = '\0'; - args[0] = exepath; - args[1] = (char*)helper; - args[2] = NULL; - - memset(&options, 0, sizeof(options)); - options.file = exepath; - options.args = args; - options.exit_cb = exit_cb; - - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | - UV_READABLE_PIPE | UV_WRITABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*)channel; - options.stdio_count = 1; - - r = uv_spawn(uv_default_loop(), process, &options); - ASSERT(r == 0); -} - - -static void on_tcp_write(uv_write_t* req, int status) { - ASSERT(status == 0); - ASSERT(req->handle == (uv_stream_t*)&tcp_connection); - tcp_write_cb_called++; -} - - -static void on_read_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -static void on_tcp_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - ASSERT(nread > 0); - ASSERT(memcmp("hello again\n", buf->base, nread) == 0); - ASSERT(tcp == (uv_stream_t*)&tcp_connection); - free(buf->base); - - tcp_read_cb_called++; - - uv_close((uv_handle_t*)tcp, NULL); - uv_close((uv_handle_t*)&channel, NULL); -} - - -static void on_read_connection(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - int r; - uv_buf_t outbuf; - uv_pipe_t* pipe; - uv_handle_type pending; - - pipe = (uv_pipe_t*) handle; - if (nread == 0) { - /* Everything OK, but nothing read. */ - free(buf->base); - return; - } - - if (nread < 0) { - if (nread == UV_EOF) { - free(buf->base); - return; - } - - printf("error recving on channel: %s\n", uv_strerror(nread)); - abort(); - } - - fprintf(stderr, "got %d bytes\n", (int)nread); - - ASSERT(1 == uv_pipe_pending_count(pipe)); - pending = uv_pipe_pending_type(pipe); - - ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE); - read_cb_called++; - - /* Accept the pending TCP connection */ - ASSERT(pending == UV_TCP); - r = uv_tcp_init(uv_default_loop(), &tcp_connection); - ASSERT(r == 0); - - r = uv_accept(handle, (uv_stream_t*)&tcp_connection); - ASSERT(r == 0); - - /* Make sure that the expected data is correctly multiplexed. */ - ASSERT(memcmp("hello\n", buf->base, nread) == 0); - - /* Write/read to/from the connection */ - outbuf = uv_buf_init("world\n", 6); - r = uv_write(&write_req, (uv_stream_t*)&tcp_connection, &outbuf, 1, - on_tcp_write); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)&tcp_connection, on_read_alloc, on_tcp_read); - ASSERT(r == 0); - - free(buf->base); -} - - -static int run_ipc_test(const char* helper, uv_read_cb read_cb) { - uv_process_t process; - int r; - - spawn_helper(&channel, &process, helper); - uv_read_start((uv_stream_t*)&channel, on_alloc, read_cb); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(ipc_listen_before_write) { - int r = run_ipc_test("ipc_helper_listen_before_write", on_read); - ASSERT(local_conn_accepted == 1); - ASSERT(remote_conn_accepted == 1); - ASSERT(read_cb_called == 1); - ASSERT(exit_cb_called == 1); - return r; -} - - -TEST_IMPL(ipc_listen_after_write) { - int r = run_ipc_test("ipc_helper_listen_after_write", on_read); - ASSERT(local_conn_accepted == 1); - ASSERT(remote_conn_accepted == 1); - ASSERT(read_cb_called == 1); - ASSERT(exit_cb_called == 1); - return r; -} - - -TEST_IMPL(ipc_tcp_connection) { - int r = run_ipc_test("ipc_helper_tcp_connection", on_read_connection); - ASSERT(read_cb_called == 1); - ASSERT(tcp_write_cb_called == 1); - ASSERT(tcp_read_cb_called == 1); - ASSERT(exit_cb_called == 1); - return r; -} - - -#ifdef _WIN32 -TEST_IMPL(listen_with_simultaneous_accepts) { - uv_tcp_t server; - int r; - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_tcp_simultaneous_accepts(&server, 1); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL); - ASSERT(r == 0); - ASSERT(server.reqs_pending == 32); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(listen_no_simultaneous_accepts) { - uv_tcp_t server; - int r; - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_tcp_simultaneous_accepts(&server, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL); - ASSERT(r == 0); - ASSERT(server.reqs_pending == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(ipc_listen_after_bind_twice) { - int r = run_ipc_test("ipc_helper_bind_twice", on_read_listen_after_bound_twice); - ASSERT(read_cb_called == 2); - ASSERT(exit_cb_called == 1); - return r; -} -#endif - - -/* Everything here runs in a child process. */ - -static tcp_conn conn; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void conn_notify_write_cb(uv_write_t* req, int status) { - uv_close((uv_handle_t*)&tcp_server, close_cb); - uv_close((uv_handle_t*)&channel, close_cb); -} - - -static void tcp_connection_write_cb(uv_write_t* req, int status) { - ASSERT((uv_handle_t*)&conn.conn == (uv_handle_t*)req->handle); - uv_close((uv_handle_t*)req->handle, close_cb); - uv_close((uv_handle_t*)&channel, close_cb); - uv_close((uv_handle_t*)&tcp_server, close_cb); - tcp_conn_write_cb_called++; -} - - -static void on_tcp_child_process_read(uv_stream_t* tcp, - ssize_t nread, - const uv_buf_t* buf) { - uv_buf_t outbuf; - int r; - - if (nread < 0) { - if (nread == UV_EOF) { - free(buf->base); - return; - } - - printf("error recving on tcp connection: %s\n", uv_strerror(nread)); - abort(); - } - - ASSERT(nread > 0); - ASSERT(memcmp("world\n", buf->base, nread) == 0); - on_pipe_read_called++; - free(buf->base); - - /* Write to the socket */ - outbuf = uv_buf_init("hello again\n", 12); - r = uv_write(&conn.tcp_write_req, tcp, &outbuf, 1, tcp_connection_write_cb); - ASSERT(r == 0); - - tcp_conn_read_cb_called++; -} - - -static void connect_child_process_cb(uv_connect_t* req, int status) { - int r; - - ASSERT(status == 0); - r = uv_read_start(req->handle, on_read_alloc, on_tcp_child_process_read); - ASSERT(r == 0); -} - - -static void ipc_on_connection(uv_stream_t* server, int status) { - int r; - uv_buf_t buf; - - if (!connection_accepted) { - /* - * Accept the connection and close it. Also let the other - * side know. - */ - ASSERT(status == 0); - ASSERT((uv_stream_t*)&tcp_server == server); - - r = uv_tcp_init(server->loop, &conn.conn); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)&conn.conn); - ASSERT(r == 0); - - uv_close((uv_handle_t*)&conn.conn, close_cb); - - buf = uv_buf_init("accepted_connection\n", 20); - r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1, - NULL, conn_notify_write_cb); - ASSERT(r == 0); - - connection_accepted = 1; - } -} - - -static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) { - int r; - uv_buf_t buf; - uv_tcp_t* conn; - - ASSERT(status == 0); - ASSERT((uv_stream_t*)&tcp_server == server); - - conn = malloc(sizeof(*conn)); - ASSERT(conn); - - r = uv_tcp_init(server->loop, conn); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)conn); - ASSERT(r == 0); - - /* Send the accepted connection to the other process */ - buf = uv_buf_init("hello\n", 6); - r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1, - (uv_stream_t*)conn, NULL); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) conn, - on_read_alloc, - on_tcp_child_process_read); - ASSERT(r == 0); - - uv_close((uv_handle_t*)conn, close_cb); -} - - -int ipc_helper(int listen_after_write) { - /* - * This is launched from test-ipc.c. stdin is a duplex channel that we - * over which a handle will be transmitted. - */ - struct sockaddr_in addr; - uv_write_t write_req; - int r; - uv_buf_t buf; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_pipe_init(uv_default_loop(), &channel, 1); - ASSERT(r == 0); - - uv_pipe_open(&channel, 0); - - ASSERT(1 == uv_is_readable((uv_stream_t*) &channel)); - ASSERT(1 == uv_is_writable((uv_stream_t*) &channel)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &channel)); - - r = uv_tcp_init(uv_default_loop(), &tcp_server); - ASSERT(r == 0); - - r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - if (!listen_after_write) { - r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection); - ASSERT(r == 0); - } - - buf = uv_buf_init("hello\n", 6); - r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1, - (uv_stream_t*)&tcp_server, NULL); - ASSERT(r == 0); - - if (listen_after_write) { - r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection); - ASSERT(r == 0); - } - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(connection_accepted == 1); - ASSERT(close_cb_called == 3); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -int ipc_helper_tcp_connection(void) { - /* - * This is launched from test-ipc.c. stdin is a duplex channel - * over which a handle will be transmitted. - */ - - int r; - struct sockaddr_in addr; - - r = uv_pipe_init(uv_default_loop(), &channel, 1); - ASSERT(r == 0); - - uv_pipe_open(&channel, 0); - - ASSERT(1 == uv_is_readable((uv_stream_t*) &channel)); - ASSERT(1 == uv_is_writable((uv_stream_t*) &channel)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &channel)); - - r = uv_tcp_init(uv_default_loop(), &tcp_server); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection_tcp_conn); - ASSERT(r == 0); - - /* Make a connection to the server */ - r = uv_tcp_init(uv_default_loop(), &conn.conn); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_connect(&conn.conn_req, - (uv_tcp_t*) &conn.conn, - (const struct sockaddr*) &addr, - connect_child_process_cb); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(tcp_conn_read_cb_called == 1); - ASSERT(tcp_conn_write_cb_called == 1); - ASSERT(close_cb_called == 4); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -int ipc_helper_bind_twice(void) { - /* - * This is launched from test-ipc.c. stdin is a duplex channel - * over which two handles will be transmitted. - */ - struct sockaddr_in addr; - uv_write_t write_req; - uv_write_t write_req2; - int r; - uv_buf_t buf; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_pipe_init(uv_default_loop(), &channel, 1); - ASSERT(r == 0); - - uv_pipe_open(&channel, 0); - - ASSERT(1 == uv_is_readable((uv_stream_t*) &channel)); - ASSERT(1 == uv_is_writable((uv_stream_t*) &channel)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &channel)); - - buf = uv_buf_init("hello\n", 6); - - r = uv_tcp_init(uv_default_loop(), &tcp_server); - ASSERT(r == 0); - r = uv_tcp_init(uv_default_loop(), &tcp_server2); - ASSERT(r == 0); - - r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - r = uv_tcp_bind(&tcp_server2, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1, - (uv_stream_t*)&tcp_server, NULL); - ASSERT(r == 0); - r = uv_write2(&write_req2, (uv_stream_t*)&channel, &buf, 1, - (uv_stream_t*)&tcp_server2, NULL); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-list.h b/outside/libuv-v1.7.5/test/test-list.h deleted file mode 100644 index 8ee74391af..0000000000 --- a/outside/libuv-v1.7.5/test/test-list.h +++ /dev/null @@ -1,722 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -TEST_DECLARE (platform_output) -TEST_DECLARE (callback_order) -TEST_DECLARE (close_order) -TEST_DECLARE (run_once) -TEST_DECLARE (run_nowait) -TEST_DECLARE (loop_alive) -TEST_DECLARE (loop_close) -TEST_DECLARE (loop_stop) -TEST_DECLARE (loop_update_time) -TEST_DECLARE (loop_backend_timeout) -TEST_DECLARE (loop_configure) -TEST_DECLARE (default_loop_close) -TEST_DECLARE (barrier_1) -TEST_DECLARE (barrier_2) -TEST_DECLARE (barrier_3) -TEST_DECLARE (condvar_1) -TEST_DECLARE (condvar_2) -TEST_DECLARE (condvar_3) -TEST_DECLARE (condvar_4) -TEST_DECLARE (condvar_5) -TEST_DECLARE (semaphore_1) -TEST_DECLARE (semaphore_2) -TEST_DECLARE (semaphore_3) -TEST_DECLARE (tty) -TEST_DECLARE (tty_file) -TEST_DECLARE (stdio_over_pipes) -TEST_DECLARE (ip6_pton) -TEST_DECLARE (ipc_listen_before_write) -TEST_DECLARE (ipc_listen_after_write) -#ifndef _WIN32 -TEST_DECLARE (ipc_send_recv_pipe) -#endif -TEST_DECLARE (ipc_send_recv_tcp) -TEST_DECLARE (ipc_tcp_connection) -TEST_DECLARE (tcp_ping_pong) -TEST_DECLARE (tcp_ping_pong_v6) -TEST_DECLARE (pipe_ping_pong) -TEST_DECLARE (delayed_accept) -TEST_DECLARE (multiple_listen) -#ifndef _WIN32 -TEST_DECLARE (tcp_write_after_connect) -#endif -TEST_DECLARE (tcp_writealot) -TEST_DECLARE (tcp_write_fail) -TEST_DECLARE (tcp_try_write) -TEST_DECLARE (tcp_write_queue_order) -TEST_DECLARE (tcp_open) -TEST_DECLARE (tcp_open_twice) -TEST_DECLARE (tcp_connect_error_after_write) -TEST_DECLARE (tcp_shutdown_after_write) -TEST_DECLARE (tcp_bind_error_addrinuse) -TEST_DECLARE (tcp_bind_error_addrnotavail_1) -TEST_DECLARE (tcp_bind_error_addrnotavail_2) -TEST_DECLARE (tcp_bind_error_fault) -TEST_DECLARE (tcp_bind_error_inval) -TEST_DECLARE (tcp_bind_localhost_ok) -TEST_DECLARE (tcp_bind_invalid_flags) -TEST_DECLARE (tcp_listen_without_bind) -TEST_DECLARE (tcp_connect_error_fault) -TEST_DECLARE (tcp_connect_timeout) -TEST_DECLARE (tcp_close_while_connecting) -TEST_DECLARE (tcp_close) -TEST_DECLARE (tcp_create_early) -TEST_DECLARE (tcp_create_early_bad_bind) -TEST_DECLARE (tcp_create_early_bad_domain) -TEST_DECLARE (tcp_create_early_accept) -#ifndef _WIN32 -TEST_DECLARE (tcp_close_accept) -TEST_DECLARE (tcp_oob) -#endif -TEST_DECLARE (tcp_flags) -TEST_DECLARE (tcp_write_to_half_open_connection) -TEST_DECLARE (tcp_unexpected_read) -TEST_DECLARE (tcp_read_stop) -TEST_DECLARE (tcp_bind6_error_addrinuse) -TEST_DECLARE (tcp_bind6_error_addrnotavail) -TEST_DECLARE (tcp_bind6_error_fault) -TEST_DECLARE (tcp_bind6_error_inval) -TEST_DECLARE (tcp_bind6_localhost_ok) -TEST_DECLARE (udp_bind) -TEST_DECLARE (udp_bind_reuseaddr) -TEST_DECLARE (udp_create_early) -TEST_DECLARE (udp_create_early_bad_bind) -TEST_DECLARE (udp_create_early_bad_domain) -TEST_DECLARE (udp_send_and_recv) -TEST_DECLARE (udp_send_immediate) -TEST_DECLARE (udp_send_unreachable) -TEST_DECLARE (udp_multicast_join) -TEST_DECLARE (udp_multicast_join6) -TEST_DECLARE (udp_multicast_ttl) -TEST_DECLARE (udp_multicast_interface) -TEST_DECLARE (udp_multicast_interface6) -TEST_DECLARE (udp_dgram_too_big) -TEST_DECLARE (udp_dual_stack) -TEST_DECLARE (udp_ipv6_only) -TEST_DECLARE (udp_options) -TEST_DECLARE (udp_options6) -TEST_DECLARE (udp_no_autobind) -TEST_DECLARE (udp_open) -TEST_DECLARE (udp_open_twice) -TEST_DECLARE (udp_try_send) -TEST_DECLARE (pipe_bind_error_addrinuse) -TEST_DECLARE (pipe_bind_error_addrnotavail) -TEST_DECLARE (pipe_bind_error_inval) -TEST_DECLARE (pipe_connect_multiple) -TEST_DECLARE (pipe_listen_without_bind) -TEST_DECLARE (pipe_connect_bad_name) -TEST_DECLARE (pipe_connect_to_file) -TEST_DECLARE (pipe_connect_on_prepare) -TEST_DECLARE (pipe_getsockname) -TEST_DECLARE (pipe_getsockname_abstract) -TEST_DECLARE (pipe_getsockname_blocking) -TEST_DECLARE (pipe_pending_instances) -TEST_DECLARE (pipe_sendmsg) -TEST_DECLARE (pipe_server_close) -TEST_DECLARE (connection_fail) -TEST_DECLARE (connection_fail_doesnt_auto_close) -TEST_DECLARE (shutdown_close_tcp) -TEST_DECLARE (shutdown_close_pipe) -TEST_DECLARE (shutdown_eof) -TEST_DECLARE (shutdown_twice) -TEST_DECLARE (callback_stack) -TEST_DECLARE (error_message) -TEST_DECLARE (timer) -TEST_DECLARE (timer_init) -TEST_DECLARE (timer_again) -TEST_DECLARE (timer_start_twice) -TEST_DECLARE (timer_order) -TEST_DECLARE (timer_huge_timeout) -TEST_DECLARE (timer_huge_repeat) -TEST_DECLARE (timer_run_once) -TEST_DECLARE (timer_from_check) -TEST_DECLARE (timer_null_callback) -TEST_DECLARE (idle_starvation) -TEST_DECLARE (loop_handles) -TEST_DECLARE (get_loadavg) -TEST_DECLARE (walk_handles) -TEST_DECLARE (watcher_cross_stop) -TEST_DECLARE (ref) -TEST_DECLARE (idle_ref) -TEST_DECLARE (async_ref) -TEST_DECLARE (prepare_ref) -TEST_DECLARE (check_ref) -TEST_DECLARE (unref_in_prepare_cb) -TEST_DECLARE (timer_ref) -TEST_DECLARE (timer_ref2) -TEST_DECLARE (fs_event_ref) -TEST_DECLARE (fs_poll_ref) -TEST_DECLARE (tcp_ref) -TEST_DECLARE (tcp_ref2) -TEST_DECLARE (tcp_ref2b) -TEST_DECLARE (tcp_ref3) -TEST_DECLARE (tcp_ref4) -TEST_DECLARE (udp_ref) -TEST_DECLARE (udp_ref2) -TEST_DECLARE (udp_ref3) -TEST_DECLARE (pipe_ref) -TEST_DECLARE (pipe_ref2) -TEST_DECLARE (pipe_ref3) -TEST_DECLARE (pipe_ref4) -#ifndef _WIN32 -TEST_DECLARE (pipe_close_stdout_read_stdin) -#endif -TEST_DECLARE (pipe_set_non_blocking) -TEST_DECLARE (process_ref) -TEST_DECLARE (has_ref) -TEST_DECLARE (active) -TEST_DECLARE (embed) -TEST_DECLARE (async) -TEST_DECLARE (async_null_cb) -TEST_DECLARE (get_currentexe) -TEST_DECLARE (process_title) -TEST_DECLARE (cwd_and_chdir) -TEST_DECLARE (get_memory) -TEST_DECLARE (handle_fileno) -TEST_DECLARE (homedir) -TEST_DECLARE (hrtime) -TEST_DECLARE (getaddrinfo_fail) -TEST_DECLARE (getaddrinfo_fail_sync) -TEST_DECLARE (getaddrinfo_basic) -TEST_DECLARE (getaddrinfo_basic_sync) -TEST_DECLARE (getaddrinfo_concurrent) -TEST_DECLARE (getnameinfo_basic_ip4) -TEST_DECLARE (getnameinfo_basic_ip4_sync) -TEST_DECLARE (getnameinfo_basic_ip6) -TEST_DECLARE (getsockname_tcp) -TEST_DECLARE (getsockname_udp) -TEST_DECLARE (fail_always) -TEST_DECLARE (pass_always) -TEST_DECLARE (socket_buffer_size) -TEST_DECLARE (spawn_fails) -#ifndef _WIN32 -TEST_DECLARE (spawn_fails_check_for_waitpid_cleanup) -#endif -TEST_DECLARE (spawn_exit_code) -TEST_DECLARE (spawn_stdout) -TEST_DECLARE (spawn_stdin) -TEST_DECLARE (spawn_stdio_greater_than_3) -TEST_DECLARE (spawn_ignored_stdio) -TEST_DECLARE (spawn_and_kill) -TEST_DECLARE (spawn_detached) -TEST_DECLARE (spawn_and_kill_with_std) -TEST_DECLARE (spawn_and_ping) -TEST_DECLARE (spawn_preserve_env) -TEST_DECLARE (spawn_setuid_fails) -TEST_DECLARE (spawn_setgid_fails) -TEST_DECLARE (spawn_stdout_to_file) -TEST_DECLARE (spawn_stdout_and_stderr_to_file) -TEST_DECLARE (spawn_stdout_and_stderr_to_file2) -TEST_DECLARE (spawn_stdout_and_stderr_to_file_swap) -TEST_DECLARE (spawn_auto_unref) -TEST_DECLARE (spawn_closed_process_io) -TEST_DECLARE (spawn_reads_child_path) -TEST_DECLARE (spawn_inherit_streams) -TEST_DECLARE (fs_poll) -TEST_DECLARE (fs_poll_getpath) -TEST_DECLARE (kill) -TEST_DECLARE (fs_file_noent) -TEST_DECLARE (fs_file_nametoolong) -TEST_DECLARE (fs_file_loop) -TEST_DECLARE (fs_file_async) -TEST_DECLARE (fs_file_sync) -TEST_DECLARE (fs_file_write_null_buffer) -TEST_DECLARE (fs_async_dir) -TEST_DECLARE (fs_async_sendfile) -TEST_DECLARE (fs_mkdtemp) -TEST_DECLARE (fs_fstat) -TEST_DECLARE (fs_access) -TEST_DECLARE (fs_chmod) -TEST_DECLARE (fs_unlink_readonly) -TEST_DECLARE (fs_chown) -TEST_DECLARE (fs_link) -TEST_DECLARE (fs_readlink) -TEST_DECLARE (fs_symlink) -TEST_DECLARE (fs_symlink_dir) -TEST_DECLARE (fs_utime) -TEST_DECLARE (fs_futime) -TEST_DECLARE (fs_file_open_append) -TEST_DECLARE (fs_stat_missing_path) -TEST_DECLARE (fs_read_file_eof) -TEST_DECLARE (fs_event_watch_dir) -TEST_DECLARE (fs_event_watch_dir_recursive) -TEST_DECLARE (fs_event_watch_file) -TEST_DECLARE (fs_event_watch_file_twice) -TEST_DECLARE (fs_event_watch_file_current_dir) -TEST_DECLARE (fs_event_no_callback_after_close) -TEST_DECLARE (fs_event_no_callback_on_close) -TEST_DECLARE (fs_event_immediate_close) -TEST_DECLARE (fs_event_close_with_pending_event) -TEST_DECLARE (fs_event_close_in_callback) -TEST_DECLARE (fs_event_start_and_close) -TEST_DECLARE (fs_event_error_reporting) -TEST_DECLARE (fs_event_getpath) -TEST_DECLARE (fs_scandir_empty_dir) -TEST_DECLARE (fs_scandir_file) -TEST_DECLARE (fs_open_dir) -TEST_DECLARE (fs_rename_to_existing_file) -TEST_DECLARE (fs_write_multiple_bufs) -TEST_DECLARE (fs_read_write_null_arguments) -TEST_DECLARE (fs_write_alotof_bufs) -TEST_DECLARE (fs_write_alotof_bufs_with_offset) -TEST_DECLARE (threadpool_queue_work_simple) -TEST_DECLARE (threadpool_queue_work_einval) -TEST_DECLARE (threadpool_multiple_event_loops) -TEST_DECLARE (threadpool_cancel_getaddrinfo) -TEST_DECLARE (threadpool_cancel_getnameinfo) -TEST_DECLARE (threadpool_cancel_work) -TEST_DECLARE (threadpool_cancel_fs) -TEST_DECLARE (threadpool_cancel_single) -TEST_DECLARE (thread_local_storage) -TEST_DECLARE (thread_mutex) -TEST_DECLARE (thread_rwlock) -TEST_DECLARE (thread_rwlock_trylock) -TEST_DECLARE (thread_create) -TEST_DECLARE (thread_equal) -TEST_DECLARE (dlerror) -TEST_DECLARE (poll_duplex) -TEST_DECLARE (poll_unidirectional) -TEST_DECLARE (poll_close) - -TEST_DECLARE (ip4_addr) -TEST_DECLARE (ip6_addr_link_local) - -#ifdef _WIN32 -TEST_DECLARE (poll_close_doesnt_corrupt_stack) -TEST_DECLARE (poll_closesocket) -TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows) -#if !defined(USING_UV_SHARED) -TEST_DECLARE (argument_escaping) -TEST_DECLARE (environment_creation) -#endif -TEST_DECLARE (listen_with_simultaneous_accepts) -TEST_DECLARE (listen_no_simultaneous_accepts) -TEST_DECLARE (fs_stat_root) -TEST_DECLARE (spawn_with_an_odd_path) -TEST_DECLARE (ipc_listen_after_bind_twice) -#else -TEST_DECLARE (emfile) -TEST_DECLARE (close_fd) -TEST_DECLARE (spawn_fs_open) -TEST_DECLARE (spawn_setuid_setgid) -TEST_DECLARE (we_get_signal) -TEST_DECLARE (we_get_signals) -TEST_DECLARE (signal_multiple_loops) -TEST_DECLARE (closed_fd_events) -#endif -#ifdef __APPLE__ -TEST_DECLARE (osx_select) -TEST_DECLARE (osx_select_many_fds) -#endif -HELPER_DECLARE (tcp4_echo_server) -HELPER_DECLARE (tcp6_echo_server) -HELPER_DECLARE (udp4_echo_server) -HELPER_DECLARE (pipe_echo_server) - - -TASK_LIST_START - TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000) - -#if 0 - TEST_ENTRY (callback_order) -#endif - TEST_ENTRY (close_order) - TEST_ENTRY (run_once) - TEST_ENTRY (run_nowait) - TEST_ENTRY (loop_alive) - TEST_ENTRY (loop_close) - TEST_ENTRY (loop_stop) - TEST_ENTRY (loop_update_time) - TEST_ENTRY (loop_backend_timeout) - TEST_ENTRY (loop_configure) - TEST_ENTRY (default_loop_close) - TEST_ENTRY (barrier_1) - TEST_ENTRY (barrier_2) - TEST_ENTRY (barrier_3) - TEST_ENTRY (condvar_1) - TEST_ENTRY (condvar_2) - TEST_ENTRY (condvar_3) - TEST_ENTRY (condvar_4) - TEST_ENTRY (condvar_5) - TEST_ENTRY (semaphore_1) - TEST_ENTRY (semaphore_2) - TEST_ENTRY (semaphore_3) - - TEST_ENTRY (pipe_connect_bad_name) - TEST_ENTRY (pipe_connect_to_file) - TEST_ENTRY (pipe_connect_on_prepare) - - TEST_ENTRY (pipe_server_close) -#ifndef _WIN32 - TEST_ENTRY (pipe_close_stdout_read_stdin) -#endif - TEST_ENTRY (pipe_set_non_blocking) - TEST_ENTRY (tty) - TEST_ENTRY (tty_file) - TEST_ENTRY (stdio_over_pipes) - TEST_ENTRY (ip6_pton) - TEST_ENTRY (ipc_listen_before_write) - TEST_ENTRY (ipc_listen_after_write) -#ifndef _WIN32 - TEST_ENTRY (ipc_send_recv_pipe) -#endif - TEST_ENTRY (ipc_send_recv_tcp) - TEST_ENTRY (ipc_tcp_connection) - - TEST_ENTRY (tcp_ping_pong) - TEST_HELPER (tcp_ping_pong, tcp4_echo_server) - - TEST_ENTRY (tcp_ping_pong_v6) - TEST_HELPER (tcp_ping_pong_v6, tcp6_echo_server) - - TEST_ENTRY (pipe_ping_pong) - TEST_HELPER (pipe_ping_pong, pipe_echo_server) - - TEST_ENTRY (delayed_accept) - TEST_ENTRY (multiple_listen) - -#ifndef _WIN32 - TEST_ENTRY (tcp_write_after_connect) -#endif - - TEST_ENTRY (tcp_writealot) - TEST_HELPER (tcp_writealot, tcp4_echo_server) - - TEST_ENTRY (tcp_write_fail) - TEST_HELPER (tcp_write_fail, tcp4_echo_server) - - TEST_ENTRY (tcp_try_write) - - TEST_ENTRY (tcp_write_queue_order) - - TEST_ENTRY (tcp_open) - TEST_HELPER (tcp_open, tcp4_echo_server) - TEST_ENTRY (tcp_open_twice) - - TEST_ENTRY (tcp_shutdown_after_write) - TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server) - - TEST_ENTRY (tcp_connect_error_after_write) - TEST_ENTRY (tcp_bind_error_addrinuse) - TEST_ENTRY (tcp_bind_error_addrnotavail_1) - TEST_ENTRY (tcp_bind_error_addrnotavail_2) - TEST_ENTRY (tcp_bind_error_fault) - TEST_ENTRY (tcp_bind_error_inval) - TEST_ENTRY (tcp_bind_localhost_ok) - TEST_ENTRY (tcp_bind_invalid_flags) - TEST_ENTRY (tcp_listen_without_bind) - TEST_ENTRY (tcp_connect_error_fault) - TEST_ENTRY (tcp_connect_timeout) - TEST_ENTRY (tcp_close_while_connecting) - TEST_ENTRY (tcp_close) - TEST_ENTRY (tcp_create_early) - TEST_ENTRY (tcp_create_early_bad_bind) - TEST_ENTRY (tcp_create_early_bad_domain) - TEST_ENTRY (tcp_create_early_accept) -#ifndef _WIN32 - TEST_ENTRY (tcp_close_accept) - TEST_ENTRY (tcp_oob) -#endif - TEST_ENTRY (tcp_flags) - TEST_ENTRY (tcp_write_to_half_open_connection) - TEST_ENTRY (tcp_unexpected_read) - - TEST_ENTRY (tcp_read_stop) - TEST_HELPER (tcp_read_stop, tcp4_echo_server) - - TEST_ENTRY (tcp_bind6_error_addrinuse) - TEST_ENTRY (tcp_bind6_error_addrnotavail) - TEST_ENTRY (tcp_bind6_error_fault) - TEST_ENTRY (tcp_bind6_error_inval) - TEST_ENTRY (tcp_bind6_localhost_ok) - - TEST_ENTRY (udp_bind) - TEST_ENTRY (udp_bind_reuseaddr) - TEST_ENTRY (udp_create_early) - TEST_ENTRY (udp_create_early_bad_bind) - TEST_ENTRY (udp_create_early_bad_domain) - TEST_ENTRY (udp_send_and_recv) - TEST_ENTRY (udp_send_immediate) - TEST_ENTRY (udp_send_unreachable) - TEST_ENTRY (udp_dgram_too_big) - TEST_ENTRY (udp_dual_stack) - TEST_ENTRY (udp_ipv6_only) - TEST_ENTRY (udp_options) - TEST_ENTRY (udp_options6) - TEST_ENTRY (udp_no_autobind) - TEST_ENTRY (udp_multicast_interface) - TEST_ENTRY (udp_multicast_interface6) - TEST_ENTRY (udp_multicast_join) - TEST_ENTRY (udp_multicast_join6) - TEST_ENTRY (udp_multicast_ttl) - TEST_ENTRY (udp_try_send) - - TEST_ENTRY (udp_open) - TEST_HELPER (udp_open, udp4_echo_server) - TEST_ENTRY (udp_open_twice) - - TEST_ENTRY (pipe_bind_error_addrinuse) - TEST_ENTRY (pipe_bind_error_addrnotavail) - TEST_ENTRY (pipe_bind_error_inval) - TEST_ENTRY (pipe_connect_multiple) - TEST_ENTRY (pipe_listen_without_bind) - TEST_ENTRY (pipe_getsockname) - TEST_ENTRY (pipe_getsockname_abstract) - TEST_ENTRY (pipe_getsockname_blocking) - TEST_ENTRY (pipe_pending_instances) - TEST_ENTRY (pipe_sendmsg) - - TEST_ENTRY (connection_fail) - TEST_ENTRY (connection_fail_doesnt_auto_close) - - TEST_ENTRY (shutdown_close_tcp) - TEST_HELPER (shutdown_close_tcp, tcp4_echo_server) - TEST_ENTRY (shutdown_close_pipe) - TEST_HELPER (shutdown_close_pipe, pipe_echo_server) - - TEST_ENTRY (shutdown_eof) - TEST_HELPER (shutdown_eof, tcp4_echo_server) - - TEST_ENTRY (shutdown_twice) - TEST_HELPER (shutdown_twice, tcp4_echo_server) - - TEST_ENTRY (callback_stack) - TEST_HELPER (callback_stack, tcp4_echo_server) - - TEST_ENTRY (error_message) - - TEST_ENTRY (timer) - TEST_ENTRY (timer_init) - TEST_ENTRY (timer_again) - TEST_ENTRY (timer_start_twice) - TEST_ENTRY (timer_order) - TEST_ENTRY (timer_huge_timeout) - TEST_ENTRY (timer_huge_repeat) - TEST_ENTRY (timer_run_once) - TEST_ENTRY (timer_from_check) - TEST_ENTRY (timer_null_callback) - - TEST_ENTRY (idle_starvation) - - TEST_ENTRY (ref) - TEST_ENTRY (idle_ref) - TEST_ENTRY (fs_poll_ref) - TEST_ENTRY (async_ref) - TEST_ENTRY (prepare_ref) - TEST_ENTRY (check_ref) - TEST_ENTRY (unref_in_prepare_cb) - TEST_ENTRY (timer_ref) - TEST_ENTRY (timer_ref2) - TEST_ENTRY (fs_event_ref) - TEST_ENTRY (tcp_ref) - TEST_ENTRY (tcp_ref2) - TEST_ENTRY (tcp_ref2b) - TEST_ENTRY (tcp_ref3) - TEST_HELPER (tcp_ref3, tcp4_echo_server) - TEST_ENTRY (tcp_ref4) - TEST_HELPER (tcp_ref4, tcp4_echo_server) - TEST_ENTRY (udp_ref) - TEST_ENTRY (udp_ref2) - TEST_ENTRY (udp_ref3) - TEST_HELPER (udp_ref3, udp4_echo_server) - TEST_ENTRY (pipe_ref) - TEST_ENTRY (pipe_ref2) - TEST_ENTRY (pipe_ref3) - TEST_HELPER (pipe_ref3, pipe_echo_server) - TEST_ENTRY (pipe_ref4) - TEST_HELPER (pipe_ref4, pipe_echo_server) - TEST_ENTRY (process_ref) - TEST_ENTRY (has_ref) - - TEST_ENTRY (loop_handles) - TEST_ENTRY (walk_handles) - - TEST_ENTRY (watcher_cross_stop) - - TEST_ENTRY (active) - - TEST_ENTRY (embed) - - TEST_ENTRY (async) - TEST_ENTRY (async_null_cb) - - TEST_ENTRY (get_currentexe) - - TEST_ENTRY (process_title) - - TEST_ENTRY (cwd_and_chdir) - - TEST_ENTRY (get_memory) - - TEST_ENTRY (get_loadavg) - - TEST_ENTRY (handle_fileno) - - TEST_ENTRY (homedir) - - TEST_ENTRY (hrtime) - - TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000) - TEST_ENTRY (getaddrinfo_fail_sync) - - TEST_ENTRY (getaddrinfo_basic) - TEST_ENTRY (getaddrinfo_basic_sync) - TEST_ENTRY (getaddrinfo_concurrent) - - TEST_ENTRY (getnameinfo_basic_ip4) - TEST_ENTRY (getnameinfo_basic_ip4_sync) - TEST_ENTRY (getnameinfo_basic_ip6) - - TEST_ENTRY (getsockname_tcp) - TEST_ENTRY (getsockname_udp) - - TEST_ENTRY (poll_duplex) - TEST_ENTRY (poll_unidirectional) - TEST_ENTRY (poll_close) - - TEST_ENTRY (socket_buffer_size) - - TEST_ENTRY (spawn_fails) -#ifndef _WIN32 - TEST_ENTRY (spawn_fails_check_for_waitpid_cleanup) -#endif - TEST_ENTRY (spawn_exit_code) - TEST_ENTRY (spawn_stdout) - TEST_ENTRY (spawn_stdin) - TEST_ENTRY (spawn_stdio_greater_than_3) - TEST_ENTRY (spawn_ignored_stdio) - TEST_ENTRY (spawn_and_kill) - TEST_ENTRY (spawn_detached) - TEST_ENTRY (spawn_and_kill_with_std) - TEST_ENTRY (spawn_and_ping) - TEST_ENTRY (spawn_preserve_env) - TEST_ENTRY (spawn_setuid_fails) - TEST_ENTRY (spawn_setgid_fails) - TEST_ENTRY (spawn_stdout_to_file) - TEST_ENTRY (spawn_stdout_and_stderr_to_file) - TEST_ENTRY (spawn_stdout_and_stderr_to_file2) - TEST_ENTRY (spawn_stdout_and_stderr_to_file_swap) - TEST_ENTRY (spawn_auto_unref) - TEST_ENTRY (spawn_closed_process_io) - TEST_ENTRY (spawn_reads_child_path) - TEST_ENTRY (spawn_inherit_streams) - TEST_ENTRY (fs_poll) - TEST_ENTRY (fs_poll_getpath) - TEST_ENTRY (kill) - -#ifdef _WIN32 - TEST_ENTRY (poll_close_doesnt_corrupt_stack) - TEST_ENTRY (poll_closesocket) - TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows) -#if !defined(USING_UV_SHARED) - TEST_ENTRY (argument_escaping) - TEST_ENTRY (environment_creation) -# endif - TEST_ENTRY (listen_with_simultaneous_accepts) - TEST_ENTRY (listen_no_simultaneous_accepts) - TEST_ENTRY (fs_stat_root) - TEST_ENTRY (spawn_with_an_odd_path) - TEST_ENTRY (ipc_listen_after_bind_twice) -#else - TEST_ENTRY (emfile) - TEST_ENTRY (close_fd) - TEST_ENTRY (spawn_fs_open) - TEST_ENTRY (spawn_setuid_setgid) - TEST_ENTRY (we_get_signal) - TEST_ENTRY (we_get_signals) - TEST_ENTRY (signal_multiple_loops) - TEST_ENTRY (closed_fd_events) -#endif - -#ifdef __APPLE__ - TEST_ENTRY (osx_select) - TEST_ENTRY (osx_select_many_fds) -#endif - - TEST_ENTRY (fs_file_noent) - TEST_ENTRY (fs_file_nametoolong) - TEST_ENTRY (fs_file_loop) - TEST_ENTRY (fs_file_async) - TEST_ENTRY (fs_file_sync) - TEST_ENTRY (fs_file_write_null_buffer) - TEST_ENTRY (fs_async_dir) - TEST_ENTRY (fs_async_sendfile) - TEST_ENTRY (fs_mkdtemp) - TEST_ENTRY (fs_fstat) - TEST_ENTRY (fs_access) - TEST_ENTRY (fs_chmod) - TEST_ENTRY (fs_unlink_readonly) - TEST_ENTRY (fs_chown) - TEST_ENTRY (fs_utime) - TEST_ENTRY (fs_futime) - TEST_ENTRY (fs_readlink) - TEST_ENTRY (fs_symlink) - TEST_ENTRY (fs_symlink_dir) - TEST_ENTRY (fs_stat_missing_path) - TEST_ENTRY (fs_read_file_eof) - TEST_ENTRY (fs_file_open_append) - TEST_ENTRY (fs_event_watch_dir) - TEST_ENTRY (fs_event_watch_dir_recursive) - TEST_ENTRY (fs_event_watch_file) - TEST_ENTRY (fs_event_watch_file_twice) - TEST_ENTRY (fs_event_watch_file_current_dir) - TEST_ENTRY (fs_event_no_callback_after_close) - TEST_ENTRY (fs_event_no_callback_on_close) - TEST_ENTRY (fs_event_immediate_close) - TEST_ENTRY (fs_event_close_with_pending_event) - TEST_ENTRY (fs_event_close_in_callback) - TEST_ENTRY (fs_event_start_and_close) - TEST_ENTRY (fs_event_error_reporting) - TEST_ENTRY (fs_event_getpath) - TEST_ENTRY (fs_scandir_empty_dir) - TEST_ENTRY (fs_scandir_file) - TEST_ENTRY (fs_open_dir) - TEST_ENTRY (fs_rename_to_existing_file) - TEST_ENTRY (fs_write_multiple_bufs) - TEST_ENTRY (fs_write_alotof_bufs) - TEST_ENTRY (fs_write_alotof_bufs_with_offset) - TEST_ENTRY (fs_read_write_null_arguments) - TEST_ENTRY (threadpool_queue_work_simple) - TEST_ENTRY (threadpool_queue_work_einval) - TEST_ENTRY (threadpool_multiple_event_loops) - TEST_ENTRY (threadpool_cancel_getaddrinfo) - TEST_ENTRY (threadpool_cancel_getnameinfo) - TEST_ENTRY (threadpool_cancel_work) - TEST_ENTRY (threadpool_cancel_fs) - TEST_ENTRY (threadpool_cancel_single) - TEST_ENTRY (thread_local_storage) - TEST_ENTRY (thread_mutex) - TEST_ENTRY (thread_rwlock) - TEST_ENTRY (thread_rwlock_trylock) - TEST_ENTRY (thread_create) - TEST_ENTRY (thread_equal) - TEST_ENTRY (dlerror) - TEST_ENTRY (ip4_addr) - TEST_ENTRY (ip6_addr_link_local) -#if 0 - /* These are for testing the test runner. */ - TEST_ENTRY (fail_always) - TEST_ENTRY (pass_always) -#endif -TASK_LIST_END diff --git a/outside/libuv-v1.7.5/test/test-loop-alive.c b/outside/libuv-v1.7.5/test/test-loop-alive.c deleted file mode 100644 index cf4d301930..0000000000 --- a/outside/libuv-v1.7.5/test/test-loop-alive.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_timer_t timer_handle; - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle); -} - - -static uv_work_t work_req; - -static void work_cb(uv_work_t* req) { - ASSERT(req); -} - -static void after_work_cb(uv_work_t* req, int status) { - ASSERT(req); - ASSERT(status == 0); -} - - -TEST_IMPL(loop_alive) { - int r; - ASSERT(!uv_loop_alive(uv_default_loop())); - - /* loops with handles are alive */ - uv_timer_init(uv_default_loop(), &timer_handle); - uv_timer_start(&timer_handle, timer_cb, 100, 0); - ASSERT(uv_loop_alive(uv_default_loop())); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - ASSERT(!uv_loop_alive(uv_default_loop())); - - /* loops with requests are alive */ - r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb); - ASSERT(r == 0); - ASSERT(uv_loop_alive(uv_default_loop())); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - ASSERT(!uv_loop_alive(uv_default_loop())); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-loop-close.c b/outside/libuv-v1.7.5/test/test-loop-close.c deleted file mode 100644 index 5aec234ed0..0000000000 --- a/outside/libuv-v1.7.5/test/test-loop-close.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_timer_t timer_handle; - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle); - uv_stop(handle->loop); -} - - -TEST_IMPL(loop_close) { - int r; - uv_loop_t loop; - - ASSERT(0 == uv_loop_init(&loop)); - - uv_timer_init(&loop, &timer_handle); - uv_timer_start(&timer_handle, timer_cb, 100, 100); - - ASSERT(UV_EBUSY == uv_loop_close(&loop)); - - uv_run(&loop, UV_RUN_DEFAULT); - - uv_close((uv_handle_t*) &timer_handle, NULL); - r = uv_run(&loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(0 == uv_loop_close(&loop)); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-loop-configure.c b/outside/libuv-v1.7.5/test/test-loop-configure.c deleted file mode 100644 index d057c1ed8a..0000000000 --- a/outside/libuv-v1.7.5/test/test-loop-configure.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2014, Ben Noordhuis - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static void timer_cb(uv_timer_t* handle) { - uv_close((uv_handle_t*) handle, NULL); -} - - -TEST_IMPL(loop_configure) { - uv_timer_t timer_handle; - uv_loop_t loop; - ASSERT(0 == uv_loop_init(&loop)); -#ifdef _WIN32 - ASSERT(UV_ENOSYS == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, 0)); -#else - ASSERT(0 == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF)); -#endif - ASSERT(0 == uv_timer_init(&loop, &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 10, 0)); - ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); - ASSERT(0 == uv_loop_close(&loop)); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-loop-handles.c b/outside/libuv-v1.7.5/test/test-loop-handles.c deleted file mode 100644 index c3e8498ae9..0000000000 --- a/outside/libuv-v1.7.5/test/test-loop-handles.c +++ /dev/null @@ -1,337 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* Tests commented out with XXX are ones that are failing on Linux */ - -/* - * Purpose of this test is to check semantics of starting and stopping - * prepare, check and idle watchers. - * - * - A watcher must be able to safely stop or close itself; - * - Once a watcher is stopped or closed its callback should never be called. - * - If a watcher is closed, it is implicitly stopped and its close_cb should - * be called exactly once. - * - A watcher can safely start and stop other watchers of the same type. - * - Prepare and check watchers are called once per event loop iterations. - * - All active idle watchers are queued when the event loop has no more work - * to do. This is done repeatedly until all idle watchers are inactive. - * - If a watcher starts another watcher of the same type its callback is not - * immediately queued. For check and prepare watchers, that means that if - * a watcher makes another of the same type active, it'll not be called until - * the next event loop iteration. For idle. watchers this means that the - * newly activated idle watcher might not be queued immediately. - * - Prepare, check, idle watchers keep the event loop alive even when they're - * not active. - * - * This is what the test globally does: - * - * - prepare_1 is always active and counts event loop iterations. It also - * creates and starts prepare_2 every other iteration. Finally it verifies - * that no idle watchers are active before polling. - * - prepare_2 is started by prepare_1 every other iteration. It immediately - * stops itself. It verifies that a watcher is not queued immediately - * if created by another watcher of the same type. - * - There's a check watcher that stops the event loop after a certain number - * of iterations. It starts a varying number of idle_1 watchers. - * - Idle_1 watchers stop themselves after being called a few times. All idle_1 - * watchers try to start the idle_2 watcher if it is not already started or - * awaiting its close callback. - * - The idle_2 watcher always exists but immediately closes itself after - * being started by a check_1 watcher. It verifies that a watcher is - * implicitly stopped when closed, and that a watcher can close itself - * safely. - * - There is a repeating timer. It does not keep the event loop alive - * (ev_unref) but makes sure that the loop keeps polling the system for - * events. - */ - - -#include "uv.h" -#include "task.h" - -#include - - -#define IDLE_COUNT 7 -#define ITERATIONS 21 -#define TIMEOUT 100 - - -static uv_prepare_t prepare_1_handle; -static uv_prepare_t prepare_2_handle; - -static uv_check_t check_handle; - -static uv_idle_t idle_1_handles[IDLE_COUNT]; -static uv_idle_t idle_2_handle; - -static uv_timer_t timer_handle; - - -static int loop_iteration = 0; - -static int prepare_1_cb_called = 0; -static int prepare_1_close_cb_called = 0; - -static int prepare_2_cb_called = 0; -static int prepare_2_close_cb_called = 0; - -static int check_cb_called = 0; -static int check_close_cb_called = 0; - -static int idle_1_cb_called = 0; -static int idle_1_close_cb_called = 0; -static int idles_1_active = 0; - -static int idle_2_cb_called = 0; -static int idle_2_close_cb_called = 0; -static int idle_2_cb_started = 0; -static int idle_2_is_active = 0; - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer_handle); -} - - -static void idle_2_close_cb(uv_handle_t* handle) { - fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n"); - fflush(stderr); - - ASSERT(handle == (uv_handle_t*)&idle_2_handle); - - ASSERT(idle_2_is_active); - - idle_2_close_cb_called++; - idle_2_is_active = 0; -} - - -static void idle_2_cb(uv_idle_t* handle) { - fprintf(stderr, "%s", "IDLE_2_CB\n"); - fflush(stderr); - - ASSERT(handle == &idle_2_handle); - - idle_2_cb_called++; - - uv_close((uv_handle_t*)handle, idle_2_close_cb); -} - - -static void idle_1_cb(uv_idle_t* handle) { - int r; - - fprintf(stderr, "%s", "IDLE_1_CB\n"); - fflush(stderr); - - ASSERT(handle != NULL); - ASSERT(idles_1_active > 0); - - /* Init idle_2 and make it active */ - if (!idle_2_is_active && !uv_is_closing((uv_handle_t*)&idle_2_handle)) { - r = uv_idle_init(uv_default_loop(), &idle_2_handle); - ASSERT(r == 0); - r = uv_idle_start(&idle_2_handle, idle_2_cb); - ASSERT(r == 0); - idle_2_is_active = 1; - idle_2_cb_started++; - } - - idle_1_cb_called++; - - if (idle_1_cb_called % 5 == 0) { - r = uv_idle_stop((uv_idle_t*)handle); - ASSERT(r == 0); - idles_1_active--; - } -} - - -static void idle_1_close_cb(uv_handle_t* handle) { - fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n"); - fflush(stderr); - - ASSERT(handle != NULL); - - idle_1_close_cb_called++; -} - - -static void prepare_1_close_cb(uv_handle_t* handle) { - fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB"); - fflush(stderr); - ASSERT(handle == (uv_handle_t*)&prepare_1_handle); - - prepare_1_close_cb_called++; -} - - -static void check_close_cb(uv_handle_t* handle) { - fprintf(stderr, "%s", "CHECK_CLOSE_CB\n"); - fflush(stderr); - ASSERT(handle == (uv_handle_t*)&check_handle); - - check_close_cb_called++; -} - - -static void prepare_2_close_cb(uv_handle_t* handle) { - fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n"); - fflush(stderr); - ASSERT(handle == (uv_handle_t*)&prepare_2_handle); - - prepare_2_close_cb_called++; -} - - -static void check_cb(uv_check_t* handle) { - int i, r; - - fprintf(stderr, "%s", "CHECK_CB\n"); - fflush(stderr); - ASSERT(handle == &check_handle); - - if (loop_iteration < ITERATIONS) { - /* Make some idle watchers active */ - for (i = 0; i < 1 + (loop_iteration % IDLE_COUNT); i++) { - r = uv_idle_start(&idle_1_handles[i], idle_1_cb); - ASSERT(r == 0); - idles_1_active++; - } - - } else { - /* End of the test - close all handles */ - uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb); - uv_close((uv_handle_t*)&check_handle, check_close_cb); - uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb); - - for (i = 0; i < IDLE_COUNT; i++) { - uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb); - } - - /* This handle is closed/recreated every time, close it only if it is */ - /* active.*/ - if (idle_2_is_active) { - uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb); - } - } - - check_cb_called++; -} - - -static void prepare_2_cb(uv_prepare_t* handle) { - int r; - - fprintf(stderr, "%s", "PREPARE_2_CB\n"); - fflush(stderr); - ASSERT(handle == &prepare_2_handle); - - /* prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), */ - /* and it stops itself immediately. A started watcher is not queued */ - /* until the next round, so when this callback is made */ - /* (loop_iteration % 2 == 0) cannot be true. */ - ASSERT(loop_iteration % 2 != 0); - - r = uv_prepare_stop((uv_prepare_t*)handle); - ASSERT(r == 0); - - prepare_2_cb_called++; -} - - -static void prepare_1_cb(uv_prepare_t* handle) { - int r; - - fprintf(stderr, "%s", "PREPARE_1_CB\n"); - fflush(stderr); - ASSERT(handle == &prepare_1_handle); - - if (loop_iteration % 2 == 0) { - r = uv_prepare_start(&prepare_2_handle, prepare_2_cb); - ASSERT(r == 0); - } - - prepare_1_cb_called++; - loop_iteration++; - - printf("Loop iteration %d of %d.\n", loop_iteration, ITERATIONS); -} - - -TEST_IMPL(loop_handles) { - int i; - int r; - - r = uv_prepare_init(uv_default_loop(), &prepare_1_handle); - ASSERT(r == 0); - r = uv_prepare_start(&prepare_1_handle, prepare_1_cb); - ASSERT(r == 0); - - r = uv_check_init(uv_default_loop(), &check_handle); - ASSERT(r == 0); - r = uv_check_start(&check_handle, check_cb); - ASSERT(r == 0); - - /* initialize only, prepare_2 is started by prepare_1_cb */ - r = uv_prepare_init(uv_default_loop(), &prepare_2_handle); - ASSERT(r == 0); - - for (i = 0; i < IDLE_COUNT; i++) { - /* initialize only, idle_1 handles are started by check_cb */ - r = uv_idle_init(uv_default_loop(), &idle_1_handles[i]); - ASSERT(r == 0); - } - - /* don't init or start idle_2, both is done by idle_1_cb */ - - /* the timer callback is there to keep the event loop polling */ - /* unref it as it is not supposed to keep the loop alive */ - r = uv_timer_init(uv_default_loop(), &timer_handle); - ASSERT(r == 0); - r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT); - ASSERT(r == 0); - uv_unref((uv_handle_t*)&timer_handle); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(loop_iteration == ITERATIONS); - - ASSERT(prepare_1_cb_called == ITERATIONS); - ASSERT(prepare_1_close_cb_called == 1); - - ASSERT(prepare_2_cb_called == floor(ITERATIONS / 2.0)); - ASSERT(prepare_2_close_cb_called == 1); - - ASSERT(check_cb_called == ITERATIONS); - ASSERT(check_close_cb_called == 1); - - /* idle_1_cb should be called a lot */ - ASSERT(idle_1_close_cb_called == IDLE_COUNT); - - ASSERT(idle_2_close_cb_called == idle_2_cb_started); - ASSERT(idle_2_is_active == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-loop-stop.c b/outside/libuv-v1.7.5/test/test-loop-stop.c deleted file mode 100644 index 14b8c11186..0000000000 --- a/outside/libuv-v1.7.5/test/test-loop-stop.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_prepare_t prepare_handle; -static uv_timer_t timer_handle; -static int prepare_called = 0; -static int timer_called = 0; -static int num_ticks = 10; - - -static void prepare_cb(uv_prepare_t* handle) { - ASSERT(handle == &prepare_handle); - prepare_called++; - if (prepare_called == num_ticks) - uv_prepare_stop(handle); -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer_handle); - timer_called++; - if (timer_called == 1) - uv_stop(uv_default_loop()); - else if (timer_called == num_ticks) - uv_timer_stop(handle); -} - - -TEST_IMPL(loop_stop) { - int r; - uv_prepare_init(uv_default_loop(), &prepare_handle); - uv_prepare_start(&prepare_handle, prepare_cb); - uv_timer_init(uv_default_loop(), &timer_handle); - uv_timer_start(&timer_handle, timer_cb, 100, 100); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r != 0); - ASSERT(timer_called == 1); - - r = uv_run(uv_default_loop(), UV_RUN_NOWAIT); - ASSERT(r != 0); - ASSERT(prepare_called > 1); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - ASSERT(timer_called == 10); - ASSERT(prepare_called == 10); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-loop-time.c b/outside/libuv-v1.7.5/test/test-loop-time.c deleted file mode 100644 index a2db42ccee..0000000000 --- a/outside/libuv-v1.7.5/test/test-loop-time.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -TEST_IMPL(loop_update_time) { - uint64_t start; - - start = uv_now(uv_default_loop()); - while (uv_now(uv_default_loop()) - start < 1000) - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -static void cb(uv_timer_t* timer) { - uv_close((uv_handle_t*)timer, NULL); -} - -TEST_IMPL(loop_backend_timeout) { - uv_loop_t *loop = uv_default_loop(); - uv_timer_t timer; - int r; - - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - - ASSERT(!uv_loop_alive(loop)); - ASSERT(uv_backend_timeout(loop) == 0); - - r = uv_timer_start(&timer, cb, 1000, 0); /* 1 sec */ - ASSERT(r == 0); - ASSERT(uv_backend_timeout(loop) > 100); /* 0.1 sec */ - ASSERT(uv_backend_timeout(loop) <= 1000); /* 1 sec */ - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - ASSERT(uv_backend_timeout(loop) == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-multiple-listen.c b/outside/libuv-v1.7.5/test/test-multiple-listen.c deleted file mode 100644 index 4ae5fa67b3..0000000000 --- a/outside/libuv-v1.7.5/test/test-multiple-listen.c +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - -static int connection_cb_called = 0; -static int close_cb_called = 0; -static int connect_cb_called = 0; -static uv_tcp_t server; -static uv_tcp_t client; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void connection_cb(uv_stream_t* tcp, int status) { - ASSERT(status == 0); - uv_close((uv_handle_t*)&server, close_cb); - connection_cb_called++; -} - - -static void start_server(void) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server, 128, connection_cb); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server, 128, connection_cb); - ASSERT(r == 0); -} - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - free(req); - uv_close((uv_handle_t*)&client, close_cb); - connect_cb_called++; -} - - -static void client_connect(void) { - struct sockaddr_in addr; - uv_connect_t* connect_req = malloc(sizeof *connect_req); - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(connect_req != NULL); - - r = uv_tcp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_tcp_connect(connect_req, - &client, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); -} - - - -TEST_IMPL(multiple_listen) { - start_server(); - - client_connect(); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(connection_cb_called == 1); - ASSERT(connect_cb_called == 1); - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-mutexes.c b/outside/libuv-v1.7.5/test/test-mutexes.c deleted file mode 100644 index 4aeac73b4c..0000000000 --- a/outside/libuv-v1.7.5/test/test-mutexes.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -/* The mutex and rwlock tests are really poor. - * They're very basic sanity checks and nothing more. - * Apologies if that rhymes. - */ - -TEST_IMPL(thread_mutex) { - uv_mutex_t mutex; - int r; - - r = uv_mutex_init(&mutex); - ASSERT(r == 0); - - uv_mutex_lock(&mutex); - uv_mutex_unlock(&mutex); - uv_mutex_destroy(&mutex); - - return 0; -} - - -TEST_IMPL(thread_rwlock) { - uv_rwlock_t rwlock; - int r; - - r = uv_rwlock_init(&rwlock); - ASSERT(r == 0); - - uv_rwlock_rdlock(&rwlock); - uv_rwlock_rdunlock(&rwlock); - uv_rwlock_wrlock(&rwlock); - uv_rwlock_wrunlock(&rwlock); - uv_rwlock_destroy(&rwlock); - - return 0; -} - - -TEST_IMPL(thread_rwlock_trylock) { - uv_rwlock_t rwlock; - int r; - - r = uv_rwlock_init(&rwlock); - ASSERT(r == 0); - - /* No locks held. */ - - r = uv_rwlock_trywrlock(&rwlock); - ASSERT(r == 0); - - /* Write lock held. */ - - r = uv_rwlock_tryrdlock(&rwlock); - ASSERT(r == UV_EBUSY); - r = uv_rwlock_trywrlock(&rwlock); - ASSERT(r == UV_EBUSY); - - uv_rwlock_wrunlock(&rwlock); - - /* No locks held. */ - - r = uv_rwlock_tryrdlock(&rwlock); - ASSERT(r == 0); - - /* One read lock held. */ - - r = uv_rwlock_tryrdlock(&rwlock); - ASSERT(r == 0); - - /* Two read locks held. */ - - r = uv_rwlock_trywrlock(&rwlock); - ASSERT(r == UV_EBUSY); - - uv_rwlock_rdunlock(&rwlock); - - /* One read lock held. */ - - uv_rwlock_rdunlock(&rwlock); - - /* No read locks held. */ - - r = uv_rwlock_trywrlock(&rwlock); - ASSERT(r == 0); - - /* Write lock held. */ - - uv_rwlock_wrunlock(&rwlock); - - /* No locks held. */ - - uv_rwlock_destroy(&rwlock); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-osx-select.c b/outside/libuv-v1.7.5/test/test-osx-select.c deleted file mode 100644 index a0afda9181..0000000000 --- a/outside/libuv-v1.7.5/test/test-osx-select.c +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#ifdef __APPLE__ - -#include -#include - -static int read_count; - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - static char slab[1024]; - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { - fprintf(stdout, "got data %d\n", ++read_count); - fflush(stdout); - - if (read_count == 3) - uv_close((uv_handle_t*) stream, NULL); -} - - -TEST_IMPL(osx_select) { - int r; - int fd; - size_t i; - size_t len; - const char* str; - uv_tty_t tty; - - fd = open("/dev/tty", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno)); - fflush(stderr); - return TEST_SKIP; - } - - r = uv_tty_init(uv_default_loop(), &tty, fd, 1); - ASSERT(r == 0); - - uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb); - - /* Emulate user-input */ - str = "got some input\n" - "with a couple of lines\n" - "feel pretty happy\n"; - for (i = 0, len = strlen(str); i < len; i++) { - r = ioctl(fd, TIOCSTI, str + i); - ASSERT(r == 0); - } - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(read_count == 3); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(osx_select_many_fds) { - int r; - int fd; - size_t i; - size_t len; - const char* str; - struct sockaddr_in addr; - uv_tty_t tty; - uv_tcp_t tcps[1500]; - - TEST_FILE_LIMIT(ARRAY_SIZE(tcps) + 100); - - r = uv_ip4_addr("127.0.0.1", 0, &addr); - ASSERT(r == 0); - - for (i = 0; i < ARRAY_SIZE(tcps); i++) { - r = uv_tcp_init(uv_default_loop(), &tcps[i]); - ASSERT(r == 0); - r = uv_tcp_bind(&tcps[i], (const struct sockaddr *) &addr, 0); - ASSERT(r == 0); - uv_unref((uv_handle_t*) &tcps[i]); - } - - fd = open("/dev/tty", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno)); - fflush(stderr); - return TEST_SKIP; - } - - r = uv_tty_init(uv_default_loop(), &tty, fd, 1); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb); - ASSERT(r == 0); - - /* Emulate user-input */ - str = "got some input\n" - "with a couple of lines\n" - "feel pretty happy\n"; - for (i = 0, len = strlen(str); i < len; i++) { - r = ioctl(fd, TIOCSTI, str + i); - ASSERT(r == 0); - } - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(read_count == 3); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* __APPLE__ */ diff --git a/outside/libuv-v1.7.5/test/test-pass-always.c b/outside/libuv-v1.7.5/test/test-pass-always.c deleted file mode 100644 index 4fb58ff94b..0000000000 --- a/outside/libuv-v1.7.5/test/test-pass-always.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "task.h" - - -TEST_IMPL(pass_always) { - /* This test always passes. It is used to test the test runner. */ - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-ping-pong.c b/outside/libuv-v1.7.5/test/test-ping-pong.c deleted file mode 100644 index c074178541..0000000000 --- a/outside/libuv-v1.7.5/test/test-ping-pong.c +++ /dev/null @@ -1,270 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -static int completed_pingers = 0; - -#define NUM_PINGS 1000 - -/* 64 bytes is enough for a pinger */ -#define BUFSIZE 10240 - -static char PING[] = "PING\n"; -static int pinger_on_connect_count; - - -typedef struct { - int pongs; - int state; - union { - uv_tcp_t tcp; - uv_pipe_t pipe; - } stream; - uv_connect_t connect_req; - char read_buffer[BUFSIZE]; -} pinger_t; - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf->base = malloc(size); - buf->len = size; -} - - -static void pinger_on_close(uv_handle_t* handle) { - pinger_t* pinger = (pinger_t*)handle->data; - - ASSERT(NUM_PINGS == pinger->pongs); - - free(pinger); - - completed_pingers++; -} - - -static void pinger_after_write(uv_write_t *req, int status) { - ASSERT(status == 0); - free(req); -} - - -static void pinger_write_ping(pinger_t* pinger) { - uv_write_t *req; - uv_buf_t buf; - - buf = uv_buf_init(PING, sizeof(PING) - 1); - - req = malloc(sizeof(*req)); - if (uv_write(req, - (uv_stream_t*) &pinger->stream.tcp, - &buf, - 1, - pinger_after_write)) { - FATAL("uv_write failed"); - } - - puts("PING"); -} - - -static void pinger_read_cb(uv_stream_t* stream, - ssize_t nread, - const uv_buf_t* buf) { - ssize_t i; - pinger_t* pinger; - - pinger = (pinger_t*)stream->data; - - if (nread < 0) { - ASSERT(nread == UV_EOF); - - puts("got EOF"); - free(buf->base); - - uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close); - - return; - } - - /* Now we count the pings */ - for (i = 0; i < nread; i++) { - ASSERT(buf->base[i] == PING[pinger->state]); - pinger->state = (pinger->state + 1) % (sizeof(PING) - 1); - - if (pinger->state != 0) - continue; - - printf("PONG %d\n", pinger->pongs); - pinger->pongs++; - - if (pinger->pongs < NUM_PINGS) { - pinger_write_ping(pinger); - } else { - uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close); - break; - } - } - - free(buf->base); -} - - -static void pinger_on_connect(uv_connect_t *req, int status) { - pinger_t *pinger = (pinger_t*)req->handle->data; - - pinger_on_connect_count++; - - ASSERT(status == 0); - - ASSERT(1 == uv_is_readable(req->handle)); - ASSERT(1 == uv_is_writable(req->handle)); - ASSERT(0 == uv_is_closing((uv_handle_t *) req->handle)); - - pinger_write_ping(pinger); - - uv_read_start((uv_stream_t*)(req->handle), alloc_cb, pinger_read_cb); -} - - -/* same ping-pong test, but using IPv6 connection */ -static void tcp_pinger_v6_new(void) { - int r; - struct sockaddr_in6 server_addr; - pinger_t *pinger; - - - ASSERT(0 ==uv_ip6_addr("::1", TEST_PORT, &server_addr)); - pinger = malloc(sizeof(*pinger)); - ASSERT(pinger != NULL); - pinger->state = 0; - pinger->pongs = 0; - - /* Try to connect to the server and do NUM_PINGS ping-pongs. */ - r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp); - pinger->stream.tcp.data = pinger; - ASSERT(!r); - - /* We are never doing multiple reads/connects at a time anyway. */ - /* so these handles can be pre-initialized. */ - r = uv_tcp_connect(&pinger->connect_req, - &pinger->stream.tcp, - (const struct sockaddr*) &server_addr, - pinger_on_connect); - ASSERT(!r); - - /* Synchronous connect callbacks are not allowed. */ - ASSERT(pinger_on_connect_count == 0); -} - - -static void tcp_pinger_new(void) { - int r; - struct sockaddr_in server_addr; - pinger_t *pinger; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); - pinger = malloc(sizeof(*pinger)); - ASSERT(pinger != NULL); - pinger->state = 0; - pinger->pongs = 0; - - /* Try to connect to the server and do NUM_PINGS ping-pongs. */ - r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp); - pinger->stream.tcp.data = pinger; - ASSERT(!r); - - /* We are never doing multiple reads/connects at a time anyway. */ - /* so these handles can be pre-initialized. */ - r = uv_tcp_connect(&pinger->connect_req, - &pinger->stream.tcp, - (const struct sockaddr*) &server_addr, - pinger_on_connect); - ASSERT(!r); - - /* Synchronous connect callbacks are not allowed. */ - ASSERT(pinger_on_connect_count == 0); -} - - -static void pipe_pinger_new(void) { - int r; - pinger_t *pinger; - - pinger = (pinger_t*)malloc(sizeof(*pinger)); - ASSERT(pinger != NULL); - pinger->state = 0; - pinger->pongs = 0; - - /* Try to connect to the server and do NUM_PINGS ping-pongs. */ - r = uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0); - pinger->stream.pipe.data = pinger; - ASSERT(!r); - - /* We are never doing multiple reads/connects at a time anyway. */ - /* so these handles can be pre-initialized. */ - - uv_pipe_connect(&pinger->connect_req, &pinger->stream.pipe, TEST_PIPENAME, - pinger_on_connect); - - /* Synchronous connect callbacks are not allowed. */ - ASSERT(pinger_on_connect_count == 0); -} - - -TEST_IMPL(tcp_ping_pong) { - tcp_pinger_new(); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(completed_pingers == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_ping_pong_v6) { - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - tcp_pinger_v6_new(); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(completed_pingers == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_ping_pong) { - pipe_pinger_new(); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(completed_pingers == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-bind-error.c b/outside/libuv-v1.7.5/test/test-pipe-bind-error.c deleted file mode 100644 index 38b57db699..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-bind-error.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -#ifdef _WIN32 -# define BAD_PIPENAME "bad-pipe" -#else -# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there" -#endif - - -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -TEST_IMPL(pipe_bind_error_addrinuse) { - uv_pipe_t server1, server2; - int r; - - r = uv_pipe_init(uv_default_loop(), &server1, 0); - ASSERT(r == 0); - r = uv_pipe_bind(&server1, TEST_PIPENAME); - ASSERT(r == 0); - - r = uv_pipe_init(uv_default_loop(), &server2, 0); - ASSERT(r == 0); - r = uv_pipe_bind(&server2, TEST_PIPENAME); - ASSERT(r == UV_EADDRINUSE); - - r = uv_listen((uv_stream_t*)&server1, SOMAXCONN, NULL); - ASSERT(r == 0); - r = uv_listen((uv_stream_t*)&server2, SOMAXCONN, NULL); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server1, close_cb); - uv_close((uv_handle_t*)&server2, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_bind_error_addrnotavail) { - uv_pipe_t server; - int r; - - r = uv_pipe_init(uv_default_loop(), &server, 0); - ASSERT(r == 0); - - r = uv_pipe_bind(&server, BAD_PIPENAME); - ASSERT(r == UV_EACCES); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_bind_error_inval) { - uv_pipe_t server; - int r; - - r = uv_pipe_init(uv_default_loop(), &server, 0); - ASSERT(r == 0); - r = uv_pipe_bind(&server, TEST_PIPENAME); - ASSERT(r == 0); - r = uv_pipe_bind(&server, TEST_PIPENAME_2); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_listen_without_bind) { - uv_pipe_t server; - int r; - - r = uv_pipe_init(uv_default_loop(), &server, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-close-stdout-read-stdin.c b/outside/libuv-v1.7.5/test/test-pipe-close-stdout-read-stdin.c deleted file mode 100644 index ee8bb2a9a8..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-close-stdout-read-stdin.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef _WIN32 - -#include -#include -#include -#include - -#include "uv.h" -#include "task.h" - -void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf) -{ - static char buffer[1024]; - - buf->base = buffer; - buf->len = sizeof(buffer); -} - -void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf) -{ - if (nread < 0) { - uv_close((uv_handle_t*)stream, NULL); - return; - } -} - -/* - * This test is a reproduction of joyent/libuv#1419 . - */ -TEST_IMPL(pipe_close_stdout_read_stdin) { - int r = -1; - int pid; - int fd[2]; - int status; - uv_pipe_t stdin_pipe; - - r = pipe(fd); - ASSERT(r == 0); - - if ((pid = fork()) == 0) { - /* - * Make the read side of the pipe our stdin. - * The write side will be closed by the parent process. - */ - close(fd[1]); - close(0); - r = dup(fd[0]); - ASSERT(r != -1); - - /* Create a stream that reads from the pipe. */ - r = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)&stdin_pipe, 0); - ASSERT(r == 0); - - r = uv_pipe_open((uv_pipe_t *)&stdin_pipe, 0); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t *)&stdin_pipe, alloc_buffer, read_stdin); - ASSERT(r == 0); - - /* - * Because the other end of the pipe was closed, there should - * be no event left to process after one run of the event loop. - * Otherwise, it means that events were not processed correctly. - */ - ASSERT(uv_run(uv_default_loop(), UV_RUN_NOWAIT) == 0); - } else { - /* - * Close both ends of the pipe so that the child - * get a POLLHUP event when it tries to read from - * the other end. - */ - close(fd[1]); - close(fd[0]); - - waitpid(pid, &status, 0); - ASSERT(WIFEXITED(status) && WEXITSTATUS(status) == 0); - } - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* ifndef _WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-pipe-connect-error.c b/outside/libuv-v1.7.5/test/test-pipe-connect-error.c deleted file mode 100644 index ebb2a6ca82..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-connect-error.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -#ifdef _WIN32 -# define BAD_PIPENAME "bad-pipe" -#else -# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there" -#endif - - -static int close_cb_called = 0; -static int connect_cb_called = 0; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void connect_cb(uv_connect_t* connect_req, int status) { - ASSERT(status == UV_ENOENT); - uv_close((uv_handle_t*)connect_req->handle, close_cb); - connect_cb_called++; -} - - -static void connect_cb_file(uv_connect_t* connect_req, int status) { - ASSERT(status == UV_ENOTSOCK || status == UV_ECONNREFUSED); - uv_close((uv_handle_t*)connect_req->handle, close_cb); - connect_cb_called++; -} - - -TEST_IMPL(pipe_connect_bad_name) { - uv_pipe_t client; - uv_connect_t req; - int r; - - r = uv_pipe_init(uv_default_loop(), &client, 0); - ASSERT(r == 0); - uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - ASSERT(connect_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_connect_to_file) { - const char* path = "test/fixtures/empty_file"; - uv_pipe_t client; - uv_connect_t req; - int r; - - r = uv_pipe_init(uv_default_loop(), &client, 0); - ASSERT(r == 0); - uv_pipe_connect(&req, &client, path, connect_cb_file); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - ASSERT(connect_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-connect-multiple.c b/outside/libuv-v1.7.5/test/test-pipe-connect-multiple.c deleted file mode 100644 index 3de5a9a0bf..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-connect-multiple.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (c) 2015 Saúl Ibarra Corretgé . - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -static int connection_cb_called = 0; -static int connect_cb_called = 0; - -#define NUM_CLIENTS 4 - -typedef struct { - uv_pipe_t pipe_handle; - uv_connect_t conn_req; -} client_t; - -static uv_pipe_t server_handle; -static client_t clients[NUM_CLIENTS]; -static uv_pipe_t connections[NUM_CLIENTS]; - - -static void connection_cb(uv_stream_t* server, int status) { - int r; - uv_pipe_t* conn; - ASSERT(status == 0); - - conn = &connections[connection_cb_called]; - r = uv_pipe_init(server->loop, conn, 0); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)conn); - ASSERT(r == 0); - - if (++connection_cb_called == NUM_CLIENTS && - connect_cb_called == NUM_CLIENTS) { - uv_stop(server->loop); - } -} - - -static void connect_cb(uv_connect_t* connect_req, int status) { - ASSERT(status == 0); - if (++connect_cb_called == NUM_CLIENTS && - connection_cb_called == NUM_CLIENTS) { - uv_stop(connect_req->handle->loop); - } -} - - -TEST_IMPL(pipe_connect_multiple) { - int i; - int r; - uv_loop_t* loop; - - loop = uv_default_loop(); - - r = uv_pipe_init(loop, &server_handle, 0); - ASSERT(r == 0); - - r = uv_pipe_bind(&server_handle, TEST_PIPENAME); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server_handle, 128, connection_cb); - ASSERT(r == 0); - - for (i = 0; i < NUM_CLIENTS; i++) { - r = uv_pipe_init(loop, &clients[i].pipe_handle, 0); - ASSERT(r == 0); - uv_pipe_connect(&clients[i].conn_req, - &clients[i].pipe_handle, - TEST_PIPENAME, - connect_cb); - } - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(connection_cb_called == NUM_CLIENTS); - ASSERT(connect_cb_called == NUM_CLIENTS); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-connect-prepare.c b/outside/libuv-v1.7.5/test/test-pipe-connect-prepare.c deleted file mode 100644 index a86e7284a7..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-connect-prepare.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2015 Saúl Ibarra Corretgé . - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -#ifdef _WIN32 -# define BAD_PIPENAME "bad-pipe" -#else -# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there" -#endif - - -static int close_cb_called = 0; -static int connect_cb_called = 0; - -static uv_pipe_t pipe_handle; -static uv_prepare_t prepare_handle; -static uv_connect_t conn_req; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void connect_cb(uv_connect_t* connect_req, int status) { - ASSERT(status == UV_ENOENT); - connect_cb_called++; - uv_close((uv_handle_t*)&prepare_handle, close_cb); - uv_close((uv_handle_t*)&pipe_handle, close_cb); -} - - -static void prepare_cb(uv_prepare_t* handle) { - ASSERT(handle == &prepare_handle); - uv_pipe_connect(&conn_req, &pipe_handle, BAD_PIPENAME, connect_cb); -} - - -TEST_IMPL(pipe_connect_on_prepare) { - int r; - - r = uv_pipe_init(uv_default_loop(), &pipe_handle, 0); - ASSERT(r == 0); - - r = uv_prepare_init(uv_default_loop(), &prepare_handle); - ASSERT(r == 0); - r = uv_prepare_start(&prepare_handle, prepare_cb); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(close_cb_called == 2); - ASSERT(connect_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-getsockname.c b/outside/libuv-v1.7.5/test/test-pipe-getsockname.c deleted file mode 100644 index 5e036f9d52..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-getsockname.c +++ /dev/null @@ -1,263 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#include - -#if defined(__linux__) - #include - #include -#endif - -#ifndef _WIN32 -# include /* close */ -#else -# include -#endif - -static uv_pipe_t pipe_client; -static uv_pipe_t pipe_server; -static uv_connect_t connect_req; - -static int pipe_close_cb_called = 0; -static int pipe_client_connect_cb_called = 0; - - -static void pipe_close_cb(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*) &pipe_client || - handle == (uv_handle_t*) &pipe_server); - pipe_close_cb_called++; -} - - -static void pipe_client_connect_cb(uv_connect_t* req, int status) { - char buf[1024]; - size_t len; - int r; - - ASSERT(req == &connect_req); - ASSERT(status == 0); - - len = sizeof buf; - r = uv_pipe_getpeername(&pipe_client, buf, &len); - ASSERT(r == 0); - - ASSERT(buf[len - 1] != 0); - ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0); - - len = sizeof buf; - r = uv_pipe_getsockname(&pipe_client, buf, &len); - ASSERT(r == 0 && len == 0); - - pipe_client_connect_cb_called++; - - - uv_close((uv_handle_t*) &pipe_client, pipe_close_cb); - uv_close((uv_handle_t*) &pipe_server, pipe_close_cb); -} - - -static void pipe_server_connection_cb(uv_stream_t* handle, int status) { - /* This function *may* be called, depending on whether accept or the - * connection callback is called first. - */ - ASSERT(status == 0); -} - - -TEST_IMPL(pipe_getsockname) { - uv_loop_t* loop; - char buf[1024]; - size_t len; - int r; - - loop = uv_default_loop(); - ASSERT(loop != NULL); - - r = uv_pipe_init(loop, &pipe_server, 0); - ASSERT(r == 0); - - len = sizeof buf; - r = uv_pipe_getsockname(&pipe_server, buf, &len); - ASSERT(r == UV_EBADF); - - len = sizeof buf; - r = uv_pipe_getpeername(&pipe_server, buf, &len); - ASSERT(r == UV_EBADF); - - r = uv_pipe_bind(&pipe_server, TEST_PIPENAME); - ASSERT(r == 0); - - len = sizeof buf; - r = uv_pipe_getsockname(&pipe_server, buf, &len); - ASSERT(r == 0); - - ASSERT(buf[len - 1] != 0); - ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0); - - len = sizeof buf; - r = uv_pipe_getpeername(&pipe_server, buf, &len); - ASSERT(r == UV_ENOTCONN); - - r = uv_listen((uv_stream_t*) &pipe_server, 0, pipe_server_connection_cb); - ASSERT(r == 0); - - r = uv_pipe_init(loop, &pipe_client, 0); - ASSERT(r == 0); - - len = sizeof buf; - r = uv_pipe_getsockname(&pipe_client, buf, &len); - ASSERT(r == UV_EBADF); - - len = sizeof buf; - r = uv_pipe_getpeername(&pipe_client, buf, &len); - ASSERT(r == UV_EBADF); - - uv_pipe_connect(&connect_req, &pipe_client, TEST_PIPENAME, pipe_client_connect_cb); - - len = sizeof buf; - r = uv_pipe_getsockname(&pipe_client, buf, &len); - ASSERT(r == 0 && len == 0); - - len = sizeof buf; - r = uv_pipe_getpeername(&pipe_client, buf, &len); - ASSERT(r == 0); - - ASSERT(buf[len - 1] != 0); - ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - ASSERT(pipe_client_connect_cb_called == 1); - ASSERT(pipe_close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_getsockname_abstract) { -#if defined(__linux__) - char buf[1024]; - size_t len; - int r; - int sock; - struct sockaddr_un sun; - socklen_t sun_len; - char abstract_pipe[] = "\0test-pipe"; - - sock = socket(AF_LOCAL, SOCK_STREAM, 0); - ASSERT(sock != -1); - - sun_len = sizeof sun; - memset(&sun, 0, sun_len); - sun.sun_family = AF_UNIX; - memcpy(sun.sun_path, abstract_pipe, sizeof abstract_pipe); - - r = bind(sock, (struct sockaddr*)&sun, sun_len); - ASSERT(r == 0); - - r = uv_pipe_init(uv_default_loop(), &pipe_server, 0); - ASSERT(r == 0); - r = uv_pipe_open(&pipe_server, sock); - ASSERT(r == 0); - - len = sizeof buf; - r = uv_pipe_getsockname(&pipe_server, buf, &len); - ASSERT(r == 0); - - ASSERT(memcmp(buf, abstract_pipe, sizeof abstract_pipe) == 0); - - uv_close((uv_handle_t*)&pipe_server, pipe_close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - close(sock); - - ASSERT(pipe_close_cb_called == 1); - MAKE_VALGRIND_HAPPY(); - return 0; -#else - MAKE_VALGRIND_HAPPY(); - return 0; -#endif -} - -TEST_IMPL(pipe_getsockname_blocking) { -#ifdef _WIN32 - HANDLE readh, writeh; - int readfd; - char buf1[1024], buf2[1024]; - size_t len1, len2; - int r; - - r = CreatePipe(&readh, &writeh, NULL, 65536); - ASSERT(r != 0); - - r = uv_pipe_init(uv_default_loop(), &pipe_client, 0); - ASSERT(r == 0); - readfd = _open_osfhandle((intptr_t)readh, _O_RDONLY); - ASSERT(r != -1); - r = uv_pipe_open(&pipe_client, readfd); - ASSERT(r == 0); - r = uv_read_start((uv_stream_t*)&pipe_client, NULL, NULL); - ASSERT(r == 0); - Sleep(100); - r = uv_read_stop((uv_stream_t*)&pipe_client); - ASSERT(r == 0); - - len1 = sizeof buf1; - r = uv_pipe_getsockname(&pipe_client, buf1, &len1); - ASSERT(r == 0); - ASSERT(buf1[len1 - 1] != 0); - - r = uv_read_start((uv_stream_t*)&pipe_client, NULL, NULL); - ASSERT(r == 0); - Sleep(100); - - len2 = sizeof buf2; - r = uv_pipe_getsockname(&pipe_client, buf2, &len2); - ASSERT(r == 0); - ASSERT(buf2[len2 - 1] != 0); - - r = uv_read_stop((uv_stream_t*)&pipe_client); - ASSERT(r == 0); - - ASSERT(len1 == len2); - ASSERT(memcmp(buf1, buf2, len1) == 0); - - pipe_close_cb_called = 0; - uv_close((uv_handle_t*)&pipe_client, pipe_close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(pipe_close_cb_called == 1); - - _close(readfd); - CloseHandle(writeh); -#endif - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-pending-instances.c b/outside/libuv-v1.7.5/test/test-pipe-pending-instances.c deleted file mode 100644 index b6ff911a0f..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-pending-instances.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2015 Saúl Ibarra Corretgé . - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -static void connection_cb(uv_stream_t* server, int status) { - ASSERT(0 && "this will never be called"); -} - - -TEST_IMPL(pipe_pending_instances) { - int r; - uv_pipe_t pipe_handle; - uv_loop_t* loop; - - loop = uv_default_loop(); - - r = uv_pipe_init(loop, &pipe_handle, 0); - ASSERT(r == 0); - - uv_pipe_pending_instances(&pipe_handle, 8); - - r = uv_pipe_bind(&pipe_handle, TEST_PIPENAME); - ASSERT(r == 0); - - uv_pipe_pending_instances(&pipe_handle, 16); - - r = uv_listen((uv_stream_t*)&pipe_handle, 128, connection_cb); - ASSERT(r == 0); - - uv_close((uv_handle_t*)&pipe_handle, NULL); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-sendmsg.c b/outside/libuv-v1.7.5/test/test-pipe-sendmsg.c deleted file mode 100644 index f6d893b449..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-sendmsg.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -#ifndef _WIN32 - -#include -#include -#include -#include -#include -#include -#include - - -/* NOTE: size should be divisible by 2 */ -static uv_pipe_t incoming[4]; -static unsigned int incoming_count; -static unsigned int close_called; - - -static void set_nonblocking(uv_os_sock_t sock) { - int r; -#ifdef _WIN32 - unsigned long on = 1; - r = ioctlsocket(sock, FIONBIO, &on); - ASSERT(r == 0); -#else - int flags = fcntl(sock, F_GETFL, 0); - ASSERT(flags >= 0); - r = fcntl(sock, F_SETFL, flags | O_NONBLOCK); - ASSERT(r >= 0); -#endif -} - - - - -static void close_cb(uv_handle_t* handle) { - close_called++; -} - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - static char base[1]; - - buf->base = base; - buf->len = sizeof(base); -} - - -static void read_cb(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - uv_pipe_t* p; - uv_pipe_t* inc; - uv_handle_type pending; - unsigned int i; - - p = (uv_pipe_t*) handle; - ASSERT(nread >= 0); - - while (uv_pipe_pending_count(p) != 0) { - pending = uv_pipe_pending_type(p); - ASSERT(pending == UV_NAMED_PIPE); - - ASSERT(incoming_count < ARRAY_SIZE(incoming)); - inc = &incoming[incoming_count++]; - ASSERT(0 == uv_pipe_init(p->loop, inc, 0)); - ASSERT(0 == uv_accept(handle, (uv_stream_t*) inc)); - } - - if (incoming_count != ARRAY_SIZE(incoming)) - return; - - ASSERT(0 == uv_read_stop((uv_stream_t*) p)); - uv_close((uv_handle_t*) p, close_cb); - for (i = 0; i < ARRAY_SIZE(incoming); i++) - uv_close((uv_handle_t*) &incoming[i], close_cb); -} - - -TEST_IMPL(pipe_sendmsg) { - uv_pipe_t p; - int r; - int fds[2]; - int send_fds[ARRAY_SIZE(incoming)]; - struct msghdr msg; - char scratch[64]; - struct cmsghdr *cmsg; - unsigned int i; - uv_buf_t buf; - - ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fds)); - for (i = 0; i < ARRAY_SIZE(send_fds); i += 2) - ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, send_fds + i)); - ASSERT(i == ARRAY_SIZE(send_fds)); - ASSERT(0 == uv_pipe_init(uv_default_loop(), &p, 1)); - ASSERT(0 == uv_pipe_open(&p, fds[1])); - - buf = uv_buf_init("X", 1); - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = (struct iovec*) &buf; - msg.msg_iovlen = 1; - msg.msg_flags = 0; - - msg.msg_control = (void*) scratch; - msg.msg_controllen = CMSG_LEN(sizeof(send_fds)); - ASSERT(sizeof(scratch) >= msg.msg_controllen); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = msg.msg_controllen; - - /* silence aliasing warning */ - { - void* pv = CMSG_DATA(cmsg); - int* pi = pv; - for (i = 0; i < ARRAY_SIZE(send_fds); i++) - pi[i] = send_fds[i]; - } - - set_nonblocking(fds[1]); - ASSERT(0 == uv_read_start((uv_stream_t*) &p, alloc_cb, read_cb)); - - do - r = sendmsg(fds[0], &msg, 0); - while (r == -1 && errno == EINTR); - ASSERT(r == 1); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(ARRAY_SIZE(incoming) == incoming_count); - ASSERT(ARRAY_SIZE(incoming) + 1 == close_called); - close(fds[0]); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#else /* !_WIN32 */ - -TEST_IMPL(pipe_sendmsg) { - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* _WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-pipe-server-close.c b/outside/libuv-v1.7.5/test/test-pipe-server-close.c deleted file mode 100644 index 1dcdfffaf7..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-server-close.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -static uv_pipe_t pipe_client; -static uv_pipe_t pipe_server; -static uv_connect_t connect_req; - -static int pipe_close_cb_called = 0; -static int pipe_client_connect_cb_called = 0; - - -static void pipe_close_cb(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*) &pipe_client || - handle == (uv_handle_t*) &pipe_server); - pipe_close_cb_called++; -} - - -static void pipe_client_connect_cb(uv_connect_t* req, int status) { - ASSERT(req == &connect_req); - ASSERT(status == 0); - - pipe_client_connect_cb_called++; - - uv_close((uv_handle_t*) &pipe_client, pipe_close_cb); - uv_close((uv_handle_t*) &pipe_server, pipe_close_cb); -} - - -static void pipe_server_connection_cb(uv_stream_t* handle, int status) { - /* This function *may* be called, depending on whether accept or the - * connection callback is called first. - */ - ASSERT(status == 0); -} - - -TEST_IMPL(pipe_server_close) { - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - ASSERT(loop != NULL); - - r = uv_pipe_init(loop, &pipe_server, 0); - ASSERT(r == 0); - - r = uv_pipe_bind(&pipe_server, TEST_PIPENAME); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*) &pipe_server, 0, pipe_server_connection_cb); - ASSERT(r == 0); - - r = uv_pipe_init(loop, &pipe_client, 0); - ASSERT(r == 0); - - uv_pipe_connect(&connect_req, &pipe_client, TEST_PIPENAME, pipe_client_connect_cb); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - ASSERT(pipe_client_connect_cb_called == 1); - ASSERT(pipe_close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-pipe-set-non-blocking.c b/outside/libuv-v1.7.5/test/test-pipe-set-non-blocking.c deleted file mode 100644 index fcc9fc0da8..0000000000 --- a/outside/libuv-v1.7.5/test/test-pipe-set-non-blocking.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright (c) 2015, Ben Noordhuis - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#ifdef _WIN32 - -TEST_IMPL(pipe_set_non_blocking) { - RETURN_SKIP("Test not implemented on Windows."); -} - -#else /* !_WIN32 */ - -#include -#include -#include -#include -#include -#include - -struct thread_ctx { - uv_barrier_t barrier; - int fd; -}; - -static void thread_main(void* arg) { - struct thread_ctx* ctx; - char buf[4096]; - ssize_t n; - - ctx = arg; - uv_barrier_wait(&ctx->barrier); - - do - n = read(ctx->fd, buf, sizeof(buf)); - while (n > 0 || (n == -1 && errno == EINTR)); - - ASSERT(n == 0); -} - -TEST_IMPL(pipe_set_non_blocking) { - struct thread_ctx ctx; - uv_pipe_t pipe_handle; - uv_thread_t thread; - size_t nwritten; - char data[4096]; - uv_buf_t buf; - int fd[2]; - int n; - - ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0)); - ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fd)); - ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0])); - ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &pipe_handle, 1)); - - ctx.fd = fd[1]; - ASSERT(0 == uv_barrier_init(&ctx.barrier, 2)); - ASSERT(0 == uv_thread_create(&thread, thread_main, &ctx)); - uv_barrier_wait(&ctx.barrier); - - buf.len = sizeof(data); - buf.base = data; - memset(data, '.', sizeof(data)); - - nwritten = 0; - while (nwritten < 10 << 20) { - /* The stream is in blocking mode so uv_try_write() should always succeed - * with the exact number of bytes that we wanted written. - */ - n = uv_try_write((uv_stream_t*) &pipe_handle, &buf, 1); - ASSERT(n == sizeof(data)); - nwritten += n; - } - - uv_close((uv_handle_t*) &pipe_handle, NULL); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - ASSERT(0 == uv_thread_join(&thread)); - ASSERT(0 == close(fd[1])); /* fd[0] is closed by uv_close(). */ - uv_barrier_destroy(&ctx.barrier); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* !_WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-platform-output.c b/outside/libuv-v1.7.5/test/test-platform-output.c deleted file mode 100644 index 76495e14fd..0000000000 --- a/outside/libuv-v1.7.5/test/test-platform-output.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - - -TEST_IMPL(platform_output) { - char buffer[512]; - size_t rss; - size_t size; - double uptime; - uv_rusage_t rusage; - uv_cpu_info_t* cpus; - uv_interface_address_t* interfaces; - int count; - int i; - int err; - - err = uv_get_process_title(buffer, sizeof(buffer)); - ASSERT(err == 0); - printf("uv_get_process_title: %s\n", buffer); - - size = sizeof(buffer); - err = uv_cwd(buffer, &size); - ASSERT(err == 0); - printf("uv_cwd: %s\n", buffer); - - err = uv_resident_set_memory(&rss); - ASSERT(err == 0); - printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss); - - err = uv_uptime(&uptime); - ASSERT(err == 0); - ASSERT(uptime > 0); - printf("uv_uptime: %f\n", uptime); - - err = uv_getrusage(&rusage); - ASSERT(err == 0); - ASSERT(rusage.ru_utime.tv_sec >= 0); - ASSERT(rusage.ru_utime.tv_usec >= 0); - ASSERT(rusage.ru_stime.tv_sec >= 0); - ASSERT(rusage.ru_stime.tv_usec >= 0); - printf("uv_getrusage:\n"); - printf(" user: %llu sec %llu microsec\n", - (unsigned long long) rusage.ru_utime.tv_sec, - (unsigned long long) rusage.ru_utime.tv_usec); - printf(" system: %llu sec %llu microsec\n", - (unsigned long long) rusage.ru_stime.tv_sec, - (unsigned long long) rusage.ru_stime.tv_usec); - - err = uv_cpu_info(&cpus, &count); - ASSERT(err == 0); - - printf("uv_cpu_info:\n"); - for (i = 0; i < count; i++) { - printf(" model: %s\n", cpus[i].model); - printf(" speed: %d\n", cpus[i].speed); - printf(" times.sys: %llu\n", (unsigned long long) cpus[i].cpu_times.sys); - printf(" times.user: %llu\n", - (unsigned long long) cpus[i].cpu_times.user); - printf(" times.idle: %llu\n", - (unsigned long long) cpus[i].cpu_times.idle); - printf(" times.irq: %llu\n", (unsigned long long) cpus[i].cpu_times.irq); - printf(" times.nice: %llu\n", - (unsigned long long) cpus[i].cpu_times.nice); - } - uv_free_cpu_info(cpus, count); - - err = uv_interface_addresses(&interfaces, &count); - ASSERT(err == 0); - - printf("uv_interface_addresses:\n"); - for (i = 0; i < count; i++) { - printf(" name: %s\n", interfaces[i].name); - printf(" internal: %d\n", interfaces[i].is_internal); - printf(" physical address: "); - printf("%02x:%02x:%02x:%02x:%02x:%02x\n", - (unsigned char)interfaces[i].phys_addr[0], - (unsigned char)interfaces[i].phys_addr[1], - (unsigned char)interfaces[i].phys_addr[2], - (unsigned char)interfaces[i].phys_addr[3], - (unsigned char)interfaces[i].phys_addr[4], - (unsigned char)interfaces[i].phys_addr[5]); - - if (interfaces[i].address.address4.sin_family == AF_INET) { - uv_ip4_name(&interfaces[i].address.address4, buffer, sizeof(buffer)); - } else if (interfaces[i].address.address4.sin_family == AF_INET6) { - uv_ip6_name(&interfaces[i].address.address6, buffer, sizeof(buffer)); - } - - printf(" address: %s\n", buffer); - - if (interfaces[i].netmask.netmask4.sin_family == AF_INET) { - uv_ip4_name(&interfaces[i].netmask.netmask4, buffer, sizeof(buffer)); - printf(" netmask: %s\n", buffer); - } else if (interfaces[i].netmask.netmask4.sin_family == AF_INET6) { - uv_ip6_name(&interfaces[i].netmask.netmask6, buffer, sizeof(buffer)); - printf(" netmask: %s\n", buffer); - } else { - printf(" netmask: none\n"); - } - } - uv_free_interface_addresses(interfaces, count); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-poll-close-doesnt-corrupt-stack.c b/outside/libuv-v1.7.5/test/test-poll-close-doesnt-corrupt-stack.c deleted file mode 100644 index fc2cc004f1..0000000000 --- a/outside/libuv-v1.7.5/test/test-poll-close-doesnt-corrupt-stack.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright Bert Belder, and other libuv contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifdef _WIN32 - -#include -#include - -#include "uv.h" -#include "task.h" - -#ifdef _MSC_VER /* msvc */ -# define NO_INLINE __declspec(noinline) -#else /* gcc */ -# define NO_INLINE __attribute__ ((noinline)) -#endif - - -uv_os_sock_t sock; -uv_poll_t handle; - -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* h) { - close_cb_called++; -} - - -static void poll_cb(uv_poll_t* h, int status, int events) { - ASSERT(0 && "should never get here"); -} - - -static void NO_INLINE close_socket_and_verify_stack() { - const uint32_t MARKER = 0xDEADBEEF; - const int VERIFY_AFTER = 10; /* ms */ - int r; - - volatile uint32_t data[65536]; - size_t i; - - for (i = 0; i < ARRAY_SIZE(data); i++) - data[i] = MARKER; - - r = closesocket(sock); - ASSERT(r == 0); - - uv_sleep(VERIFY_AFTER); - - for (i = 0; i < ARRAY_SIZE(data); i++) - ASSERT(data[i] == MARKER); -} - - -TEST_IMPL(poll_close_doesnt_corrupt_stack) { - struct WSAData wsa_data; - int r; - unsigned long on; - struct sockaddr_in addr; - - r = WSAStartup(MAKEWORD(2, 2), &wsa_data); - ASSERT(r == 0); - - sock = socket(AF_INET, SOCK_STREAM, 0); - ASSERT(sock != INVALID_SOCKET); - on = 1; - r = ioctlsocket(sock, FIONBIO, &on); - ASSERT(r == 0); - - r = uv_ip4_addr("127.0.0.1", TEST_PORT, &addr); - ASSERT(r == 0); - - r = connect(sock, (const struct sockaddr*) &addr, sizeof addr); - ASSERT(r != 0); - ASSERT(WSAGetLastError() == WSAEWOULDBLOCK); - - r = uv_poll_init_socket(uv_default_loop(), &handle, sock); - ASSERT(r == 0); - r = uv_poll_start(&handle, UV_READABLE | UV_WRITABLE, poll_cb); - ASSERT(r == 0); - - uv_close((uv_handle_t*) &handle, close_cb); - - close_socket_and_verify_stack(); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* _WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-poll-close.c b/outside/libuv-v1.7.5/test/test-poll-close.c deleted file mode 100644 index 2eccddf5b0..0000000000 --- a/outside/libuv-v1.7.5/test/test-poll-close.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#ifndef _WIN32 -# include -# include -# include -#endif - -#include "uv.h" -#include "task.h" - -#define NUM_SOCKETS 64 - - -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -TEST_IMPL(poll_close) { - uv_os_sock_t sockets[NUM_SOCKETS]; - uv_poll_t poll_handles[NUM_SOCKETS]; - int i; - -#ifdef _WIN32 - { - struct WSAData wsa_data; - int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); - ASSERT(r == 0); - } -#endif - - for (i = 0; i < NUM_SOCKETS; i++) { - sockets[i] = socket(AF_INET, SOCK_STREAM, 0); - uv_poll_init_socket(uv_default_loop(), &poll_handles[i], sockets[i]); - uv_poll_start(&poll_handles[i], UV_READABLE | UV_WRITABLE, NULL); - } - - for (i = 0; i < NUM_SOCKETS; i++) { - uv_close((uv_handle_t*) &poll_handles[i], close_cb); - } - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == NUM_SOCKETS); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-poll-closesocket.c b/outside/libuv-v1.7.5/test/test-poll-closesocket.c deleted file mode 100644 index 4db74a01f6..0000000000 --- a/outside/libuv-v1.7.5/test/test-poll-closesocket.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifdef _WIN32 - -#include - -#include "uv.h" -#include "task.h" - -uv_os_sock_t sock; -uv_poll_t handle; - -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* h) { - close_cb_called++; -} - - -static void poll_cb(uv_poll_t* h, int status, int events) { - int r; - - ASSERT(status == 0); - ASSERT(h == &handle); - - r = uv_poll_start(&handle, UV_READABLE, poll_cb); - ASSERT(r == 0); - - closesocket(sock); - uv_close((uv_handle_t*) &handle, close_cb); - -} - - -TEST_IMPL(poll_closesocket) { - struct WSAData wsa_data; - int r; - unsigned long on; - struct sockaddr_in addr; - - r = WSAStartup(MAKEWORD(2, 2), &wsa_data); - ASSERT(r == 0); - - sock = socket(AF_INET, SOCK_STREAM, 0); - ASSERT(sock != INVALID_SOCKET); - on = 1; - r = ioctlsocket(sock, FIONBIO, &on); - ASSERT(r == 0); - - r = uv_ip4_addr("127.0.0.1", TEST_PORT, &addr); - ASSERT(r == 0); - - r = connect(sock, (const struct sockaddr*) &addr, sizeof addr); - ASSERT(r != 0); - ASSERT(WSAGetLastError() == WSAEWOULDBLOCK); - - r = uv_poll_init_socket(uv_default_loop(), &handle, sock); - ASSERT(r == 0); - r = uv_poll_start(&handle, UV_WRITABLE, poll_cb); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif diff --git a/outside/libuv-v1.7.5/test/test-poll.c b/outside/libuv-v1.7.5/test/test-poll.c deleted file mode 100644 index be8b00c32c..0000000000 --- a/outside/libuv-v1.7.5/test/test-poll.c +++ /dev/null @@ -1,560 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#ifndef _WIN32 -# include -# include -#endif - -#include "uv.h" -#include "task.h" - - -#define NUM_CLIENTS 5 -#define TRANSFER_BYTES (1 << 16) - -#undef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)); - - -typedef enum { - UNIDIRECTIONAL, - DUPLEX -} test_mode_t; - -typedef struct connection_context_s { - uv_poll_t poll_handle; - uv_timer_t timer_handle; - uv_os_sock_t sock; - size_t read, sent; - int is_server_connection; - int open_handles; - int got_fin, sent_fin; - unsigned int events, delayed_events; -} connection_context_t; - -typedef struct server_context_s { - uv_poll_t poll_handle; - uv_os_sock_t sock; - int connections; -} server_context_t; - - -static void delay_timer_cb(uv_timer_t* timer); - - -static test_mode_t test_mode = DUPLEX; - -static int closed_connections = 0; - -static int valid_writable_wakeups = 0; -static int spurious_writable_wakeups = 0; - - -static int got_eagain(void) { -#ifdef _WIN32 - return WSAGetLastError() == WSAEWOULDBLOCK; -#else - return errno == EAGAIN - || errno == EINPROGRESS -#ifdef EWOULDBLOCK - || errno == EWOULDBLOCK; -#endif - ; -#endif -} - - -static uv_os_sock_t create_bound_socket (struct sockaddr_in bind_addr) { - uv_os_sock_t sock; - int r; - - sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); -#ifdef _WIN32 - ASSERT(sock != INVALID_SOCKET); -#else - ASSERT(sock >= 0); -#endif - -#ifndef _WIN32 - { - /* Allow reuse of the port. */ - int yes = 1; - r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); - ASSERT(r == 0); - } -#endif - - r = bind(sock, (const struct sockaddr*) &bind_addr, sizeof bind_addr); - ASSERT(r == 0); - - return sock; -} - - -static void close_socket(uv_os_sock_t sock) { - int r; -#ifdef _WIN32 - r = closesocket(sock); -#else - r = close(sock); -#endif - ASSERT(r == 0); -} - - -static connection_context_t* create_connection_context( - uv_os_sock_t sock, int is_server_connection) { - int r; - connection_context_t* context; - - context = (connection_context_t*) malloc(sizeof *context); - ASSERT(context != NULL); - - context->sock = sock; - context->is_server_connection = is_server_connection; - context->read = 0; - context->sent = 0; - context->open_handles = 0; - context->events = 0; - context->delayed_events = 0; - context->got_fin = 0; - context->sent_fin = 0; - - r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock); - context->open_handles++; - context->poll_handle.data = context; - ASSERT(r == 0); - - r = uv_timer_init(uv_default_loop(), &context->timer_handle); - context->open_handles++; - context->timer_handle.data = context; - ASSERT(r == 0); - - return context; -} - - -static void connection_close_cb(uv_handle_t* handle) { - connection_context_t* context = (connection_context_t*) handle->data; - - if (--context->open_handles == 0) { - if (test_mode == DUPLEX || context->is_server_connection) { - ASSERT(context->read == TRANSFER_BYTES); - } else { - ASSERT(context->read == 0); - } - - if (test_mode == DUPLEX || !context->is_server_connection) { - ASSERT(context->sent == TRANSFER_BYTES); - } else { - ASSERT(context->sent == 0); - } - - closed_connections++; - - free(context); - } -} - - -static void destroy_connection_context(connection_context_t* context) { - uv_close((uv_handle_t*) &context->poll_handle, connection_close_cb); - uv_close((uv_handle_t*) &context->timer_handle, connection_close_cb); -} - - -static void connection_poll_cb(uv_poll_t* handle, int status, int events) { - connection_context_t* context = (connection_context_t*) handle->data; - unsigned int new_events; - int r; - - ASSERT(status == 0); - ASSERT(events & context->events); - ASSERT(!(events & ~context->events)); - - new_events = context->events; - - if (events & UV_READABLE) { - int action = rand() % 7; - - switch (action) { - case 0: - case 1: { - /* Read a couple of bytes. */ - static char buffer[74]; - r = recv(context->sock, buffer, sizeof buffer, 0); - ASSERT(r >= 0); - - if (r > 0) { - context->read += r; - } else { - /* Got FIN. */ - context->got_fin = 1; - new_events &= ~UV_READABLE; - } - - break; - } - - case 2: - case 3: { - /* Read until EAGAIN. */ - static char buffer[931]; - r = recv(context->sock, buffer, sizeof buffer, 0); - ASSERT(r >= 0); - - while (r > 0) { - context->read += r; - r = recv(context->sock, buffer, sizeof buffer, 0); - } - - if (r == 0) { - /* Got FIN. */ - context->got_fin = 1; - new_events &= ~UV_READABLE; - } else { - ASSERT(got_eagain()); - } - - break; - } - - case 4: - /* Ignore. */ - break; - - case 5: - /* Stop reading for a while. Restart in timer callback. */ - new_events &= ~UV_READABLE; - if (!uv_is_active((uv_handle_t*) &context->timer_handle)) { - context->delayed_events = UV_READABLE; - uv_timer_start(&context->timer_handle, delay_timer_cb, 10, 0); - } else { - context->delayed_events |= UV_READABLE; - } - break; - - case 6: - /* Fudge with the event mask. */ - uv_poll_start(&context->poll_handle, UV_WRITABLE, connection_poll_cb); - uv_poll_start(&context->poll_handle, UV_READABLE, connection_poll_cb); - context->events = UV_READABLE; - break; - - default: - ASSERT(0); - } - } - - if (events & UV_WRITABLE) { - if (context->sent < TRANSFER_BYTES && - !(test_mode == UNIDIRECTIONAL && context->is_server_connection)) { - /* We have to send more bytes. */ - int action = rand() % 7; - - switch (action) { - case 0: - case 1: { - /* Send a couple of bytes. */ - static char buffer[103]; - - int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer); - ASSERT(send_bytes > 0); - - r = send(context->sock, buffer, send_bytes, 0); - - if (r < 0) { - ASSERT(got_eagain()); - spurious_writable_wakeups++; - break; - } - - ASSERT(r > 0); - context->sent += r; - valid_writable_wakeups++; - break; - } - - case 2: - case 3: { - /* Send until EAGAIN. */ - static char buffer[1234]; - - int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer); - ASSERT(send_bytes > 0); - - r = send(context->sock, buffer, send_bytes, 0); - - if (r < 0) { - ASSERT(got_eagain()); - spurious_writable_wakeups++; - break; - } - - ASSERT(r > 0); - valid_writable_wakeups++; - context->sent += r; - - while (context->sent < TRANSFER_BYTES) { - send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer); - ASSERT(send_bytes > 0); - - r = send(context->sock, buffer, send_bytes, 0); - - if (r <= 0) break; - context->sent += r; - } - ASSERT(r > 0 || got_eagain()); - break; - } - - case 4: - /* Ignore. */ - break; - - case 5: - /* Stop sending for a while. Restart in timer callback. */ - new_events &= ~UV_WRITABLE; - if (!uv_is_active((uv_handle_t*) &context->timer_handle)) { - context->delayed_events = UV_WRITABLE; - uv_timer_start(&context->timer_handle, delay_timer_cb, 100, 0); - } else { - context->delayed_events |= UV_WRITABLE; - } - break; - - case 6: - /* Fudge with the event mask. */ - uv_poll_start(&context->poll_handle, - UV_READABLE, - connection_poll_cb); - uv_poll_start(&context->poll_handle, - UV_WRITABLE, - connection_poll_cb); - context->events = UV_WRITABLE; - break; - - default: - ASSERT(0); - } - - } else { - /* Nothing more to write. Send FIN. */ - int r; -#ifdef _WIN32 - r = shutdown(context->sock, SD_SEND); -#else - r = shutdown(context->sock, SHUT_WR); -#endif - ASSERT(r == 0); - context->sent_fin = 1; - new_events &= ~UV_WRITABLE; - } - } - - if (context->got_fin && context->sent_fin) { - /* Sent and received FIN. Close and destroy context. */ - close_socket(context->sock); - destroy_connection_context(context); - context->events = 0; - - } else if (new_events != context->events) { - /* Poll mask changed. Call uv_poll_start again. */ - context->events = new_events; - uv_poll_start(handle, new_events, connection_poll_cb); - } - - /* Assert that uv_is_active works correctly for poll handles. */ - if (context->events != 0) { - ASSERT(1 == uv_is_active((uv_handle_t*) handle)); - } else { - ASSERT(0 == uv_is_active((uv_handle_t*) handle)); - } -} - - -static void delay_timer_cb(uv_timer_t* timer) { - connection_context_t* context = (connection_context_t*) timer->data; - int r; - - /* Timer should auto stop. */ - ASSERT(0 == uv_is_active((uv_handle_t*) timer)); - - /* Add the requested events to the poll mask. */ - ASSERT(context->delayed_events != 0); - context->events |= context->delayed_events; - context->delayed_events = 0; - - r = uv_poll_start(&context->poll_handle, - context->events, - connection_poll_cb); - ASSERT(r == 0); -} - - -static server_context_t* create_server_context( - uv_os_sock_t sock) { - int r; - server_context_t* context; - - context = (server_context_t*) malloc(sizeof *context); - ASSERT(context != NULL); - - context->sock = sock; - context->connections = 0; - - r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock); - context->poll_handle.data = context; - ASSERT(r == 0); - - return context; -} - - -static void server_close_cb(uv_handle_t* handle) { - server_context_t* context = (server_context_t*) handle->data; - free(context); -} - - -static void destroy_server_context(server_context_t* context) { - uv_close((uv_handle_t*) &context->poll_handle, server_close_cb); -} - - -static void server_poll_cb(uv_poll_t* handle, int status, int events) { - server_context_t* server_context = (server_context_t*) - handle->data; - connection_context_t* connection_context; - struct sockaddr_in addr; - socklen_t addr_len; - uv_os_sock_t sock; - int r; - - addr_len = sizeof addr; - sock = accept(server_context->sock, (struct sockaddr*) &addr, &addr_len); -#ifdef _WIN32 - ASSERT(sock != INVALID_SOCKET); -#else - ASSERT(sock >= 0); -#endif - - connection_context = create_connection_context(sock, 1); - connection_context->events = UV_READABLE | UV_WRITABLE; - r = uv_poll_start(&connection_context->poll_handle, - UV_READABLE | UV_WRITABLE, - connection_poll_cb); - ASSERT(r == 0); - - if (++server_context->connections == NUM_CLIENTS) { - close_socket(server_context->sock); - destroy_server_context(server_context); - } -} - - -static void start_server(void) { - server_context_t* context; - struct sockaddr_in addr; - uv_os_sock_t sock; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - sock = create_bound_socket(addr); - context = create_server_context(sock); - - r = listen(sock, 100); - ASSERT(r == 0); - - r = uv_poll_start(&context->poll_handle, UV_READABLE, server_poll_cb); - ASSERT(r == 0); -} - - -static void start_client(void) { - uv_os_sock_t sock; - connection_context_t* context; - struct sockaddr_in server_addr; - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); - ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr)); - - sock = create_bound_socket(addr); - context = create_connection_context(sock, 0); - - context->events = UV_READABLE | UV_WRITABLE; - r = uv_poll_start(&context->poll_handle, - UV_READABLE | UV_WRITABLE, - connection_poll_cb); - ASSERT(r == 0); - - r = connect(sock, (struct sockaddr*) &server_addr, sizeof server_addr); - ASSERT(r == 0 || got_eagain()); -} - - -static void start_poll_test(void) { - int i, r; - -#ifdef _WIN32 - { - struct WSAData wsa_data; - int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); - ASSERT(r == 0); - } -#endif - - start_server(); - - for (i = 0; i < NUM_CLIENTS; i++) - start_client(); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - /* Assert that at most five percent of the writable wakeups was spurious. */ - ASSERT(spurious_writable_wakeups == 0 || - (valid_writable_wakeups + spurious_writable_wakeups) / - spurious_writable_wakeups > 20); - - ASSERT(closed_connections == NUM_CLIENTS * 2); - - MAKE_VALGRIND_HAPPY(); -} - - -TEST_IMPL(poll_duplex) { - test_mode = DUPLEX; - start_poll_test(); - return 0; -} - - -TEST_IMPL(poll_unidirectional) { - test_mode = UNIDIRECTIONAL; - start_poll_test(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-process-title.c b/outside/libuv-v1.7.5/test/test-process-title.c deleted file mode 100644 index 29be20749b..0000000000 --- a/outside/libuv-v1.7.5/test/test-process-title.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - - -static void set_title(const char* title) { - char buffer[512]; - int err; - - err = uv_get_process_title(buffer, sizeof(buffer)); - ASSERT(err == 0); - - err = uv_set_process_title(title); - ASSERT(err == 0); - - err = uv_get_process_title(buffer, sizeof(buffer)); - ASSERT(err == 0); - - ASSERT(strcmp(buffer, title) == 0); -} - - -TEST_IMPL(process_title) { -#if defined(__sun) - RETURN_SKIP("uv_(get|set)_process_title is not implemented."); -#else - /* Check for format string vulnerabilities. */ - set_title("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); - set_title("new title"); - return 0; -#endif -} diff --git a/outside/libuv-v1.7.5/test/test-ref.c b/outside/libuv-v1.7.5/test/test-ref.c deleted file mode 100644 index ddaa173808..0000000000 --- a/outside/libuv-v1.7.5/test/test-ref.c +++ /dev/null @@ -1,442 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -static uv_write_t write_req; -static uv_shutdown_t shutdown_req; -static uv_connect_t connect_req; - -static char buffer[32767]; - -static int req_cb_called; -static int connect_cb_called; -static int write_cb_called; -static int shutdown_cb_called; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void do_close(void* handle) { - close_cb_called = 0; - uv_close((uv_handle_t*)handle, close_cb); - ASSERT(close_cb_called == 0); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(close_cb_called == 1); -} - - -static void fail_cb(void) { - FATAL("fail_cb should not have been called"); -} - - -static void fail_cb2(void) { - ASSERT(0 && "fail_cb2 should not have been called"); -} - - -static void req_cb(uv_handle_t* req, int status) { - req_cb_called++; -} - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(req == &shutdown_req); - shutdown_cb_called++; -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(req == &write_req); - uv_shutdown(&shutdown_req, req->handle, shutdown_cb); - write_cb_called++; -} - - -static void connect_and_write(uv_connect_t* req, int status) { - uv_buf_t buf = uv_buf_init(buffer, sizeof buffer); - ASSERT(req == &connect_req); - ASSERT(status == 0); - uv_write(&write_req, req->handle, &buf, 1, write_cb); - connect_cb_called++; -} - - - -static void connect_and_shutdown(uv_connect_t* req, int status) { - ASSERT(req == &connect_req); - ASSERT(status == 0); - uv_shutdown(&shutdown_req, req->handle, shutdown_cb); - connect_cb_called++; -} - - -TEST_IMPL(ref) { - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(idle_ref) { - uv_idle_t h; - uv_idle_init(uv_default_loop(), &h); - uv_idle_start(&h, (uv_idle_cb) fail_cb2); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(async_ref) { - uv_async_t h; - uv_async_init(uv_default_loop(), &h, NULL); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(prepare_ref) { - uv_prepare_t h; - uv_prepare_init(uv_default_loop(), &h); - uv_prepare_start(&h, (uv_prepare_cb) fail_cb2); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(check_ref) { - uv_check_t h; - uv_check_init(uv_default_loop(), &h); - uv_check_start(&h, (uv_check_cb) fail_cb2); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static void prepare_cb(uv_prepare_t* h) { - ASSERT(h != NULL); - uv_unref((uv_handle_t*)h); -} - - -TEST_IMPL(unref_in_prepare_cb) { - uv_prepare_t h; - uv_prepare_init(uv_default_loop(), &h); - uv_prepare_start(&h, prepare_cb); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(timer_ref) { - uv_timer_t h; - uv_timer_init(uv_default_loop(), &h); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(timer_ref2) { - uv_timer_t h; - uv_timer_init(uv_default_loop(), &h); - uv_timer_start(&h, (uv_timer_cb)fail_cb, 42, 42); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_event_ref) { - uv_fs_event_t h; - uv_fs_event_init(uv_default_loop(), &h); - uv_fs_event_start(&h, (uv_fs_event_cb)fail_cb, ".", 0); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(fs_poll_ref) { - uv_fs_poll_t h; - uv_fs_poll_init(uv_default_loop(), &h); - uv_fs_poll_start(&h, NULL, ".", 999); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_ref) { - uv_tcp_t h; - uv_tcp_init(uv_default_loop(), &h); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_ref2) { - uv_tcp_t h; - uv_tcp_init(uv_default_loop(), &h); - uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_ref2b) { - uv_tcp_t h; - uv_tcp_init(uv_default_loop(), &h); - uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb); - uv_unref((uv_handle_t*)&h); - uv_close((uv_handle_t*)&h, close_cb); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(close_cb_called == 1); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_ref3) { - struct sockaddr_in addr; - uv_tcp_t h; - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - uv_tcp_init(uv_default_loop(), &h); - uv_tcp_connect(&connect_req, - &h, - (const struct sockaddr*) &addr, - connect_and_shutdown); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(connect_cb_called == 1); - ASSERT(shutdown_cb_called == 1); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_ref4) { - struct sockaddr_in addr; - uv_tcp_t h; - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - uv_tcp_init(uv_default_loop(), &h); - uv_tcp_connect(&connect_req, - &h, - (const struct sockaddr*) &addr, - connect_and_write); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(shutdown_cb_called == 1); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_ref) { - uv_udp_t h; - uv_udp_init(uv_default_loop(), &h); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_ref2) { - struct sockaddr_in addr; - uv_udp_t h; - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - uv_udp_init(uv_default_loop(), &h); - uv_udp_bind(&h, (const struct sockaddr*) &addr, 0); - uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_ref3) { - struct sockaddr_in addr; - uv_buf_t buf = uv_buf_init("PING", 4); - uv_udp_send_t req; - uv_udp_t h; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - uv_udp_init(uv_default_loop(), &h); - uv_udp_send(&req, - &h, - &buf, - 1, - (const struct sockaddr*) &addr, - (uv_udp_send_cb) req_cb); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(req_cb_called == 1); - do_close(&h); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_ref) { - uv_pipe_t h; - uv_pipe_init(uv_default_loop(), &h, 0); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_ref2) { - uv_pipe_t h; - uv_pipe_init(uv_default_loop(), &h, 0); - uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_ref3) { - uv_pipe_t h; - uv_pipe_init(uv_default_loop(), &h, 0); - uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_shutdown); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(connect_cb_called == 1); - ASSERT(shutdown_cb_called == 1); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(pipe_ref4) { - uv_pipe_t h; - uv_pipe_init(uv_default_loop(), &h, 0); - uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_write); - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(shutdown_cb_called == 1); - do_close(&h); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(process_ref) { - /* spawn_helper4 blocks indefinitely. */ - char *argv[] = { NULL, "spawn_helper4", NULL }; - uv_process_options_t options; - size_t exepath_size; - char exepath[256]; - uv_process_t h; - int r; - - memset(&options, 0, sizeof(options)); - exepath_size = sizeof(exepath); - - r = uv_exepath(exepath, &exepath_size); - ASSERT(r == 0); - - argv[0] = exepath; - options.file = exepath; - options.args = argv; - options.exit_cb = NULL; - - r = uv_spawn(uv_default_loop(), &h, &options); - ASSERT(r == 0); - - uv_unref((uv_handle_t*)&h); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - r = uv_process_kill(&h, /* SIGTERM */ 15); - ASSERT(r == 0); - - do_close(&h); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(has_ref) { - uv_idle_t h; - uv_idle_init(uv_default_loop(), &h); - uv_ref((uv_handle_t*)&h); - ASSERT(uv_has_ref((uv_handle_t*)&h) == 1); - uv_unref((uv_handle_t*)&h); - ASSERT(uv_has_ref((uv_handle_t*)&h) == 0); - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-run-nowait.c b/outside/libuv-v1.7.5/test/test-run-nowait.c deleted file mode 100644 index 43524f636d..0000000000 --- a/outside/libuv-v1.7.5/test/test-run-nowait.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_timer_t timer_handle; -static int timer_called = 0; - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer_handle); - timer_called = 1; -} - - -TEST_IMPL(run_nowait) { - int r; - uv_timer_init(uv_default_loop(), &timer_handle); - uv_timer_start(&timer_handle, timer_cb, 100, 100); - - r = uv_run(uv_default_loop(), UV_RUN_NOWAIT); - ASSERT(r != 0); - ASSERT(timer_called == 0); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-run-once.c b/outside/libuv-v1.7.5/test/test-run-once.c deleted file mode 100644 index 10cbf95e4a..0000000000 --- a/outside/libuv-v1.7.5/test/test-run-once.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#define NUM_TICKS 64 - -static uv_idle_t idle_handle; -static int idle_counter; - - -static void idle_cb(uv_idle_t* handle) { - ASSERT(handle == &idle_handle); - - if (++idle_counter == NUM_TICKS) - uv_idle_stop(handle); -} - - -TEST_IMPL(run_once) { - uv_idle_init(uv_default_loop(), &idle_handle); - uv_idle_start(&idle_handle, idle_cb); - - while (uv_run(uv_default_loop(), UV_RUN_ONCE)); - ASSERT(idle_counter == NUM_TICKS); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-semaphore.c b/outside/libuv-v1.7.5/test/test-semaphore.c deleted file mode 100644 index ac03bb08f1..0000000000 --- a/outside/libuv-v1.7.5/test/test-semaphore.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -typedef struct { - uv_mutex_t mutex; - uv_sem_t sem; - int delay; - volatile int posted; -} worker_config; - - -static void worker(void* arg) { - worker_config* c = arg; - - if (c->delay) - uv_sleep(c->delay); - - uv_mutex_lock(&c->mutex); - ASSERT(c->posted == 0); - uv_sem_post(&c->sem); - c->posted = 1; - uv_mutex_unlock(&c->mutex); -} - - -TEST_IMPL(semaphore_1) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - - ASSERT(0 == uv_sem_init(&wc.sem, 0)); - ASSERT(0 == uv_mutex_init(&wc.mutex)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_sleep(100); - uv_mutex_lock(&wc.mutex); - ASSERT(wc.posted == 1); - uv_sem_wait(&wc.sem); /* should not block */ - uv_mutex_unlock(&wc.mutex); /* ergo, it should be ok to unlock after wait */ - - ASSERT(0 == uv_thread_join(&thread)); - uv_mutex_destroy(&wc.mutex); - uv_sem_destroy(&wc.sem); - - return 0; -} - - -TEST_IMPL(semaphore_2) { - uv_thread_t thread; - worker_config wc; - - memset(&wc, 0, sizeof(wc)); - wc.delay = 100; - - ASSERT(0 == uv_sem_init(&wc.sem, 0)); - ASSERT(0 == uv_mutex_init(&wc.mutex)); - ASSERT(0 == uv_thread_create(&thread, worker, &wc)); - - uv_sem_wait(&wc.sem); - - ASSERT(0 == uv_thread_join(&thread)); - uv_mutex_destroy(&wc.mutex); - uv_sem_destroy(&wc.sem); - - return 0; -} - - -TEST_IMPL(semaphore_3) { - uv_sem_t sem; - - ASSERT(0 == uv_sem_init(&sem, 3)); - uv_sem_wait(&sem); /* should not block */ - uv_sem_wait(&sem); /* should not block */ - ASSERT(0 == uv_sem_trywait(&sem)); - ASSERT(UV_EAGAIN == uv_sem_trywait(&sem)); - - uv_sem_post(&sem); - ASSERT(0 == uv_sem_trywait(&sem)); - ASSERT(UV_EAGAIN == uv_sem_trywait(&sem)); - - uv_sem_destroy(&sem); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-shutdown-close.c b/outside/libuv-v1.7.5/test/test-shutdown-close.c deleted file mode 100644 index 78c369be2d..0000000000 --- a/outside/libuv-v1.7.5/test/test-shutdown-close.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* - * These tests verify that the uv_shutdown callback is always made, even when - * it is immediately followed by an uv_close call. - */ - -#include "uv.h" -#include "task.h" - - -static uv_shutdown_t shutdown_req; -static uv_connect_t connect_req; - -static int connect_cb_called = 0; -static int shutdown_cb_called = 0; -static int close_cb_called = 0; - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(req == &shutdown_req); - ASSERT(status == 0 || status == UV_ECANCELED); - shutdown_cb_called++; -} - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - int r; - - ASSERT(req == &connect_req); - ASSERT(status == 0); - - r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb); - ASSERT(r == 0); - ASSERT(0 == uv_is_closing((uv_handle_t*) req->handle)); - uv_close((uv_handle_t*) req->handle, close_cb); - ASSERT(1 == uv_is_closing((uv_handle_t*) req->handle)); - - connect_cb_called++; -} - - -TEST_IMPL(shutdown_close_tcp) { - struct sockaddr_in addr; - uv_tcp_t h; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - r = uv_tcp_init(uv_default_loop(), &h); - ASSERT(r == 0); - r = uv_tcp_connect(&connect_req, - &h, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(connect_cb_called == 1); - ASSERT(shutdown_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(shutdown_close_pipe) { - uv_pipe_t h; - int r; - - r = uv_pipe_init(uv_default_loop(), &h, 0); - ASSERT(r == 0); - uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_cb); - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(connect_cb_called == 1); - ASSERT(shutdown_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-shutdown-eof.c b/outside/libuv-v1.7.5/test/test-shutdown-eof.c deleted file mode 100644 index 9f95e7561f..0000000000 --- a/outside/libuv-v1.7.5/test/test-shutdown-eof.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - -static uv_timer_t timer; -static uv_tcp_t tcp; -static uv_connect_t connect_req; -static uv_write_t write_req; -static uv_shutdown_t shutdown_req; -static uv_buf_t qbuf; -static int got_q; -static int got_eof; -static int called_connect_cb; -static int called_shutdown_cb; -static int called_tcp_close_cb; -static int called_timer_close_cb; -static int called_timer_cb; - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf->base = malloc(size); - buf->len = size; -} - - -static void read_cb(uv_stream_t* t, ssize_t nread, const uv_buf_t* buf) { - ASSERT((uv_tcp_t*)t == &tcp); - - if (nread == 0) { - free(buf->base); - return; - } - - if (!got_q) { - ASSERT(nread == 1); - ASSERT(!got_eof); - ASSERT(buf->base[0] == 'Q'); - free(buf->base); - got_q = 1; - puts("got Q"); - } else { - ASSERT(nread == UV_EOF); - if (buf->base) { - free(buf->base); - } - got_eof = 1; - puts("got EOF"); - } -} - - -static void shutdown_cb(uv_shutdown_t *req, int status) { - ASSERT(req == &shutdown_req); - - ASSERT(called_connect_cb == 1); - ASSERT(!got_eof); - ASSERT(called_tcp_close_cb == 0); - ASSERT(called_timer_close_cb == 0); - ASSERT(called_timer_cb == 0); - - called_shutdown_cb++; -} - - -static void connect_cb(uv_connect_t *req, int status) { - ASSERT(status == 0); - ASSERT(req == &connect_req); - - /* Start reading from our connection so we can receive the EOF. */ - uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb); - - /* - * Write the letter 'Q' to gracefully kill the echo-server. This will not - * effect our connection. - */ - uv_write(&write_req, (uv_stream_t*) &tcp, &qbuf, 1, NULL); - - /* Shutdown our end of the connection. */ - uv_shutdown(&shutdown_req, (uv_stream_t*) &tcp, shutdown_cb); - - called_connect_cb++; - ASSERT(called_shutdown_cb == 0); -} - - -static void tcp_close_cb(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*) &tcp); - - ASSERT(called_connect_cb == 1); - ASSERT(got_q); - ASSERT(got_eof); - ASSERT(called_timer_cb == 1); - - called_tcp_close_cb++; -} - - -static void timer_close_cb(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*) &timer); - called_timer_close_cb++; -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer); - uv_close((uv_handle_t*) handle, timer_close_cb); - - /* - * The most important assert of the test: we have not received - * tcp_close_cb yet. - */ - ASSERT(called_tcp_close_cb == 0); - uv_close((uv_handle_t*) &tcp, tcp_close_cb); - - called_timer_cb++; -} - - -/* - * This test has a client which connects to the echo_server and immediately - * issues a shutdown. The echo-server, in response, will also shutdown their - * connection. We check, with a timer, that libuv is not automatically - * calling uv_close when the client receives the EOF from echo-server. - */ -TEST_IMPL(shutdown_eof) { - struct sockaddr_in server_addr; - int r; - - qbuf.base = "Q"; - qbuf.len = 1; - - r = uv_timer_init(uv_default_loop(), &timer); - ASSERT(r == 0); - - uv_timer_start(&timer, timer_cb, 100, 0); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); - r = uv_tcp_init(uv_default_loop(), &tcp); - ASSERT(!r); - - r = uv_tcp_connect(&connect_req, - &tcp, - (const struct sockaddr*) &server_addr, - connect_cb); - ASSERT(!r); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(called_connect_cb == 1); - ASSERT(called_shutdown_cb == 1); - ASSERT(got_eof); - ASSERT(got_q); - ASSERT(called_tcp_close_cb == 1); - ASSERT(called_timer_close_cb == 1); - ASSERT(called_timer_cb == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - diff --git a/outside/libuv-v1.7.5/test/test-shutdown-twice.c b/outside/libuv-v1.7.5/test/test-shutdown-twice.c deleted file mode 100644 index 75c0543549..0000000000 --- a/outside/libuv-v1.7.5/test/test-shutdown-twice.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* - * This is a regression test for issue #1113 (calling uv_shutdown twice will - * leave a ghost request in the system) - */ - -#include "uv.h" -#include "task.h" - -static uv_shutdown_t req1; -static uv_shutdown_t req2; - -static int shutdown_cb_called = 0; - -static void close_cb(uv_handle_t* handle) { - -} - -static void shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(req == &req1); - ASSERT(status == 0); - shutdown_cb_called++; - uv_close((uv_handle_t*) req->handle, close_cb); -} - -static void connect_cb(uv_connect_t* req, int status) { - int r; - - ASSERT(status == 0); - - r = uv_shutdown(&req1, req->handle, shutdown_cb); - ASSERT(r == 0); - r = uv_shutdown(&req2, req->handle, shutdown_cb); - ASSERT(r != 0); - -} - -TEST_IMPL(shutdown_twice) { - struct sockaddr_in addr; - uv_loop_t* loop; - int r; - uv_tcp_t h; - - uv_connect_t connect_req; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - loop = uv_default_loop(); - - r = uv_tcp_init(loop, &h); - - r = uv_tcp_connect(&connect_req, - &h, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(shutdown_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-signal-multiple-loops.c b/outside/libuv-v1.7.5/test/test-signal-multiple-loops.c deleted file mode 100644 index 158129919b..0000000000 --- a/outside/libuv-v1.7.5/test/test-signal-multiple-loops.c +++ /dev/null @@ -1,290 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - - -/* This test does not pretend to be cross-platform. */ -#ifndef _WIN32 - -#include "uv.h" -#include "task.h" - -#include -#include -#include -#include -#include -#include -#include - -/* The value of NUM_SIGNAL_HANDLING_THREADS is not arbitrary; it needs to be a - * multiple of three for reasons that will become clear when you scroll down. - * We're basically creating three different thread groups. The total needs - * to be divisible by three in order for the numbers in the final check to - * match up. - */ -#define NUM_SIGNAL_HANDLING_THREADS 24 -#define NUM_LOOP_CREATING_THREADS 10 - -enum signal_action { - ONLY_SIGUSR1, - ONLY_SIGUSR2, - SIGUSR1_AND_SIGUSR2 -}; - -static uv_sem_t sem; -static uv_mutex_t counter_lock; -static volatile int stop = 0; - -static volatile int signal1_cb_counter = 0; -static volatile int signal2_cb_counter = 0; -static volatile int loop_creation_counter = 0; - - -static void increment_counter(volatile int* counter) { - uv_mutex_lock(&counter_lock); - ++(*counter); - uv_mutex_unlock(&counter_lock); -} - - -static void signal1_cb(uv_signal_t* handle, int signum) { - ASSERT(signum == SIGUSR1); - increment_counter(&signal1_cb_counter); - uv_signal_stop(handle); -} - - -static void signal2_cb(uv_signal_t* handle, int signum) { - ASSERT(signum == SIGUSR2); - increment_counter(&signal2_cb_counter); - uv_signal_stop(handle); -} - - -static void signal_handling_worker(void* context) { - enum signal_action action; - uv_signal_t signal1a; - uv_signal_t signal1b; - uv_signal_t signal2; - uv_loop_t loop; - int r; - - action = (enum signal_action) (uintptr_t) context; - - ASSERT(0 == uv_loop_init(&loop)); - - /* Setup the signal watchers and start them. */ - if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { - r = uv_signal_init(&loop, &signal1a); - ASSERT(r == 0); - r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); - ASSERT(r == 0); - r = uv_signal_init(&loop, &signal1b); - ASSERT(r == 0); - r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); - ASSERT(r == 0); - } - - if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { - r = uv_signal_init(&loop, &signal2); - ASSERT(r == 0); - r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); - ASSERT(r == 0); - } - - /* Signal watchers are now set up. */ - uv_sem_post(&sem); - - /* Wait for all signals. The signal callbacks stop the watcher, so uv_run - * will return when all signal watchers caught a signal. - */ - r = uv_run(&loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - /* Restart the signal watchers. */ - if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { - r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); - ASSERT(r == 0); - r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); - ASSERT(r == 0); - } - - if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { - r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); - ASSERT(r == 0); - } - - /* Wait for signals once more. */ - uv_sem_post(&sem); - - r = uv_run(&loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - /* Close the watchers. */ - if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { - uv_close((uv_handle_t*) &signal1a, NULL); - uv_close((uv_handle_t*) &signal1b, NULL); - } - - if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { - uv_close((uv_handle_t*) &signal2, NULL); - } - - /* Wait for the signal watchers to close. */ - r = uv_run(&loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - uv_loop_close(&loop); -} - - -static void signal_unexpected_cb(uv_signal_t* handle, int signum) { - ASSERT(0 && "signal_unexpected_cb should never be called"); -} - - -static void loop_creating_worker(void* context) { - (void) context; - - do { - uv_loop_t *loop; - uv_signal_t signal; - int r; - - loop = malloc(sizeof(*loop)); - ASSERT(loop != NULL); - ASSERT(0 == uv_loop_init(loop)); - - r = uv_signal_init(loop, &signal); - ASSERT(r == 0); - - r = uv_signal_start(&signal, signal_unexpected_cb, SIGTERM); - ASSERT(r == 0); - - uv_close((uv_handle_t*) &signal, NULL); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - uv_loop_close(loop); - free(loop); - - increment_counter(&loop_creation_counter); - } while (!stop); -} - - -TEST_IMPL(signal_multiple_loops) { - uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS]; - uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS]; - enum signal_action action; - sigset_t sigset; - int i; - int r; - - r = uv_sem_init(&sem, 0); - ASSERT(r == 0); - - r = uv_mutex_init(&counter_lock); - ASSERT(r == 0); - - /* Create a couple of threads that create a destroy loops continuously. */ - for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) { - r = uv_thread_create(&loop_creating_threads[i], - loop_creating_worker, - NULL); - ASSERT(r == 0); - } - - /* Create a couple of threads that actually handle signals. */ - for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) { - switch (i % 3) { - case 0: action = ONLY_SIGUSR1; break; - case 1: action = ONLY_SIGUSR2; break; - case 2: action = SIGUSR1_AND_SIGUSR2; break; - } - - r = uv_thread_create(&signal_handling_threads[i], - signal_handling_worker, - (void*) (uintptr_t) action); - ASSERT(r == 0); - } - - /* Wait until all threads have started and set up their signal watchers. */ - for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) - uv_sem_wait(&sem); - - r = kill(getpid(), SIGUSR1); - ASSERT(r == 0); - r = kill(getpid(), SIGUSR2); - ASSERT(r == 0); - - /* Wait for all threads to handle these signals. */ - for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) - uv_sem_wait(&sem); - - /* Block all signals to this thread, so we are sure that from here the signal - * handler runs in another thread. This is is more likely to catch thread and - * signal safety issues if there are any. - */ - sigfillset(&sigset); - pthread_sigmask(SIG_SETMASK, &sigset, NULL); - - r = kill(getpid(), SIGUSR1); - ASSERT(r == 0); - r = kill(getpid(), SIGUSR2); - ASSERT(r == 0); - - /* Wait for all signal handling threads to exit. */ - for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) { - r = uv_thread_join(&signal_handling_threads[i]); - ASSERT(r == 0); - } - - /* Tell all loop creating threads to stop. */ - stop = 1; - - /* Wait for all loop creating threads to exit. */ - for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) { - r = uv_thread_join(&loop_creating_threads[i]); - ASSERT(r == 0); - } - - printf("signal1_cb calls: %d\n", signal1_cb_counter); - printf("signal2_cb calls: %d\n", signal2_cb_counter); - printf("loops created and destroyed: %d\n", loop_creation_counter); - - /* The division by three reflects the fact that we spawn three different - * thread groups of (NUM_SIGNAL_HANDLING_THREADS / 3) threads each. - */ - ASSERT(signal1_cb_counter == 8 * (NUM_SIGNAL_HANDLING_THREADS / 3)); - ASSERT(signal2_cb_counter == 4 * (NUM_SIGNAL_HANDLING_THREADS / 3)); - - /* We don't know exactly how much loops will be created and destroyed, but at - * least there should be 1 for every loop creating thread. - */ - ASSERT(loop_creation_counter >= NUM_LOOP_CREATING_THREADS); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* !_WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-signal.c b/outside/libuv-v1.7.5/test/test-signal.c deleted file mode 100644 index fcdd8e4d2d..0000000000 --- a/outside/libuv-v1.7.5/test/test-signal.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - - -/* This test does not pretend to be cross-platform. */ -#ifndef _WIN32 - -#include "uv.h" -#include "task.h" - -#include -#include -#include -#include -#include -#include -#include - -#define NSIGNALS 10 - -struct timer_ctx { - unsigned int ncalls; - uv_timer_t handle; - int signum; -}; - -struct signal_ctx { - enum { CLOSE, STOP } stop_or_close; - unsigned int ncalls; - uv_signal_t handle; - int signum; -}; - - -static void signal_cb(uv_signal_t* handle, int signum) { - struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle); - ASSERT(signum == ctx->signum); - - if (++ctx->ncalls == NSIGNALS) { - if (ctx->stop_or_close == STOP) - uv_signal_stop(handle); - else if (ctx->stop_or_close == CLOSE) - uv_close((uv_handle_t*)handle, NULL); - else - ASSERT(0); - } -} - - -static void timer_cb(uv_timer_t* handle) { - struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle); - - raise(ctx->signum); - - if (++ctx->ncalls == NSIGNALS) - uv_close((uv_handle_t*)handle, NULL); -} - - -static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) { - ctx->ncalls = 0; - ctx->signum = signum; - ctx->stop_or_close = CLOSE; - ASSERT(0 == uv_signal_init(loop, &ctx->handle)); - ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum)); -} - - -static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) { - ctx->ncalls = 0; - ctx->signum = signum; - ASSERT(0 == uv_timer_init(loop, &ctx->handle)); - ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5)); -} - - -TEST_IMPL(we_get_signal) { - struct signal_ctx sc; - struct timer_ctx tc; - uv_loop_t* loop; - - loop = uv_default_loop(); - start_timer(loop, SIGCHLD, &tc); - start_watcher(loop, SIGCHLD, &sc); - sc.stop_or_close = STOP; /* stop, don't close the signal handle */ - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(tc.ncalls == NSIGNALS); - ASSERT(sc.ncalls == NSIGNALS); - - start_timer(loop, SIGCHLD, &tc); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(tc.ncalls == NSIGNALS); - ASSERT(sc.ncalls == NSIGNALS); - - sc.ncalls = 0; - sc.stop_or_close = CLOSE; /* now close it when it's done */ - uv_signal_start(&sc.handle, signal_cb, SIGCHLD); - - start_timer(loop, SIGCHLD, &tc); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(tc.ncalls == NSIGNALS); - ASSERT(sc.ncalls == NSIGNALS); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(we_get_signals) { - struct signal_ctx sc[4]; - struct timer_ctx tc[2]; - uv_loop_t* loop; - unsigned int i; - - loop = uv_default_loop(); - start_watcher(loop, SIGUSR1, sc + 0); - start_watcher(loop, SIGUSR1, sc + 1); - start_watcher(loop, SIGUSR2, sc + 2); - start_watcher(loop, SIGUSR2, sc + 3); - start_timer(loop, SIGUSR1, tc + 0); - start_timer(loop, SIGUSR2, tc + 1); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - for (i = 0; i < ARRAY_SIZE(sc); i++) - ASSERT(sc[i].ncalls == NSIGNALS); - - for (i = 0; i < ARRAY_SIZE(tc); i++) - ASSERT(tc[i].ncalls == NSIGNALS); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* _WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-socket-buffer-size.c b/outside/libuv-v1.7.5/test/test-socket-buffer-size.c deleted file mode 100644 index 72f8c2524c..0000000000 --- a/outside/libuv-v1.7.5/test/test-socket-buffer-size.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -static uv_udp_t udp; -static uv_tcp_t tcp; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void check_buffer_size(uv_handle_t* handle) { - int value; - - value = 0; - ASSERT(0 == uv_recv_buffer_size(handle, &value)); - ASSERT(value > 0); - - value = 10000; - ASSERT(0 == uv_recv_buffer_size(handle, &value)); - - value = 0; - ASSERT(0 == uv_recv_buffer_size(handle, &value)); - /* linux sets double the value */ - ASSERT(value == 10000 || value == 20000); -} - - -TEST_IMPL(socket_buffer_size) { - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp)); - ASSERT(0 == uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0)); - check_buffer_size((uv_handle_t*) &tcp); - uv_close((uv_handle_t*) &tcp, close_cb); - - ASSERT(0 == uv_udp_init(uv_default_loop(), &udp)); - ASSERT(0 == uv_udp_bind(&udp, (struct sockaddr*) &addr, 0)); - check_buffer_size((uv_handle_t*) &udp); - uv_close((uv_handle_t*) &udp, close_cb); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-spawn.c b/outside/libuv-v1.7.5/test/test-spawn.c deleted file mode 100644 index e71f0f7d53..0000000000 --- a/outside/libuv-v1.7.5/test/test-spawn.c +++ /dev/null @@ -1,1706 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#include -#include -#include - -#ifdef _WIN32 -# if defined(__MINGW32__) -# include -# endif -# include -# include -#else -# include -# include -#endif - - -static int close_cb_called; -static int exit_cb_called; -static uv_process_t process; -static uv_timer_t timer; -static uv_process_options_t options; -static char exepath[1024]; -static size_t exepath_size = 1024; -static char* args[3]; -static int no_term_signal; -static int timer_counter; - -#define OUTPUT_SIZE 1024 -static char output[OUTPUT_SIZE]; -static int output_used; - - -static void close_cb(uv_handle_t* handle) { - printf("close_cb\n"); - close_cb_called++; -} - -static void exit_cb(uv_process_t* process, - int64_t exit_status, - int term_signal) { - printf("exit_cb\n"); - exit_cb_called++; - ASSERT(exit_status == 1); - ASSERT(term_signal == 0); - uv_close((uv_handle_t*)process, close_cb); -} - - -static void fail_cb(uv_process_t* process, - int64_t exit_status, - int term_signal) { - ASSERT(0 && "fail_cb called"); -} - - -static void kill_cb(uv_process_t* process, - int64_t exit_status, - int term_signal) { - int err; - - printf("exit_cb\n"); - exit_cb_called++; -#ifdef _WIN32 - ASSERT(exit_status == 1); -#else - ASSERT(exit_status == 0); -#endif - ASSERT(no_term_signal || term_signal == 15); - uv_close((uv_handle_t*)process, close_cb); - - /* - * Sending signum == 0 should check if the - * child process is still alive, not kill it. - * This process should be dead. - */ - err = uv_kill(process->pid, 0); - ASSERT(err == UV_ESRCH); -} - -static void detach_failure_cb(uv_process_t* process, - int64_t exit_status, - int term_signal) { - printf("detach_cb\n"); - exit_cb_called++; -} - -static void on_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = output + output_used; - buf->len = OUTPUT_SIZE - output_used; -} - - -static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - if (nread > 0) { - output_used += nread; - } else if (nread < 0) { - ASSERT(nread == UV_EOF); - uv_close((uv_handle_t*)tcp, close_cb); - } -} - - -static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - uv_read_stop(tcp); - on_read(tcp, nread, buf); -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(status == 0); - uv_close((uv_handle_t*)req->handle, close_cb); -} - - -static void init_process_options(char* test, uv_exit_cb exit_cb) { - /* Note spawn_helper1 defined in test/run-tests.c */ - int r = uv_exepath(exepath, &exepath_size); - ASSERT(r == 0); - exepath[exepath_size] = '\0'; - args[0] = exepath; - args[1] = test; - args[2] = NULL; - options.file = exepath; - options.args = args; - options.exit_cb = exit_cb; - options.flags = 0; -} - - -static void timer_cb(uv_timer_t* handle) { - uv_process_kill(&process, /* SIGTERM */ 15); - uv_close((uv_handle_t*)handle, close_cb); -} - - -static void timer_counter_cb(uv_timer_t* handle) { - ++timer_counter; -} - - -TEST_IMPL(spawn_fails) { - int r; - - init_process_options("", fail_cb); - options.file = options.args[0] = "program-that-had-better-not-exist"; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == UV_ENOENT || r == UV_EACCES); - ASSERT(0 == uv_is_active((uv_handle_t*) &process)); - uv_close((uv_handle_t*) &process, NULL); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -#ifndef _WIN32 -TEST_IMPL(spawn_fails_check_for_waitpid_cleanup) { - int r; - int status; - int err; - - init_process_options("", fail_cb); - options.file = options.args[0] = "program-that-had-better-not-exist"; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == UV_ENOENT || r == UV_EACCES); - ASSERT(0 == uv_is_active((uv_handle_t*) &process)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - /* verify the child is successfully cleaned up within libuv */ - do - err = waitpid(process.pid, &status, 0); - while (err == -1 && errno == EINTR); - - ASSERT(err == -1); - ASSERT(errno == ECHILD); - - uv_close((uv_handle_t*) &process, NULL); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif - - -TEST_IMPL(spawn_exit_code) { - int r; - - init_process_options("spawn_helper1", exit_cb); - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_stdout) { - int r; - uv_pipe_t out; - uv_stdio_container_t stdio[2]; - - init_process_options("spawn_helper2", exit_cb); - - uv_pipe_init(uv_default_loop(), &out, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - options.stdio_count = 2; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */ - printf("output is: %s", output); - ASSERT(strcmp("hello world\n", output) == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_stdout_to_file) { - int r; - uv_file file; - uv_fs_t fs_req; - uv_stdio_container_t stdio[2]; - uv_buf_t buf; - - /* Setup. */ - unlink("stdout_file"); - - init_process_options("spawn_helper2", exit_cb); - - r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR, - S_IRUSR | S_IWUSR, NULL); - ASSERT(r != -1); - uv_fs_req_cleanup(&fs_req); - - file = r; - - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_INHERIT_FD; - options.stdio[1].data.fd = file; - options.stdio_count = 2; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - buf = uv_buf_init(output, sizeof(output)); - r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL); - ASSERT(r == 12); - uv_fs_req_cleanup(&fs_req); - - r = uv_fs_close(NULL, &fs_req, file, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&fs_req); - - printf("output is: %s", output); - ASSERT(strcmp("hello world\n", output) == 0); - - /* Cleanup. */ - unlink("stdout_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_stdout_and_stderr_to_file) { - int r; - uv_file file; - uv_fs_t fs_req; - uv_stdio_container_t stdio[3]; - uv_buf_t buf; - - /* Setup. */ - unlink("stdout_file"); - - init_process_options("spawn_helper6", exit_cb); - - r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR, - S_IRUSR | S_IWUSR, NULL); - ASSERT(r != -1); - uv_fs_req_cleanup(&fs_req); - - file = r; - - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_INHERIT_FD; - options.stdio[1].data.fd = file; - options.stdio[2].flags = UV_INHERIT_FD; - options.stdio[2].data.fd = file; - options.stdio_count = 3; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - buf = uv_buf_init(output, sizeof(output)); - r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL); - ASSERT(r == 27); - uv_fs_req_cleanup(&fs_req); - - r = uv_fs_close(NULL, &fs_req, file, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&fs_req); - - printf("output is: %s", output); - ASSERT(strcmp("hello world\nhello errworld\n", output) == 0); - - /* Cleanup. */ - unlink("stdout_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_stdout_and_stderr_to_file2) { -#ifndef _WIN32 - int r; - uv_file file; - uv_fs_t fs_req; - uv_stdio_container_t stdio[3]; - uv_buf_t buf; - - /* Setup. */ - unlink("stdout_file"); - - init_process_options("spawn_helper6", exit_cb); - - /* Replace stderr with our file */ - r = uv_fs_open(NULL, - &fs_req, - "stdout_file", - O_CREAT | O_RDWR, - S_IRUSR | S_IWUSR, - NULL); - ASSERT(r != -1); - uv_fs_req_cleanup(&fs_req); - file = dup2(r, STDERR_FILENO); - ASSERT(file != -1); - - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_INHERIT_FD; - options.stdio[1].data.fd = file; - options.stdio[2].flags = UV_INHERIT_FD; - options.stdio[2].data.fd = file; - options.stdio_count = 3; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - buf = uv_buf_init(output, sizeof(output)); - r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL); - ASSERT(r == 27); - uv_fs_req_cleanup(&fs_req); - - r = uv_fs_close(NULL, &fs_req, file, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&fs_req); - - printf("output is: %s", output); - ASSERT(strcmp("hello world\nhello errworld\n", output) == 0); - - /* Cleanup. */ - unlink("stdout_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -#else - RETURN_SKIP("Unix only test"); -#endif -} - - -TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) { -#ifndef _WIN32 - int r; - uv_file stdout_file; - uv_file stderr_file; - uv_fs_t fs_req; - uv_stdio_container_t stdio[3]; - uv_buf_t buf; - - /* Setup. */ - unlink("stdout_file"); - unlink("stderr_file"); - - init_process_options("spawn_helper6", exit_cb); - - /* open 'stdout_file' and replace STDOUT_FILENO with it */ - r = uv_fs_open(NULL, - &fs_req, - "stdout_file", - O_CREAT | O_RDWR, - S_IRUSR | S_IWUSR, - NULL); - ASSERT(r != -1); - uv_fs_req_cleanup(&fs_req); - stdout_file = dup2(r, STDOUT_FILENO); - ASSERT(stdout_file != -1); - - /* open 'stderr_file' and replace STDERR_FILENO with it */ - r = uv_fs_open(NULL, &fs_req, "stderr_file", O_CREAT | O_RDWR, - S_IRUSR | S_IWUSR, NULL); - ASSERT(r != -1); - uv_fs_req_cleanup(&fs_req); - stderr_file = dup2(r, STDERR_FILENO); - ASSERT(stderr_file != -1); - - /* now we're going to swap them: the child process' stdout will be our - * stderr_file and vice versa */ - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_INHERIT_FD; - options.stdio[1].data.fd = stderr_file; - options.stdio[2].flags = UV_INHERIT_FD; - options.stdio[2].data.fd = stdout_file; - options.stdio_count = 3; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - buf = uv_buf_init(output, sizeof(output)); - - /* check the content of stdout_file */ - r = uv_fs_read(NULL, &fs_req, stdout_file, &buf, 1, 0, NULL); - ASSERT(r >= 15); - uv_fs_req_cleanup(&fs_req); - - r = uv_fs_close(NULL, &fs_req, stdout_file, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&fs_req); - - printf("output is: %s", output); - ASSERT(strncmp("hello errworld\n", output, 15) == 0); - - /* check the content of stderr_file */ - r = uv_fs_read(NULL, &fs_req, stderr_file, &buf, 1, 0, NULL); - ASSERT(r >= 12); - uv_fs_req_cleanup(&fs_req); - - r = uv_fs_close(NULL, &fs_req, stderr_file, NULL); - ASSERT(r == 0); - uv_fs_req_cleanup(&fs_req); - - printf("output is: %s", output); - ASSERT(strncmp("hello world\n", output, 12) == 0); - - /* Cleanup. */ - unlink("stdout_file"); - unlink("stderr_file"); - - MAKE_VALGRIND_HAPPY(); - return 0; -#else - RETURN_SKIP("Unix only test"); -#endif -} - - -TEST_IMPL(spawn_stdin) { - int r; - uv_pipe_t out; - uv_pipe_t in; - uv_write_t write_req; - uv_buf_t buf; - uv_stdio_container_t stdio[2]; - char buffer[] = "hello-from-spawn_stdin"; - - init_process_options("spawn_helper3", exit_cb); - - uv_pipe_init(uv_default_loop(), &out, 0); - uv_pipe_init(uv_default_loop(), &in, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*)∈ - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - options.stdio_count = 2; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - buf.base = buffer; - buf.len = sizeof(buffer); - r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 3); /* Once for process twice for the pipe. */ - ASSERT(strcmp(buffer, output) == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_stdio_greater_than_3) { - int r; - uv_pipe_t pipe; - uv_stdio_container_t stdio[4]; - - init_process_options("spawn_helper5", exit_cb); - - uv_pipe_init(uv_default_loop(), &pipe, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_IGNORE; - options.stdio[2].flags = UV_IGNORE; - options.stdio[3].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[3].data.stream = (uv_stream_t*)&pipe; - options.stdio_count = 4; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &pipe, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */ - printf("output from stdio[3] is: %s", output); - ASSERT(strcmp("fourth stdio!\n", output) == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_ignored_stdio) { - int r; - - init_process_options("spawn_helper6", exit_cb); - - options.stdio = NULL; - options.stdio_count = 0; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_and_kill) { - int r; - - init_process_options("spawn_helper4", kill_cb); - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_timer_init(uv_default_loop(), &timer); - ASSERT(r == 0); - - r = uv_timer_start(&timer, timer_cb, 500, 0); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 2); /* Once for process and once for timer. */ - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_preserve_env) { - int r; - uv_pipe_t out; - uv_stdio_container_t stdio[2]; - - init_process_options("spawn_helper7", exit_cb); - - uv_pipe_init(uv_default_loop(), &out, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*) &out; - options.stdio_count = 2; - - r = putenv("ENV_TEST=testval"); - ASSERT(r == 0); - - /* Explicitly set options.env to NULL to test for env clobbering. */ - options.env = NULL; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 2); - - printf("output is: %s", output); - ASSERT(strcmp("testval", output) == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_detached) { - int r; - - init_process_options("spawn_helper4", detach_failure_cb); - - options.flags |= UV_PROCESS_DETACHED; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - uv_unref((uv_handle_t*)&process); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 0); - - r = uv_kill(process.pid, 0); - ASSERT(r == 0); - - r = uv_kill(process.pid, 15); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -TEST_IMPL(spawn_and_kill_with_std) { - int r; - uv_pipe_t in, out, err; - uv_write_t write; - char message[] = "Nancy's joining me because the message this evening is " - "not my message but ours."; - uv_buf_t buf; - uv_stdio_container_t stdio[3]; - - init_process_options("spawn_helper4", kill_cb); - - r = uv_pipe_init(uv_default_loop(), &in, 0); - ASSERT(r == 0); - - r = uv_pipe_init(uv_default_loop(), &out, 0); - ASSERT(r == 0); - - r = uv_pipe_init(uv_default_loop(), &err, 0); - ASSERT(r == 0); - - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*)∈ - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - options.stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[2].data.stream = (uv_stream_t*)&err; - options.stdio_count = 3; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - buf = uv_buf_init(message, sizeof message); - r = uv_write(&write, (uv_stream_t*) &in, &buf, 1, write_cb); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &err, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_timer_init(uv_default_loop(), &timer); - ASSERT(r == 0); - - r = uv_timer_start(&timer, timer_cb, 500, 0); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 5); /* process x 1, timer x 1, stdio x 3. */ - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_and_ping) { - uv_write_t write_req; - uv_pipe_t in, out; - uv_buf_t buf; - uv_stdio_container_t stdio[2]; - int r; - - init_process_options("spawn_helper3", exit_cb); - buf = uv_buf_init("TEST", 4); - - uv_pipe_init(uv_default_loop(), &out, 0); - uv_pipe_init(uv_default_loop(), &in, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*)∈ - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - options.stdio_count = 2; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - /* Sending signum == 0 should check if the - * child process is still alive, not kill it. - */ - r = uv_process_kill(&process, 0); - ASSERT(r == 0); - - r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(strcmp(output, "TEST") == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_same_stdout_stderr) { - uv_write_t write_req; - uv_pipe_t in, out; - uv_buf_t buf; - uv_stdio_container_t stdio[3]; - int r; - - init_process_options("spawn_helper3", exit_cb); - buf = uv_buf_init("TEST", 4); - - uv_pipe_init(uv_default_loop(), &out, 0); - uv_pipe_init(uv_default_loop(), &in, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*)∈ - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - options.stdio_count = 2; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - /* Sending signum == 0 should check if the - * child process is still alive, not kill it. - */ - r = uv_process_kill(&process, 0); - ASSERT(r == 0); - - r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(strcmp(output, "TEST") == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_closed_process_io) { - uv_pipe_t in; - uv_write_t write_req; - uv_buf_t buf; - uv_stdio_container_t stdio[2]; - static char buffer[] = "hello-from-spawn_stdin\n"; - - init_process_options("spawn_helper3", exit_cb); - - uv_pipe_init(uv_default_loop(), &in, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*) ∈ - options.stdio_count = 1; - - close(0); /* Close process stdin. */ - - ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); - - buf = uv_buf_init(buffer, sizeof(buffer)); - ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb)); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 2); /* process, child stdin */ - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(kill) { - int r; - -#ifdef _WIN32 - no_term_signal = 1; -#endif - - init_process_options("spawn_helper4", kill_cb); - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - /* Sending signum == 0 should check if the - * child process is still alive, not kill it. - */ - r = uv_kill(process.pid, 0); - ASSERT(r == 0); - - /* Kill the process. */ - r = uv_kill(process.pid, /* SIGTERM */ 15); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -#ifdef _WIN32 -TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) { - int r; - uv_pipe_t out; - char name[64]; - HANDLE pipe_handle; - uv_stdio_container_t stdio[2]; - - init_process_options("spawn_helper2", exit_cb); - - uv_pipe_init(uv_default_loop(), &out, 0); - options.stdio = stdio; - options.stdio[0].flags = UV_IGNORE; - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - options.stdio_count = 2; - - /* Create a pipe that'll cause a collision. */ - _snprintf(name, - sizeof(name), - "\\\\.\\pipe\\uv\\%p-%d", - &out, - GetCurrentProcessId()); - pipe_handle = CreateNamedPipeA(name, - PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - 10, - 65536, - 65536, - 0, - NULL); - ASSERT(pipe_handle != INVALID_HANDLE_VALUE); - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */ - printf("output is: %s", output); - ASSERT(strcmp("hello world\n", output) == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -#if !defined(USING_UV_SHARED) -int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr); -WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target); - -TEST_IMPL(argument_escaping) { - const WCHAR* test_str[] = { - L"", - L"HelloWorld", - L"Hello World", - L"Hello\"World", - L"Hello World\\", - L"Hello\\\"World", - L"Hello\\World", - L"Hello\\\\World", - L"Hello World\\", - L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"" - }; - const int count = sizeof(test_str) / sizeof(*test_str); - WCHAR** test_output; - WCHAR* command_line; - WCHAR** cracked; - size_t total_size = 0; - int i; - int num_args; - int result; - - char* verbatim[] = { - "cmd.exe", - "/c", - "c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"", - NULL - }; - WCHAR* verbatim_output; - WCHAR* non_verbatim_output; - - test_output = calloc(count, sizeof(WCHAR*)); - ASSERT(test_output != NULL); - for (i = 0; i < count; ++i) { - test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR)); - quote_cmd_arg(test_str[i], test_output[i]); - wprintf(L"input : %s\n", test_str[i]); - wprintf(L"output: %s\n", test_output[i]); - total_size += wcslen(test_output[i]) + 1; - } - command_line = calloc(total_size + 1, sizeof(WCHAR)); - ASSERT(command_line != NULL); - for (i = 0; i < count; ++i) { - wcscat(command_line, test_output[i]); - wcscat(command_line, L" "); - } - command_line[total_size - 1] = L'\0'; - - wprintf(L"command_line: %s\n", command_line); - - cracked = CommandLineToArgvW(command_line, &num_args); - for (i = 0; i < num_args; ++i) { - wprintf(L"%d: %s\t%s\n", i, test_str[i], cracked[i]); - ASSERT(wcscmp(test_str[i], cracked[i]) == 0); - } - - LocalFree(cracked); - for (i = 0; i < count; ++i) { - free(test_output[i]); - } - - result = make_program_args(verbatim, 1, &verbatim_output); - ASSERT(result == 0); - result = make_program_args(verbatim, 0, &non_verbatim_output); - ASSERT(result == 0); - - wprintf(L" verbatim_output: %s\n", verbatim_output); - wprintf(L"non_verbatim_output: %s\n", non_verbatim_output); - - ASSERT(wcscmp(verbatim_output, - L"cmd.exe /c c:\\path\\to\\node.exe --eval " - L"\"require('c:\\\\path\\\\to\\\\test.js')\"") == 0); - ASSERT(wcscmp(non_verbatim_output, - L"cmd.exe /c \"c:\\path\\to\\node.exe --eval " - L"\\\"require('c:\\\\path\\\\to\\\\test.js')\\\"\"") == 0); - - free(verbatim_output); - free(non_verbatim_output); - - return 0; -} - -int make_program_env(char** env_block, WCHAR** dst_ptr); - -TEST_IMPL(environment_creation) { - int i; - char* environment[] = { - "FOO=BAR", - "SYSTEM=ROOT", /* substring of a supplied var name */ - "SYSTEMROOTED=OMG", /* supplied var name is a substring */ - "TEMP=C:\\Temp", - "INVALID", - "BAZ=QUX", - "B_Z=QUX", - "B\xe2\x82\xacZ=QUX", - "B\xf0\x90\x80\x82Z=QUX", - "B\xef\xbd\xa1Z=QUX", - "B\xf0\xa3\x91\x96Z=QUX", - "BAZ", /* repeat, invalid variable */ - NULL - }; - WCHAR* wenvironment[] = { - L"BAZ=QUX", - L"B_Z=QUX", - L"B\x20acZ=QUX", - L"B\xd800\xdc02Z=QUX", - L"B\xd84d\xdc56Z=QUX", - L"B\xff61Z=QUX", - L"FOO=BAR", - L"SYSTEM=ROOT", /* substring of a supplied var name */ - L"SYSTEMROOTED=OMG", /* supplied var name is a substring */ - L"TEMP=C:\\Temp", - }; - WCHAR* from_env[] = { - /* list should be kept in sync with list - * in process.c, minus variables in wenvironment */ - L"HOMEDRIVE", - L"HOMEPATH", - L"LOGONSERVER", - L"PATH", - L"USERDOMAIN", - L"USERNAME", - L"USERPROFILE", - L"SYSTEMDRIVE", - L"SYSTEMROOT", - L"WINDIR", - /* test for behavior in the absence of a - * required-environment variable: */ - L"ZTHIS_ENV_VARIABLE_DOES_NOT_EXIST", - }; - int found_in_loc_env[ARRAY_SIZE(wenvironment)] = {0}; - int found_in_usr_env[ARRAY_SIZE(from_env)] = {0}; - WCHAR *expected[ARRAY_SIZE(from_env)]; - int result; - WCHAR* str; - WCHAR* prev; - WCHAR* env; - - for (i = 0; i < ARRAY_SIZE(from_env); i++) { - /* copy expected additions to environment locally */ - size_t len = GetEnvironmentVariableW(from_env[i], NULL, 0); - if (len == 0) { - found_in_usr_env[i] = 1; - str = malloc(1 * sizeof(WCHAR)); - *str = 0; - expected[i] = str; - } else { - size_t name_len = wcslen(from_env[i]); - str = malloc((name_len+1+len) * sizeof(WCHAR)); - wmemcpy(str, from_env[i], name_len); - expected[i] = str; - str += name_len; - *str++ = L'='; - GetEnvironmentVariableW(from_env[i], str, len); - } - } - - result = make_program_env(environment, &env); - ASSERT(result == 0); - - for (str = env, prev = NULL; *str; prev = str, str += wcslen(str) + 1) { - int found = 0; -#if 0 - _cputws(str); - putchar('\n'); -#endif - for (i = 0; i < ARRAY_SIZE(wenvironment) && !found; i++) { - if (!wcscmp(str, wenvironment[i])) { - ASSERT(!found_in_loc_env[i]); - found_in_loc_env[i] = 1; - found = 1; - } - } - for (i = 0; i < ARRAY_SIZE(expected) && !found; i++) { - if (!wcscmp(str, expected[i])) { - ASSERT(!found_in_usr_env[i]); - found_in_usr_env[i] = 1; - found = 1; - } - } - if (prev) { /* verify sort order -- requires Vista */ -#if _WIN32_WINNT >= 0x0600 && \ - (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR)) - ASSERT(CompareStringOrdinal(prev, -1, str, -1, TRUE) == 1); -#endif - } - ASSERT(found); /* verify that we expected this variable */ - } - - /* verify that we found all expected variables */ - for (i = 0; i < ARRAY_SIZE(wenvironment); i++) { - ASSERT(found_in_loc_env[i]); - } - for (i = 0; i < ARRAY_SIZE(expected); i++) { - ASSERT(found_in_usr_env[i]); - } - - return 0; -} -#endif - -/* Regression test for issue #909 */ -TEST_IMPL(spawn_with_an_odd_path) { - int r; - - char newpath[2048]; - char *path = getenv("PATH"); - ASSERT(path != NULL); - snprintf(newpath, 2048, ";.;%s", path); - SetEnvironmentVariable("PATH", newpath); - - init_process_options("", exit_cb); - options.file = options.args[0] = "program-that-had-better-not-exist"; - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == UV_ENOENT || r == UV_EACCES); - ASSERT(0 == uv_is_active((uv_handle_t*) &process)); - uv_close((uv_handle_t*) &process, NULL); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif - -#ifndef _WIN32 -TEST_IMPL(spawn_setuid_setgid) { - int r; - struct passwd* pw; - - /* if not root, then this will fail. */ - uv_uid_t uid = getuid(); - if (uid != 0) { - fprintf(stderr, "spawn_setuid_setgid skipped: not root\n"); - return 0; - } - - init_process_options("spawn_helper1", exit_cb); - - /* become the "nobody" user. */ - pw = getpwnam("nobody"); - ASSERT(pw != NULL); - options.uid = pw->pw_uid; - options.gid = pw->pw_gid; - options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID; - - r = uv_spawn(uv_default_loop(), &process, &options); - if (r == UV_EACCES) - RETURN_SKIP("user 'nobody' cannot access the test runner"); - - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif - - -#ifndef _WIN32 -TEST_IMPL(spawn_setuid_fails) { - int r; - - /* if root, become nobody. */ - uv_uid_t uid = getuid(); - if (uid == 0) { - struct passwd* pw; - pw = getpwnam("nobody"); - ASSERT(pw != NULL); - ASSERT(0 == setgid(pw->pw_gid)); - ASSERT(0 == setuid(pw->pw_uid)); - } - - init_process_options("spawn_helper1", fail_cb); - - options.flags |= UV_PROCESS_SETUID; - options.uid = 0; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == UV_EPERM); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_setgid_fails) { - int r; - - /* if root, become nobody. */ - uv_uid_t uid = getuid(); - if (uid == 0) { - struct passwd* pw; - pw = getpwnam("nobody"); - ASSERT(pw != NULL); - ASSERT(0 == setgid(pw->pw_gid)); - ASSERT(0 == setuid(pw->pw_uid)); - } - - init_process_options("spawn_helper1", fail_cb); - - options.flags |= UV_PROCESS_SETGID; - options.gid = 0; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == UV_EPERM); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif - - -#ifdef _WIN32 - -static void exit_cb_unexpected(uv_process_t* process, - int64_t exit_status, - int term_signal) { - ASSERT(0 && "should not have been called"); -} - - -TEST_IMPL(spawn_setuid_fails) { - int r; - - init_process_options("spawn_helper1", exit_cb_unexpected); - - options.flags |= UV_PROCESS_SETUID; - options.uid = (uv_uid_t) -42424242; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == UV_ENOTSUP); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(spawn_setgid_fails) { - int r; - - init_process_options("spawn_helper1", exit_cb_unexpected); - - options.flags |= UV_PROCESS_SETGID; - options.gid = (uv_gid_t) -42424242; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == UV_ENOTSUP); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif - - -TEST_IMPL(spawn_auto_unref) { - init_process_options("spawn_helper1", NULL); - ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(0 == uv_is_closing((uv_handle_t*) &process)); - uv_close((uv_handle_t*) &process, NULL); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(1 == uv_is_closing((uv_handle_t*) &process)); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -#ifndef _WIN32 -TEST_IMPL(spawn_fs_open) { - int fd; - uv_fs_t fs_req; - uv_pipe_t in; - uv_write_t write_req; - uv_buf_t buf; - uv_stdio_container_t stdio[1]; - - fd = uv_fs_open(NULL, &fs_req, "/dev/null", O_RDWR, 0, NULL); - ASSERT(fd >= 0); - uv_fs_req_cleanup(&fs_req); - - init_process_options("spawn_helper8", exit_cb); - - ASSERT(0 == uv_pipe_init(uv_default_loop(), &in, 0)); - - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*) ∈ - options.stdio_count = 1; - - ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); - - buf = uv_buf_init((char*) &fd, sizeof(fd)); - ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb)); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(0 == uv_fs_close(NULL, &fs_req, fd, NULL)); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 2); /* One for `in`, one for process */ - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif /* !_WIN32 */ - - -#ifndef _WIN32 -TEST_IMPL(closed_fd_events) { - uv_stdio_container_t stdio[3]; - uv_pipe_t pipe_handle; - int fd[2]; - - /* create a pipe and share it with a child process */ - ASSERT(0 == pipe(fd)); - - /* spawn_helper4 blocks indefinitely. */ - init_process_options("spawn_helper4", exit_cb); - options.stdio_count = 3; - options.stdio = stdio; - options.stdio[0].flags = UV_INHERIT_FD; - options.stdio[0].data.fd = fd[0]; - options.stdio[1].flags = UV_IGNORE; - options.stdio[2].flags = UV_IGNORE; - - ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); - uv_unref((uv_handle_t*) &process); - - /* read from the pipe with uv */ - ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0)); - ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0])); - fd[0] = -1; - - ASSERT(0 == uv_read_start((uv_stream_t*) &pipe_handle, on_alloc, on_read_once)); - - ASSERT(1 == write(fd[1], "", 1)); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); - - /* should have received just one byte */ - ASSERT(output_used == 1); - - /* close the pipe and see if we still get events */ - uv_close((uv_handle_t*) &pipe_handle, close_cb); - - ASSERT(1 == write(fd[1], "", 1)); - - ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); - ASSERT(0 == uv_timer_start(&timer, timer_counter_cb, 10, 0)); - - /* see if any spurious events interrupt the timer */ - if (1 == uv_run(uv_default_loop(), UV_RUN_ONCE)) - /* have to run again to really trigger the timer */ - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); - - ASSERT(timer_counter == 1); - - /* cleanup */ - ASSERT(0 == uv_process_kill(&process, /* SIGTERM */ 15)); - ASSERT(0 == close(fd[1])); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif /* !_WIN32 */ - -TEST_IMPL(spawn_reads_child_path) { - int r; - int len; - char file[64]; - char path[1024]; - char* env[3]; - - /* Need to carry over the dynamic linker path when the test runner is - * linked against libuv.so, see https://github.com/libuv/libuv/issues/85. - */ -#if defined(__APPLE__) - static const char dyld_path_var[] = "DYLD_LIBRARY_PATH"; -#else - static const char dyld_path_var[] = "LD_LIBRARY_PATH"; -#endif - - /* Set up the process, but make sure that the file to run is relative and */ - /* requires a lookup into PATH */ - init_process_options("spawn_helper1", exit_cb); - - /* Set up the PATH env variable */ - for (len = strlen(exepath); - exepath[len - 1] != '/' && exepath[len - 1] != '\\'; - len--); - strcpy(file, exepath + len); - exepath[len] = 0; - strcpy(path, "PATH="); - strcpy(path + 5, exepath); - - env[0] = path; - env[1] = getenv(dyld_path_var); - env[2] = NULL; - - if (env[1] != NULL) { - static char buf[1024 + sizeof(dyld_path_var)]; - snprintf(buf, sizeof(buf), "%s=%s", dyld_path_var, env[1]); - env[1] = buf; - } - - options.file = file; - options.args[0] = file; - options.env = env; - - r = uv_spawn(uv_default_loop(), &process, &options); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#ifndef _WIN32 -static int mpipe(int *fds) { - if (pipe(fds) == -1) - return -1; - if (fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 || - fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) { - close(fds[0]); - close(fds[1]); - return -1; - } - return 0; -} -#else -static int mpipe(int *fds) { - SECURITY_ATTRIBUTES attr; - HANDLE readh, writeh; - attr.nLength = sizeof(attr); - attr.lpSecurityDescriptor = NULL; - attr.bInheritHandle = FALSE; - if (!CreatePipe(&readh, &writeh, &attr, 0)) - return -1; - fds[0] = _open_osfhandle((intptr_t)readh, 0); - fds[1] = _open_osfhandle((intptr_t)writeh, 0); - if (fds[0] == -1 || fds[1] == -1) { - CloseHandle(readh); - CloseHandle(writeh); - return -1; - } - return 0; -} -#endif /* !_WIN32 */ - -TEST_IMPL(spawn_inherit_streams) { - uv_process_t child_req; - uv_stdio_container_t child_stdio[2]; - int fds_stdin[2]; - int fds_stdout[2]; - uv_pipe_t pipe_stdin_child; - uv_pipe_t pipe_stdout_child; - uv_pipe_t pipe_stdin_parent; - uv_pipe_t pipe_stdout_parent; - unsigned char ubuf[OUTPUT_SIZE - 1]; - uv_buf_t buf; - unsigned int i; - int r; - uv_write_t write_req; - uv_loop_t* loop; - - init_process_options("spawn_helper9", exit_cb); - - loop = uv_default_loop(); - ASSERT(uv_pipe_init(loop, &pipe_stdin_child, 0) == 0); - ASSERT(uv_pipe_init(loop, &pipe_stdout_child, 0) == 0); - ASSERT(uv_pipe_init(loop, &pipe_stdin_parent, 0) == 0); - ASSERT(uv_pipe_init(loop, &pipe_stdout_parent, 0) == 0); - - ASSERT(mpipe(fds_stdin) != -1); - ASSERT(mpipe(fds_stdout) != -1); - - ASSERT(uv_pipe_open(&pipe_stdin_child, fds_stdin[0]) == 0); - ASSERT(uv_pipe_open(&pipe_stdout_child, fds_stdout[1]) == 0); - ASSERT(uv_pipe_open(&pipe_stdin_parent, fds_stdin[1]) == 0); - ASSERT(uv_pipe_open(&pipe_stdout_parent, fds_stdout[0]) == 0); - - child_stdio[0].flags = UV_INHERIT_STREAM; - child_stdio[0].data.stream = (uv_stream_t *)&pipe_stdin_child; - - child_stdio[1].flags = UV_INHERIT_STREAM; - child_stdio[1].data.stream = (uv_stream_t *)&pipe_stdout_child; - - options.stdio = child_stdio; - options.stdio_count = 2; - - ASSERT(uv_spawn(loop, &child_req, &options) == 0); - - uv_close((uv_handle_t*)&pipe_stdin_child, NULL); - uv_close((uv_handle_t*)&pipe_stdout_child, NULL); - - buf = uv_buf_init((char*)ubuf, sizeof ubuf); - for (i = 0; i < sizeof ubuf; ++i) - ubuf[i] = i & 255u; - memset(output, 0, sizeof ubuf); - - r = uv_write(&write_req, - (uv_stream_t*)&pipe_stdin_parent, - &buf, - 1, - write_cb); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)&pipe_stdout_parent, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 3); - - r = memcmp(ubuf, output, sizeof ubuf); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -/* Helper for child process of spawn_inherit_streams */ -#ifndef _WIN32 -int spawn_stdin_stdout(void) { - char buf[1024]; - char* pbuf; - for (;;) { - ssize_t r, w, c; - do { - r = read(0, buf, sizeof buf); - } while (r == -1 && errno == EINTR); - if (r == 0) { - return 1; - } - ASSERT(r > 0); - c = r; - pbuf = buf; - while (c) { - do { - w = write(1, pbuf, (size_t)c); - } while (w == -1 && errno == EINTR); - ASSERT(w >= 0); - pbuf = pbuf + w; - c = c - w; - } - } - return 2; -} -#else -int spawn_stdin_stdout(void) { - char buf[1024]; - char* pbuf; - HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE); - HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); - ASSERT(h_stdin != INVALID_HANDLE_VALUE); - ASSERT(h_stdout != INVALID_HANDLE_VALUE); - for (;;) { - DWORD n_read; - DWORD n_written; - DWORD to_write; - if (!ReadFile(h_stdin, buf, sizeof buf, &n_read, NULL)) { - ASSERT(GetLastError() == ERROR_BROKEN_PIPE); - return 1; - } - to_write = n_read; - pbuf = buf; - while (to_write) { - ASSERT(WriteFile(h_stdout, pbuf, to_write, &n_written, NULL)); - to_write -= n_written; - pbuf += n_written; - } - } - return 2; -} -#endif /* !_WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-stdio-over-pipes.c b/outside/libuv-v1.7.5/test/test-stdio-over-pipes.c deleted file mode 100644 index 1574476104..0000000000 --- a/outside/libuv-v1.7.5/test/test-stdio-over-pipes.c +++ /dev/null @@ -1,255 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -static char exepath[1024]; -static size_t exepath_size = 1024; -static char* args[3]; -static uv_process_options_t options; -static int close_cb_called; -static int exit_cb_called; -static int on_read_cb_called; -static int after_write_cb_called; -static uv_pipe_t in; -static uv_pipe_t out; -static uv_loop_t* loop; -#define OUTPUT_SIZE 1024 -static char output[OUTPUT_SIZE]; -static int output_used; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void exit_cb(uv_process_t* process, - int64_t exit_status, - int term_signal) { - printf("exit_cb\n"); - exit_cb_called++; - ASSERT(exit_status == 0); - ASSERT(term_signal == 0); - uv_close((uv_handle_t*)process, close_cb); - uv_close((uv_handle_t*)&in, close_cb); - uv_close((uv_handle_t*)&out, close_cb); -} - - -static void init_process_options(char* test, uv_exit_cb exit_cb) { - int r = uv_exepath(exepath, &exepath_size); - ASSERT(r == 0); - exepath[exepath_size] = '\0'; - args[0] = exepath; - args[1] = test; - args[2] = NULL; - options.file = exepath; - options.args = args; - options.exit_cb = exit_cb; -} - - -static void on_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = output + output_used; - buf->len = OUTPUT_SIZE - output_used; -} - - -static void after_write(uv_write_t* req, int status) { - if (status) { - fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); - ASSERT(0); - } - - /* Free the read/write buffer and the request */ - free(req); - - after_write_cb_called++; -} - - -static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* rdbuf) { - uv_write_t* req; - uv_buf_t wrbuf; - int r; - - ASSERT(nread > 0 || nread == UV_EOF); - - if (nread > 0) { - output_used += nread; - if (output_used == 12) { - ASSERT(memcmp("hello world\n", output, 12) == 0); - wrbuf = uv_buf_init(output, output_used); - req = malloc(sizeof(*req)); - r = uv_write(req, (uv_stream_t*)&in, &wrbuf, 1, after_write); - ASSERT(r == 0); - } - } - - on_read_cb_called++; -} - - -TEST_IMPL(stdio_over_pipes) { - int r; - uv_process_t process; - uv_stdio_container_t stdio[2]; - - loop = uv_default_loop(); - - init_process_options("stdio_over_pipes_helper", exit_cb); - - uv_pipe_init(loop, &out, 0); - uv_pipe_init(loop, &in, 0); - - options.stdio = stdio; - options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; - options.stdio[0].data.stream = (uv_stream_t*)∈ - options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; - options.stdio[1].data.stream = (uv_stream_t*)&out; - options.stdio_count = 2; - - r = uv_spawn(loop, &process, &options); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(on_read_cb_called > 1); - ASSERT(after_write_cb_called == 1); - ASSERT(exit_cb_called == 1); - ASSERT(close_cb_called == 3); - ASSERT(memcmp("hello world\n", output, 12) == 0); - ASSERT(output_used == 12); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -/* Everything here runs in a child process. */ - -static int on_pipe_read_called; -static int after_write_called; -static uv_pipe_t stdin_pipe; -static uv_pipe_t stdout_pipe; - -static void on_pipe_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - ASSERT(nread > 0); - ASSERT(memcmp("hello world\n", buf->base, nread) == 0); - on_pipe_read_called++; - - free(buf->base); - - uv_close((uv_handle_t*)&stdin_pipe, close_cb); - uv_close((uv_handle_t*)&stdout_pipe, close_cb); -} - - -static void after_pipe_write(uv_write_t* req, int status) { - ASSERT(status == 0); - after_write_called++; -} - - -static void on_read_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -int stdio_over_pipes_helper(void) { - /* Write several buffers to test that the write order is preserved. */ - char* buffers[] = { - "he", - "ll", - "o ", - "wo", - "rl", - "d", - "\n" - }; - - uv_write_t write_req[ARRAY_SIZE(buffers)]; - uv_buf_t buf[ARRAY_SIZE(buffers)]; - unsigned int i; - int r; - uv_loop_t* loop = uv_default_loop(); - - ASSERT(UV_NAMED_PIPE == uv_guess_handle(0)); - ASSERT(UV_NAMED_PIPE == uv_guess_handle(1)); - - r = uv_pipe_init(loop, &stdin_pipe, 0); - ASSERT(r == 0); - r = uv_pipe_init(loop, &stdout_pipe, 0); - ASSERT(r == 0); - - uv_pipe_open(&stdin_pipe, 0); - uv_pipe_open(&stdout_pipe, 1); - - /* Unref both stdio handles to make sure that all writes complete. */ - uv_unref((uv_handle_t*)&stdin_pipe); - uv_unref((uv_handle_t*)&stdout_pipe); - - for (i = 0; i < ARRAY_SIZE(buffers); i++) { - buf[i] = uv_buf_init((char*)buffers[i], strlen(buffers[i])); - } - - for (i = 0; i < ARRAY_SIZE(buffers); i++) { - r = uv_write(&write_req[i], (uv_stream_t*)&stdout_pipe, &buf[i], 1, - after_pipe_write); - ASSERT(r == 0); - } - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(after_write_called == 7); - ASSERT(on_pipe_read_called == 0); - ASSERT(close_cb_called == 0); - - uv_ref((uv_handle_t*)&stdout_pipe); - uv_ref((uv_handle_t*)&stdin_pipe); - - r = uv_read_start((uv_stream_t*)&stdin_pipe, on_read_alloc, on_pipe_read); - ASSERT(r == 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(after_write_called == 7); - ASSERT(on_pipe_read_called == 1); - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-bind-error.c b/outside/libuv-v1.7.5/test/test-tcp-bind-error.c deleted file mode 100644 index 10ed68e10e..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-bind-error.c +++ /dev/null @@ -1,216 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -TEST_IMPL(tcp_bind_error_addrinuse) { - struct sockaddr_in addr; - uv_tcp_t server1, server2; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - r = uv_tcp_init(uv_default_loop(), &server1); - ASSERT(r == 0); - r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_tcp_init(uv_default_loop(), &server2); - ASSERT(r == 0); - r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server1, 128, NULL); - ASSERT(r == 0); - r = uv_listen((uv_stream_t*)&server2, 128, NULL); - ASSERT(r == UV_EADDRINUSE); - - uv_close((uv_handle_t*)&server1, close_cb); - uv_close((uv_handle_t*)&server2, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind_error_addrnotavail_1) { - struct sockaddr_in addr; - uv_tcp_t server; - int r; - - ASSERT(0 == uv_ip4_addr("127.255.255.255", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - /* It seems that Linux is broken here - bind succeeds. */ - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0 || r == UV_EADDRNOTAVAIL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind_error_addrnotavail_2) { - struct sockaddr_in addr; - uv_tcp_t server; - int r; - - ASSERT(0 == uv_ip4_addr("4.4.4.4", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == UV_EADDRNOTAVAIL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind_error_fault) { - char garbage[] = - "blah blah blah blah blah blah blah blah blah blah blah blah"; - struct sockaddr_in* garbage_addr; - uv_tcp_t server; - int r; - - garbage_addr = (struct sockaddr_in*) &garbage; - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -/* Notes: On Linux uv_bind(server, NULL) will segfault the program. */ - -TEST_IMPL(tcp_bind_error_inval) { - struct sockaddr_in addr1; - struct sockaddr_in addr2; - uv_tcp_t server; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr1)); - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT_2, &addr2)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind_localhost_ok) { - struct sockaddr_in addr; - uv_tcp_t server; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind_invalid_flags) { - struct sockaddr_in addr; - uv_tcp_t server; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, UV_TCP_IPV6ONLY); - ASSERT(r == UV_EINVAL); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_listen_without_bind) { - int r; - uv_tcp_t server; - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_listen((uv_stream_t*)&server, 128, NULL); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-bind6-error.c b/outside/libuv-v1.7.5/test/test-tcp-bind6-error.c deleted file mode 100644 index b762bcb3d1..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-bind6-error.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -static int close_cb_called = 0; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -TEST_IMPL(tcp_bind6_error_addrinuse) { - struct sockaddr_in6 addr; - uv_tcp_t server1, server2; - int r; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server1); - ASSERT(r == 0); - r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_tcp_init(uv_default_loop(), &server2); - ASSERT(r == 0); - r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&server1, 128, NULL); - ASSERT(r == 0); - r = uv_listen((uv_stream_t*)&server2, 128, NULL); - ASSERT(r == UV_EADDRINUSE); - - uv_close((uv_handle_t*)&server1, close_cb); - uv_close((uv_handle_t*)&server2, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind6_error_addrnotavail) { - struct sockaddr_in6 addr; - uv_tcp_t server; - int r; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - ASSERT(0 == uv_ip6_addr("4:4:4:4:4:4:4:4", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == UV_EADDRNOTAVAIL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind6_error_fault) { - char garbage[] = - "blah blah blah blah blah blah blah blah blah blah blah blah"; - struct sockaddr_in6* garbage_addr; - uv_tcp_t server; - int r; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - garbage_addr = (struct sockaddr_in6*) &garbage; - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -/* Notes: On Linux uv_bind6(server, NULL) will segfault the program. */ - -TEST_IMPL(tcp_bind6_error_inval) { - struct sockaddr_in6 addr1; - struct sockaddr_in6 addr2; - uv_tcp_t server; - int r; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr1)); - ASSERT(0 == uv_ip6_addr("::", TEST_PORT_2, &addr2)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_bind6_localhost_ok) { - struct sockaddr_in6 addr; - uv_tcp_t server; - int r; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-close-accept.c b/outside/libuv-v1.7.5/test/test-tcp-close-accept.c deleted file mode 100644 index 5517aaf99e..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-close-accept.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* this test is Unix only */ -#ifndef _WIN32 - -#include "uv.h" -#include "task.h" - -#include -#include - -static struct sockaddr_in addr; -static uv_tcp_t tcp_server; -static uv_tcp_t tcp_outgoing[2]; -static uv_tcp_t tcp_incoming[ARRAY_SIZE(tcp_outgoing)]; -static uv_connect_t connect_reqs[ARRAY_SIZE(tcp_outgoing)]; -static uv_tcp_t tcp_check; -static uv_connect_t tcp_check_req; -static uv_write_t write_reqs[ARRAY_SIZE(tcp_outgoing)]; -static unsigned int got_connections; -static unsigned int close_cb_called; -static unsigned int write_cb_called; -static unsigned int read_cb_called; - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - -static void write_cb(uv_write_t* req, int status) { - ASSERT(status == 0); - write_cb_called++; -} - -static void connect_cb(uv_connect_t* req, int status) { - unsigned int i; - uv_buf_t buf; - uv_stream_t* outgoing; - - if (req == &tcp_check_req) { - ASSERT(status != 0); - - /* Close check and incoming[0], time to finish test */ - uv_close((uv_handle_t*) &tcp_incoming[0], close_cb); - uv_close((uv_handle_t*) &tcp_check, close_cb); - return; - } - - ASSERT(status == 0); - ASSERT(connect_reqs <= req); - ASSERT(req <= connect_reqs + ARRAY_SIZE(connect_reqs)); - i = req - connect_reqs; - - buf = uv_buf_init("x", 1); - outgoing = (uv_stream_t*) &tcp_outgoing[i]; - ASSERT(0 == uv_write(&write_reqs[i], outgoing, &buf, 1, write_cb)); -} - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - static char slab[1]; - buf->base = slab; - buf->len = sizeof(slab); -} - -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { - uv_loop_t* loop; - unsigned int i; - - /* Only first stream should receive read events */ - ASSERT(stream == (uv_stream_t*) &tcp_incoming[0]); - ASSERT(0 == uv_read_stop(stream)); - ASSERT(1 == nread); - - loop = stream->loop; - read_cb_called++; - - /* Close all active incomings, except current one */ - for (i = 1; i < got_connections; i++) - uv_close((uv_handle_t*) &tcp_incoming[i], close_cb); - - /* Create new fd that should be one of the closed incomings */ - ASSERT(0 == uv_tcp_init(loop, &tcp_check)); - ASSERT(0 == uv_tcp_connect(&tcp_check_req, - &tcp_check, - (const struct sockaddr*) &addr, - connect_cb)); - ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_check, alloc_cb, read_cb)); - - /* Close server, so no one will connect to it */ - uv_close((uv_handle_t*) &tcp_server, close_cb); -} - -static void connection_cb(uv_stream_t* server, int status) { - unsigned int i; - uv_tcp_t* incoming; - - ASSERT(server == (uv_stream_t*) &tcp_server); - - /* Ignore tcp_check connection */ - if (got_connections == ARRAY_SIZE(tcp_incoming)) - return; - - /* Accept everyone */ - incoming = &tcp_incoming[got_connections++]; - ASSERT(0 == uv_tcp_init(server->loop, incoming)); - ASSERT(0 == uv_accept(server, (uv_stream_t*) incoming)); - - if (got_connections != ARRAY_SIZE(tcp_incoming)) - return; - - /* Once all clients are accepted - start reading */ - for (i = 0; i < ARRAY_SIZE(tcp_incoming); i++) { - incoming = &tcp_incoming[i]; - ASSERT(0 == uv_read_start((uv_stream_t*) incoming, alloc_cb, read_cb)); - } -} - -TEST_IMPL(tcp_close_accept) { - unsigned int i; - uv_loop_t* loop; - uv_tcp_t* client; - - /* - * A little explanation of what goes on below: - * - * We'll create server and connect to it using two clients, each writing one - * byte once connected. - * - * When all clients will be accepted by server - we'll start reading from them - * and, on first client's first byte, will close second client and server. - * After that, we'll immediately initiate new connection to server using - * tcp_check handle (thus, reusing fd from second client). - * - * In this situation uv__io_poll()'s event list should still contain read - * event for second client, and, if not cleaned up properly, `tcp_check` will - * receive stale event of second incoming and invoke `connect_cb` with zero - * status. - */ - - loop = uv_default_loop(); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - ASSERT(0 == uv_tcp_init(loop, &tcp_server)); - ASSERT(0 == uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0)); - ASSERT(0 == uv_listen((uv_stream_t*) &tcp_server, - ARRAY_SIZE(tcp_outgoing), - connection_cb)); - - for (i = 0; i < ARRAY_SIZE(tcp_outgoing); i++) { - client = tcp_outgoing + i; - - ASSERT(0 == uv_tcp_init(loop, client)); - ASSERT(0 == uv_tcp_connect(&connect_reqs[i], - client, - (const struct sockaddr*) &addr, - connect_cb)); - } - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(ARRAY_SIZE(tcp_outgoing) == got_connections); - ASSERT((ARRAY_SIZE(tcp_outgoing) + 2) == close_cb_called); - ASSERT(ARRAY_SIZE(tcp_outgoing) == write_cb_called); - ASSERT(1 == read_cb_called); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* !_WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-tcp-close-while-connecting.c b/outside/libuv-v1.7.5/test/test-tcp-close-while-connecting.c deleted file mode 100644 index 2c39b652b6..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-close-while-connecting.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_timer_t timer1_handle; -static uv_timer_t timer2_handle; -static uv_tcp_t tcp_handle; - -static int connect_cb_called; -static int timer1_cb_called; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(status == UV_ECANCELED); - uv_timer_stop(&timer2_handle); - connect_cb_called++; -} - - -static void timer1_cb(uv_timer_t* handle) { - uv_close((uv_handle_t*)handle, close_cb); - uv_close((uv_handle_t*)&tcp_handle, close_cb); - timer1_cb_called++; -} - - -static void timer2_cb(uv_timer_t* handle) { - ASSERT(0 && "should not be called"); -} - - -TEST_IMPL(tcp_close_while_connecting) { - uv_connect_t connect_req; - struct sockaddr_in addr; - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - ASSERT(0 == uv_ip4_addr("1.2.3.4", TEST_PORT, &addr)); - ASSERT(0 == uv_tcp_init(loop, &tcp_handle)); - r = uv_tcp_connect(&connect_req, - &tcp_handle, - (const struct sockaddr*) &addr, - connect_cb); - if (r == UV_ENETUNREACH) - RETURN_SKIP("Network unreachable."); - ASSERT(r == 0); - ASSERT(0 == uv_timer_init(loop, &timer1_handle)); - ASSERT(0 == uv_timer_start(&timer1_handle, timer1_cb, 50, 0)); - ASSERT(0 == uv_timer_init(loop, &timer2_handle)); - ASSERT(0 == uv_timer_start(&timer2_handle, timer2_cb, 86400 * 1000, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - ASSERT(connect_cb_called == 1); - ASSERT(timer1_cb_called == 1); - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-close.c b/outside/libuv-v1.7.5/test/test-tcp-close.c deleted file mode 100644 index e65885aa55..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-close.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include /* memset */ - -#define NUM_WRITE_REQS 32 - -static uv_tcp_t tcp_handle; -static uv_connect_t connect_req; - -static int write_cb_called; -static int close_cb_called; - -static void connect_cb(uv_connect_t* req, int status); -static void write_cb(uv_write_t* req, int status); -static void close_cb(uv_handle_t* handle); - - -static void connect_cb(uv_connect_t* conn_req, int status) { - uv_write_t* req; - uv_buf_t buf; - int i, r; - - buf = uv_buf_init("PING", 4); - for (i = 0; i < NUM_WRITE_REQS; i++) { - req = malloc(sizeof *req); - ASSERT(req != NULL); - - r = uv_write(req, (uv_stream_t*)&tcp_handle, &buf, 1, write_cb); - ASSERT(r == 0); - } - - uv_close((uv_handle_t*)&tcp_handle, close_cb); -} - - -static void write_cb(uv_write_t* req, int status) { - /* write callbacks should run before the close callback */ - ASSERT(close_cb_called == 0); - ASSERT(req->handle == (uv_stream_t*)&tcp_handle); - write_cb_called++; - free(req); -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*)&tcp_handle); - close_cb_called++; -} - - -static void connection_cb(uv_stream_t* server, int status) { - ASSERT(status == 0); -} - - -static void start_server(uv_loop_t* loop, uv_tcp_t* handle) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init(loop, handle); - ASSERT(r == 0); - - r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)handle, 128, connection_cb); - ASSERT(r == 0); - - uv_unref((uv_handle_t*)handle); -} - - -/* Check that pending write requests have their callbacks - * invoked when the handle is closed. - */ -TEST_IMPL(tcp_close) { - struct sockaddr_in addr; - uv_tcp_t tcp_server; - uv_loop_t* loop; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - loop = uv_default_loop(); - - /* We can't use the echo server, it doesn't handle ECONNRESET. */ - start_server(loop, &tcp_server); - - r = uv_tcp_init(loop, &tcp_handle); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &tcp_handle, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - ASSERT(write_cb_called == 0); - ASSERT(close_cb_called == 0); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - printf("%d of %d write reqs seen\n", write_cb_called, NUM_WRITE_REQS); - - ASSERT(write_cb_called == NUM_WRITE_REQS); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-connect-error-after-write.c b/outside/libuv-v1.7.5/test/test-tcp-connect-error-after-write.c deleted file mode 100644 index 3f2e3572da..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-connect-error-after-write.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -static int connect_cb_called; -static int write_cb_called; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(status < 0); - connect_cb_called++; - uv_close((uv_handle_t*)req->handle, close_cb); -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(status < 0); - write_cb_called++; -} - - -/* - * Try to connect to an address on which nothing listens, get ECONNREFUSED - * (uv errno 12) and get connect_cb() called once with status != 0. - * Related issue: https://github.com/joyent/libuv/issues/443 - */ -TEST_IMPL(tcp_connect_error_after_write) { - uv_connect_t connect_req; - struct sockaddr_in addr; - uv_write_t write_req; - uv_tcp_t conn; - uv_buf_t buf; - int r; - -#ifdef _WIN32 - fprintf(stderr, "This test is disabled on Windows for now.\n"); - fprintf(stderr, "See https://github.com/joyent/libuv/issues/444\n"); - return 0; /* windows slackers... */ -#endif - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - buf = uv_buf_init("TEST", 4); - - r = uv_tcp_init(uv_default_loop(), &conn); - ASSERT(r == 0); - - r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb); - ASSERT(r == UV_EBADF); - - r = uv_tcp_connect(&connect_req, - &conn, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-connect-error.c b/outside/libuv-v1.7.5/test/test-tcp-connect-error.c deleted file mode 100644 index eab1eeb254..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-connect-error.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -static int connect_cb_called = 0; -static int close_cb_called = 0; - - - -static void connect_cb(uv_connect_t* handle, int status) { - ASSERT(handle != NULL); - connect_cb_called++; -} - - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -TEST_IMPL(tcp_connect_error_fault) { - const char garbage[] = - "blah blah blah blah blah blah blah blah blah blah blah blah"; - const struct sockaddr_in* garbage_addr; - uv_tcp_t server; - int r; - uv_connect_t req; - - garbage_addr = (const struct sockaddr_in*) &garbage; - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_connect(&req, - &server, - (const struct sockaddr*) garbage_addr, - connect_cb); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(connect_cb_called == 0); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-connect-timeout.c b/outside/libuv-v1.7.5/test/test-tcp-connect-timeout.c deleted file mode 100644 index 081424b800..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-connect-timeout.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -static int connect_cb_called; -static int close_cb_called; - -static uv_connect_t connect_req; -static uv_timer_t timer; -static uv_tcp_t conn; - -static void connect_cb(uv_connect_t* req, int status); -static void timer_cb(uv_timer_t* handle); -static void close_cb(uv_handle_t* handle); - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(req == &connect_req); - ASSERT(status == UV_ECANCELED); - connect_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer); - uv_close((uv_handle_t*)&conn, close_cb); - uv_close((uv_handle_t*)&timer, close_cb); -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*)&conn || handle == (uv_handle_t*)&timer); - close_cb_called++; -} - - -/* Verify that connecting to an unreachable address or port doesn't hang - * the event loop. - */ -TEST_IMPL(tcp_connect_timeout) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("8.8.8.8", 9999, &addr)); - - r = uv_timer_init(uv_default_loop(), &timer); - ASSERT(r == 0); - - r = uv_timer_start(&timer, timer_cb, 50, 0); - ASSERT(r == 0); - - r = uv_tcp_init(uv_default_loop(), &conn); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &conn, - (const struct sockaddr*) &addr, - connect_cb); - if (r == UV_ENETUNREACH) - RETURN_SKIP("Network unreachable."); - ASSERT(r == 0); - - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-connect6-error.c b/outside/libuv-v1.7.5/test/test-tcp-connect6-error.c deleted file mode 100644 index 91ac0a3a10..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-connect6-error.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -static int connect_cb_called = 0; -static int close_cb_called = 0; - - -static void connect_cb(uv_connect_t* handle, int status) { - ASSERT(handle != NULL); - connect_cb_called++; -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -TEST_IMPL(tcp_connect6_error_fault) { - const char garbage[] = - "blah blah blah blah blah blah blah blah blah blah blah blah"; - const struct sockaddr_in6* garbage_addr; - uv_tcp_t server; - int r; - uv_connect_t req; - - garbage_addr = (const struct sockaddr_in6*) &garbage; - - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_connect(&req, - &server, - (const struct sockaddr*) garbage_addr, - connect_cb); - ASSERT(r == UV_EINVAL); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(connect_cb_called == 0); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-create-socket-early.c b/outside/libuv-v1.7.5/test/test-tcp-create-socket-early.c deleted file mode 100644 index 65650adcc2..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-create-socket-early.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (c) 2015 Saúl Ibarra Corretgé . - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - -#ifdef _WIN32 -# define INVALID_FD (INVALID_HANDLE_VALUE) -#else -# define INVALID_FD (-1) -#endif - - -static void on_connect(uv_connect_t* req, int status) { - ASSERT(status == 0); - uv_close((uv_handle_t*) req->handle, NULL); -} - - -static void on_connection(uv_stream_t* server, int status) { - uv_tcp_t* handle; - int r; - - ASSERT(status == 0); - - handle = malloc(sizeof(*handle)); - ASSERT(handle != NULL); - - r = uv_tcp_init_ex(server->loop, handle, AF_INET); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)handle); - ASSERT(r == UV_EBUSY); - - uv_close((uv_handle_t*) server, NULL); - uv_close((uv_handle_t*) handle, (uv_close_cb)free); -} - - -static void tcp_listener(uv_loop_t* loop, uv_tcp_t* server) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_tcp_init(loop, server); - ASSERT(r == 0); - - r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*) server, 128, on_connection); - ASSERT(r == 0); -} - - -static void tcp_connector(uv_loop_t* loop, uv_tcp_t* client, uv_connect_t* req) { - struct sockaddr_in server_addr; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); - - r = uv_tcp_init(loop, client); - ASSERT(r == 0); - - r = uv_tcp_connect(req, - client, - (const struct sockaddr*) &server_addr, - on_connect); - ASSERT(r == 0); -} - - -TEST_IMPL(tcp_create_early) { - struct sockaddr_in addr; - struct sockaddr_in sockname; - uv_tcp_t client; - uv_os_fd_t fd; - int r, namelen; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET); - ASSERT(r == 0); - - r = uv_fileno((const uv_handle_t*) &client, &fd); - ASSERT(r == 0); - ASSERT(fd != INVALID_FD); - - /* Windows returns WSAEINVAL if the socket is not bound */ -#ifndef _WIN32 - namelen = sizeof sockname; - r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); - ASSERT(r == 0); - ASSERT(sockname.sin_family == AF_INET); -#endif - - r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - namelen = sizeof sockname; - r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); - ASSERT(r == 0); - ASSERT(memcmp(&addr.sin_addr, - &sockname.sin_addr, - sizeof(addr.sin_addr)) == 0); - - uv_close((uv_handle_t*) &client, NULL); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_create_early_bad_bind) { - struct sockaddr_in addr; - uv_tcp_t client; - uv_os_fd_t fd; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET6); - ASSERT(r == 0); - - r = uv_fileno((const uv_handle_t*) &client, &fd); - ASSERT(r == 0); - ASSERT(fd != INVALID_FD); - - /* Windows returns WSAEINVAL if the socket is not bound */ -#ifndef _WIN32 - { - int namelen; - struct sockaddr_in6 sockname; - namelen = sizeof sockname; - r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); - ASSERT(r == 0); - ASSERT(sockname.sin6_family == AF_INET6); - } -#endif - - r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0); -#ifndef _WIN32 - ASSERT(r == UV_EINVAL); -#else - ASSERT(r == UV_EFAULT); -#endif - - uv_close((uv_handle_t*) &client, NULL); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_create_early_bad_domain) { - uv_tcp_t client; - int r; - - r = uv_tcp_init_ex(uv_default_loop(), &client, 47); - ASSERT(r == UV_EINVAL); - - r = uv_tcp_init_ex(uv_default_loop(), &client, 1024); - ASSERT(r == UV_EINVAL); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_create_early_accept) { - uv_tcp_t client, server; - uv_connect_t connect_req; - - tcp_listener(uv_default_loop(), &server); - tcp_connector(uv_default_loop(), &client, &connect_req); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-flags.c b/outside/libuv-v1.7.5/test/test-tcp-flags.c deleted file mode 100644 index 68afb39f45..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-flags.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - - -TEST_IMPL(tcp_flags) { - uv_loop_t* loop; - uv_tcp_t handle; - int r; - - loop = uv_default_loop(); - - r = uv_tcp_init(loop, &handle); - ASSERT(r == 0); - - r = uv_tcp_nodelay(&handle, 1); - ASSERT(r == 0); - - r = uv_tcp_keepalive(&handle, 1, 60); - ASSERT(r == 0); - - uv_close((uv_handle_t*)&handle, NULL); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-oob.c b/outside/libuv-v1.7.5/test/test-tcp-oob.c deleted file mode 100644 index fc011ee495..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-oob.c +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright Fedor Indutny. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#if !defined(_WIN32) - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -static uv_tcp_t server_handle; -static uv_tcp_t client_handle; -static uv_tcp_t peer_handle; -static uv_idle_t idle; -static uv_connect_t connect_req; -static int ticks; -static const int kMaxTicks = 10; - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char storage[1024]; - *buf = uv_buf_init(storage, sizeof(storage)); -} - - -static void idle_cb(uv_idle_t* idle) { - if (++ticks < kMaxTicks) - return; - - uv_close((uv_handle_t*) &server_handle, NULL); - uv_close((uv_handle_t*) &client_handle, NULL); - uv_close((uv_handle_t*) &peer_handle, NULL); - uv_close((uv_handle_t*) idle, NULL); -} - - -static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { - ASSERT(nread > 0); - ASSERT(0 == uv_idle_start(&idle, idle_cb)); -} - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(req->handle == (uv_stream_t*) &client_handle); - ASSERT(0 == status); -} - - -static void connection_cb(uv_stream_t* handle, int status) { - int r; - uv_os_fd_t fd; - - ASSERT(0 == status); - ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle)); - ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb)); - - /* Send some OOB data */ - ASSERT(0 == uv_fileno((uv_handle_t*) &client_handle, &fd)); - - ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &client_handle, 1)); - - /* The problem triggers only on a second message, it seem that xnu is not - * triggering `kevent()` for the first one - */ - do { - r = send(fd, "hello", 5, MSG_OOB); - } while (r < 0 && errno == EINTR); - ASSERT(5 == r); - - do { - r = send(fd, "hello", 5, MSG_OOB); - } while (r < 0 && errno == EINTR); - ASSERT(5 == r); - - ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &client_handle, 0)); -} - - -TEST_IMPL(tcp_oob) { - struct sockaddr_in addr; - uv_loop_t* loop; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - loop = uv_default_loop(); - - ASSERT(0 == uv_tcp_init(loop, &server_handle)); - ASSERT(0 == uv_tcp_init(loop, &client_handle)); - ASSERT(0 == uv_tcp_init(loop, &peer_handle)); - ASSERT(0 == uv_idle_init(loop, &idle)); - ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); - ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); - - /* Ensure two separate packets */ - ASSERT(0 == uv_tcp_nodelay(&client_handle, 1)); - - ASSERT(0 == uv_tcp_connect(&connect_req, - &client_handle, - (const struct sockaddr*) &addr, - connect_cb)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - ASSERT(ticks == kMaxTicks); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -#endif diff --git a/outside/libuv-v1.7.5/test/test-tcp-open.c b/outside/libuv-v1.7.5/test/test-tcp-open.c deleted file mode 100644 index 6c8d43d000..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-open.c +++ /dev/null @@ -1,220 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#include - -#ifndef _WIN32 -# include -#endif - -static int shutdown_cb_called = 0; -static int connect_cb_called = 0; -static int write_cb_called = 0; -static int close_cb_called = 0; - -static uv_connect_t connect_req; -static uv_shutdown_t shutdown_req; -static uv_write_t write_req; - - -static void startup(void) { -#ifdef _WIN32 - struct WSAData wsa_data; - int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); - ASSERT(r == 0); -#endif -} - - -static uv_os_sock_t create_tcp_socket(void) { - uv_os_sock_t sock; - - sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); -#ifdef _WIN32 - ASSERT(sock != INVALID_SOCKET); -#else - ASSERT(sock >= 0); -#endif - -#ifndef _WIN32 - { - /* Allow reuse of the port. */ - int yes = 1; - int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); - ASSERT(r == 0); - } -#endif - - return sock; -} - - -static void close_socket(uv_os_sock_t sock) { - int r; -#ifdef _WIN32 - r = closesocket(sock); -#else - r = close(sock); -#endif - ASSERT(r == 0); -} - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(req == &shutdown_req); - ASSERT(status == 0); - - /* Now we wait for the EOF */ - shutdown_cb_called++; -} - - -static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - ASSERT(tcp != NULL); - - if (nread >= 0) { - ASSERT(nread == 4); - ASSERT(memcmp("PING", buf->base, nread) == 0); - } - else { - ASSERT(nread == UV_EOF); - printf("GOT EOF\n"); - uv_close((uv_handle_t*)tcp, close_cb); - } -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); - - if (status) { - fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); - ASSERT(0); - } - - write_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - uv_buf_t buf = uv_buf_init("PING", 4); - uv_stream_t* stream; - int r; - - ASSERT(req == &connect_req); - ASSERT(status == 0); - - stream = req->handle; - connect_cb_called++; - - r = uv_write(&write_req, stream, &buf, 1, write_cb); - ASSERT(r == 0); - - /* Shutdown on drain. */ - r = uv_shutdown(&shutdown_req, stream, shutdown_cb); - ASSERT(r == 0); - - /* Start reading */ - r = uv_read_start(stream, alloc_cb, read_cb); - ASSERT(r == 0); -} - - -TEST_IMPL(tcp_open) { - struct sockaddr_in addr; - uv_tcp_t client; - uv_os_sock_t sock; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - startup(); - sock = create_tcp_socket(); - - r = uv_tcp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_tcp_open(&client, sock); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &client, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(shutdown_cb_called == 1); - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tcp_open_twice) { - uv_tcp_t client; - uv_os_sock_t sock1, sock2; - int r; - - startup(); - sock1 = create_tcp_socket(); - sock2 = create_tcp_socket(); - - r = uv_tcp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_tcp_open(&client, sock1); - ASSERT(r == 0); - - r = uv_tcp_open(&client, sock2); - ASSERT(r == UV_EBUSY); - close_socket(sock2); - - uv_close((uv_handle_t*) &client, NULL); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-read-stop.c b/outside/libuv-v1.7.5/test/test-tcp-read-stop.c deleted file mode 100644 index 488e8fb49a..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-read-stop.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_timer_t timer_handle; -static uv_tcp_t tcp_handle; -static uv_write_t write_req; - - -static void fail_cb(void) { - ASSERT(0 && "fail_cb called"); -} - - -static void write_cb(uv_write_t* req, int status) { - uv_close((uv_handle_t*) &timer_handle, NULL); - uv_close((uv_handle_t*) &tcp_handle, NULL); -} - - -static void timer_cb(uv_timer_t* handle) { - uv_buf_t buf = uv_buf_init("PING", 4); - ASSERT(0 == uv_write(&write_req, - (uv_stream_t*) &tcp_handle, - &buf, - 1, - write_cb)); - ASSERT(0 == uv_read_stop((uv_stream_t*) &tcp_handle)); -} - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(0 == status); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0)); - ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_handle, - (uv_alloc_cb) fail_cb, - (uv_read_cb) fail_cb)); -} - - -TEST_IMPL(tcp_read_stop) { - uv_connect_t connect_req; - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); - ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp_handle)); - ASSERT(0 == uv_tcp_connect(&connect_req, - &tcp_handle, - (const struct sockaddr*) &addr, - connect_cb)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - MAKE_VALGRIND_HAPPY(); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-shutdown-after-write.c b/outside/libuv-v1.7.5/test/test-tcp-shutdown-after-write.c deleted file mode 100644 index 463b4b0d79..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-shutdown-after-write.c +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static void write_cb(uv_write_t* req, int status); -static void shutdown_cb(uv_shutdown_t* req, int status); - -static uv_tcp_t conn; -static uv_timer_t timer; -static uv_connect_t connect_req; -static uv_write_t write_req; -static uv_shutdown_t shutdown_req; - -static int connect_cb_called; -static int write_cb_called; -static int shutdown_cb_called; - -static int conn_close_cb_called; -static int timer_close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - if (handle == (uv_handle_t*)&conn) - conn_close_cb_called++; - else if (handle == (uv_handle_t*)&timer) - timer_close_cb_called++; - else - ASSERT(0 && "bad handle in close_cb"); -} - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[64]; - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void timer_cb(uv_timer_t* handle) { - uv_buf_t buf; - int r; - - uv_close((uv_handle_t*)handle, close_cb); - - buf = uv_buf_init("TEST", 4); - r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb); - ASSERT(r == 0); - - r = uv_shutdown(&shutdown_req, (uv_stream_t*)&conn, shutdown_cb); - ASSERT(r == 0); -} - - -static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { -} - - -static void connect_cb(uv_connect_t* req, int status) { - int r; - - ASSERT(status == 0); - connect_cb_called++; - - r = uv_read_start((uv_stream_t*)&conn, alloc_cb, read_cb); - ASSERT(r == 0); -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(status == 0); - write_cb_called++; -} - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - ASSERT(status == 0); - shutdown_cb_called++; - uv_close((uv_handle_t*)&conn, close_cb); -} - - -TEST_IMPL(tcp_shutdown_after_write) { - struct sockaddr_in addr; - uv_loop_t* loop; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - loop = uv_default_loop(); - - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - - r = uv_timer_start(&timer, timer_cb, 125, 0); - ASSERT(r == 0); - - r = uv_tcp_init(loop, &conn); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &conn, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(shutdown_cb_called == 1); - ASSERT(conn_close_cb_called == 1); - ASSERT(timer_close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-try-write.c b/outside/libuv-v1.7.5/test/test-tcp-try-write.c deleted file mode 100644 index 8a60136b64..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-try-write.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define MAX_BYTES 1024 * 1024 - -static uv_tcp_t server; -static uv_tcp_t client; -static uv_tcp_t incoming; -static int connect_cb_called; -static int close_cb_called; -static int connection_cb_called; -static int bytes_read; -static int bytes_written; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - int r; - uv_buf_t buf; - ASSERT(status == 0); - connect_cb_called++; - - do { - buf = uv_buf_init("PING", 4); - r = uv_try_write((uv_stream_t*) &client, &buf, 1); - ASSERT(r > 0 || r == UV_EAGAIN); - if (r > 0) { - bytes_written += r; - break; - } - } while (1); - uv_close((uv_handle_t*) &client, close_cb); -} - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - static char base[1024]; - - buf->base = base; - buf->len = sizeof(base); -} - - -static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - if (nread < 0) { - uv_close((uv_handle_t*) tcp, close_cb); - uv_close((uv_handle_t*) &server, close_cb); - return; - } - - bytes_read += nread; -} - - -static void connection_cb(uv_stream_t* tcp, int status) { - ASSERT(status == 0); - - ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); - ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); - - connection_cb_called++; - ASSERT(0 == uv_read_start((uv_stream_t*) &incoming, alloc_cb, read_cb)); -} - - -static void start_server(void) { - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); - ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0)); - ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb)); -} - - -TEST_IMPL(tcp_try_write) { - uv_connect_t connect_req; - struct sockaddr_in addr; - - start_server(); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); - ASSERT(0 == uv_tcp_connect(&connect_req, - &client, - (struct sockaddr*) &addr, - connect_cb)); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - ASSERT(connect_cb_called == 1); - ASSERT(close_cb_called == 3); - ASSERT(connection_cb_called == 1); - ASSERT(bytes_read == bytes_written); - ASSERT(bytes_written > 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-unexpected-read.c b/outside/libuv-v1.7.5/test/test-tcp-unexpected-read.c deleted file mode 100644 index c7b981456b..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-unexpected-read.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_check_t check_handle; -static uv_timer_t timer_handle; -static uv_tcp_t server_handle; -static uv_tcp_t client_handle; -static uv_tcp_t peer_handle; -static uv_write_t write_req; -static uv_connect_t connect_req; - -static unsigned long ticks; /* event loop ticks */ - - -static void check_cb(uv_check_t* handle) { - ticks++; -} - - -static void timer_cb(uv_timer_t* handle) { - uv_close((uv_handle_t*) &check_handle, NULL); - uv_close((uv_handle_t*) &timer_handle, NULL); - uv_close((uv_handle_t*) &server_handle, NULL); - uv_close((uv_handle_t*) &client_handle, NULL); - uv_close((uv_handle_t*) &peer_handle, NULL); -} - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - ASSERT(0 && "alloc_cb should not have been called"); -} - - -static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { - ASSERT(0 && "read_cb should not have been called"); -} - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(req->handle == (uv_stream_t*) &client_handle); - ASSERT(0 == status); -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(req->handle == (uv_stream_t*) &peer_handle); - ASSERT(0 == status); -} - - -static void connection_cb(uv_stream_t* handle, int status) { - uv_buf_t buf; - - buf = uv_buf_init("PING", 4); - - ASSERT(0 == status); - ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle)); - ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb)); - ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &peer_handle, - &buf, 1, write_cb)); -} - - -TEST_IMPL(tcp_unexpected_read) { - struct sockaddr_in addr; - uv_loop_t* loop; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - loop = uv_default_loop(); - - ASSERT(0 == uv_timer_init(loop, &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1000, 0)); - ASSERT(0 == uv_check_init(loop, &check_handle)); - ASSERT(0 == uv_check_start(&check_handle, check_cb)); - ASSERT(0 == uv_tcp_init(loop, &server_handle)); - ASSERT(0 == uv_tcp_init(loop, &client_handle)); - ASSERT(0 == uv_tcp_init(loop, &peer_handle)); - ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); - ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); - ASSERT(0 == uv_tcp_connect(&connect_req, - &client_handle, - (const struct sockaddr*) &addr, - connect_cb)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - /* This is somewhat inexact but the idea is that the event loop should not - * start busy looping when the server sends a message and the client isn't - * reading. - */ - ASSERT(ticks <= 20); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-write-after-connect.c b/outside/libuv-v1.7.5/test/test-tcp-write-after-connect.c deleted file mode 100644 index aa03228f13..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-write-after-connect.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef _WIN32 - -#include "uv.h" -#include "task.h" - -uv_loop_t loop; -uv_tcp_t tcp_client; -uv_connect_t connection_request; -uv_write_t write_request; -uv_buf_t buf = { "HELLO", 4 }; - - -static void write_cb(uv_write_t *req, int status) { - ASSERT(status == UV_ECANCELED); - uv_close((uv_handle_t*) req->handle, NULL); -} - - -static void connect_cb(uv_connect_t *req, int status) { - ASSERT(status == UV_ECONNREFUSED); -} - - -TEST_IMPL(tcp_write_after_connect) { - struct sockaddr_in sa; - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); - ASSERT(0 == uv_loop_init(&loop)); - ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); - - ASSERT(0 == uv_tcp_connect(&connection_request, - &tcp_client, - (const struct sockaddr *) - &sa, - connect_cb)); - - ASSERT(0 == uv_write(&write_request, - (uv_stream_t *)&tcp_client, - &buf, 1, - write_cb)); - - uv_run(&loop, UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif diff --git a/outside/libuv-v1.7.5/test/test-tcp-write-fail.c b/outside/libuv-v1.7.5/test/test-tcp-write-fail.c deleted file mode 100644 index 2840d81610..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-write-fail.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#ifndef _WIN32 -# include -#endif - - -static int connect_cb_called = 0; -static int write_cb_called = 0; -static int close_cb_called = 0; - -static uv_connect_t connect_req; -static uv_write_t write_req; - - -static void close_socket(uv_tcp_t* sock) { - uv_os_fd_t fd; - int r; - - r = uv_fileno((uv_handle_t*)sock, &fd); - ASSERT(r == 0); -#ifdef _WIN32 - r = closesocket(fd); -#else - r = close(fd); -#endif - ASSERT(r == 0); -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); - - ASSERT(status != 0); - fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); - write_cb_called++; - - uv_close((uv_handle_t*)(req->handle), close_cb); -} - - -static void connect_cb(uv_connect_t* req, int status) { - uv_buf_t buf; - uv_stream_t* stream; - int r; - - ASSERT(req == &connect_req); - ASSERT(status == 0); - - stream = req->handle; - connect_cb_called++; - - /* close the socket, the hard way */ - close_socket((uv_tcp_t*)stream); - - buf = uv_buf_init("hello\n", 6); - r = uv_write(&write_req, stream, &buf, 1, write_cb); - ASSERT(r == 0); -} - - -TEST_IMPL(tcp_write_fail) { - struct sockaddr_in addr; - uv_tcp_t client; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_tcp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &client, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-write-queue-order.c b/outside/libuv-v1.7.5/test/test-tcp-write-queue-order.c deleted file mode 100644 index aa4d2acc24..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-write-queue-order.c +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include - -#include "uv.h" -#include "task.h" - -#define REQ_COUNT 10000 - -static uv_timer_t timer; -static uv_tcp_t server; -static uv_tcp_t client; -static uv_tcp_t incoming; -static int connect_cb_called; -static int close_cb_called; -static int connection_cb_called; -static int write_callbacks; -static int write_cancelled_callbacks; -static int write_error_callbacks; - -static uv_write_t write_requests[REQ_COUNT]; - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - -void timer_cb(uv_timer_t* handle) { - uv_close((uv_handle_t*) &client, close_cb); - uv_close((uv_handle_t*) &server, close_cb); - uv_close((uv_handle_t*) &incoming, close_cb); -} - -void write_cb(uv_write_t* req, int status) { - if (status == 0) - write_callbacks++; - else if (status == UV_ECANCELED) - write_cancelled_callbacks++; - else - write_error_callbacks++; -} - -static void connect_cb(uv_connect_t* req, int status) { - static char base[1024]; - int r; - int i; - uv_buf_t buf; - - ASSERT(status == 0); - connect_cb_called++; - - buf = uv_buf_init(base, sizeof(base)); - - for (i = 0; i < REQ_COUNT; i++) { - r = uv_write(&write_requests[i], - req->handle, - &buf, - 1, - write_cb); - ASSERT(r == 0); - } -} - - -static void connection_cb(uv_stream_t* tcp, int status) { - ASSERT(status == 0); - - ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); - ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); - - connection_cb_called++; -} - - -static void start_server(void) { - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); - ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0)); - ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb)); -} - - -TEST_IMPL(tcp_write_queue_order) { - uv_connect_t connect_req; - struct sockaddr_in addr; - - start_server(); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); - ASSERT(0 == uv_tcp_connect(&connect_req, - &client, - (struct sockaddr*) &addr, - connect_cb)); - - ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); - ASSERT(0 == uv_timer_start(&timer, timer_cb, 100, 0)); - - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - ASSERT(connect_cb_called == 1); - ASSERT(connection_cb_called == 1); - ASSERT(write_callbacks > 0); - ASSERT(write_cancelled_callbacks > 0); - ASSERT(write_callbacks + - write_error_callbacks + - write_cancelled_callbacks == REQ_COUNT); - ASSERT(close_cb_called == 3); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-write-to-half-open-connection.c b/outside/libuv-v1.7.5/test/test-tcp-write-to-half-open-connection.c deleted file mode 100644 index 2fa2ae7225..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-write-to-half-open-connection.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -static void connection_cb(uv_stream_t* server, int status); -static void connect_cb(uv_connect_t* req, int status); -static void write_cb(uv_write_t* req, int status); -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); -static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); - -static uv_tcp_t tcp_server; -static uv_tcp_t tcp_client; -static uv_tcp_t tcp_peer; /* client socket as accept()-ed by server */ -static uv_connect_t connect_req; -static uv_write_t write_req; - -static int write_cb_called; -static int read_cb_called; - -static void connection_cb(uv_stream_t* server, int status) { - int r; - uv_buf_t buf; - - ASSERT(server == (uv_stream_t*)&tcp_server); - ASSERT(status == 0); - - r = uv_tcp_init(server->loop, &tcp_peer); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)&tcp_peer); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)&tcp_peer, alloc_cb, read_cb); - ASSERT(r == 0); - - buf.base = "hello\n"; - buf.len = 6; - - r = uv_write(&write_req, (uv_stream_t*)&tcp_peer, &buf, 1, write_cb); - ASSERT(r == 0); -} - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[1024]; - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { - if (nread < 0) { - fprintf(stderr, "read_cb error: %s\n", uv_err_name(nread)); - ASSERT(nread == UV_ECONNRESET || nread == UV_EOF); - - uv_close((uv_handle_t*)&tcp_server, NULL); - uv_close((uv_handle_t*)&tcp_peer, NULL); - } - - read_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - ASSERT(req == &connect_req); - ASSERT(status == 0); - - /* Close the client. */ - uv_close((uv_handle_t*)&tcp_client, NULL); -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(status == 0); - write_cb_called++; -} - - -TEST_IMPL(tcp_write_to_half_open_connection) { - struct sockaddr_in addr; - uv_loop_t* loop; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - loop = uv_default_loop(); - ASSERT(loop != NULL); - - r = uv_tcp_init(loop, &tcp_server); - ASSERT(r == 0); - - r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_listen((uv_stream_t*)&tcp_server, 1, connection_cb); - ASSERT(r == 0); - - r = uv_tcp_init(loop, &tcp_client); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &tcp_client, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(write_cb_called > 0); - ASSERT(read_cb_called > 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tcp-writealot.c b/outside/libuv-v1.7.5/test/test-tcp-writealot.c deleted file mode 100644 index 6cfe2ebb18..0000000000 --- a/outside/libuv-v1.7.5/test/test-tcp-writealot.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include - - -#define WRITES 3 -#define CHUNKS_PER_WRITE 4096 -#define CHUNK_SIZE 10024 /* 10 kb */ - -#define TOTAL_BYTES (WRITES * CHUNKS_PER_WRITE * CHUNK_SIZE) - -static char* send_buffer; - -static int shutdown_cb_called = 0; -static int connect_cb_called = 0; -static int write_cb_called = 0; -static int close_cb_called = 0; -static size_t bytes_sent = 0; -static size_t bytes_sent_done = 0; -static size_t bytes_received_done = 0; - -static uv_connect_t connect_req; -static uv_shutdown_t shutdown_req; -static uv_write_t write_reqs[WRITES]; - - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf->base = malloc(size); - buf->len = size; -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void shutdown_cb(uv_shutdown_t* req, int status) { - uv_tcp_t* tcp; - - ASSERT(req == &shutdown_req); - ASSERT(status == 0); - - tcp = (uv_tcp_t*)(req->handle); - - /* The write buffer should be empty by now. */ - ASSERT(tcp->write_queue_size == 0); - - /* Now we wait for the EOF */ - shutdown_cb_called++; - - /* We should have had all the writes called already. */ - ASSERT(write_cb_called == WRITES); -} - - -static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - ASSERT(tcp != NULL); - - if (nread >= 0) { - bytes_received_done += nread; - } - else { - ASSERT(nread == UV_EOF); - printf("GOT EOF\n"); - uv_close((uv_handle_t*)tcp, close_cb); - } - - free(buf->base); -} - - -static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); - - if (status) { - fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); - ASSERT(0); - } - - bytes_sent_done += CHUNKS_PER_WRITE * CHUNK_SIZE; - write_cb_called++; -} - - -static void connect_cb(uv_connect_t* req, int status) { - uv_buf_t send_bufs[CHUNKS_PER_WRITE]; - uv_stream_t* stream; - int i, j, r; - - ASSERT(req == &connect_req); - ASSERT(status == 0); - - stream = req->handle; - connect_cb_called++; - - /* Write a lot of data */ - for (i = 0; i < WRITES; i++) { - uv_write_t* write_req = write_reqs + i; - - for (j = 0; j < CHUNKS_PER_WRITE; j++) { - send_bufs[j] = uv_buf_init(send_buffer + bytes_sent, CHUNK_SIZE); - bytes_sent += CHUNK_SIZE; - } - - r = uv_write(write_req, stream, send_bufs, CHUNKS_PER_WRITE, write_cb); - ASSERT(r == 0); - } - - /* Shutdown on drain. */ - r = uv_shutdown(&shutdown_req, stream, shutdown_cb); - ASSERT(r == 0); - - /* Start reading */ - r = uv_read_start(stream, alloc_cb, read_cb); - ASSERT(r == 0); -} - - -TEST_IMPL(tcp_writealot) { - struct sockaddr_in addr; - uv_tcp_t client; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - send_buffer = calloc(1, TOTAL_BYTES); - ASSERT(send_buffer != NULL); - - r = uv_tcp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_tcp_connect(&connect_req, - &client, - (const struct sockaddr*) &addr, - connect_cb); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(shutdown_cb_called == 1); - ASSERT(connect_cb_called == 1); - ASSERT(write_cb_called == WRITES); - ASSERT(close_cb_called == 1); - ASSERT(bytes_sent == TOTAL_BYTES); - ASSERT(bytes_sent_done == TOTAL_BYTES); - ASSERT(bytes_received_done == TOTAL_BYTES); - - free(send_buffer); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-thread-equal.c b/outside/libuv-v1.7.5/test/test-thread-equal.c deleted file mode 100644 index 27c07ee2c7..0000000000 --- a/outside/libuv-v1.7.5/test/test-thread-equal.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -uv_thread_t main_thread_id; -uv_thread_t subthreads[2]; - -static void check_thread(void* arg) { - uv_thread_t *thread_id = arg; - uv_thread_t self_id = uv_thread_self(); - ASSERT(uv_thread_equal(&main_thread_id, &self_id) == 0); - *thread_id = uv_thread_self(); -} - -TEST_IMPL(thread_equal) { - uv_thread_t threads[2]; - main_thread_id = uv_thread_self(); - ASSERT(0 != uv_thread_equal(&main_thread_id, &main_thread_id)); - ASSERT(0 == uv_thread_create(threads + 0, check_thread, subthreads + 0)); - ASSERT(0 == uv_thread_create(threads + 1, check_thread, subthreads + 1)); - ASSERT(0 == uv_thread_join(threads + 0)); - ASSERT(0 == uv_thread_join(threads + 1)); - ASSERT(0 == uv_thread_equal(subthreads + 0, subthreads + 1)); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-thread.c b/outside/libuv-v1.7.5/test/test-thread.c deleted file mode 100644 index 7f3321aa06..0000000000 --- a/outside/libuv-v1.7.5/test/test-thread.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include /* memset */ - -struct getaddrinfo_req { - uv_thread_t thread_id; - unsigned int counter; - uv_loop_t* loop; - uv_getaddrinfo_t handle; -}; - - -struct fs_req { - uv_thread_t thread_id; - unsigned int counter; - uv_loop_t* loop; - uv_fs_t handle; -}; - - -struct test_thread { - uv_thread_t thread_id; - volatile int thread_called; -}; - -static void getaddrinfo_do(struct getaddrinfo_req* req); -static void getaddrinfo_cb(uv_getaddrinfo_t* handle, - int status, - struct addrinfo* res); -static void fs_do(struct fs_req* req); -static void fs_cb(uv_fs_t* handle); - -static volatile int thread_called; -static uv_key_t tls_key; - - -static void getaddrinfo_do(struct getaddrinfo_req* req) { - int r; - - r = uv_getaddrinfo(req->loop, - &req->handle, - getaddrinfo_cb, - "localhost", - NULL, - NULL); - ASSERT(r == 0); -} - - -static void getaddrinfo_cb(uv_getaddrinfo_t* handle, - int status, - struct addrinfo* res) { - struct getaddrinfo_req* req; - - ASSERT(status == 0); - - req = container_of(handle, struct getaddrinfo_req, handle); - uv_freeaddrinfo(res); - - if (--req->counter) - getaddrinfo_do(req); -} - - -static void fs_do(struct fs_req* req) { - int r; - - r = uv_fs_stat(req->loop, &req->handle, ".", fs_cb); - ASSERT(r == 0); -} - - -static void fs_cb(uv_fs_t* handle) { - struct fs_req* req = container_of(handle, struct fs_req, handle); - - uv_fs_req_cleanup(handle); - - if (--req->counter) - fs_do(req); -} - - -static void do_work(void* arg) { - struct getaddrinfo_req getaddrinfo_reqs[16]; - struct fs_req fs_reqs[16]; - uv_loop_t* loop; - size_t i; - int r; - struct test_thread* thread = arg; - - loop = malloc(sizeof *loop); - ASSERT(loop != NULL); - ASSERT(0 == uv_loop_init(loop)); - - for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) { - struct getaddrinfo_req* req = getaddrinfo_reqs + i; - req->counter = 16; - req->loop = loop; - getaddrinfo_do(req); - } - - for (i = 0; i < ARRAY_SIZE(fs_reqs); i++) { - struct fs_req* req = fs_reqs + i; - req->counter = 16; - req->loop = loop; - fs_do(req); - } - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(0 == uv_loop_close(loop)); - free(loop); - thread->thread_called = 1; -} - - -static void thread_entry(void* arg) { - ASSERT(arg == (void *) 42); - thread_called++; -} - - -TEST_IMPL(thread_create) { - uv_thread_t tid; - int r; - - r = uv_thread_create(&tid, thread_entry, (void *) 42); - ASSERT(r == 0); - - r = uv_thread_join(&tid); - ASSERT(r == 0); - - ASSERT(thread_called == 1); - - return 0; -} - - -/* Hilariously bad test name. Run a lot of tasks in the thread pool and verify - * that each "finished" callback is run in its originating thread. - */ -TEST_IMPL(threadpool_multiple_event_loops) { - struct test_thread threads[8]; - size_t i; - int r; - - memset(threads, 0, sizeof(threads)); - - for (i = 0; i < ARRAY_SIZE(threads); i++) { - r = uv_thread_create(&threads[i].thread_id, do_work, &threads[i]); - ASSERT(r == 0); - } - - for (i = 0; i < ARRAY_SIZE(threads); i++) { - r = uv_thread_join(&threads[i].thread_id); - ASSERT(r == 0); - ASSERT(threads[i].thread_called); - } - - return 0; -} - - -static void tls_thread(void* arg) { - ASSERT(NULL == uv_key_get(&tls_key)); - uv_key_set(&tls_key, arg); - ASSERT(arg == uv_key_get(&tls_key)); - uv_key_set(&tls_key, NULL); - ASSERT(NULL == uv_key_get(&tls_key)); -} - - -TEST_IMPL(thread_local_storage) { - char name[] = "main"; - uv_thread_t threads[2]; - ASSERT(0 == uv_key_create(&tls_key)); - ASSERT(NULL == uv_key_get(&tls_key)); - uv_key_set(&tls_key, name); - ASSERT(name == uv_key_get(&tls_key)); - ASSERT(0 == uv_thread_create(threads + 0, tls_thread, threads + 0)); - ASSERT(0 == uv_thread_create(threads + 1, tls_thread, threads + 1)); - ASSERT(0 == uv_thread_join(threads + 0)); - ASSERT(0 == uv_thread_join(threads + 1)); - uv_key_delete(&tls_key); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-threadpool-cancel.c b/outside/libuv-v1.7.5/test/test-threadpool-cancel.c deleted file mode 100644 index cb45622451..0000000000 --- a/outside/libuv-v1.7.5/test/test-threadpool-cancel.c +++ /dev/null @@ -1,361 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#define INIT_CANCEL_INFO(ci, what) \ - do { \ - (ci)->reqs = (what); \ - (ci)->nreqs = ARRAY_SIZE(what); \ - (ci)->stride = sizeof((what)[0]); \ - } \ - while (0) - -struct cancel_info { - void* reqs; - unsigned nreqs; - unsigned stride; - uv_timer_t timer_handle; -}; - -static uv_cond_t signal_cond; -static uv_mutex_t signal_mutex; -static uv_mutex_t wait_mutex; -static unsigned num_threads; -static unsigned fs_cb_called; -static unsigned work_cb_called; -static unsigned done_cb_called; -static unsigned done2_cb_called; -static unsigned timer_cb_called; - - -static void work_cb(uv_work_t* req) { - uv_mutex_lock(&signal_mutex); - uv_cond_signal(&signal_cond); - uv_mutex_unlock(&signal_mutex); - - uv_mutex_lock(&wait_mutex); - uv_mutex_unlock(&wait_mutex); - - work_cb_called++; -} - - -static void done_cb(uv_work_t* req, int status) { - done_cb_called++; - free(req); -} - - -static void saturate_threadpool(void) { - uv_work_t* req; - - ASSERT(0 == uv_cond_init(&signal_cond)); - ASSERT(0 == uv_mutex_init(&signal_mutex)); - ASSERT(0 == uv_mutex_init(&wait_mutex)); - - uv_mutex_lock(&signal_mutex); - uv_mutex_lock(&wait_mutex); - - for (num_threads = 0; /* empty */; num_threads++) { - req = malloc(sizeof(*req)); - ASSERT(req != NULL); - ASSERT(0 == uv_queue_work(uv_default_loop(), req, work_cb, done_cb)); - - /* Expect to get signalled within 350 ms, otherwise assume that - * the thread pool is saturated. As with any timing dependent test, - * this is obviously not ideal. - */ - if (uv_cond_timedwait(&signal_cond, - &signal_mutex, - (uint64_t) (350 * 1e6))) { - ASSERT(0 == uv_cancel((uv_req_t*) req)); - break; - } - } -} - - -static void unblock_threadpool(void) { - uv_mutex_unlock(&signal_mutex); - uv_mutex_unlock(&wait_mutex); -} - - -static void cleanup_threadpool(void) { - ASSERT(done_cb_called == num_threads + 1); /* +1 == cancelled work req. */ - ASSERT(work_cb_called == num_threads); - - uv_cond_destroy(&signal_cond); - uv_mutex_destroy(&signal_mutex); - uv_mutex_destroy(&wait_mutex); -} - - -static void fs_cb(uv_fs_t* req) { - ASSERT(req->result == UV_ECANCELED); - uv_fs_req_cleanup(req); - fs_cb_called++; -} - - -static void getaddrinfo_cb(uv_getaddrinfo_t* req, - int status, - struct addrinfo* res) { - ASSERT(status == UV_EAI_CANCELED); - ASSERT(res == NULL); - uv_freeaddrinfo(res); /* Should not crash. */ -} - - -static void getnameinfo_cb(uv_getnameinfo_t* handle, - int status, - const char* hostname, - const char* service) { - ASSERT(status == UV_EAI_CANCELED); - ASSERT(hostname == NULL); - ASSERT(service == NULL); -} - - -static void work2_cb(uv_work_t* req) { - ASSERT(0 && "work2_cb called"); -} - - -static void done2_cb(uv_work_t* req, int status) { - ASSERT(status == UV_ECANCELED); - done2_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - struct cancel_info* ci; - uv_req_t* req; - unsigned i; - - ci = container_of(handle, struct cancel_info, timer_handle); - - for (i = 0; i < ci->nreqs; i++) { - req = (uv_req_t*) ((char*) ci->reqs + i * ci->stride); - ASSERT(0 == uv_cancel(req)); - } - - uv_close((uv_handle_t*) &ci->timer_handle, NULL); - unblock_threadpool(); - timer_cb_called++; -} - - -static void nop_work_cb(uv_work_t* req) { -} - - -static void nop_done_cb(uv_work_t* req, int status) { - req->data = "OK"; -} - - -TEST_IMPL(threadpool_cancel_getaddrinfo) { - uv_getaddrinfo_t reqs[4]; - struct cancel_info ci; - struct addrinfo hints; - uv_loop_t* loop; - int r; - - INIT_CANCEL_INFO(&ci, reqs); - loop = uv_default_loop(); - saturate_threadpool(); - - r = uv_getaddrinfo(loop, reqs + 0, getaddrinfo_cb, "fail", NULL, NULL); - ASSERT(r == 0); - - r = uv_getaddrinfo(loop, reqs + 1, getaddrinfo_cb, NULL, "fail", NULL); - ASSERT(r == 0); - - r = uv_getaddrinfo(loop, reqs + 2, getaddrinfo_cb, "fail", "fail", NULL); - ASSERT(r == 0); - - r = uv_getaddrinfo(loop, reqs + 3, getaddrinfo_cb, "fail", NULL, &hints); - ASSERT(r == 0); - - ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); - ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(1 == timer_cb_called); - - cleanup_threadpool(); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(threadpool_cancel_getnameinfo) { - uv_getnameinfo_t reqs[4]; - struct sockaddr_in addr4; - struct cancel_info ci; - uv_loop_t* loop; - int r; - - r = uv_ip4_addr("127.0.0.1", 80, &addr4); - ASSERT(r == 0); - - INIT_CANCEL_INFO(&ci, reqs); - loop = uv_default_loop(); - saturate_threadpool(); - - r = uv_getnameinfo(loop, reqs + 0, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); - ASSERT(r == 0); - - r = uv_getnameinfo(loop, reqs + 1, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); - ASSERT(r == 0); - - r = uv_getnameinfo(loop, reqs + 2, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); - ASSERT(r == 0); - - r = uv_getnameinfo(loop, reqs + 3, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); - ASSERT(r == 0); - - ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); - ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(1 == timer_cb_called); - - cleanup_threadpool(); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(threadpool_cancel_work) { - struct cancel_info ci; - uv_work_t reqs[16]; - uv_loop_t* loop; - unsigned i; - - INIT_CANCEL_INFO(&ci, reqs); - loop = uv_default_loop(); - saturate_threadpool(); - - for (i = 0; i < ARRAY_SIZE(reqs); i++) - ASSERT(0 == uv_queue_work(loop, reqs + i, work2_cb, done2_cb)); - - ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); - ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(1 == timer_cb_called); - ASSERT(ARRAY_SIZE(reqs) == done2_cb_called); - - cleanup_threadpool(); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(threadpool_cancel_fs) { - struct cancel_info ci; - uv_fs_t reqs[25]; - uv_loop_t* loop; - unsigned n; - uv_buf_t iov; - - INIT_CANCEL_INFO(&ci, reqs); - loop = uv_default_loop(); - saturate_threadpool(); - iov = uv_buf_init(NULL, 0); - - /* Needs to match ARRAY_SIZE(fs_reqs). */ - n = 0; - ASSERT(0 == uv_fs_chmod(loop, reqs + n++, "/", 0, fs_cb)); - ASSERT(0 == uv_fs_chown(loop, reqs + n++, "/", 0, 0, fs_cb)); - ASSERT(0 == uv_fs_close(loop, reqs + n++, 0, fs_cb)); - ASSERT(0 == uv_fs_fchmod(loop, reqs + n++, 0, 0, fs_cb)); - ASSERT(0 == uv_fs_fchown(loop, reqs + n++, 0, 0, 0, fs_cb)); - ASSERT(0 == uv_fs_fdatasync(loop, reqs + n++, 0, fs_cb)); - ASSERT(0 == uv_fs_fstat(loop, reqs + n++, 0, fs_cb)); - ASSERT(0 == uv_fs_fsync(loop, reqs + n++, 0, fs_cb)); - ASSERT(0 == uv_fs_ftruncate(loop, reqs + n++, 0, 0, fs_cb)); - ASSERT(0 == uv_fs_futime(loop, reqs + n++, 0, 0, 0, fs_cb)); - ASSERT(0 == uv_fs_link(loop, reqs + n++, "/", "/", fs_cb)); - ASSERT(0 == uv_fs_lstat(loop, reqs + n++, "/", fs_cb)); - ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb)); - ASSERT(0 == uv_fs_open(loop, reqs + n++, "/", 0, 0, fs_cb)); - ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, &iov, 1, 0, fs_cb)); - ASSERT(0 == uv_fs_scandir(loop, reqs + n++, "/", 0, fs_cb)); - ASSERT(0 == uv_fs_readlink(loop, reqs + n++, "/", fs_cb)); - ASSERT(0 == uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb)); - ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb)); - ASSERT(0 == uv_fs_sendfile(loop, reqs + n++, 0, 0, 0, 0, fs_cb)); - ASSERT(0 == uv_fs_stat(loop, reqs + n++, "/", fs_cb)); - ASSERT(0 == uv_fs_symlink(loop, reqs + n++, "/", "/", 0, fs_cb)); - ASSERT(0 == uv_fs_unlink(loop, reqs + n++, "/", fs_cb)); - ASSERT(0 == uv_fs_utime(loop, reqs + n++, "/", 0, 0, fs_cb)); - ASSERT(0 == uv_fs_write(loop, reqs + n++, 0, &iov, 1, 0, fs_cb)); - ASSERT(n == ARRAY_SIZE(reqs)); - - ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); - ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(n == fs_cb_called); - ASSERT(1 == timer_cb_called); - - cleanup_threadpool(); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(threadpool_cancel_single) { - uv_loop_t* loop; - uv_work_t req; - int cancelled; - int i; - - loop = uv_default_loop(); - for (i = 0; i < 5000; i++) { - req.data = NULL; - ASSERT(0 == uv_queue_work(loop, &req, nop_work_cb, nop_done_cb)); - - cancelled = uv_cancel((uv_req_t*) &req); - if (cancelled == 0) - break; - - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - } - - if (cancelled != 0) { - fputs("Failed to cancel a work req in 5,000 iterations, giving up.\n", - stderr); - return 1; - } - - ASSERT(req.data == NULL); - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - ASSERT(req.data != NULL); /* Should have been updated by nop_done_cb(). */ - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-threadpool.c b/outside/libuv-v1.7.5/test/test-threadpool.c deleted file mode 100644 index e3d17d7546..0000000000 --- a/outside/libuv-v1.7.5/test/test-threadpool.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static int work_cb_count; -static int after_work_cb_count; -static uv_work_t work_req; -static char data; - - -static void work_cb(uv_work_t* req) { - ASSERT(req == &work_req); - ASSERT(req->data == &data); - work_cb_count++; -} - - -static void after_work_cb(uv_work_t* req, int status) { - ASSERT(status == 0); - ASSERT(req == &work_req); - ASSERT(req->data == &data); - after_work_cb_count++; -} - - -TEST_IMPL(threadpool_queue_work_simple) { - int r; - - work_req.data = &data; - r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb); - ASSERT(r == 0); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(work_cb_count == 1); - ASSERT(after_work_cb_count == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(threadpool_queue_work_einval) { - int r; - - work_req.data = &data; - r = uv_queue_work(uv_default_loop(), &work_req, NULL, after_work_cb); - ASSERT(r == UV_EINVAL); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(work_cb_count == 0); - ASSERT(after_work_cb_count == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-timer-again.c b/outside/libuv-v1.7.5/test/test-timer-again.c deleted file mode 100644 index f93c509be5..0000000000 --- a/outside/libuv-v1.7.5/test/test-timer-again.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -static int close_cb_called = 0; -static int repeat_1_cb_called = 0; -static int repeat_2_cb_called = 0; - -static int repeat_2_cb_allowed = 0; - -static uv_timer_t dummy, repeat_1, repeat_2; - -static uint64_t start_time; - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - - close_cb_called++; -} - - -static void repeat_1_cb(uv_timer_t* handle) { - int r; - - ASSERT(handle == &repeat_1); - ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50); - - fprintf(stderr, "repeat_1_cb called after %ld ms\n", - (long int)(uv_now(uv_default_loop()) - start_time)); - fflush(stderr); - - repeat_1_cb_called++; - - r = uv_timer_again(&repeat_2); - ASSERT(r == 0); - - if (repeat_1_cb_called == 10) { - uv_close((uv_handle_t*)handle, close_cb); - /* We're not calling uv_timer_again on repeat_2 any more, so after this */ - /* timer_2_cb is expected. */ - repeat_2_cb_allowed = 1; - return; - } -} - - -static void repeat_2_cb(uv_timer_t* handle) { - ASSERT(handle == &repeat_2); - ASSERT(repeat_2_cb_allowed); - - fprintf(stderr, "repeat_2_cb called after %ld ms\n", - (long int)(uv_now(uv_default_loop()) - start_time)); - fflush(stderr); - - repeat_2_cb_called++; - - if (uv_timer_get_repeat(&repeat_2) == 0) { - ASSERT(0 == uv_is_active((uv_handle_t*) handle)); - uv_close((uv_handle_t*)handle, close_cb); - return; - } - - fprintf(stderr, "uv_timer_get_repeat %ld ms\n", - (long int)uv_timer_get_repeat(&repeat_2)); - fflush(stderr); - ASSERT(uv_timer_get_repeat(&repeat_2) == 100); - - /* This shouldn't take effect immediately. */ - uv_timer_set_repeat(&repeat_2, 0); -} - - -TEST_IMPL(timer_again) { - int r; - - start_time = uv_now(uv_default_loop()); - ASSERT(0 < start_time); - - /* Verify that it is not possible to uv_timer_again a never-started timer. */ - r = uv_timer_init(uv_default_loop(), &dummy); - ASSERT(r == 0); - r = uv_timer_again(&dummy); - ASSERT(r == UV_EINVAL); - uv_unref((uv_handle_t*)&dummy); - - /* Start timer repeat_1. */ - r = uv_timer_init(uv_default_loop(), &repeat_1); - ASSERT(r == 0); - r = uv_timer_start(&repeat_1, repeat_1_cb, 50, 0); - ASSERT(r == 0); - ASSERT(uv_timer_get_repeat(&repeat_1) == 0); - - /* Actually make repeat_1 repeating. */ - uv_timer_set_repeat(&repeat_1, 50); - ASSERT(uv_timer_get_repeat(&repeat_1) == 50); - - /* - * Start another repeating timer. It'll be again()ed by the repeat_1 so - * it should not time out until repeat_1 stops. - */ - r = uv_timer_init(uv_default_loop(), &repeat_2); - ASSERT(r == 0); - r = uv_timer_start(&repeat_2, repeat_2_cb, 100, 100); - ASSERT(r == 0); - ASSERT(uv_timer_get_repeat(&repeat_2) == 100); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(repeat_1_cb_called == 10); - ASSERT(repeat_2_cb_called == 2); - ASSERT(close_cb_called == 2); - - fprintf(stderr, "Test took %ld ms (expected ~700 ms)\n", - (long int)(uv_now(uv_default_loop()) - start_time)); - fflush(stderr); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-timer-from-check.c b/outside/libuv-v1.7.5/test/test-timer-from-check.c deleted file mode 100644 index a18c7e1fb9..0000000000 --- a/outside/libuv-v1.7.5/test/test-timer-from-check.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -static uv_prepare_t prepare_handle; -static uv_check_t check_handle; -static uv_timer_t timer_handle; - -static int prepare_cb_called; -static int check_cb_called; -static int timer_cb_called; - - -static void prepare_cb(uv_prepare_t* handle) { - ASSERT(0 == uv_prepare_stop(&prepare_handle)); - ASSERT(0 == prepare_cb_called); - ASSERT(1 == check_cb_called); - ASSERT(0 == timer_cb_called); - prepare_cb_called++; -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(0 == uv_timer_stop(&timer_handle)); - ASSERT(1 == prepare_cb_called); - ASSERT(1 == check_cb_called); - ASSERT(0 == timer_cb_called); - timer_cb_called++; -} - - -static void check_cb(uv_check_t* handle) { - ASSERT(0 == uv_check_stop(&check_handle)); - ASSERT(0 == uv_timer_stop(&timer_handle)); /* Runs before timer_cb. */ - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0)); - ASSERT(0 == uv_prepare_start(&prepare_handle, prepare_cb)); - ASSERT(0 == prepare_cb_called); - ASSERT(0 == check_cb_called); - ASSERT(0 == timer_cb_called); - check_cb_called++; -} - - -TEST_IMPL(timer_from_check) { - ASSERT(0 == uv_prepare_init(uv_default_loop(), &prepare_handle)); - ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle)); - ASSERT(0 == uv_check_start(&check_handle, check_cb)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - ASSERT(1 == prepare_cb_called); - ASSERT(1 == check_cb_called); - ASSERT(1 == timer_cb_called); - uv_close((uv_handle_t*) &prepare_handle, NULL); - uv_close((uv_handle_t*) &check_handle, NULL); - uv_close((uv_handle_t*) &timer_handle, NULL); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-timer.c b/outside/libuv-v1.7.5/test/test-timer.c deleted file mode 100644 index aba050fd64..0000000000 --- a/outside/libuv-v1.7.5/test/test-timer.c +++ /dev/null @@ -1,303 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - - -static int once_cb_called = 0; -static int once_close_cb_called = 0; -static int repeat_cb_called = 0; -static int repeat_close_cb_called = 0; -static int order_cb_called = 0; -static uint64_t start_time; -static uv_timer_t tiny_timer; -static uv_timer_t huge_timer1; -static uv_timer_t huge_timer2; - - -static void once_close_cb(uv_handle_t* handle) { - printf("ONCE_CLOSE_CB\n"); - - ASSERT(handle != NULL); - ASSERT(0 == uv_is_active(handle)); - - once_close_cb_called++; -} - - -static void once_cb(uv_timer_t* handle) { - printf("ONCE_CB %d\n", once_cb_called); - - ASSERT(handle != NULL); - ASSERT(0 == uv_is_active((uv_handle_t*) handle)); - - once_cb_called++; - - uv_close((uv_handle_t*)handle, once_close_cb); - - /* Just call this randomly for the code coverage. */ - uv_update_time(uv_default_loop()); -} - - -static void repeat_close_cb(uv_handle_t* handle) { - printf("REPEAT_CLOSE_CB\n"); - - ASSERT(handle != NULL); - - repeat_close_cb_called++; -} - - -static void repeat_cb(uv_timer_t* handle) { - printf("REPEAT_CB\n"); - - ASSERT(handle != NULL); - ASSERT(1 == uv_is_active((uv_handle_t*) handle)); - - repeat_cb_called++; - - if (repeat_cb_called == 5) { - uv_close((uv_handle_t*)handle, repeat_close_cb); - } -} - - -static void never_cb(uv_timer_t* handle) { - FATAL("never_cb should never be called"); -} - - -TEST_IMPL(timer) { - uv_timer_t once_timers[10]; - uv_timer_t *once; - uv_timer_t repeat, never; - unsigned int i; - int r; - - start_time = uv_now(uv_default_loop()); - ASSERT(0 < start_time); - - /* Let 10 timers time out in 500 ms total. */ - for (i = 0; i < ARRAY_SIZE(once_timers); i++) { - once = once_timers + i; - r = uv_timer_init(uv_default_loop(), once); - ASSERT(r == 0); - r = uv_timer_start(once, once_cb, i * 50, 0); - ASSERT(r == 0); - } - - /* The 11th timer is a repeating timer that runs 4 times */ - r = uv_timer_init(uv_default_loop(), &repeat); - ASSERT(r == 0); - r = uv_timer_start(&repeat, repeat_cb, 100, 100); - ASSERT(r == 0); - - /* The 12th timer should not do anything. */ - r = uv_timer_init(uv_default_loop(), &never); - ASSERT(r == 0); - r = uv_timer_start(&never, never_cb, 100, 100); - ASSERT(r == 0); - r = uv_timer_stop(&never); - ASSERT(r == 0); - uv_unref((uv_handle_t*)&never); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(once_cb_called == 10); - ASSERT(once_close_cb_called == 10); - printf("repeat_cb_called %d\n", repeat_cb_called); - ASSERT(repeat_cb_called == 5); - ASSERT(repeat_close_cb_called == 1); - - ASSERT(500 <= uv_now(uv_default_loop()) - start_time); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(timer_start_twice) { - uv_timer_t once; - int r; - - r = uv_timer_init(uv_default_loop(), &once); - ASSERT(r == 0); - r = uv_timer_start(&once, never_cb, 86400 * 1000, 0); - ASSERT(r == 0); - r = uv_timer_start(&once, once_cb, 10, 0); - ASSERT(r == 0); - r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(once_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(timer_init) { - uv_timer_t handle; - - ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); - ASSERT(0 == uv_timer_get_repeat(&handle)); - ASSERT(0 == uv_is_active((uv_handle_t*) &handle)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static void order_cb_a(uv_timer_t *handle) { - ASSERT(order_cb_called++ == *(int*)handle->data); -} - - -static void order_cb_b(uv_timer_t *handle) { - ASSERT(order_cb_called++ == *(int*)handle->data); -} - - -TEST_IMPL(timer_order) { - int first; - int second; - uv_timer_t handle_a; - uv_timer_t handle_b; - - first = 0; - second = 1; - ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_b)); - - /* Test for starting handle_a then handle_b */ - handle_a.data = &first; - ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0)); - handle_b.data = &second; - ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - ASSERT(order_cb_called == 2); - - ASSERT(0 == uv_timer_stop(&handle_a)); - ASSERT(0 == uv_timer_stop(&handle_b)); - - /* Test for starting handle_b then handle_a */ - order_cb_called = 0; - handle_b.data = &first; - ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0)); - - handle_a.data = &second; - ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - - ASSERT(order_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static void tiny_timer_cb(uv_timer_t* handle) { - ASSERT(handle == &tiny_timer); - uv_close((uv_handle_t*) &tiny_timer, NULL); - uv_close((uv_handle_t*) &huge_timer1, NULL); - uv_close((uv_handle_t*) &huge_timer2, NULL); -} - - -TEST_IMPL(timer_huge_timeout) { - ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer2)); - ASSERT(0 == uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0)); - ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0)); - ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static void huge_repeat_cb(uv_timer_t* handle) { - static int ncalls; - - if (ncalls == 0) - ASSERT(handle == &huge_timer1); - else - ASSERT(handle == &tiny_timer); - - if (++ncalls == 10) { - uv_close((uv_handle_t*) &tiny_timer, NULL); - uv_close((uv_handle_t*) &huge_timer1, NULL); - } -} - - -TEST_IMPL(timer_huge_repeat) { - ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1)); - ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2)); - ASSERT(0 == uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -static unsigned int timer_run_once_timer_cb_called; - - -static void timer_run_once_timer_cb(uv_timer_t* handle) { - timer_run_once_timer_cb_called++; -} - - -TEST_IMPL(timer_run_once) { - uv_timer_t timer_handle; - - ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); - ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); - ASSERT(1 == timer_run_once_timer_cb_called); - - ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); - ASSERT(2 == timer_run_once_timer_cb_called); - - uv_close((uv_handle_t*) &timer_handle, NULL); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(timer_null_callback) { - uv_timer_t handle; - - ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); - ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-tty.c b/outside/libuv-v1.7.5/test/test-tty.c deleted file mode 100644 index 81e612c1d6..0000000000 --- a/outside/libuv-v1.7.5/test/test-tty.c +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#ifdef _WIN32 -# include -# include -#else /* Unix */ -# include -# include -#endif - -#include -#include - - -TEST_IMPL(tty) { - int r, width, height; - int ttyin_fd, ttyout_fd; - uv_tty_t tty_in, tty_out; - uv_loop_t* loop = uv_default_loop(); - - /* Make sure we have an FD that refers to a tty */ -#ifdef _WIN32 - HANDLE handle; - handle = CreateFileA("conin$", - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - ASSERT(handle != INVALID_HANDLE_VALUE); - ttyin_fd = _open_osfhandle((intptr_t) handle, 0); - - handle = CreateFileA("conout$", - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - ASSERT(handle != INVALID_HANDLE_VALUE); - ttyout_fd = _open_osfhandle((intptr_t) handle, 0); - -#else /* unix */ - ttyin_fd = open("/dev/tty", O_RDONLY, 0); - if (ttyin_fd < 0) { - fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno)); - fflush(stderr); - return TEST_SKIP; - } - - ttyout_fd = open("/dev/tty", O_WRONLY, 0); - if (ttyout_fd < 0) { - fprintf(stderr, "Cannot open /dev/tty as write-only: %s\n", strerror(errno)); - fflush(stderr); - return TEST_SKIP; - } -#endif - - ASSERT(ttyin_fd >= 0); - ASSERT(ttyout_fd >= 0); - - ASSERT(UV_UNKNOWN_HANDLE == uv_guess_handle(-1)); - - ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); - ASSERT(UV_TTY == uv_guess_handle(ttyout_fd)); - - r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ - ASSERT(r == 0); - - r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 0); /* Writable. */ - ASSERT(r == 0); - - r = uv_tty_get_winsize(&tty_out, &width, &height); - ASSERT(r == 0); - - printf("width=%d height=%d\n", width, height); - - if (width == 0 && height == 0) { - /* Some environments such as containers or Jenkins behave like this - * sometimes */ - MAKE_VALGRIND_HAPPY(); - return TEST_SKIP; - } - - /* - * Is it a safe assumption that most people have terminals larger than - * 10x10? - */ - ASSERT(width > 10); - ASSERT(height > 10); - - /* Turn on raw mode. */ - r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); - ASSERT(r == 0); - - /* Turn off raw mode. */ - r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_NORMAL); - ASSERT(r == 0); - - /* Calling uv_tty_reset_mode() repeatedly should not clobber errno. */ - errno = 0; - ASSERT(0 == uv_tty_reset_mode()); - ASSERT(0 == uv_tty_reset_mode()); - ASSERT(0 == uv_tty_reset_mode()); - ASSERT(0 == errno); - - /* TODO check the actual mode! */ - - uv_close((uv_handle_t*) &tty_in, NULL); - uv_close((uv_handle_t*) &tty_out, NULL); - - uv_run(loop, UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(tty_file) { -#ifndef _WIN32 - uv_loop_t loop; - uv_tty_t tty; - int fd; - - ASSERT(0 == uv_loop_init(&loop)); - - fd = open("test/fixtures/empty_file", O_RDONLY); - if (fd != -1) { - ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); - ASSERT(0 == close(fd)); - } - - fd = open("/dev/random", O_RDONLY); - if (fd != -1) { - ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); - ASSERT(0 == close(fd)); - } - - fd = open("/dev/zero", O_RDONLY); - if (fd != -1) { - ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); - ASSERT(0 == close(fd)); - } - - fd = open("/dev/tty", O_RDONLY); - if (fd != -1) { - ASSERT(0 == uv_tty_init(&loop, &tty, fd, 1)); - ASSERT(0 == close(fd)); - uv_close((uv_handle_t*) &tty, NULL); - } - - ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); - ASSERT(0 == uv_loop_close(&loop)); - - MAKE_VALGRIND_HAPPY(); -#endif - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-bind.c b/outside/libuv-v1.7.5/test/test-udp-bind.c deleted file mode 100644 index a1e080ee70..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-bind.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - - -TEST_IMPL(udp_bind) { - struct sockaddr_in addr; - uv_loop_t* loop; - uv_udp_t h1, h2; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - loop = uv_default_loop(); - - r = uv_udp_init(loop, &h1); - ASSERT(r == 0); - - r = uv_udp_init(loop, &h2); - ASSERT(r == 0); - - r = uv_udp_bind(&h1, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_udp_bind(&h2, (const struct sockaddr*) &addr, 0); - ASSERT(r == UV_EADDRINUSE); - - uv_close((uv_handle_t*) &h1, NULL); - uv_close((uv_handle_t*) &h2, NULL); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_bind_reuseaddr) { - struct sockaddr_in addr; - uv_loop_t* loop; - uv_udp_t h1, h2; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - loop = uv_default_loop(); - - r = uv_udp_init(loop, &h1); - ASSERT(r == 0); - - r = uv_udp_init(loop, &h2); - ASSERT(r == 0); - - r = uv_udp_bind(&h1, (const struct sockaddr*) &addr, UV_UDP_REUSEADDR); - ASSERT(r == 0); - - r = uv_udp_bind(&h2, (const struct sockaddr*) &addr, UV_UDP_REUSEADDR); - ASSERT(r == 0); - - uv_close((uv_handle_t*) &h1, NULL); - uv_close((uv_handle_t*) &h2, NULL); - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-create-socket-early.c b/outside/libuv-v1.7.5/test/test-udp-create-socket-early.c deleted file mode 100644 index 3d0152428b..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-create-socket-early.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright (c) 2015 Saúl Ibarra Corretgé . - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include - -#ifdef _WIN32 -# define INVALID_FD (INVALID_HANDLE_VALUE) -#else -# define INVALID_FD (-1) -#endif - - -TEST_IMPL(udp_create_early) { - struct sockaddr_in addr; - struct sockaddr_in sockname; - uv_udp_t client; - uv_os_fd_t fd; - int r, namelen; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET); - ASSERT(r == 0); - - r = uv_fileno((const uv_handle_t*) &client, &fd); - ASSERT(r == 0); - ASSERT(fd != INVALID_FD); - - /* Windows returns WSAEINVAL if the socket is not bound */ -#ifndef _WIN32 - namelen = sizeof sockname; - r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); - ASSERT(r == 0); - ASSERT(sockname.sin_family == AF_INET); -#endif - - r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - namelen = sizeof sockname; - r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); - ASSERT(r == 0); - ASSERT(memcmp(&addr.sin_addr, - &sockname.sin_addr, - sizeof(addr.sin_addr)) == 0); - - uv_close((uv_handle_t*) &client, NULL); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_create_early_bad_bind) { - struct sockaddr_in addr; - uv_udp_t client; - uv_os_fd_t fd; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET6); - ASSERT(r == 0); - - r = uv_fileno((const uv_handle_t*) &client, &fd); - ASSERT(r == 0); - ASSERT(fd != INVALID_FD); - - /* Windows returns WSAEINVAL if the socket is not bound */ -#ifndef _WIN32 - { - int namelen; - struct sockaddr_in6 sockname; - namelen = sizeof sockname; - r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); - ASSERT(r == 0); - ASSERT(sockname.sin6_family == AF_INET6); - } -#endif - - r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); -#ifndef _WIN32 - ASSERT(r == UV_EINVAL); -#else - ASSERT(r == UV_EFAULT); -#endif - - uv_close((uv_handle_t*) &client, NULL); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_create_early_bad_domain) { - uv_udp_t client; - int r; - - r = uv_udp_init_ex(uv_default_loop(), &client, 47); - ASSERT(r == UV_EINVAL); - - r = uv_udp_init_ex(uv_default_loop(), &client, 1024); - ASSERT(r == UV_EINVAL); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-dgram-too-big.c b/outside/libuv-v1.7.5/test/test-udp-dgram-too-big.c deleted file mode 100644 index bd44c42528..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-dgram-too-big.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &handle_) - -#define CHECK_REQ(req) \ - ASSERT((req) == &req_); - -static uv_udp_t handle_; -static uv_udp_send_t req_; - -static int send_cb_called; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - close_cb_called++; -} - - -static void send_cb(uv_udp_send_t* req, int status) { - CHECK_REQ(req); - CHECK_HANDLE(req->handle); - - ASSERT(status == UV_EMSGSIZE); - - uv_close((uv_handle_t*)req->handle, close_cb); - send_cb_called++; -} - - -TEST_IMPL(udp_dgram_too_big) { - char dgram[65536]; /* 64K MTU is unlikely, even on localhost */ - struct sockaddr_in addr; - uv_buf_t buf; - int r; - - memset(dgram, 42, sizeof dgram); /* silence valgrind */ - - r = uv_udp_init(uv_default_loop(), &handle_); - ASSERT(r == 0); - - buf = uv_buf_init(dgram, sizeof dgram); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_send(&req_, - &handle_, - &buf, - 1, - (const struct sockaddr*) &addr, - send_cb); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(send_cb_called == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(send_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-ipv6.c b/outside/libuv-v1.7.5/test/test-udp-ipv6.c deleted file mode 100644 index 1d5720ce73..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-ipv6.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server \ - || (uv_udp_t*)(handle) == &client \ - || (uv_timer_t*)(handle) == &timeout) - -#define CHECK_REQ(req) \ - ASSERT((req) == &req_); - -static uv_udp_t client; -static uv_udp_t server; -static uv_udp_send_t req_; -static uv_timer_t timeout; - -static int send_cb_called; -static int recv_cb_called; -static int close_cb_called; - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - CHECK_HANDLE(handle); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - close_cb_called++; -} - - -static void send_cb(uv_udp_send_t* req, int status) { - CHECK_REQ(req); - CHECK_HANDLE(req->handle); - ASSERT(status == 0); - send_cb_called++; -} - - -static void ipv6_recv_fail(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - ASSERT(0 && "this function should not have been called"); -} - - -static void ipv6_recv_ok(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - CHECK_HANDLE(handle); - ASSERT(nread >= 0); - - if (nread) - recv_cb_called++; -} - - -static void timeout_cb(uv_timer_t* timer) { - uv_close((uv_handle_t*)&server, close_cb); - uv_close((uv_handle_t*)&client, close_cb); - uv_close((uv_handle_t*)&timeout, close_cb); -} - - -static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) { - struct sockaddr_in6 addr6; - struct sockaddr_in addr; - uv_buf_t buf; - int r; - - ASSERT(0 == uv_ip6_addr("::0", TEST_PORT, &addr6)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_udp_bind(&server, (const struct sockaddr*) &addr6, bind_flags); - ASSERT(r == 0); - - r = uv_udp_recv_start(&server, alloc_cb, recv_cb); - ASSERT(r == 0); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - buf = uv_buf_init("PING", 4); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_send(&req_, - &client, - &buf, - 1, - (const struct sockaddr*) &addr, - send_cb); - ASSERT(r == 0); - - r = uv_timer_init(uv_default_loop(), &timeout); - ASSERT(r == 0); - - r = uv_timer_start(&timeout, timeout_cb, 500, 0); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(send_cb_called == 0); - ASSERT(recv_cb_called == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 3); - - MAKE_VALGRIND_HAPPY(); -} - - -TEST_IMPL(udp_dual_stack) { - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - do_test(ipv6_recv_ok, 0); - - ASSERT(recv_cb_called == 1); - ASSERT(send_cb_called == 1); - - return 0; -} - - -TEST_IMPL(udp_ipv6_only) { - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - do_test(ipv6_recv_fail, UV_UDP_IPV6ONLY); - - ASSERT(recv_cb_called == 0); - ASSERT(send_cb_called == 1); - - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-multicast-interface.c b/outside/libuv-v1.7.5/test/test-udp-multicast-interface.c deleted file mode 100644 index 71001a77e0..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-multicast-interface.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int sv_send_cb_called; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - close_cb_called++; -} - - -static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0 || status == UV_ENETUNREACH); - CHECK_HANDLE(req->handle); - - sv_send_cb_called++; - - uv_close((uv_handle_t*) req->handle, close_cb); -} - - -TEST_IMPL(udp_multicast_interface) { - int r; - uv_udp_send_t req; - uv_buf_t buf; - struct sockaddr_in addr; - struct sockaddr_in baddr; - - ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &baddr)); - r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0); - ASSERT(r == 0); - - r = uv_udp_set_multicast_interface(&server, "0.0.0.0"); - ASSERT(r == 0); - - /* server sends "PING" */ - buf = uv_buf_init("PING", 4); - r = uv_udp_send(&req, - &server, - &buf, - 1, - (const struct sockaddr*)&addr, - sv_send_cb); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(sv_send_cb_called == 0); - - /* run the loop till all events are processed */ - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(sv_send_cb_called == 1); - ASSERT(close_cb_called == 1); - - ASSERT(client.send_queue_size == 0); - ASSERT(server.send_queue_size == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-multicast-interface6.c b/outside/libuv-v1.7.5/test/test-udp-multicast-interface6.c deleted file mode 100644 index d3881e83bb..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-multicast-interface6.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int sv_send_cb_called; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - close_cb_called++; -} - - -static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - CHECK_HANDLE(req->handle); - - sv_send_cb_called++; - - uv_close((uv_handle_t*) req->handle, close_cb); -} - - -TEST_IMPL(udp_multicast_interface6) { - int r; - uv_udp_send_t req; - uv_buf_t buf; - struct sockaddr_in6 addr; - struct sockaddr_in6 baddr; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - ASSERT(0 == uv_ip6_addr("::", 0, &baddr)); - r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0); - ASSERT(r == 0); - -#if defined(__APPLE__) || defined(__FreeBSD__) - r = uv_udp_set_multicast_interface(&server, "::1%lo0"); -#else - r = uv_udp_set_multicast_interface(&server, NULL); -#endif - ASSERT(r == 0); - - /* server sends "PING" */ - buf = uv_buf_init("PING", 4); - r = uv_udp_send(&req, - &server, - &buf, - 1, - (const struct sockaddr*)&addr, - sv_send_cb); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(sv_send_cb_called == 0); - - /* run the loop till all events are processed */ - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(sv_send_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-multicast-join.c b/outside/libuv-v1.7.5/test/test-udp-multicast-join.c deleted file mode 100644 index 6110a8d922..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-multicast-join.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int cl_recv_cb_called; - -static int sv_send_cb_called; - -static int close_cb_called; - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - CHECK_HANDLE(handle); - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - close_cb_called++; -} - - -static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - CHECK_HANDLE(req->handle); - - sv_send_cb_called++; - - uv_close((uv_handle_t*) req->handle, close_cb); -} - - -static void cl_recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - CHECK_HANDLE(handle); - ASSERT(flags == 0); - - cl_recv_cb_called++; - - if (nread < 0) { - ASSERT(0 && "unexpected error"); - } - - if (nread == 0) { - /* Returning unused buffer */ - /* Don't count towards cl_recv_cb_called */ - ASSERT(addr == NULL); - return; - } - - ASSERT(addr != NULL); - ASSERT(nread == 4); - ASSERT(!memcmp("PING", buf->base, nread)); - - /* we are done with the client handle, we can close it */ - uv_close((uv_handle_t*) &client, close_cb); -} - - -TEST_IMPL(udp_multicast_join) { - int r; - uv_udp_send_t req; - uv_buf_t buf; - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - /* bind to the desired port */ - r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - /* join the multicast channel */ - r = uv_udp_set_membership(&client, "239.255.0.1", NULL, UV_JOIN_GROUP); - if (r == UV_ENODEV) - RETURN_SKIP("No multicast support."); - ASSERT(r == 0); - - r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb); - ASSERT(r == 0); - - buf = uv_buf_init("PING", 4); - - /* server sends "PING" */ - r = uv_udp_send(&req, - &server, - &buf, - 1, - (const struct sockaddr*) &addr, - sv_send_cb); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(cl_recv_cb_called == 0); - ASSERT(sv_send_cb_called == 0); - - /* run the loop till all events are processed */ - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(cl_recv_cb_called == 1); - ASSERT(sv_send_cb_called == 1); - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-multicast-join6.c b/outside/libuv-v1.7.5/test/test-udp-multicast-join6.c deleted file mode 100644 index 873cb6d811..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-multicast-join6.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int cl_recv_cb_called; - -static int sv_send_cb_called; - -static int close_cb_called; - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - CHECK_HANDLE(handle); - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - close_cb_called++; -} - - -static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - CHECK_HANDLE(req->handle); - - sv_send_cb_called++; - - uv_close((uv_handle_t*) req->handle, close_cb); -} - - -static void cl_recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - CHECK_HANDLE(handle); - ASSERT(flags == 0); - - cl_recv_cb_called++; - - if (nread < 0) { - ASSERT(0 && "unexpected error"); - } - - if (nread == 0) { - /* Returning unused buffer */ - /* Don't count towards cl_recv_cb_called */ - ASSERT(addr == NULL); - return; - } - - ASSERT(addr != NULL); - ASSERT(nread == 4); - ASSERT(!memcmp("PING", buf->base, nread)); - - /* we are done with the client handle, we can close it */ - uv_close((uv_handle_t*) &client, close_cb); -} - - -TEST_IMPL(udp_multicast_join6) { - int r; - uv_udp_send_t req; - uv_buf_t buf; - struct sockaddr_in6 addr; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - /* bind to the desired port */ - r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - /* join the multicast channel */ -#if defined(__APPLE__) - r = uv_udp_set_membership(&client, "ff02::1", "::1%lo0", UV_JOIN_GROUP); -#else - r = uv_udp_set_membership(&client, "ff02::1", NULL, UV_JOIN_GROUP); -#endif - if (r == UV_ENODEV) { - MAKE_VALGRIND_HAPPY(); - RETURN_SKIP("No ipv6 multicast route"); - } - - ASSERT(r == 0); - - r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb); - ASSERT(r == 0); - - buf = uv_buf_init("PING", 4); - - /* server sends "PING" */ - r = uv_udp_send(&req, - &server, - &buf, - 1, - (const struct sockaddr*) &addr, - sv_send_cb); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(cl_recv_cb_called == 0); - ASSERT(sv_send_cb_called == 0); - - /* run the loop till all events are processed */ - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(cl_recv_cb_called == 1); - ASSERT(sv_send_cb_called == 1); - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-multicast-ttl.c b/outside/libuv-v1.7.5/test/test-udp-multicast-ttl.c deleted file mode 100644 index 7f1af9b9dd..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-multicast-ttl.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int sv_send_cb_called; -static int close_cb_called; - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - close_cb_called++; -} - - -static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0 || status == UV_ENETUNREACH); - CHECK_HANDLE(req->handle); - - sv_send_cb_called++; - - uv_close((uv_handle_t*) req->handle, close_cb); -} - - -TEST_IMPL(udp_multicast_ttl) { - int r; - uv_udp_send_t req; - uv_buf_t buf; - struct sockaddr_in addr; - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr)); - r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_udp_set_multicast_ttl(&server, 32); - ASSERT(r == 0); - - /* server sends "PING" */ - buf = uv_buf_init("PING", 4); - ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr)); - r = uv_udp_send(&req, - &server, - &buf, - 1, - (const struct sockaddr*) &addr, - sv_send_cb); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(sv_send_cb_called == 0); - - /* run the loop till all events are processed */ - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(sv_send_cb_called == 1); - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-open.c b/outside/libuv-v1.7.5/test/test-udp-open.c deleted file mode 100644 index 4d77f45d36..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-open.c +++ /dev/null @@ -1,204 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#include - -#ifndef _WIN32 -# include -#endif - -static int send_cb_called = 0; -static int close_cb_called = 0; - -static uv_udp_send_t send_req; - - -static void startup(void) { -#ifdef _WIN32 - struct WSAData wsa_data; - int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); - ASSERT(r == 0); -#endif -} - - -static uv_os_sock_t create_udp_socket(void) { - uv_os_sock_t sock; - - sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); -#ifdef _WIN32 - ASSERT(sock != INVALID_SOCKET); -#else - ASSERT(sock >= 0); -#endif - -#ifndef _WIN32 - { - /* Allow reuse of the port. */ - int yes = 1; - int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); - ASSERT(r == 0); - } -#endif - - return sock; -} - - -static void close_socket(uv_os_sock_t sock) { - int r; -#ifdef _WIN32 - r = closesocket(sock); -#else - r = close(sock); -#endif - ASSERT(r == 0); -} - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); - close_cb_called++; -} - - -static void recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - int r; - - if (nread < 0) { - ASSERT(0 && "unexpected error"); - } - - if (nread == 0) { - /* Returning unused buffer */ - /* Don't count towards sv_recv_cb_called */ - ASSERT(addr == NULL); - return; - } - - ASSERT(flags == 0); - - ASSERT(addr != NULL); - ASSERT(nread == 4); - ASSERT(memcmp("PING", buf->base, nread) == 0); - - r = uv_udp_recv_stop(handle); - ASSERT(r == 0); - - uv_close((uv_handle_t*) handle, close_cb); -} - - -static void send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - - send_cb_called++; -} - - -TEST_IMPL(udp_open) { - struct sockaddr_in addr; - uv_buf_t buf = uv_buf_init("PING", 4); - uv_udp_t client; - uv_os_sock_t sock; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - startup(); - sock = create_udp_socket(); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_udp_open(&client, sock); - ASSERT(r == 0); - - r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_udp_recv_start(&client, alloc_cb, recv_cb); - ASSERT(r == 0); - - r = uv_udp_send(&send_req, - &client, - &buf, - 1, - (const struct sockaddr*) &addr, - send_cb); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(send_cb_called == 1); - ASSERT(close_cb_called == 1); - - ASSERT(client.send_queue_size == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_open_twice) { - uv_udp_t client; - uv_os_sock_t sock1, sock2; - int r; - - startup(); - sock1 = create_udp_socket(); - sock2 = create_udp_socket(); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_udp_open(&client, sock1); - ASSERT(r == 0); - - r = uv_udp_open(&client, sock2); - ASSERT(r == UV_EBUSY); - close_socket(sock2); - - uv_close((uv_handle_t*) &client, NULL); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-options.c b/outside/libuv-v1.7.5/test/test-udp-options.c deleted file mode 100644 index 0da1786f50..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-options.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - - -static int udp_options_test(const struct sockaddr* addr) { - static int invalid_ttls[] = { -1, 0, 256 }; - uv_loop_t* loop; - uv_udp_t h; - int i, r; - - loop = uv_default_loop(); - - r = uv_udp_init(loop, &h); - ASSERT(r == 0); - - uv_unref((uv_handle_t*)&h); /* don't keep the loop alive */ - - r = uv_udp_bind(&h, addr, 0); - ASSERT(r == 0); - - r = uv_udp_set_broadcast(&h, 1); - r |= uv_udp_set_broadcast(&h, 1); - r |= uv_udp_set_broadcast(&h, 0); - r |= uv_udp_set_broadcast(&h, 0); - ASSERT(r == 0); - - /* values 1-255 should work */ - for (i = 1; i <= 255; i++) { - r = uv_udp_set_ttl(&h, i); - ASSERT(r == 0); - } - - for (i = 0; i < (int) ARRAY_SIZE(invalid_ttls); i++) { - r = uv_udp_set_ttl(&h, invalid_ttls[i]); - ASSERT(r == UV_EINVAL); - } - - r = uv_udp_set_multicast_loop(&h, 1); - r |= uv_udp_set_multicast_loop(&h, 1); - r |= uv_udp_set_multicast_loop(&h, 0); - r |= uv_udp_set_multicast_loop(&h, 0); - ASSERT(r == 0); - - /* values 0-255 should work */ - for (i = 0; i <= 255; i++) { - r = uv_udp_set_multicast_ttl(&h, i); - ASSERT(r == 0); - } - - /* anything >255 should fail */ - r = uv_udp_set_multicast_ttl(&h, 256); - ASSERT(r == UV_EINVAL); - /* don't test ttl=-1, it's a valid value on some platforms */ - - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - - -TEST_IMPL(udp_options) { - struct sockaddr_in addr; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - return udp_options_test((const struct sockaddr*) &addr); -} - - -TEST_IMPL(udp_options6) { - struct sockaddr_in6 addr; - - if (!can_ipv6()) - RETURN_SKIP("IPv6 not supported"); - - ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr)); - return udp_options_test((const struct sockaddr*) &addr); -} - - -TEST_IMPL(udp_no_autobind) { - uv_loop_t* loop; - uv_udp_t h; - - loop = uv_default_loop(); - - ASSERT(0 == uv_udp_init(loop, &h)); - ASSERT(UV_EBADF == uv_udp_set_multicast_ttl(&h, 32)); - ASSERT(UV_EBADF == uv_udp_set_broadcast(&h, 1)); - ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1)); - ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1)); - ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0")); - - uv_close((uv_handle_t*) &h, NULL); - - ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-send-and-recv.c b/outside/libuv-v1.7.5/test/test-udp-send-and-recv.c deleted file mode 100644 index 633a16727b..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-send-and-recv.c +++ /dev/null @@ -1,214 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int cl_send_cb_called; -static int cl_recv_cb_called; - -static int sv_send_cb_called; -static int sv_recv_cb_called; - -static int close_cb_called; - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - CHECK_HANDLE(handle); - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - ASSERT(1 == uv_is_closing(handle)); - close_cb_called++; -} - - -static void cl_recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - CHECK_HANDLE(handle); - ASSERT(flags == 0); - - if (nread < 0) { - ASSERT(0 && "unexpected error"); - } - - if (nread == 0) { - /* Returning unused buffer */ - /* Don't count towards cl_recv_cb_called */ - ASSERT(addr == NULL); - return; - } - - ASSERT(addr != NULL); - ASSERT(nread == 4); - ASSERT(!memcmp("PONG", buf->base, nread)); - - cl_recv_cb_called++; - - uv_close((uv_handle_t*) handle, close_cb); -} - - -static void cl_send_cb(uv_udp_send_t* req, int status) { - int r; - - ASSERT(req != NULL); - ASSERT(status == 0); - CHECK_HANDLE(req->handle); - - r = uv_udp_recv_start(req->handle, alloc_cb, cl_recv_cb); - ASSERT(r == 0); - - cl_send_cb_called++; -} - - -static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - CHECK_HANDLE(req->handle); - - uv_close((uv_handle_t*) req->handle, close_cb); - free(req); - - sv_send_cb_called++; -} - - -static void sv_recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* rcvbuf, - const struct sockaddr* addr, - unsigned flags) { - uv_udp_send_t* req; - uv_buf_t sndbuf; - int r; - - if (nread < 0) { - ASSERT(0 && "unexpected error"); - } - - if (nread == 0) { - /* Returning unused buffer */ - /* Don't count towards sv_recv_cb_called */ - ASSERT(addr == NULL); - return; - } - - CHECK_HANDLE(handle); - ASSERT(flags == 0); - - ASSERT(addr != NULL); - ASSERT(nread == 4); - ASSERT(!memcmp("PING", rcvbuf->base, nread)); - - /* FIXME? `uv_udp_recv_stop` does what it says: recv_cb is not called - * anymore. That's problematic because the read buffer won't be returned - * either... Not sure I like that but it's consistent with `uv_read_stop`. - */ - r = uv_udp_recv_stop(handle); - ASSERT(r == 0); - - req = malloc(sizeof *req); - ASSERT(req != NULL); - - sndbuf = uv_buf_init("PONG", 4); - r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb); - ASSERT(r == 0); - - sv_recv_cb_called++; -} - - -TEST_IMPL(udp_send_and_recv) { - struct sockaddr_in addr; - uv_udp_send_t req; - uv_buf_t buf; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - /* client sends "PING", expects "PONG" */ - buf = uv_buf_init("PING", 4); - - r = uv_udp_send(&req, - &client, - &buf, - 1, - (const struct sockaddr*) &addr, - cl_send_cb); - ASSERT(r == 0); - - ASSERT(close_cb_called == 0); - ASSERT(cl_send_cb_called == 0); - ASSERT(cl_recv_cb_called == 0); - ASSERT(sv_send_cb_called == 0); - ASSERT(sv_recv_cb_called == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(cl_send_cb_called == 1); - ASSERT(cl_recv_cb_called == 1); - ASSERT(sv_send_cb_called == 1); - ASSERT(sv_recv_cb_called == 1); - ASSERT(close_cb_called == 2); - - ASSERT(client.send_queue_size == 0); - ASSERT(server.send_queue_size == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-send-immediate.c b/outside/libuv-v1.7.5/test/test-udp-send-immediate.c deleted file mode 100644 index 0999f6b342..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-send-immediate.c +++ /dev/null @@ -1,148 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int cl_send_cb_called; -static int sv_recv_cb_called; -static int close_cb_called; - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - CHECK_HANDLE(handle); - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - ASSERT(1 == uv_is_closing(handle)); - close_cb_called++; -} - - -static void cl_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - CHECK_HANDLE(req->handle); - - cl_send_cb_called++; -} - - -static void sv_recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* rcvbuf, - const struct sockaddr* addr, - unsigned flags) { - if (nread < 0) { - ASSERT(0 && "unexpected error"); - } - - if (nread == 0) { - /* Returning unused buffer */ - /* Don't count towards sv_recv_cb_called */ - ASSERT(addr == NULL); - return; - } - - CHECK_HANDLE(handle); - ASSERT(flags == 0); - - ASSERT(addr != NULL); - ASSERT(nread == 4); - ASSERT(memcmp("PING", rcvbuf->base, nread) == 0 || - memcmp("PANG", rcvbuf->base, nread) == 0); - - if (++sv_recv_cb_called == 2) { - uv_close((uv_handle_t*) &server, close_cb); - uv_close((uv_handle_t*) &client, close_cb); - } -} - - -TEST_IMPL(udp_send_immediate) { - struct sockaddr_in addr; - uv_udp_send_t req1, req2; - uv_buf_t buf; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - /* client sends "PING", then "PANG" */ - buf = uv_buf_init("PING", 4); - - r = uv_udp_send(&req1, - &client, - &buf, - 1, - (const struct sockaddr*) &addr, - cl_send_cb); - ASSERT(r == 0); - - buf = uv_buf_init("PANG", 4); - - r = uv_udp_send(&req2, - &client, - &buf, - 1, - (const struct sockaddr*) &addr, - cl_send_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(cl_send_cb_called == 2); - ASSERT(sv_recv_cb_called == 2); - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-send-unreachable.c b/outside/libuv-v1.7.5/test/test-udp-send-unreachable.c deleted file mode 100644 index c6500320d7..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-send-unreachable.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &client) - -static uv_udp_t client; -static uv_timer_t timer; - -static int send_cb_called; -static int recv_cb_called; -static int close_cb_called; -static int alloc_cb_called; -static int timer_cb_called; - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - CHECK_HANDLE(handle); - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); - alloc_cb_called++; -} - - -static void close_cb(uv_handle_t* handle) { - ASSERT(1 == uv_is_closing(handle)); - close_cb_called++; -} - - -static void send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - CHECK_HANDLE(req->handle); - send_cb_called++; -} - - -static void recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* rcvbuf, - const struct sockaddr* addr, - unsigned flags) { - CHECK_HANDLE(handle); - recv_cb_called++; - - if (nread < 0) { - ASSERT(0 && "unexpected error"); - } else if (nread == 0) { - /* Returning unused buffer */ - ASSERT(addr == NULL); - } else { - ASSERT(addr != NULL); - } -} - - -static void timer_cb(uv_timer_t* h) { - ASSERT(h == &timer); - timer_cb_called++; - uv_close((uv_handle_t*) &client, close_cb); - uv_close((uv_handle_t*) h, close_cb); -} - - -TEST_IMPL(udp_send_unreachable) { - struct sockaddr_in addr; - struct sockaddr_in addr2; - uv_udp_send_t req1, req2; - uv_buf_t buf; - int r; - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT_2, &addr2)); - - r = uv_timer_init( uv_default_loop(), &timer ); - ASSERT(r == 0); - - r = uv_timer_start( &timer, timer_cb, 1000, 0 ); - ASSERT(r == 0); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - r = uv_udp_bind(&client, (const struct sockaddr*) &addr2, 0); - ASSERT(r == 0); - - r = uv_udp_recv_start(&client, alloc_cb, recv_cb); - ASSERT(r == 0); - - /* client sends "PING", then "PANG" */ - buf = uv_buf_init("PING", 4); - - r = uv_udp_send(&req1, - &client, - &buf, - 1, - (const struct sockaddr*) &addr, - send_cb); - ASSERT(r == 0); - - buf = uv_buf_init("PANG", 4); - - r = uv_udp_send(&req2, - &client, - &buf, - 1, - (const struct sockaddr*) &addr, - send_cb); - ASSERT(r == 0); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(send_cb_called == 2); - ASSERT(recv_cb_called == alloc_cb_called); - ASSERT(timer_cb_called == 1); - ASSERT(close_cb_called == 2); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-udp-try-send.c b/outside/libuv-v1.7.5/test/test-udp-try-send.c deleted file mode 100644 index 7b6de36548..0000000000 --- a/outside/libuv-v1.7.5/test/test-udp-try-send.c +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include -#include - -#ifdef _WIN32 - -TEST_IMPL(udp_try_send) { - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#else /* !_WIN32 */ - -#define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) - -static uv_udp_t server; -static uv_udp_t client; - -static int sv_recv_cb_called; - -static int close_cb_called; - - -static void alloc_cb(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - static char slab[65536]; - CHECK_HANDLE(handle); - ASSERT(suggested_size <= sizeof(slab)); - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void close_cb(uv_handle_t* handle) { - CHECK_HANDLE(handle); - ASSERT(uv_is_closing(handle)); - close_cb_called++; -} - - -static void sv_recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* rcvbuf, - const struct sockaddr* addr, - unsigned flags) { - ASSERT(nread > 0); - - if (nread == 0) { - ASSERT(addr == NULL); - return; - } - - ASSERT(nread == 4); - ASSERT(addr != NULL); - - ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0); - uv_close((uv_handle_t*) handle, close_cb); - uv_close((uv_handle_t*) &client, close_cb); - - sv_recv_cb_called++; -} - - -TEST_IMPL(udp_try_send) { - struct sockaddr_in addr; - static char buffer[64 * 1024]; - uv_buf_t buf; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &server); - ASSERT(r == 0); - - r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - - r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); - ASSERT(r == 0); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - - r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); - - buf = uv_buf_init(buffer, sizeof(buffer)); - r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &addr); - ASSERT(r == UV_EMSGSIZE); - - buf = uv_buf_init("EXIT", 4); - r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &addr); - ASSERT(r == 4); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 2); - ASSERT(sv_recv_cb_called == 1); - - ASSERT(client.send_queue_size == 0); - ASSERT(server.send_queue_size == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#endif /* !_WIN32 */ diff --git a/outside/libuv-v1.7.5/test/test-walk-handles.c b/outside/libuv-v1.7.5/test/test-walk-handles.c deleted file mode 100644 index 4b0ca6ebc5..0000000000 --- a/outside/libuv-v1.7.5/test/test-walk-handles.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -static char magic_cookie[] = "magic cookie"; -static int seen_timer_handle; -static uv_timer_t timer; - - -static void walk_cb(uv_handle_t* handle, void* arg) { - ASSERT(arg == (void*)magic_cookie); - - if (handle == (uv_handle_t*)&timer) { - seen_timer_handle++; - } else { - ASSERT(0 && "unexpected handle"); - } -} - - -static void timer_cb(uv_timer_t* handle) { - ASSERT(handle == &timer); - - uv_walk(handle->loop, walk_cb, magic_cookie); - uv_close((uv_handle_t*)handle, NULL); -} - - -TEST_IMPL(walk_handles) { - uv_loop_t* loop; - int r; - - loop = uv_default_loop(); - - r = uv_timer_init(loop, &timer); - ASSERT(r == 0); - - r = uv_timer_start(&timer, timer_cb, 1, 0); - ASSERT(r == 0); - - /* Start event loop, expect to see the timer handle in walk_cb. */ - ASSERT(seen_timer_handle == 0); - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - ASSERT(seen_timer_handle == 1); - - /* Loop is finished, walk_cb should not see our timer handle. */ - seen_timer_handle = 0; - uv_walk(loop, walk_cb, magic_cookie); - ASSERT(seen_timer_handle == 0); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/test/test-watcher-cross-stop.c b/outside/libuv-v1.7.5/test/test-watcher-cross-stop.c deleted file mode 100644 index 910ed0fb61..0000000000 --- a/outside/libuv-v1.7.5/test/test-watcher-cross-stop.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" - -#include -#include - -/* NOTE: Number should be big enough to trigger this problem */ -static uv_udp_t sockets[2500]; -static uv_udp_send_t reqs[ARRAY_SIZE(sockets)]; -static char slab[1]; -static unsigned int recv_cb_called; -static unsigned int send_cb_called; -static unsigned int close_cb_called; - -static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { - buf->base = slab; - buf->len = sizeof(slab); -} - - -static void recv_cb(uv_udp_t* handle, - ssize_t nread, - const uv_buf_t* buf, - const struct sockaddr* addr, - unsigned flags) { - recv_cb_called++; -} - - -static void send_cb(uv_udp_send_t* req, int status) { - send_cb_called++; -} - - -static void close_cb(uv_handle_t* handle) { - close_cb_called++; -} - - -TEST_IMPL(watcher_cross_stop) { - uv_loop_t* loop = uv_default_loop(); - unsigned int i; - struct sockaddr_in addr; - uv_buf_t buf; - char big_string[1024]; - - TEST_FILE_LIMIT(ARRAY_SIZE(sockets) + 32); - - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - memset(big_string, 'A', sizeof(big_string)); - buf = uv_buf_init(big_string, sizeof(big_string)); - - for (i = 0; i < ARRAY_SIZE(sockets); i++) { - ASSERT(0 == uv_udp_init(loop, &sockets[i])); - ASSERT(0 == uv_udp_bind(&sockets[i], - (const struct sockaddr*) &addr, - UV_UDP_REUSEADDR)); - ASSERT(0 == uv_udp_recv_start(&sockets[i], alloc_cb, recv_cb)); - ASSERT(0 == uv_udp_send(&reqs[i], - &sockets[i], - &buf, - 1, - (const struct sockaddr*) &addr, - send_cb)); - } - - while (recv_cb_called == 0) - uv_run(loop, UV_RUN_ONCE); - - for (i = 0; i < ARRAY_SIZE(sockets); i++) - uv_close((uv_handle_t*) &sockets[i], close_cb); - - ASSERT(recv_cb_called > 0); - - uv_run(loop, UV_RUN_DEFAULT); - - ASSERT(ARRAY_SIZE(sockets) == send_cb_called); - ASSERT(ARRAY_SIZE(sockets) == close_cb_called); - - MAKE_VALGRIND_HAPPY(); - return 0; -} diff --git a/outside/libuv-v1.7.5/uv.gyp b/outside/libuv-v1.7.5/uv.gyp deleted file mode 100644 index 8049faa7a6..0000000000 --- a/outside/libuv-v1.7.5/uv.gyp +++ /dev/null @@ -1,500 +0,0 @@ -{ - 'target_defaults': { - 'conditions': [ - ['OS != "win"', { - 'defines': [ - '_LARGEFILE_SOURCE', - '_FILE_OFFSET_BITS=64', - ], - 'conditions': [ - ['OS=="solaris"', { - 'cflags': [ '-pthreads' ], - }], - ['OS not in "solaris android"', { - 'cflags': [ '-pthread' ], - }], - ], - }], - ], - 'xcode_settings': { - 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' ], - 'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ], - } - }, - - 'targets': [ - { - 'target_name': 'libuv', - 'type': '<(uv_library)', - 'include_dirs': [ - 'include', - 'src/', - ], - 'direct_dependent_settings': { - 'include_dirs': [ 'include' ], - 'conditions': [ - ['OS != "win"', { - 'defines': [ - '_LARGEFILE_SOURCE', - '_FILE_OFFSET_BITS=64', - ], - }], - ['OS in "mac ios"', { - 'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ], - }], - ['OS == "linux"', { - 'defines': [ '_POSIX_C_SOURCE=200112' ], - }], - ], - }, - 'sources': [ - 'common.gypi', - 'include/uv.h', - 'include/tree.h', - 'include/uv-errno.h', - 'include/uv-threadpool.h', - 'include/uv-version.h', - 'src/fs-poll.c', - 'src/heap-inl.h', - 'src/inet.c', - 'src/queue.h', - 'src/threadpool.c', - 'src/uv-common.c', - 'src/uv-common.h', - 'src/version.c' - ], - 'conditions': [ - [ 'OS=="win"', { - 'defines': [ - '_WIN32_WINNT=0x0600', - '_GNU_SOURCE', - ], - 'sources': [ - 'include/uv-win.h', - 'src/win/async.c', - 'src/win/atomicops-inl.h', - 'src/win/core.c', - 'src/win/dl.c', - 'src/win/error.c', - 'src/win/fs.c', - 'src/win/fs-event.c', - 'src/win/getaddrinfo.c', - 'src/win/getnameinfo.c', - 'src/win/handle.c', - 'src/win/handle-inl.h', - 'src/win/internal.h', - 'src/win/loop-watcher.c', - 'src/win/pipe.c', - 'src/win/thread.c', - 'src/win/poll.c', - 'src/win/process.c', - 'src/win/process-stdio.c', - 'src/win/req.c', - 'src/win/req-inl.h', - 'src/win/signal.c', - 'src/win/stream.c', - 'src/win/stream-inl.h', - 'src/win/tcp.c', - 'src/win/tty.c', - 'src/win/timer.c', - 'src/win/udp.c', - 'src/win/util.c', - 'src/win/winapi.c', - 'src/win/winapi.h', - 'src/win/winsock.c', - 'src/win/winsock.h', - ], - 'link_settings': { - 'libraries': [ - '-ladvapi32', - '-liphlpapi', - '-lpsapi', - '-lshell32', - '-luserenv', - '-lws2_32' - ], - }, - }, { # Not Windows i.e. POSIX - 'cflags': [ - '-g', - '--std=gnu89', - '-pedantic', - '-Wall', - '-Wextra', - '-Wno-unused-parameter', - ], - 'sources': [ - 'include/uv-unix.h', - 'include/uv-linux.h', - 'include/uv-sunos.h', - 'include/uv-darwin.h', - 'include/uv-bsd.h', - 'include/uv-aix.h', - 'src/unix/async.c', - 'src/unix/atomic-ops.h', - 'src/unix/core.c', - 'src/unix/dl.c', - 'src/unix/fs.c', - 'src/unix/getaddrinfo.c', - 'src/unix/getnameinfo.c', - 'src/unix/internal.h', - 'src/unix/loop.c', - 'src/unix/loop-watcher.c', - 'src/unix/pipe.c', - 'src/unix/poll.c', - 'src/unix/process.c', - 'src/unix/signal.c', - 'src/unix/spinlock.h', - 'src/unix/stream.c', - 'src/unix/tcp.c', - 'src/unix/thread.c', - 'src/unix/timer.c', - 'src/unix/tty.c', - 'src/unix/udp.c', - ], - 'link_settings': { - 'libraries': [ '-lm' ], - 'conditions': [ - ['OS=="solaris"', { - 'ldflags': [ '-pthreads' ], - }], - ['OS != "solaris" and OS != "android"', { - 'ldflags': [ '-pthread' ], - }], - ], - }, - 'conditions': [ - ['uv_library=="shared_library"', { - 'cflags': [ '-fPIC' ], - }], - ['uv_library=="shared_library" and OS!="mac"', { - # This will cause gyp to set soname - # Must correspond with UV_VERSION_MAJOR - # in include/uv-version.h - 'product_extension': 'so.1', - }], - ], - }], - [ 'OS in "linux mac ios android"', { - 'sources': [ 'src/unix/proctitle.c' ], - }], - [ 'OS in "mac ios"', { - 'sources': [ - 'src/unix/darwin.c', - 'src/unix/fsevents.c', - 'src/unix/darwin-proctitle.c', - ], - 'defines': [ - '_DARWIN_USE_64_BIT_INODE=1', - '_DARWIN_UNLIMITED_SELECT=1', - ] - }], - [ 'OS!="mac"', { - # Enable on all platforms except OS X. The antique gcc/clang that - # ships with Xcode emits waaaay too many false positives. - 'cflags': [ '-Wstrict-aliasing' ], - }], - [ 'OS=="linux"', { - 'defines': [ '_GNU_SOURCE' ], - 'sources': [ - 'src/unix/linux-core.c', - 'src/unix/linux-inotify.c', - 'src/unix/linux-syscalls.c', - 'src/unix/linux-syscalls.h', - ], - 'link_settings': { - 'libraries': [ '-ldl', '-lrt' ], - }, - }], - [ 'OS=="android"', { - 'sources': [ - 'src/unix/linux-core.c', - 'src/unix/linux-inotify.c', - 'src/unix/linux-syscalls.c', - 'src/unix/linux-syscalls.h', - 'src/unix/pthread-fixes.c', - 'src/unix/android-ifaddrs.c' - ], - 'link_settings': { - 'libraries': [ '-ldl' ], - }, - }], - [ 'OS=="solaris"', { - 'sources': [ 'src/unix/sunos.c' ], - 'defines': [ - '__EXTENSIONS__', - '_XOPEN_SOURCE=500', - ], - 'link_settings': { - 'libraries': [ - '-lkstat', - '-lnsl', - '-lsendfile', - '-lsocket', - ], - }, - }], - [ 'OS=="aix"', { - 'sources': [ 'src/unix/aix.c' ], - 'defines': [ - '_ALL_SOURCE', - '_XOPEN_SOURCE=500', - '_LINUX_SOURCE_COMPAT', - ], - 'link_settings': { - 'libraries': [ - '-lperfstat', - ], - }, - }], - [ 'OS=="freebsd" or OS=="dragonflybsd"', { - 'sources': [ 'src/unix/freebsd.c' ], - }], - [ 'OS=="openbsd"', { - 'sources': [ 'src/unix/openbsd.c' ], - }], - [ 'OS=="netbsd"', { - 'sources': [ 'src/unix/netbsd.c' ], - }], - [ 'OS in "freebsd dragonflybsd openbsd netbsd".split()', { - 'link_settings': { - 'libraries': [ '-lkvm' ], - }, - }], - [ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', { - 'sources': [ 'src/unix/kqueue.c' ], - }], - ['uv_library=="shared_library"', { - 'defines': [ 'BUILDING_UV_SHARED=1' ] - }], - ] - }, - - { - 'target_name': 'run-tests', - 'type': 'executable', - 'dependencies': [ 'libuv' ], - 'sources': [ - 'test/blackhole-server.c', - 'test/echo-server.c', - 'test/run-tests.c', - 'test/runner.c', - 'test/runner.h', - 'test/test-get-loadavg.c', - 'test/task.h', - 'test/test-active.c', - 'test/test-async.c', - 'test/test-async-null-cb.c', - 'test/test-callback-stack.c', - 'test/test-callback-order.c', - 'test/test-close-fd.c', - 'test/test-close-order.c', - 'test/test-connection-fail.c', - 'test/test-cwd-and-chdir.c', - 'test/test-default-loop-close.c', - 'test/test-delayed-accept.c', - 'test/test-error.c', - 'test/test-embed.c', - 'test/test-emfile.c', - 'test/test-fail-always.c', - 'test/test-fs.c', - 'test/test-fs-event.c', - 'test/test-get-currentexe.c', - 'test/test-get-memory.c', - 'test/test-getaddrinfo.c', - 'test/test-getnameinfo.c', - 'test/test-getsockname.c', - 'test/test-handle-fileno.c', - 'test/test-homedir.c', - 'test/test-hrtime.c', - 'test/test-idle.c', - 'test/test-ip6-addr.c', - 'test/test-ipc.c', - 'test/test-ipc-send-recv.c', - 'test/test-list.h', - 'test/test-loop-handles.c', - 'test/test-loop-alive.c', - 'test/test-loop-close.c', - 'test/test-loop-stop.c', - 'test/test-loop-time.c', - 'test/test-loop-configure.c', - 'test/test-walk-handles.c', - 'test/test-watcher-cross-stop.c', - 'test/test-multiple-listen.c', - 'test/test-osx-select.c', - 'test/test-pass-always.c', - 'test/test-ping-pong.c', - 'test/test-pipe-bind-error.c', - 'test/test-pipe-connect-error.c', - 'test/test-pipe-connect-multiple.c', - 'test/test-pipe-connect-prepare.c', - 'test/test-pipe-getsockname.c', - 'test/test-pipe-pending-instances.c', - 'test/test-pipe-sendmsg.c', - 'test/test-pipe-server-close.c', - 'test/test-pipe-close-stdout-read-stdin.c', - 'test/test-pipe-set-non-blocking.c', - 'test/test-platform-output.c', - 'test/test-poll.c', - 'test/test-poll-close.c', - 'test/test-poll-close-doesnt-corrupt-stack.c', - 'test/test-poll-closesocket.c', - 'test/test-process-title.c', - 'test/test-ref.c', - 'test/test-run-nowait.c', - 'test/test-run-once.c', - 'test/test-semaphore.c', - 'test/test-shutdown-close.c', - 'test/test-shutdown-eof.c', - 'test/test-shutdown-twice.c', - 'test/test-signal.c', - 'test/test-signal-multiple-loops.c', - 'test/test-socket-buffer-size.c', - 'test/test-spawn.c', - 'test/test-fs-poll.c', - 'test/test-stdio-over-pipes.c', - 'test/test-tcp-bind-error.c', - 'test/test-tcp-bind6-error.c', - 'test/test-tcp-close.c', - 'test/test-tcp-close-accept.c', - 'test/test-tcp-close-while-connecting.c', - 'test/test-tcp-create-socket-early.c', - 'test/test-tcp-connect-error-after-write.c', - 'test/test-tcp-shutdown-after-write.c', - 'test/test-tcp-flags.c', - 'test/test-tcp-connect-error.c', - 'test/test-tcp-connect-timeout.c', - 'test/test-tcp-connect6-error.c', - 'test/test-tcp-open.c', - 'test/test-tcp-write-to-half-open-connection.c', - 'test/test-tcp-write-after-connect.c', - 'test/test-tcp-writealot.c', - 'test/test-tcp-write-fail.c', - 'test/test-tcp-try-write.c', - 'test/test-tcp-unexpected-read.c', - 'test/test-tcp-oob.c', - 'test/test-tcp-read-stop.c', - 'test/test-tcp-write-queue-order.c', - 'test/test-threadpool.c', - 'test/test-threadpool-cancel.c', - 'test/test-thread-equal.c', - 'test/test-mutexes.c', - 'test/test-thread.c', - 'test/test-barrier.c', - 'test/test-condvar.c', - 'test/test-timer-again.c', - 'test/test-timer-from-check.c', - 'test/test-timer.c', - 'test/test-tty.c', - 'test/test-udp-bind.c', - 'test/test-udp-create-socket-early.c', - 'test/test-udp-dgram-too-big.c', - 'test/test-udp-ipv6.c', - 'test/test-udp-open.c', - 'test/test-udp-options.c', - 'test/test-udp-send-and-recv.c', - 'test/test-udp-send-immediate.c', - 'test/test-udp-send-unreachable.c', - 'test/test-udp-multicast-join.c', - 'test/test-udp-multicast-join6.c', - 'test/test-dlerror.c', - 'test/test-udp-multicast-ttl.c', - 'test/test-ip4-addr.c', - 'test/test-ip6-addr.c', - 'test/test-udp-multicast-interface.c', - 'test/test-udp-multicast-interface6.c', - 'test/test-udp-try-send.c', - ], - 'conditions': [ - [ 'OS=="win"', { - 'sources': [ - 'test/runner-win.c', - 'test/runner-win.h' - ], - 'libraries': [ '-lws2_32' ] - }, { # POSIX - 'defines': [ '_GNU_SOURCE' ], - 'sources': [ - 'test/runner-unix.c', - 'test/runner-unix.h', - ], - }], - [ 'OS=="solaris"', { # make test-fs.c compile, needs _POSIX_C_SOURCE - 'defines': [ - '__EXTENSIONS__', - '_XOPEN_SOURCE=500', - ], - }], - [ 'OS=="aix"', { # make test-fs.c compile, needs _POSIX_C_SOURCE - 'defines': [ - '_ALL_SOURCE', - '_XOPEN_SOURCE=500', - ], - }], - ['uv_library=="shared_library"', { - 'defines': [ 'USING_UV_SHARED=1' ] - }], - ], - 'msvs-settings': { - 'VCLinkerTool': { - 'SubSystem': 1, # /subsystem:console - }, - }, - }, - - { - 'target_name': 'run-benchmarks', - 'type': 'executable', - 'dependencies': [ 'libuv' ], - 'sources': [ - 'test/benchmark-async.c', - 'test/benchmark-async-pummel.c', - 'test/benchmark-fs-stat.c', - 'test/benchmark-getaddrinfo.c', - 'test/benchmark-list.h', - 'test/benchmark-loop-count.c', - 'test/benchmark-million-async.c', - 'test/benchmark-million-timers.c', - 'test/benchmark-multi-accept.c', - 'test/benchmark-ping-pongs.c', - 'test/benchmark-pound.c', - 'test/benchmark-pump.c', - 'test/benchmark-sizes.c', - 'test/benchmark-spawn.c', - 'test/benchmark-thread.c', - 'test/benchmark-tcp-write-batch.c', - 'test/benchmark-udp-pummel.c', - 'test/dns-server.c', - 'test/echo-server.c', - 'test/blackhole-server.c', - 'test/run-benchmarks.c', - 'test/runner.c', - 'test/runner.h', - 'test/task.h', - ], - 'conditions': [ - [ 'OS=="win"', { - 'sources': [ - 'test/runner-win.c', - 'test/runner-win.h', - ], - 'libraries': [ '-lws2_32' ] - }, { # POSIX - 'defines': [ '_GNU_SOURCE' ], - 'sources': [ - 'test/runner-unix.c', - 'test/runner-unix.h', - ] - }], - ['uv_library=="shared_library"', { - 'defines': [ 'USING_UV_SHARED=1' ] - }], - ], - 'msvs-settings': { - 'VCLinkerTool': { - 'SubSystem': 1, # /subsystem:console - }, - }, - }, - ] -} diff --git a/outside/libuv-v1.7.5/vcbuild.bat b/outside/libuv-v1.7.5/vcbuild.bat deleted file mode 100644 index 696f0db30e..0000000000 --- a/outside/libuv-v1.7.5/vcbuild.bat +++ /dev/null @@ -1,153 +0,0 @@ -@echo off - -cd %~dp0 - -if /i "%1"=="help" goto help -if /i "%1"=="--help" goto help -if /i "%1"=="-help" goto help -if /i "%1"=="/help" goto help -if /i "%1"=="?" goto help -if /i "%1"=="-?" goto help -if /i "%1"=="--?" goto help -if /i "%1"=="/?" goto help - -@rem Process arguments. -set config= -set target=Build -set noprojgen= -set nobuild= -set run= -set target_arch=ia32 -set vs_toolset=x86 -set platform=WIN32 -set library=static_library - -:next-arg -if "%1"=="" goto args-done -if /i "%1"=="debug" set config=Debug&goto arg-ok -if /i "%1"=="release" set config=Release&goto arg-ok -if /i "%1"=="test" set run=run-tests.exe&goto arg-ok -if /i "%1"=="bench" set run=run-benchmarks.exe&goto arg-ok -if /i "%1"=="clean" set target=Clean&goto arg-ok -if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok -if /i "%1"=="nobuild" set nobuild=1&goto arg-ok -if /i "%1"=="x86" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok -if /i "%1"=="ia32" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok -if /i "%1"=="x64" set target_arch=x64&set platform=x64&set vs_toolset=x64&goto arg-ok -if /i "%1"=="shared" set library=shared_library&goto arg-ok -if /i "%1"=="static" set library=static_library&goto arg-ok -:arg-ok -shift -goto next-arg -:args-done - -if defined WindowsSDKDir goto select-target -if defined VCINSTALLDIR goto select-target - -@rem Look for Visual Studio 2015 -if not defined VS140COMNTOOLS goto vc-set-2013 -if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2013 -call "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset% -set GYP_MSVS_VERSION=2015 -goto select-target - -:vc-set-2013 -@rem Look for Visual Studio 2013 -if not defined VS120COMNTOOLS goto vc-set-2012 -if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012 -call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset% -set GYP_MSVS_VERSION=2013 -goto select-target - -:vc-set-2012 -@rem Look for Visual Studio 2012 -if not defined VS110COMNTOOLS goto vc-set-2010 -if not exist "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2010 -call "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset% -set GYP_MSVS_VERSION=2012 -goto select-target - -:vc-set-2010 -@rem Look for Visual Studio 2010 -if not defined VS100COMNTOOLS goto vc-set-2008 -if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2008 -call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset% -set GYP_MSVS_VERSION=2010 -goto select-target - -:vc-set-2008 -@rem Look for Visual Studio 2008 -if not defined VS90COMNTOOLS goto vc-set-notfound -if not exist "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-notfound -call "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset% -set GYP_MSVS_VERSION=2008 -goto select-target - -:vc-set-notfound -echo Warning: Visual Studio not found - -:select-target -if not "%config%"=="" goto project-gen -if "%run%"=="run-tests.exe" set config=Debug& goto project-gen -if "%run%"=="run-benchmarks.exe" set config=Release& goto project-gen -set config=Debug - -:project-gen -@rem Skip project generation if requested. -if defined noprojgen goto msbuild - -@rem Generate the VS project. -if exist build\gyp goto have_gyp -echo git clone https://chromium.googlesource.com/external/gyp build/gyp -git clone https://chromium.googlesource.com/external/gyp build/gyp -if errorlevel 1 goto gyp_install_failed -goto have_gyp - -:gyp_install_failed -echo Failed to download gyp. Make sure you have git installed, or -echo manually install gyp into %~dp0build\gyp. -exit /b 1 - -:have_gyp -if not defined PYTHON set PYTHON=python -"%PYTHON%" gyp_uv.py -Dtarget_arch=%target_arch% -Duv_library=%library% -if errorlevel 1 goto create-msvs-files-failed -if not exist uv.sln goto create-msvs-files-failed -echo Project files generated. - -:msbuild -@rem Skip project generation if requested. -if defined nobuild goto run - -@rem Check if VS build env is available -if defined VCINSTALLDIR goto msbuild-found -if defined WindowsSDKDir goto msbuild-found -echo Build skipped. To build, this file needs to run from VS cmd prompt. -goto run - -@rem Build the sln with msbuild. -:msbuild-found -msbuild uv.sln /t:%target% /p:Configuration=%config% /p:Platform="%platform%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo -if errorlevel 1 exit /b 1 - -:run -@rem Run tests if requested. -if "%run%"=="" goto exit -if not exist %config%\%run% goto exit -echo running '%config%\%run%' -%config%\%run% -goto exit - -:create-msvs-files-failed -echo Failed to create vc project files. -exit /b 1 - -:help -echo vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [x86/x64] [static/shared] -echo Examples: -echo vcbuild.bat : builds debug build -echo vcbuild.bat test : builds debug build and runs tests -echo vcbuild.bat release bench: builds release build and runs benchmarks -goto exit - -:exit From f40a9dc9e488e2a0f1da6fbd438a653fa4c32383 Mon Sep 17 00:00:00 2001 From: Raymond Pasco Date: Tue, 7 Feb 2017 12:11:25 -0800 Subject: [PATCH 2/2] Replace libuv dependencies with libuv in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f66281284..735c7f4a7e 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ https://urbit.org/docs/using/ instead. - [GNU Make](https://www.gnu.org/software/make/) - [GMP](https://gmplib.org) - [CMake](https://cmake.org) -- automake, autoconf, and libtool +- [libuv](https://libuv.org) - [OpenSSL](https://www.openssl.org) - [libsigsegv](https://www.gnu.org/software/libsigsegv/) - [libcurl](https://curl.haxx.se/libcurl/)

IlG||>&m()vh!j1bs%Xt$;1BU+W z)iGl9GvI77$4O39ztw3wP%$ae!I2Xpm=d6nHVmWIPs2^O{y~3B_Swk2H_|$lw||6K z$mWdo132(1(M?mySz4g*s*AF%=GEXP2gc}cq9-&Y^l6b8w60FtYq9MvA5XoYgC+OV zXS9)9IJpEi*mJwR1_z46Pj+&AP5iNQwy);Pxu)jD+lIlznk?whQ1qdOqq#IrIdiK; zqh;*WYPc~%;2lmd_AlOGY~GoEftPNFLgs%$yHlsb_EoSSszWZz1qv~8kHy;I?=p@# zDm15UV`BcS$$ZlKsfm(PS0Nhqw0vzk?{JNGzSf{81&)@O03)hmt!ZS5{+VZ^REn!F zg@{JzDt-;U?4>eiah0R$onhJAP%!I+cPVk=5JmR&U;=CNbkKU|^YTs;Q=e8FIVBD~ zzEPp)rb(j>eq{LmT=u|Ud{8TrV)E@R2p}B{RizA0`;xwF{=p<@QN)xJhu3@wj>i;`UD*M`qpSED!cE}MKWAxX zhMNhp|Am*D%&4Z2i=bldNuqRJ^KS9joY>;flqvg#^2uYo_*P+A*MaM*0~CahG!%i7zOxVV&5$mv{Vf_y)SWV^Rdn%Ho|^OH@K zbWS1?o|5`5m?U^tVR(@bUKRz`dMTk1t{;Oco8gx3gptjMzcl=hxkw~is{q_lAzao_ zBTS>}xCsCA?NlMsx%6gEVud(sToAKfZfBz4Q>c7A zt#6|*>6SJQOYFe^#4<2RCF62-8lfmF4NFqd0~DRQ>!fM1NQmQFhC(zYdZO+_KT!A+ z!<|l00=Bbs28LsL93uC(LUjsM_}pr4{G{PjU`>ynT3%Ubi^z$jVBDCYfYkM1!n@Ez z<27fR?yt90!}PMwnxS6(6|I;3M9Qu!KSL+(gZHO{k=7JzZ6lIt_H7d36O7Z)0VsaoCluRzBlE&8x zV$WbKe2Bd@j)UFkrM03luXER_9f;d5x8M0hub>JbD+CDsDXS;R<}4}FRw99$QW!45 z2Y9%yv@AX#{;Vdj|CFzcO?j+8ZBdm6;+CC@M!mxr>KQ4Fi z?#Y4J5NQ74!0gSpAknqjkTEATTSl`A7)cDbig*o|)7$yx za^<+{(g{L)$>ehH$D~fA^JVSV=HSC+w)I(>_eGx$gi;Zxtw>u%-BURe_~OO7lGyWL ztG^tCyeYA#c~UdAaFcAYqJ=Xf*gQ)gmdgD`f-(GW{ z>v1!RBR5tf4Ey%_l6d1T@8UOfOO7;OukKO5Z%MKk>%3A|r#_TDN08D* z)#eG6%Pmb0@d4#3jLO^;xw5ft75vR*8eO4XALQ* zqwWyrmj}9NDYC$pktum{*Jhfgo{d9UxN|-XvF@OGeS!I8?_IVyB?h{Gb0QM4ru%3r z(ikHpo!Ho4^k|ldTDArBP*E=667Vtopcz|CI-t##qHN<0% z$^KiC%y&QJsC$WTs!)*uc{}^T6ZaDP4{u2mKOOH8{1_0X*k&|a+FZGio=6T@{=C-g zJfVdc5wb&k{d-=rj4C}U_ye@KsM(5-Ll%`v8()CisF@V$>AhY>a9x(YktP_cGE|-n zA%x!U(y*Fz!WI<6-(M&Ys$#;!yU?0X=xC#KlG_n#S_!?d^ACFM_#tCe4Fl)79Z!$c z+`LP4W=ui?=~AD2PF-Y?S4hFEkK`Uah2pmkzrNDB_0_J4enqoxb@JA{`q*%{MW8(Q zrxfL24+ikkU8}&$KejZsG#3?z_dy4x|XLfUyyCE=>i?xHR!$I;qy(cAshe@%cPpsp}U z54Bwk7i6fL|H?Gvthhhz)THnQe$}rsstX%5%6q7nnh@YV73*wf-`cvfD>i>%EKB#S zd!QYWdj@OIOmrC>X2qJ&vQf7E+_}~1PO7uI7pnnFWS|b&?WCmy(U7{wPYOo;zFsdQ z(ZP+J*V~Etj?9$?&u@jx#B?+`QNK&Tew~{ZnddV**N4E+ZXN;GDgv+AF77vHFbZNh z>%bpuTHft;9)Ukl9;P3NJ<64i&9k8{=&zkQsGxGLDDJL`$b2=XJF8^pDl=k!pYCaF zxc8(s%tcS(=ZPp^!^o`p3_D%k9USpn((s-voVwG`wUEQ>uH(kn zUqsYmZ0KZL*0uG!>^!!ehaamW^N}4=BdP;jNvZ0 z=p==NaaqM~Q>i-rr*Mkn`#1X>9U*IWgm6C)V%qloqaeYrE`-|i-vv{`biTr6rbN+A zhbiQQ>e1eoaQ9WT@)!v&o`G!knUj&KVgG`RdgzJ1F^h~M-CD=1L&n^iVD@q)W=w|T zzgi1u-&U0;v~u|4^JE2yq<4`pbYwu9bmVM}?mXUCMDVECTEUgc`JBUA=`Y7-xDsg; z*0-FCRYl)+X)QtyOrYY~x&q6@;D8|cg+_5B*tMul&qvZq$sa{){UOeHgxD!xX`{43 zszZ2=BD1luqnk;HZ~k<=yV7!f=DKB~Cul0A|8EatNiiApYOv98)c)DmsfJhG@KU(_ z7#10`23GRau=gi2c_)rDi+JAk?V_s7fy%3ZbNfq&lQ;d!AOfMsU~Xs7REG9Bj0_&| zvmVTb{CJdzjYlFWBq}gc?%V44oZMan;d2gE>%J$0G;04kM#*yUgz;>m+}mfI^4vUc z!9DWgcT)yjXHw0^0;kM_C$ojTg^4ORGt{x=9eQm2a`F@%Tz(=Lb7k%x1b)Dq@900v ze*HPg$1v8u2yK9b@AS&Mfw^9{GQGOn1NBKaW=j%l*^4o4LFD>jX6ji>V)PkQ4Q4J7 zqG)FUj>S{lzVb(g=52RereTTYkx;S6&0W_Jx5YgaNR_js9jZTWQ7d3UKQd+R?$XD) zrLLwH2LT`+GT1-*^gT+1d}?p7J7~zM?ICgk{@kx-`9Cax(UY}4b!3te{&Qe^Vz7KC zic_Q%QyiM1o7N9ElHBcYD!Hxkp=AV`Yf%I=LNcG#t!hNIMtP(4)KJ7pHb50+Q4LhsnVni{r_T-b+VoJ-d z`J)OOb=C;xTAygjxK29@hi=KOn6=%*QZ4&ywz#Uye#%m-MgS{2^5Rn((t#R}B;eI& zrNxVy{#tN}te0_Hy}G}+@^5*Gl3x$qRh{qiz>bPdu$Akd$iywbp;2dHn#!+gJ4$0q zcb30Ghd$T4+owH1xQPbF7UIlo$2`GuoPGb=Njjy?H&8i>+fDdgwtpZ6f?33`qoC85 zR>ziK)dDC;HsG(NzpRXS{;7}uIQAy=_h+bUVs-GecpsIq20hY^`G_P!aH?W#soq&d zw}b^b0~haW+F(J7G)RwTt7Piu%G5zPSc;>CZ-T=nI$*GA*A%_sCV{q1HWsk%!zWIr z+`=)qroxVVC2FYgCxIJ=9>@N@kb=3SG2Y*|?HCWmr5y>7MTtHhq*P|-X8}eNCfpDI z*e{~4=H#zyZ>eIoIf|2($ppI{RN|lQW;fP(pbYyO%HQjwcHd@*lj5ahGNfHZv2|o! zwL1D%yXqT^u5MZ1mZ0IO9lLj;X(i6SdcnxUkxLqKZH`@B&L=d)uKtmBqn`p%iRC0Z z%Wxih|Jd5&)673Vks}qGHP<1bcw}JpF+3C5A14b8jf1d}nsw#8ef!b6nDE}q%4nuZ7rCLo*oSofp4pU&UeazP3H5Pk z#&#?a1yaw>wUQLiRiexld0a)ms9qnkw=cR1x1P>?k;?Xxy!l<@_L*c%9&4Fzk#dNf zgq4Joga@ovuI_I_h?h+)T32F1e#CWGCx&j6^fCN;qqvjB9qb*k)*5_l1OJ1$N&04` z@=`msLE1I|ZK&0_H{5@Drc1Bb{NCPzzdaOLvfbm~&!;4Im!5E0|CfN6<|tP|rQ%LG zNc_`dP30LLu)#@V?=Qy1&4H<%hoRFo)dN`p0y(hsqQpyCp}Rt+uY~6>!@c;D*eQI(AGqD~XyrxO6k?+E1 z@;B%YBd(EXl9!O|#KfbP(KS!m@n*I299OSew1f)%b@|Ep_Y+P(~DVoqW z@ao_ZxBIB;8u2)ekUvQry1@k}_#UEz_m)oFa-ZNSkT9pSia1PaVWjw9z3gZp!M*!) z65FUuoJ96^4wEurl=n!rV^W5mMt&+4_nynRtP|eZi`C4GP#%~U6tz>HA*-Q?f;y=? zcV`cwJ++CPKWw(=z4sf9V{1Zrb)%!+P& zJ2Mt5Y6)FDWPY&^QY~~jQXt%06mfaj&$80`)5D7|8?&$_Grd)EaMfv_p~Jw&Rhjk= z+7*~#rnGd+2f_#vR#JnT-AsY=g(Pha3fFgYy2sAC!mlVi1j~~0+g%h_qp03~{rls^ zepMRC^-&_ZkeW(KQS`kef5otlw}feHX&^)-_aQ{B-xgmL{86Vt9wufabGtFtrKv>T zd3gR%)>;5|^7EDblQaA4ZTj@P9yKhdnBe7kF<9qD zWFP&nqQl0Vmhy1dGDEi%kx;G^oe(Dy)qqdQb>rwjEx(ko8$}Y%(T3N{^NdG7PK%ST z8&6j0^q)gzqC{B9-{%+4n`x{k;08nXh7n9bi0}EsVGAo5T8m4!On+te2VwgQ0l86Q4Qa^bU1+8jEv}CCzswIpZ_|v8079Rp(R;0 zkWrooG*>3G!jJNvPx2I7n{^um?`jt(hB}g}Zd7n5iK5;}ki7YCA2Rqwh@BW?n5GZA zVYOM>6{Q)KKOPpb4}a3@-1!7$kx0wpc(@|%`l#_n+yN)jZ!@Fu!nnt}>p zS~p+5L5Le=+!&T9Tj$fk4#4aTByB9|3=Wag&UnZizfsq-7l9VTbN-0Ej6t!>oGtnC z?YcxZ@=y*#o5=M(ww=Aeistab23D80Hr?Xwi*f91ASDGv4Wy8r{!Qkn20h>sWk%&b-GE+lO!Q z$^Kad9Zd$ga8ch&W1hAU30OVBy7<^Qs#4e54B2-@SmWe?`FU@>uj^lSuP^#s=ltT? zq>PJ0HMSmD`1Ua98*_wrr}-k;wMrQ{ampNdFrsoH8dwZ;waYR-B%0mGdm4*T7dDYE9&0I-v?8^qat(&3}QF7W?+&xmNsfL^)$$N881(C71OM=M^m2mZH}W z`I(^vd`!j2Wsp7YKN*or&)@ngnBWWD{Pu&WHkIWM#~9XtnEUw#RbMmPmG~_+-kkzA zVGmVIWtReaqU$?iP=+_x^Ua7Ic55Xdm2dCHC$5ce4oiiWMSP~6FnH&fqCb~U;4Orl zqxkXcX>qN=82_|Hl57uMdKX$DK%dOxj9lT$cE@tV?Ds1((kD_vy-B72=g-O_OvD}> zcE=UN0}6l_wBydFnElpmVi&@6&di4CS&hvL^U{u`2gTMhu1pykKqboLfK&EWGki3m zGrq#piMrtOf@xGjmp&s`=Y&D1BY;C(aaXPV5Rip1wwC-tu{6v*9Zo7B{O@a(t;?|-7vc(ACVRNWSKH39VN(2`#m62JVW44esnAbq^3i|7~d^j zEYSG=IM1DUglCcpI|!q5YCR*1jwi|QBqqpTde8#&QSfEZmrjE?&F%=>mQEnuDfCIM z?J&WrN^s*pu;%zwi-G0gLEh#;*?u$B;TM(Qvpv;#ZpYTAo^{J`=Ue6R)*k+;cx_sE zVc4oce)qja@SsCLy6&><^0B{p8yZwFq@tIDRZ*||@GRiEPkSbMFtsZIHKB#^>=))= z_C|$`i3dP8DTXyAN&QZq6bO4YA_|o`io$z|Wx9N5SS9aW?ebUy9nVSSt;6s&;ako4 z{s*leL|!>)O1vClz4nE1i_*C8NiP|c*kK6`){H88IlwWtXuNOPCxWdMzR0-+CCi^; zcS8~-5w8GKUqrp;HA8eM6$$=E#MAC9e3Bk?hJb<0#E8W{PK8H1z8bNmE!jTnIT5-?#uOefV^-qCncHGsKN7(c*Njzyu zgZs8J7zxpf8^BFcmM_tzJN`uI$%Wo^iJL|$C>9uF?!|JK#!!y{V7*}W z&4#0Lt5(Y7u#D1A%lnnV%)jU7JRIb>|wu4|V zpfq40ZnzBsKUD4j7h^A`+t5Crd?0p=F=J~1cJ@H%ZZgW%apqtahMj5g1L2i(UeBTE z_b5LL6Yu9XnkZ4{%)7~Oyfut7xvq607%Qm5m(L<&5KjufPLjLeIh#ak>p!2I=NfAi zAK!YUNs?zu=CHJDT^>%BEc7x{yMuL33qf2xzsa5)AWNr*gSs95B}qJD!dQ5Oe%x&Q zRZxAe7J@V?JOOF!BRMV$bZj4{K+F&*^JblPsxm`+rTvTx`((Q#6EJ>`Ne;9qjo~;` zjMKPsK!|-P5+eUN7*uTR9jLiZ9|Z(`+|%Uf+`vo3S)%{5x{Lqpz*aNO?pOPY)s?|A zKa!d{USN?PO*D;G6qxcO6j5+gsx!`R}4N}g)B)p zzwCkJ^*zCfgBVBFWcaw52=3rpc08=y$xm}uOEU9v9je9oCnWlPO2epDnYw8suQIGA z|L$n?-Nn_8?%y&xg<5HuJ5+?-c|YH%_O6nYm!TpwpfK`1IJVO*;Q^!-D@q}$JWdlu z6|Qoxz&Qr1VBF?X_jP!JBfisZZ-36V=;>>A;Ujx!N#OlY$)bI!F|ArjENUT&j>R1I zr+COjuTeUlI^TH0pao72FumTKni zB<)_94Z1r?3bZ#;)X?Gy0~_9mim~|}HG_@0hIA3dqr;(U*EEjNvjL!T$Ozn(%4tca zV;01Lw2IRRv*wCA2ddZ?dQu@j!DW+$gVjP$G#ggue4@5m6!U|=EK~gD9M5;h`uSYwqu<=2qVoKQl^;l+bZE&TL) zLd84UuCemuBu^p4^4z-F^?hV;1!8_xg!_xy4*?_8JPgPU(wB-FSlP7_HJNW}lWfDn z-9Q^<0(Fd&hDv>;9sRNyZlEoiSup~V;KlQhPpRRQS40D;gBgISH+SgaGXO4n%rQjP zb+n>j%2_g8|KZMMr=lf0D;7AfyEIOmkqb}h(8aot4_aOAQ>k`J%_v8^eLZpN@T$?A3F3^C*wVGoM-kjT;yD zo89sh1d}dsjl^{%(h;?mN>?gxMLCYXm1O`y{QXxv4@blp6ZrIH6Hz&8{i0++c2OJI zdeD25D={5GeOMmT)okORJhbhfA8@TP2>qlDL6zoc$35e_itm8pJa0R(nGDn;aUgNI z9N8O@TCtEMI8=~2vGIGF%Rn=cmi>YGj?BF>MM`aM;EfVbsjd0(eD5}0Uels0bq7ne z$E_71lq;uq6Oc(GIfU(Fuoh5dLt%X}tUuyJsORSgChA)0ko#e4HstLe>f`0Fx(mpi z_Rnp$WW5wUZ5ojH)&6M5)VML!X;D(zDrhyD6g-=`Qx`cgU1kWfQSMm04TQ`5)bstc ze7XKz{I&-A;_E)y``UBR$kTfD4@)*rOtANj;#uY}Js|1V8w>)nnxmfH8qr;4A3qUT z;$2zKL>wooHN3uwhg)9k!ofH}r(i1F9La8aRcn*I^HlSQH{PSpQ$Oa7$b+u>iZLDH zzGs3`VNlR>p*T*x1~#wk=OlC}Ab6%n7SJN~EoJ*8!9dZ2pBC#w2_V;RQBteA%N^3@ zU0`GmFj)zOh;QEhC!_N{E#*MYPJ-1CdzcuVpmBXigr2xop!X!#EUa8NF~ck8QC4qZ zzDC40Xg99djzk6`>PWqKm62-JZAR&R+`%Q$L-(K(stSDnN?UyU*6E<`hv$=_)6PhC z24$I0sl2RL8WGPVcKj&{J|sHx_c#(9$NwaT`3EqF2@VQ)hFBSZCnlE)MCpuJ^>#c4 z)GMLitHV+dy`nfVkwX;pBp#2IV@EaKC))bstK_#6Z0b-Z;V{TY()FUS3QyHY&wZ&Yy z;w2?%Jsv%wyH&~YX)Dg|D?!R_2`qUN2yq@l3ndS4ca8iQhv%BZ<9cKi??+cX;8Mn7zo!yG4p=G+A{a2bdc}LH|J5YM^?cD5+|F?9U zO7X3Tw)`YJ>YC|};g_*@gVpMXq-NQG2S5kMC05X_b~suru{Mk{q1NU_(oeiR+aU*r zL?6pmo++J>M4Z7qjfi(#573T{D$p@f^e|)Dz)EPei4II2mtUB~i1&~B7gExc`{7KF zOJ0sThFoJK-@1L|&85S`%6M@rM_Y@dQ!dM&i?Sfsh0%t8-uRmsJ#l*BkMaUGW$1UZ zJ!uE0hxrTIgNdEFumhY$pbS!1wW);=QO}S8KOEjYS)Q&|m3orSUk;-r9X2(ohC+e& z4ic;7m~F#Zj&q4o?ue4)v8*fYmZwR!xKcv{?en1DvxhN6AQ>O3o74WRCBNkv0 z5^bLPX>jQ!$Fu~Wl)vwlqROAZHuJI#1OPxZ+$sm@O=l1k8bVoJYGms5QKR?`HwD4!17`~FX_ zO9k+#`cffgF~GUz&T3=MDU`uBY+@ho7`N@NIoT*3JgBw0mvNT?xz5XxBs$C~%%}aO z=t1zhObE%9&gf{o9k_a50)AuFaP~=lm2G7vnN~eN3&)AW)ns_`L&M~K`@U!Ngax^RXyI+bcY~UNHian} zZxK^FX&e4=ZJ$HDP#{pIR4QOEWy_=h+0hx5H)Zc?`T|@6e0Y6Z-2}kmNy#TRrNn!ymu^7Q@32kebqky-3@B z&Sy=tzVb{=2tAITg-&H9Ujvtf!R&nz3Sj~sAu$5};)6!jg`I&MbyoB^Zvh@d-H2(} zSjR96UoCtfT)MFs6`brdogysyFnAVL2Ud6K$3-cx#Qcjg!LY@QlDfmeaXA70vfXN61Uv^}P&@ z1xc$9@RW|Dk|EL)+yXv5$4ZMC!$>F$Gc2eL>+HD3 zmE}t$#J86tkYlI_p0+(ZDhPa@Qtp}73-?hD{`lor%aO@q+8bX3<2mg^H&#=jK^H|4 zvxB`74S;)7djE5lP|U5RUMj5Ftt8qnPeZO@|a@(eXREnntph z&+!Z2z0x(uMY@5FY223Vp5Vts$yH*Q2F6b=*|XuhHvBbNn3~jVPy{D$3T*)^ zcZINO2A7n*0c*NPIPNgZKCFvqVVX25{3MJnR7&SqsZ!rm=z{R_DIupv@;^Hn;8?Xu zQnNGq^9O49Lr8u|lVHd)yR@z^h_EFn$;vVFxT@|AK}!vlK+_7d+I-1QtW{<(Qna&| z;}mRE-2l6Jmr}5*vBbgaGl;9{Rml$jp3MF5YFizqs|nL3XLem%lx@A00-TGl*lf%p zW2T7X-g#yYwe2ag&nHyyd^2UITW2_;e>v5rCjrBQ3=7+pXL@`gUVHBh`1s;GPAF?a z0_cb@@v$Sn#sm)6j%bB#>E5F!r2GJ0m->Vb0|-$)vFm0!0f`V+st8Ty?RUA)A^5V1 zIAp>gwyOr5#0mJol1xMXE6a^txQ0M_``HM8O=pTD!3IXem8wXNMpuU-vstYo+MKP} z>T0&GX7iB)QLy5OUO_oimOuz|n%{~M`dtY+pU2>WL&a?9IV(_wn`smbnRc)uPBapu zrRy>B{T@teWo|IMS-68mg*NcxU^oI?Ir_~6t-xysIdJyONeE*UBh1MJhf7F)_7wO> z!qLEh@TX;2px@dP_|p;76AiO^Gw!a1i&xSN_BBi%;BK--eZg$&9AcMImqW7 z=07Wcn$t8MxOr~{TV&|A^x;kDM2`Pp1@Xpnuw73)lw8?Q8Id&ilAzJkXQu$L4Ys0` zYqaOq5C?1~DTIkK4Q;%z#7M49h<#i+Pku?d1Mu5hBYnBAh~@OVK^&=I;dGDnM!l3c z3kX)@I}%yLYQxw%FnZgo?S#RiXQjbj`b^VZ?DaVXS4$T`BOH3BD(9xhDEd!@3@-d0 z*E#Ux3fmL7@Y_(^2nSIH&f4~gvUEjdiC`cXJBJpc=--gc0e8Fs$Lm#aVOltNB;g;; zqH`WVY8Vt$X8>|8CTzrkDqPLR4kuF~Zmx%(xAq;ubUl$wcFj92vV1FgqV8v7^?m5G zME%##g`>zj*^OmLqt$T)Xa2$Ix214$9uF);g?{l%Xlfq~~C{(q?WP7u(){_hX@!tW`qd}R~(0yC5^nHhV^jTI89%-sK7 zs_E%+L|LJ*pgf(72_?cSUIfy*`BbLf0@(Cf5ro;(8A@08Ic&Xu0c-`}JH!@oLGVB* z-1+l%qQC$Bo=*XKz_GYH_r_}|7_kb$#m^-l~#kLC0+AmqvEZhPDM(JViWme zWA9SPj2rXO!1_y%W@*ZdkN*M18>HtX$LejzFnIDXQRX(}Qib*CWeXn#8XH)ymtVj0 z!H|q!xl|#SU-NrCHnzSr_Mz#=lk3^%6{YD|ef}Y6h*?M|cI<~UlHF&^KAKsEE_*#c zhfCM&O?ShzOqJ^Tbbz4|^YGP6I@_ywYegkR76=ibsqUM;sAIbGQy<+FV;7RsrG2K& zKO2|&WZC4nRpPN}<+~rEv(Oy!`(D zaQN1z5;p2ml$;RsBVutm$Y&7FEoNl_T3nb}1KE2gG%`H@uZZgn2WaS5yxb8LQLH{&|mGAkif*@ z>j7{!FO?ZUQ$~nA@qm!-9@~F?eX0aTx04$M#zp!A4XWJ8*Iu&zgVMZ*D2{f5q|1`) z?Sk~Pq|t`6Dy`%5Ea*k;gF9&SfdM4(LOShJ0X97M+5Wf$`(n^GBp-DwcOzM~7=*qu zs!#ca`>*htCjkTHV1y~={ft-pv<#Uisx$z)D|B{hf#mR$|t}4-|!em z0cd4>q$y5O0$dl$_X_~W%R|u|qD!+khl|?oa5TUj^p}+vQYUx*dPrialy5MQJu*2a z95TYYtN%0yjj9JvCx0wz+PNEmE#AUR}Y#Q@?_d$F|`4HwMJ&K)7$Sc0Y6^ znA3>%+3oY*eFo#5j5eZW;itOkgkIY%X~SUX2M=3mFBA-6tjV>ElkbSHCnnPxR70}< zp|x_;zdSn6^1PtiC3_lnH$SEea-9grjo zuUcF$%f4~niKK-68L=klH_KWW%!kt8D*YN$_~ipX`rDsSq~F#uo!@@R$u-_`)zf_P z7maQ?`Tdmv^?J%oPR!uhGMUXmvBf&JP4!9j=gqfHfCjeH%00wiuUii`ZBl6QdG_~b zD__U0HkGpf+$@ZR&h7&<7O8(EsU*+YsM9sVDKzyfOzOM8Q9W3+N}-bv*}x5FGl<$0 zGa7^cImCQZ!eVW zvB!2p^V(9z^jr7u5FING!FX;uH_or)IT8r@mr(rAn zA=s$QmN>96e|`Jd#PZW;FmS(}(v$meK9zqxT?IPXNLjY$VinkK-4Qru3$wnu6--MG zt5Vuv`-(On2G4gh8&8^p*mM7&yX#-3DFPQ#|YI?Frt z!^^W-(YZ%>z^UBN2BTxN0VxN4?$b)oqBJZxc~FGqH3s*&_y&BJiq*;d3S?G zw{K#zoGJSqedEq}P=pp1>Go!;33(%<>&ika=4Ds0TALC`9F$4S22!S7+uf>bnGCR1x0*rqtgqcK* zWRm3Rus52nM5@t&_9u54G1D`-?r|A~;w?KX?3p8p3K}Lw(pNziFGhx+g`({BaIdT(S9^6}_us zUG8Q35XqE1(==7ekw_+!d;Rv764Oalt7%S~0-ZKo+ffs)lax*?Y~GJvO4ASS5X{as(XX(5%uh z{pSz{G(~;TsiUcNL!c(1zUpD-g#LW%N&k_Ui(QWJK^1r2j5|@LG)|9%&xF1G zdwj^VW`cY9tPFQ?;U@#M*js2Fob`+_Lu7rTNYbJ{y)w~C|QOaU$4=&&wB^R;KjnB>l_=TX1SSCj)~Bz!po!5zS^k6 z0ZqlaPoet)2tVCrhg~>Z+8-(id*U>IAHiune- z%3s4KO30|~W95TiI3bwFQa-wBD#?1B^CeJry;e;k7gK}~K})+jO#0FOU&jJTrgTQ( z!Aw{0&Ca8jD{jE?y@|#(9}ihy*9ET)xU2a??DoG2D+P;SPO6)lfxDKr-vGW_;mt3z^fN&myZ)H`QQf;*F@>n4glTDD;QaT6N>tPH z@}hW6{Qj0xbQ5f%%K(@eIk7qsnUyo{Y;%vwyX8GMC>xq^t5otTZ>`N16!l0x30`u< zMt}ic)Ho)y{Td8@jZ+4~EXM};gVCvV)tEN`j4@*t`eR?@W9G&@kV4Wz4o14gKeXE( zyCeCq9sOJxLdjbDQmuO6LFv@Pv8Y#Mc%<^j!myxP#c6Xom!3kk#LI$6wqvyKX&)Jc zWLS}I45y@X5)gLa#}-eYs5ulFl`k+998_z&epe27KbQZsLw6yC8 zw?#iM$A(1|Q2lix?xpd%D#F)Ca;3&3O|~ez&+H)~W5ln7?u_bL=cP3-)(T8Tr$6l^mz07tgaiGN1Byv2mu9vm-l8n61KLNa)-J*!)8n8mgJfCr;a$3xK z@ZA5*M>#7|k%4+dC%7wJ2hyYWBpM_j>9N3r!%i?(l$eeoGp(s*7HWs2eT90%Uo*-F+;dNHO=WC2LGQ-RV8E&5m@=w>wF1`KCWqEutt=g?0|XRVT%Qq zf^oi~rzA?Arbc&`?+TO*iQEBdVOSoX-_CiwP>tqZgHOtkBSy6I8o z%WE_n3F(XB^snCNTUZ_?>AXp3Syxwd-Qf7yr7veVdsNz(yLTVaN>CksYkVrSWK(^S z29DZ?9-Q_ASx&OcxhIYux16XZQ^2G1!SX*1Rquqz?;99Dz2frwQVko1Z%m^G?^vD@ z=rU7Uo&6l3A)&y;lg4*lyGER2)2tcJwhkDXo+N^hAMc>~osB$GSldp--IKbfo+loKN z$7z!qe|#f0DqUQa87yIFzS}RW9y0i-Px>71m|bXh?!4q%?2|nCAMXO8-&eMJnkPS{ZnKdOC?C`E!6hM^KWF9S zO^z=$H5`ktS7TWeA9Ejnz;<<9%@R^Ns)Dx|1P>g`Ujp`ztGo;3_?2VV8qz?7wR?`8 z(9Hm4!xFU-!x;HJgQRq!+OBR zy(jpXYnOKQ4QyR!#K_uwQ z$?T$b#p39l?h;>ISL3%W{T{r<)R>9JiXZVhD^3knCP7#7`!NAE$n<=WU2<^{e)>VP zWVfo~s@1c<2}9cDo7~NGc*}uS)MKRphe<`?lq=^_+3VR#3HFQ7zQttxWjddn?JH1j z3t2yZG~4nMy#xMo2dWe9{Cl5Kc)=d73Wd(T)i)YzyuO4JSe36w8p{(QX6^-Q+tpNQ zEgdAB_qkmnF1qoy1d;)i;i$r85!-m5sOJ=+Yiecw6~Lw-2YYYg{n zlROIe>^5m#Yo~6eeH@^~^-WeSgv%n3G&4%!q)h&&{o~P|u9qp_l7G_(2Omj?Y4yN9ekQj=#}oCeGZq=}dd*79S8U!06?|HI;QsoZ zL-#<_cC=tP0;S9qi`=d#^ydBQGpwk=v-W(r%gLjw<15zLL0K@qd_d??|Ki~_jb?dbt z8TyrDob##q;LYkB#;w-hslw9co3bnYDjyZka>aTvcDMgU$S; zJ>R~1N{@z-VFve=9@)vJV}jnDQFhH)MhWlnx{ZanRVyOMbnnJ2TBDB!8*7J$Kc-T8 zT(T$Jgkb%%xy>Tfg<%YO{1A2|k`xrDzm{=T{y~3U$!XAtYo|*UjB3%(M(XKiKKk~q1zZ?Uw4&B^ts?rFT)Iim)AZbaic{zj0k7+ushFy0Z;52pFhItyaAHX?FTl7i;8z?wU7F}e z0wcv=ig-S07xpnY45=*mKOx@>uokAypz0uUb*s6nV)x1D1aKL|e-|A`xGCbWA1BJW zjNm*3vDC^RLGNl^yKB?6FK@LshQ4l%hNC}tLr>O-t0?D%9j2YYl4@oWM`ivm@CtfI zJ8buYcj|vl{tiF0F3*E&h$wPS-1=Du)oK8$_JjMb{xwqI@YQV4jO)g&cH6Zrg{Mkd zEj5&&pV(TrtIURi=$eZpK$=Vja`S|omSC6wcQH@^iM2jHe7Cx9iM)X;F+DzB(f4a_-;|$&3aF?2al5Z+uM6 zJn6qY?Igr3=w5X#!T5-nF^DnI9U8);8;XX`ZsTMAeo$4KI!?YBVy3NGC{!{vn!|<& zac{ksEL@d9%>#&cr zU`gX$rdC{P8eQ31ncvqe)Zm=jOA5O=4F(OqVSVpKv8oUKqA^Yi3({C4?@^ohk$vl^ z*N`gLk-hvMZb}NOie@daNA4f!W2n)neg8}236eY?~S>sm_*%S5&-XC zBF#!?`sjm@oze_RfREpqX6?aHJBXR{33FanA)-faqNDOxTkXquMt^k^`(JSN(GFet zoo{4h1eO;Yv?zPQCJnbqcUK{HVRllhYY9T0=>q1)p6>Y14B{ebT-T8WcyNmI3MCnt zFr782&tkYVQS4KKB5>`PUQj=*wQ)(pqX4P>H>oaTyee(&v z558XoYgW1}+iS_>s&nA0Rs))KJB`I4a8do&Y?fMo$&;}X;3QYE9pHqIpu4`68-NauRPa^ zOTi~YS?Pg0->Nrsb>8e1eadll&B(iaGTQLy^Z)0+di#;LJ$>wCne|n2*D@lr)StDc zj3N8-`W=P;sa{uj$qRs+cE7;e-4R(Vp%6fTYEZANq?K-Xd#Tcw5B z=eSZ)sRRwSsb>#hv)^M3PxH?wV69}@7wTZ}4?SegkuVk)k>>q8X=}ix^-YTTT-{|& ze^+1cY5dB%UP6fa+bd_E6{TeC|MmxX2hu_Pn3mi{NwLZ2741(Cyt>~fWuWK9#J^(* zyz$^kgg^D>w`kMhnRh1b4H9~ueWd}RyZY7&b7yhc4Ws&Cs@Qg)yXp?*_;9>se^Z!D zheFTJ*EP%~ckt-$F-EadSVA4v-Zz8X2UsjvpXNXQa@X>&HZ81hS!r6VdmB9uoIuDI zBPvq}up(3W7~d6crv6v;W%((vT|ie~zKEJ`vz2{_9CWy$gWbf>u_LcQE8J6(CSN3q z^iV*&=F-9)Xm~_7`N_yOuSFym_1){G|LSxv{!ow7#R|0LW=$dgaDoFg+_ngFL$tK* zmoMo0%g<g)NquuK3Dg|_FG+a23WAA3t=O=e%hOxXfKYXfacckup1EYC){dp^I=@J$EGb(9!?@ zDl0nTW>xx~=O^JCWdI*2&Mj>>^XzJG?+6|C`n+9~@YejtQF`qY`>&xsu|7{qMMWOsNJ3n9 z%+3&$-Zhb;6o(vwEMdc9f-Z*1XLCSyyE*!-%?};VEd@YN)wk$cu;&2dv;f`Fv3`oi zwMvkT-~7J0Qkp4WnCM%acMdbj{~h}u765G6o_XpLM4$5BBSBi}VG!ClTDIWxsyDgt z;|;12wu}N0L-<=X%5VhidK3b#I#?1F0iQF&Noe!5n(zi)bPzY;cvQ}di1+{_9~4)8 z{^SN7Fkfi}m0~krXTz_y(3N1(7z@2hjz5W4Z*?a_X4)Td-JB#V|Kd3zJFg*`jlA!! z5G<0J{#Fz9xcd3yf2DF400;doU|n8~ka~JYI(>V6=cPDzKGfH*0~0?j+ylLkVFqA4 zy^WcTEW_gmbJLxaUo*E5rWxhBBT@qYDH#2q;?bH44rjGpOCU+{me1<&<%d*U*?{0$ zMx^1#^y;bIY3S5{%idjKK9wJw-FQvAF$^rM$dtfu0f)tchk~C6xS97LLvg;ft%9M` zNk>OBsX+FqeSuyMUW>4#se3*T^`z@N(^XdcoT?{VAx*f?g{Ggrecl?DxJuL1tiJFd z2#v(diMD+9{geCO*DOOXeFBzT__LdLq+JI0CcWImWRI3k*400MY_9WY09iZqH!?^A ztm!j!tT6`^kTklyWyWhSH^VK|_r{~x@FU-kvj4%_d&g7xKYrs@Br+?6Lu8aq_HnEv zk&&{uka4o*$V?I95ZSBj>{&*3X7s;gYdR@=SRSe$w_Xo7E#nF-kc&81yH zdMqhb(~Ha6Hk@C~2>vsmJ#`_dh!DZ+EM8bI&@26b0*$UF$$?O-=+d}nTyL3GcWAVn zzUe_TU3OPhfqN;MUp^^1uhY%g#%gvl4wYD+T{`^w+-a1am%Po`w$Y|U5Q*?6Nubq$ zmojk!#wATJ`4#s}HpGtBR09@g+-bWgHtSp3>F=DL6~un^GO+lnx`Jy(6iSFp0#(1$ zJ;py>=t7e&Oaz-V-AfR<&A7-o+|&jklFRDPYP8G2#TwW06iUeLGFPKeoL;>nZuisU zQ?00O?ZilEiUEs5tbpmX_m;h>J=ClFL0J<1q8cJTj^*q?c^4F_m&3cDaOkTZc8xKFNcSUdBITd#EV#Rp zEH2)b6=6-rr6WJp{@A)oA$3Q8gX9D|{zyV}!OCFT#jYvc>^;N-Ujg7!3Fssq>U zfKm7$(tG+Tt6=}PJ1h(^4Z!jhC+NVI8WuSOZ2v@)$vZ#^4mtf$>Zdrc!bK-S^w!W~ z<*TilB4l0B;jRv`J0Mtn2ccSTs~2v~kNsEVCLzNhQ$W=oh|FS#?Yv&b^?}N6aAXQ3 z#MDffrl$a>cvXEOpX8jt=C$r7#a^TlAra~OClTJ<_7?Lz0EI6e2zD;IlakN2M{q`xBW`MA$8}C zO$;qI#tNm$N!J?(hthK+WKR!-2b?geA~)66ZBpEIO50m+E^9Ru8gG9O_kz-1ldnz# z6YmSM#1=}~x{A0O1D)aaWpG9sf)qmm`)B1EZf}&K7OCO0uAKxO>#r)ISb-dx}MZgzM@iV5q-#nw3pkgz(Tu zn13?w;QYmj$#&>Zpf+fAd}_<39*QZAh$4abZDct_;zDW5&WO2dfe5S@L`gC6CQ~te z0Wr7kJ7L7U`-PQdlYZR+##C%YI>xl)msq5y2ZcwT=DAieaLPG?&vHJ%G4k z0{XyP*Sf}R-DercMuTOK=axY{^Fx&3Jjmw#6~l~Sh)*cd4-x6lGi4iLS+snO9pJ>Z zy|Z!2=Bs0N0!Q1k3qdGGcnXg5@3-xC4}3VynXXeHeZk1ZZ^O@vZaTEpcy8eA1Y(jk zVlXAPW^8R*o`#R3)4ii4`r}{!La;AXlUsHte+OAN6{;kgtUaJgqu)g z@tgQ)$K*P2)V8b!zv5fig!;>H8kKkg<%Y4xWs3$pZI64abh8%eaLx|s_b%;R=~b>M zHmVSy4CR$2P-pIiA&E&|#5aIMN96Qg)u(r3F4eKbZfW~m0uCM$N{4-LT^bL<;s@SSfTX*l3$lA0NJW(KK`GkDVO)PM zwPx^L(XCga>T_VYYA*{6VxCl(`H(Vv1US*-hbi0|@W{&|2W_2P0xh1@9n7zG<{MTE zT{B#Vj>?;|nYr(dIeU`B3xeYKjSaf=41Kml2FhObK9+mEm+(d$Xjk(1*7V}I$!5%| z-BZ|ST>9tamZ8S?`RkFR2s8^ky|a}8oAAW>dcS3J_};jQHOIG`QCq*CgkhZTm>kd3 z(QzpnZYPk_d-@pn9g67B$D2jB3zfp)uxn|*bm)0$C0{J%lAu*yS2>@=1oyemYLUBZ zqP$8})j$QK{>~DW+&w2m?cT86 zOqTQ8Ru;YBMB`(W#RpRq3JIi?mY4_@4sqT7{hB?38;w^$xqrDBS}ebsN0Mm(EDAompjnIjbR%pN`w>R(1g40^>_1$u*SGn>7f|kv2wM%87-L@&=LqkXKRkq?~dsBT*&7}+< z&rOQ$ip-lN_w4uPO zNc=n*s;tUBC&kIgb^`Y=ywbxS5Zujb23%6lJGXU%Ny2TMgs4oI&UcX z4(p~8zKs3B>H1~ExHv{N#q)Y&lVq=;phS6((c}Pe-$|ad)uCdn0Eb;Ix5n`Re;~Y; zWLad+dG+nPdiRH14=6Y>m+z3cVn8MQOwEXUKjPBLH>r-Ct+DD}_w2*F6@`4179UzP zeCbX%HB0PU)+eiM`!K(pf~8|@R!dKrbSfOUPhJsvCzsB86V>t*6cm!|4d}MlTyAS+ z85}^^CSRg>IO@IALcLf@i{`Ef)b5mg``yHYvoWHbY^Ozc6dw_=VJ|u1Pf1Bq>R~Xv z63JmB>;#++BCzE=4HQ$+*SvuF#S%k;pG3(#6QRjld|tDcqtPz6B5YV9nmnM;_Qmnr^M2ki znAL{@XIn$&Z}u4#KU`^>HY>Q1qI$$@MH1*D?--h;58jLI5{{PycLq(5C)lE|OY>}Y z-5yWq;(5Vyc3YA;Tu+_3U8tY>7TWj~)P!I~5~^61Nm@ax9NJFteIV8+?_%%=i5+GA zL7|B9u1vJZE0HF4ZYDhD$y~p&+UZJMe=uTrdqf2mw$sAtSTGAes9vAAlM=DVC%fhe zJuBB82zYHE^GU95U0^GM(X+Cp-6FggfFE@xG|Nh}6x!Izf|ca!C2ErU8cMF8`g|98 z4u-!?|3bH!J1HQ3HbAtigbCTH7_mn`F>z(%RVpTV3cYk&vdgkNuF;N#nNy!&h1}EE zp+sFP&1NVTiNH+U8BI^dEzbEaSf|mqLQ!2bj?QR+e46dx+p)jq=P^ z6=?FajX=3nmsh24ZN6lA8wUPh=zg2X(#@%X2u7foS{B$~WCNyp%&tWNjrw?te3US3 z)F>)Dqb`kD;2yY}hU#PLR#|tg@g3i9-;EF_^@KO~5=KiPmz*h9oX?N8Z-kZe^VlE!3Op$Cm+t2A(mz(n?VKbU; zBiCWj7aYF#rgbDX;Z6R)i9>V#fP%j3Zj||3Z?KX#Al~wPTcetmLZJS1_o=u#fmNw+ zt4gE3lmD~rYiViGA-3JY&946MDEr{^rN+w%lvawio)*5xEp6_x9bJr9#s7ZA6x1MiEQsaoi0*Wkfc?W=cgCoqUQ11sIVi^Y|07A zC)yM8l`PE1S97ENgSm!8p}Dz`$=| zoyW2|yHX>OlGD6hcz6WH5-`6*$kj@kd}oD07Ofhir7K-f&w|ZWewRXvj8ZP~wwhD& z!FB9(1O%k~y7DA{bY(mBS#hNUb!*V5069m^2=ruR4?Kc4*`Cz1+iFp)1t=R>7}Q@R_a@ z)9y*MG*wd|`0s!okH&Xpc`eSg#a+!Jrbn8%%6j2No4-?|ejy2gqZbKDF5K!|NZ`Zm z?-!kv@*IX&-ib|b6*W|>E_Qn$LH9-94VM>IqkCXR&vu+vJ9L=C99kwJNE#1x@V6dY zS)&TR$4lUT#bZ7o@^5iQc-{@Kp(*HoY}bQbasCE+LR#h{ZB>oA^X0ci^n5eh3Ny+y zyKiae=c4Lt8^t7xF}SH8!jV8TP>@NAJjC!)N+OI}7dT+br4vP43%ASOX7_F1!D}kN zTCjXEmUM}a)O6qt*0H=8f$HkABuhm!UAIS|zBlGA4lwX|F6Zv`& zZ*Vl}vLc^hsx8QFu8Rj?96+R-pX@MuuT9PFaH0tVy#a-5*mh0QqPd-QSaAyEk zwZw4Du(=PM8W>CL*LJ50MFzO(a-|$hMsP>iOh}@<>v2}g^_~z19c?&)+1m$cWKVv) zd9Gz?{4NB(frdK@Y?m^m{wlNhO1yW_i)X68SbA^j+o z95>sdWW?j4ol7#)Jj)X_9ES8OVnOqLXOJ7C+Mt=dS1MCP;&RGs2!b`JmWeINCd< zzZ2m0f;EfjnQkdM=N`;+eRtZE(|1}%QXxWLX)ByG5>KU`Y}&-_GQ;m>B1(<0_Nnf= z^|yG>-kbw+1HmibgDqo{W~df06HmOSZ4o@o9%Kh{6wy3^$}tP9bb&JY52~ax_^N*E zpZm})FNp1*qhhyVl~D5SxE37qj$?9iN0QI#D~r1@@`SC@dnw)fbr7ZWT!COZV|>S~ z$TdAj?E8v$lov}s?B}CaKLkfF?BnzHd3+k_gL-N7wmB41<#)AGpOCGDkp|c-ywvmH z9g@I`b!Znaw|isaSy37OA^nb=jW)Xel(ah%{_U#1hJkfbuhYCab$iWA2qH`+ucwvs zN+hI;`?r5&Za*I!ZEuBA`ygQrFV8_cHKN7w4j!l5N)RMQrM311M} zH#%oE3_0?W-7`G+CfX}ZTkqaNYS!Fdy(l%1=KS(|A)C|pC|9})QZA8cS+kZC{41km zSGOJn+0MgH&FC(Wq%u=_&^vXY6iM1$KvcT2!_C?4!B59UZ4d9Lwu+7D5BR3Utqrhk z%hJvkU+q-3=TT)jPf*mThb%3WoRrgj9I2;m_NXW4F-|CVw=R~?V8&^6(1z9ea)(^E zTpd`8-Y;*zKz;=KnUP#2Rk>61Sn{OjX6R*llG^hH>f>K$iDdFU*YB_19D~DZxA|qk zldw&`I59R$NB}%74eRB%V;5?VX9H3uY}W_1)5>ZcB5ht{w%2d*JV49_`f#!lnC@Gi z>m_=%ORreSviqi-N2#IdM#juRe890mT4&5ej zsN$lr$2lh>>kGfHtrIJy9yK0nJ04!Bt8)3wHIU`#LaFIDkyY=pA=QPxWN7gLu{5NC zGiTZKPPw%{>WsDbRU6uOrWqgUfBLP@bBM{azv*1i$^PWC-dV8NfwT>`S*0#KU6A(d zwH8cI2HJ)(6UHrI77&v`0idzSf$>prQ#@K`j=SV)%uF`ufhyvGEp2$lsV@Q-JTt%= zwdy0Dt=;x5Y+1NoRXz^0VRPIN*(~yQn(y{6i1C>=j#HGHSPT8HW$gdAAIz26n9ph1 z<@^y*C`ylZrmz!D&Br__a3&$l4d}dv3C}O5!WNcqRq$2aN4SKQo>X*-g(>||KS*Yr zJu`3;jPNrf;3)S70qcx-5s>blzzpiGv0-;6OOg?QS|JU>}`e~w^P2XY8 ziApfXyx@i7FKKW0f&uM&VlH!6RXxIefkBN)vqOac9oy-eTk0K*I z@HOv`eyu+wumu}-DYcImdB(E);)qdUfi0fLhV~u|5@Ah-#7qyD-f2;oM0EKY=ftPp zKgsYmZXY&%B^Mt4S!MFDB@tXukb;wv9vRWMznuMW5#QGHw0ZX7L64{*d3Q-Ttwcnn^yQLP{r|=>=_LWd_ZKD zjeoPt{j0VghDn*R$~a!>RG}ID%XE0l=q?uhnX&J%*!1jjd*;bCKoI%qQ4T(k=^#`9 zo$gGF^ba>85A!LCN4~eZ0fN*brhs_r;H`93Ys|_@ z)6GVw!D8k>Zd!SeCtp#PcQ&JAli!xF&gC0@{_&Z<-brx24*J^OQf3BpOa^A9Rv)<2 z9OyO?adFFE>!GZ^YYC?y+O}jh?ylMyRyk?ytH(ob@Bmpz*%?6G%O7{r2&fLipq0IH zN$_L4KUxx~0&KTO+!0uFk}*A}OWkpC@?Li(9veco+#l4lX?Z&gzY41+K0@Y-t4yyx zzt-D-tL=(}1Rco!d*k}-jZX>AuxLM8wPR5BjpT1Q#<*Rw4mZ01^cr{(0b~?cm?bE9 z6$bTJKRNz$a!T6nf4dlwA(wo)DfBW=XolcaQNS(0w=DYHkSH->Xas@jOIzc`G05c)9-Z^_s!YI|#zcZAJfW^93#D z1mM*1zRZttSNpfox9ugkLoEpqJ>WY*=HcrEWcc9BU1@&QCH40uO9gOJgz(d>|K&ZV z33%lXHY1z6X~q2aB_VLD0lrkD{9m6F(x@N@Hhbmtt}Np3OYu}4l>FhO2Vb97ZJF-! z?}^zQ0SmI3+xY{fJ8P@FR-K|?4~Jhr_EM*6)SBG~{-0-|y(&%mcfqcaU%+P~lqE?s z^=9tN(g1pz&jNP&5+uh5=%~{(&$9%wUd72!R*a=lIuyn5e^z+>?}Q*L(Fn`XfSv1# ze$d^+G8$Oc`bY8+>nF6;NXX&YvLM(Y0<*H5I{tH^tEtEDqzb}*CD4oey`PbdGxfy{ z`$cE+{k^SYE)#Qm(DDN%Qjnie59`t_1(kC@TevsV@GLc(ELOKLo2KCrh4l}ORgs`g z+5DgRUtP|4P3!B9#SPlYirokQy*PfnHq|O|0i<4yS9DIx*JZzWxSK*X$EaKtt9qhB zWM|aM3rK5AQ@z#yMdlGrEAB3XB9&wMJev^PtoI>JSW83;{$+%KvJy{3f&$!v(} zys|87YrUM*UUYoKG2p+nQYGYNZq(&kCZ|x(A4m4|LxA7!z}?vbC-&#spG2n_XTXLy zFHvJ{U%s@pYG`n%ZW2;mlQX+7E`~Ga z2~5D;5|93-hROrE4r=s0F>zpoWfjzBNx0!ybckNM{#U;f*IV==LT;=Pe@3%A6O!xL zxP*PF7oV4*U6?=TSo%Y@O62btTcIOO;M^GI+!R2EYrTj>Ih)-sy3Yx;Lr+>bcalyE zYAIc{0Dc;VKTD@1%4z;*#N*eg81LH+U!6$bNR{Gjc6`4hT|DE5-g z=xBZ99A`u)i-i=6`5upIen#`3DpdRB+64WTLY&iOrzRri(v{Fu?BU|mU;y=EsBCu8 zA~i?>N}A`>;+EO=uJcsn^pv((sqN@r(^kc0;z_SYj{A`pB5m`8GwpMl;qI1F*xH#( zYt4CKl(8Xxdkr|Zv#-w)3mFg*JzxocLgw7;@$4D~kLxGD#I+l=Bss&TC;HE!v+-oV zFP&sqNE88$G_se<)eofb)c2}nm%9~%X7TQV8&WG1uxb{Z>~FnnyD3eCty>&l$% z{as>E7?h5S3P|B=^{TL9UZWMy0P&;(>2%{h4r3>P2`wq#Xz6AT5ZjJH@;~j7!liHY z$|t2h%Lz7O4Y(f1M8KUDLanHUy|=g=LM5p~uxFqdRR0ut0FrW~Ui~TMgz)euPl298 z91>4lni2j`4_}?AID0|H{{$jsmt#NGS-Ar8sq|90*x^9Yj`M2Z5!4g942t@&50Cm} z_NSJC*UT2^FQ&4M&{bagD|aUsojy(;X!Us}O(_iIq%s`-CGI)No)NEyv?RfNW5T=} z6Dbc#n4IKxfyd3U&HmF|5Th6+szWi+M)qjDM_qdBmgqol@L}LDpdJ}nzFh37v>Wc| zoly-8lZH-N^5souDZjjJc7YSGCg$3Cu4E^LU8o3FZ4rcc_YAuyc5k#39YLmK93V?) zrhq|m%zUhfOZ5ItSH!hkXW^|wm z>+sZo#!%XRMbU-p!=tBOvx0n&a@3#gyo-h;3nS5YBt8Goguo-$o%$ip#LIRUXhtg4 zK0u$H1d-Q0LhVdLf+(7G%)|pK*;_m!u}~$JAl?kmf?A z_qQ-%tzJx~v5V-8u$`}NO<1w9Ex77I0Z81G+Ht%M(>l6r>Dl<&d_LFztiOO>iB7AK zh1P$R8}bJ8*(-Fqlx;QynLxU5G~7P=mP0jh3pDe5DH9FM@8G0NHljI8kXzVj649rUnHffgM&n{1 z>z5Qx^mUR_;aHVtUx7XXSes|ExdghXSCm&7WgSM{^^LVJ8 z{9~HMrbYcbb@|s@Kf7R<)E4`)5Mt!9`OF7xzg*LfZh2@#c@e1wvH`MYz3B4L>$P zE^5!8RA&QbNWmojhuw#$KaRAT=_USWwnZM5`IpBHOtL+)wnNgqF`YdjT&dst#bD1h zSB`*kpa)XtJjxj_#;SA&nm}b4-sk9(K?`UPw&>ZHW!U~_6|Y355i(Icn>@?z4?{t+&=)g9yEw(7QM1 zp8;yy@*}erV)Wf-q-Zbx!~$BjezqN3GZ6lCcoX+iA)Oo;mpA6CiO`ki0wjQmF|N8?9+{nQR-i2T)%QBy#E z>OT#*SWiH(PQqvLDY>f(&<}Ynufl4Xiotslq3<}f$+{mv>7D*ZMxyx>Dr`uOf=K-) z{^-lXJ2@AHgf1EbcZK3}=g0NOO9FA_SJf~OW7~DRoq=L;xHNUJBUo7iRBv2O&LyOT zmq?KRp{hZ~eG#ga9X8;-s>qUflPC7*qwbfF6(Nd&$#m7Dl|_$w-@+Fd`knyN^Vb87 z$(OK*CXhJ2OpJq)7bHQgStxsuqH`;?a!eT**D7qs9-TmXlq@9EVJ7AFl@3URBCO(y zyx28)=U`h+u_Qtv6c}5MtB2{p(;^$t1N@oH$zjgt6r?Z~iTI#4TIA9GNX!$ZA5nVM)JInCe56Fj}n1Cwb*bq{iuPqTVor}LSxn%Ox;6O$)Zg-#^;XcBt zP7u+~IK3TY4W^9bnrx;+@9}PvQTWmg4O=KOx=gt0L}Y}8u@BYjdR6BTs$#u&5~&<_ z2%+;&p8{q!mc_dn5?`>XGJhu({5}n8sF$p0tc8PYP_v=5J5X_KL0eBtwb$BWNbDQQI^|xCGokC>& zA4MAR6=EtsvFQpz$~7r|09wnN6lQ!$yxCB6xH^YdBGdB=oMCw!wauWbQg3VH%eK%< zNuz{5^TZp3eQCn$O*R}jC=fsbwtdmip;RfM0$67oVjLN6GcQEZtk?+NPnzC|cou`i z1X4)ls`+dEBGvFzK*>ZEp3=tzD9ha6%_ZV>GV^>i496tMC43&Ik^SATnBx``(DvEN zVu4uvvwS(I`Jm$ps6f@Fc4qecR2^O^j82+bXHc)<0OZKkB$)*lsCp;d7(K zt&q0+YF7Q$-3dy9>VF>dn;WSWQzB3WM)UxGTNrFF%I`{8Z_g|N+JGxjRW(IAXyZ&XNbx_y&A`+Zwa*f6w4{crz> z5g_yhZNR4YgZSKa+?lRF2jL6aRsJ$D^jN-zs%tFzoHT-LjVl)~=#+QeK0dCoI62lo zd2sh&;rh8Ocr&!ZQ8=++JvQ*mFRV(e>M49bq{ z&wzynP7U?#g=Kq&fJe&t--f=%2l`J9e@txhIHs;4epmk0iZ|(7Zoh7-7_N(taNf;Y zRvp%gy-_w!{UKsr`3eeQuyUD?BFwka@jBE}bSKK`ujX=bpe2f* z(^#B@8(xVCi5klm_W2akOez#r8F5XhpkdWx||U8chtLlWEXtZwv**q@Ao5iI%*-6 z(>qSIGE*{gwtS2$#qEJ}q=amf{GB3_;(K>|=H16fRqs_-zNvFwwUqu3(74)oJ)DqA zuJKu;)*U%u~^-;%i%LMeDL^< zV#@04ZkwYNuTrU{Nb}(kXPsX4vh^!-A+pZ%kC(oM#*5$q8!}^Xq6P}H^zK`T?8HZ| zc_|i2E1WN(Iswlg-Q-YL)p3|W{pU5Wuojn?ccE#v+y~U2nR5(5Vke&QLdzMd6D+;t z#WqEhzQ1cXj8>$UoE88Cr%hpwsUj`bIJ`sVK{{bfdpauF6|UIuPzsV;*JJyo7h8lo z@D}hk(y#Y5vD|*$EpEKqR;cl%AkaP7z!dYnnd_jCV6xS9=`iMt)wXvET*266(RNb! zJ@N0weC^$sM-kqz1gh`ZaT6-QSvPzyx zhsWP3I6sdV0rztesDp|fTldy^iqfRGTZR$QOSR3dt2tfN3Toh1ol38_-8wqKugb-J zYJbVyo!ON@Hmxp~(^HRGbQKG9#dAb;8+MU|SLA$y1nVxVt}7ucYelO)?UK8bNLorsls4k4Dgk(p@GfKDY54^!NP0gRAJJ@qIj8LB5 z&t9Z3y7h~4x9IYteBP#zP;h@}kyj~VuH`1O8o_E_|2zzILDNzRIF!Fvax4uhE63soi7)?f5;aK#UNroSf|2Chu~Vpo2wtkUR+JfY<+Z+BHn2U2mM)~| zWzy8$&gk3DQY*2F^B>c%>`S8D?B90gHF>qDng};AZx3im-jv&xIX8pR)cCkn^K|iu zy|3mY*Oqp}LpJCRNYz?p#+Wm>`M)0#LeO5ox@uar7s@7yZQk0^A&S0~c4Haz$|y8a z&&n|bZ%Vv+I;(%HxA{g+@`Kc^p|wdaW92?70BzV4xsd$&AQgI4{8Ms!kV1f2`|c+-Y&8~fRbps zSHk$vD)gJq-wtjG&p3Yu!p$Gs#Z5S~w};Nppa+l(SeotK!c_WK8Ifq1PP?R}>ubEp6baG?p<+Mr@I+Y|acv`i$P}{~;Fm5q zYAkvz)n%u%-Z*ZU}#x!(sMZ}?l2l{+p6eI18_>DPxGlc=-u)I z>FB4>`(+DAY&+#|i244D_G_4wUv1{a&^EN9kIJ^D-<)LfAby?>Jt|)O7x9FQg$Kw@ znhm$v6Ou_1XZ?4x_nUo<%>{;E|1uMn=)@N!m$03q0!2gH7E={ ziNzLjQTkdmlr(gR0|IbiUG{rVzbpiaqjBlH!k-WF8K>KVmHnm6Dm!mvcxxHt*_f;s zyIi+RZp~dz3gYw)G1Zk_o8KSz%T)~Wg}w|+GKoD$ef_!fSVJoHI~bLGS`-0ypBu2~ zSnavpHo8>L949Og@(w;&QtJ-E-Nxe#??W4_OF}FAMf4p{2l?A7HrWK<;_5Wf45YJz4Vc5TH-}n9}+qdkI$`A2H zWrOZFwP&q0R&{@|G0Zs1aDl73F4I(+Sc~(8PWPCt6(DL^97BRD0O!X8Vf0uTm6_Zl)fAZSS<_QPpF)knY6$bJ zZg<<}aG~8btZ^%QF4=gV+}5|__SFSvR(}@4HG`_~oPR`&c`94jRZSoqqbaM0ne5Bsv zRVI|DOnw#6QFKhaQcg^IFEh*g9Y29n3v`9%;Ysm~Ov(WgZorP5@8e)gW%igIq8wAG z8*lXMH=6fr>8%iGJEuUvUW%D&Rs!&X`@3Wa{KEpOc_l#E;URLj{e@bciGr^^qh*si z`8ouFlTCW_5E1AI(Ce=%^lA&`?;&oHhRE$Ilj$9c>tsksGoYjQwz~ejr*^TUWM0~z zPht}^0am?YTt(_XKSC_uE(3U~THYP$tO3UBe~3Rz$i66K>VNBBTScD#27-aL;`?;D zHe&z1ywME%iSNVF4 zvsNM$=!82>ZHS!6Pl0hz44^aux1=t#PAV+6e=fshVzPiE+}+m@CJg=te35_r-LFbl zaY805pO&uC;)H;&^Ze_OhenzIP#(#j!;aFa=2j-a~8&_)w2BmP^7&Uo0N zZl}#^{+SEOONq7UI|!-s+vlUw4x@YVKVSFFPwuTr>$f2v_tW{I8@6<69_O+)n1wsv ztUgV9U->;(dhp{Q{Hw}yZ&mpd#Kxsxk3Dp-tEXl2Ug#JFWpE*K;bHL{zTTmXo)nlfbNH4covHctfE!RO-+1}M*$ z3PeVnT+e2gU2pY_;ZoPsxFE1jzY>*=`i~7eQs;B^mnM5WyLww&KGPhC0yL;sA9Kmh zs`O4N0%mM`oRl%32S-84Bp?e5mp0t^Yzz##$JT&1y8_r7A*c5L{|(dDb|C$r=Z@*` z(J{A$=$T64_!}Ct)^8JT0L=zY_v~x^?Ac`Ku#etS`;RnYBtnj9+rr3cRte#(XlTMjA7vk{ z0?5~i5|!g@*^Q?y+(&)KtFk7+5QO;0W8Zs~Cy_om#%N8Dn>G{Re#dOLcDR71qq5b} zCFg5BThD3v=U*)C0smzKLQkf;1^*)2fi}hV<6%?LgHProZK{w0r0vMYiEtHe>m+qy zcTs_N*={)BbmA(P_`;x+EHHBE>uIMN;tU>c9%X)(OZ!q->dc7e*HjUgR3TW!QOfjsv ztMX5jaO&FK@IO()J_>d-g3Ni&R%K^z8qQknqjvs1^&nq0Rl%H8Xfp{O8+;^Ro5&N? z_z|yu@>5)?#%X;%&}u&I#1ZksZzr|y;IG|VA-UwopD^KCGWEM%txY$ux_+an(4;bP zBC?9_t`-hfRBDZsUkhmKDg2|qY@uNt4xgsIELxYE3a&*#aWOkN6^xyf~N?;RjQVX{g_S1>2E&*&|a zgb@bNc*R#ADDXpt+<PzVVh_ zPwMlZgy^|TGPHrujE58iv=u4|9e)utxe94#bc)s zovDD*gZ)5}uQ(L^y9>;HdQmsLAeSiwE+s-)oK5e)1K(iRbs-Kx>Vcx+I;kIDb=4=p zIoH+rzx~N|20}#b)e*SGp!$FauLn!(Zgik7^IuGwQO_ChjSd|H5GirOR`CpgHvIbp zXR+1O^10ZJ-xCuoarGY25il@A+(GZ8^9inQhvm~Ph~N)_#jf!o#Og^SPk}%431p%Y zXF2-bo(RP&_C%-t&K$M)kW%ECKYz~}X!de^#R;f$iabBknIZh@z^P{<~JVSoFLq{M*BLebM%A-x1KQ~kl^&cHh+ z!(4s-PvcHO;M4c1O>1#`-~wUk$@AGb119)teUM^R4#b?Is|Gv|EKurgwT?S8H2OTsgQ zu^OEg5lbuHnX(V3Ks2-efUY;xNu8+nrRT}S@6NNynbXltV0O=+Q#StN+1)({u{1g0 znWj6?z;vEyOQ8=yG|M15hp+a&Y8-zGXTH%ew5R$LO2$QABl%(wMf@nCR|5Z_t6Cs=ATi}Dzfv!XU&H^B3#e^s6r~~+~ z+jTnxj?IJ*S(Rv$96~kU)e!4eH-EV}{$m(!)d!%ZH%Qvl;XAFujV;p0+bv0y-m`=~ zf9k10E37@BBq`s8gu|KMaslUM4;iqG+tL!FN{xmpaNr<$>;mGu;Sc-0O@1O;jJm%Y zopwwVMH4TWhKb3!g+_g|e0=#Hs?U2_gpust9{rku-0xZ8$}B#=V|dluRZR~E zm%$3e7cwj6Y$sH(?0;?-J=!eSNH{PLJ%cQvgQHNC>ypzHwK9`dYB0Ov(NpIz!Z{k=dki;{OR4w=2mB4(EqiP9QVt($)U9xVlA-9u=;XVJMya z+!&k0&I*LO+Y+vj#luN;frIku`r#s%Y;|U#YPf4>@&VxtoEr;=c#iduz)$V4=eLRh z1=uaGhs}h79|$>(_UWGjyy#Ckby59GkuHFJ3jh!C3&IoAZ~b#M{c%n;bNPy?JKU5rn!95C7Uh_>Jf_aUk&!PAFk?+HN9=bFuj-yHqCpwGE1vU;dNq@Vy;TMc!5*bt5h0 z>M2yuz3fj&5g$a-OBuaio{BA4hEV<8l3@__W`eDGo|($TCs0{%%pWVAKu{ z|AO!}k*F{htFm=KMWz`tUE!2ZCggm=nFum9?)N|r=?4M_YE(qO6ZGOY^GLSZJ8|F~ z8z)~{j~K#$qv`fhHoZl(aT(B}#wBJLkZ|xzuWOM~{VD~1Ef26TOD8gdB#d)sfBgLf z)&w@qpH58-$#Qps(QtafwdrNCPdB2ukS!{ni|j1=6LY;(hnp6f#SreF^#jZ}*n72p z*nHE=%z_YMHst`C>$Q;?rYR`UIpsC~Z4Pd{A~kly{cLIlp_|O5c?cH&$D157;K z6cpO=t`jwMU!0F(7-DN(Qrr)Q<W|zrb=q2+b+c}X!#&c2Om>0nkpz{r zI`R`}DnE;-?D{|$5bn`$ruiCQGH@sHt!(rkM^Gq&kRxBD>rZ})RJzAnyGzV_wNE>; zz)^jxfFf!Vq`h{_s}MVL&O!1RE5Ve!)0nJ_OcW;1!W^AS3Von-6$y}d(4pKF`u0(Z z*J@c;Ti)yz#iyn`9+cWd9b1=tFSNj4jk0cTd2gn0HW*j`kkhyOrSOfC!c$NSQ01_j z)c)89^6Pb!hc&%4hwbIcN|Q*OBi1?HM3nF}+J_W8U9dd22$<;Ncchz8z(IxbC9_WX zVIbzq+MI@DNLhL?X~DUI%Zh3N@Qo?J66K$Jo-APv1A;r zZp;D%w0`SS%{G&%DjB_&jU0a*$5zF8r=x#(*xhsznJ1Np=?xH>sk{iOH7dNpWEP<4 zpFy*MCTzSHPnr_Ky-ZC)=0U8NHHO-BDM`%yR&(m@=N}TWS32?OB-zqTnsLe!wQd>K zcyr2ou+^5(5G!T8%z|2svZ8yzeAz>NQS}$NWaI3=nLk2_jv%}V9qVTus0w6pG0F!( zDS~(e!);Q@fZ2nuSBIBHpNT*D_4lGDVfKozy;|3}HuVCMP%%yFr07=?lmxOMwU*4I z%%bEJ!%KDuvZHH~h0-Z!AAg0<52tvwB4!t;nFt?$IN>pxyI}RK{q*Jitud>lh(kJbClB0Hg*A6Gmq%=gOQdF*N`x(!+D2=lsa)0-Peu+i85T1; zzB=U_{;;!)bQ`&i2$T#cwE1l_0CYJ3HQSj4fT8`%kTj*V*L+k3T!(MuT5 z*X=wNWc2|O5m#6a%f1Np`8Eef4=*s0UXwDMsEkO?Fry2Ut1ji=zH10Os5EDEZ$yh+ z+C(^|&6W)2eBWY)^|5Or)MLdmN5hZlKcsNe;@UD&oiW01ApGu6O2?@9C)+$ZKyyMY z;Z+>Qb9Cae1pUEFF8F&m+WPr4zN+zWi@JO!t8{pSwfHs6uw@CyFe>|9{t))DUU%tM zUuN&im$aFPUc9CXujE*+I_Q3_yt;Iel)!Mjfb}Bm;dNy71J7iX**>0(!nXxy{1sw} zv&QNWAgB;nLXzoz?7BAqq%s%Ljk{hRG$x=3;=ZuK>7Y6yy;YxN{Sis`tE)C_w<5gX zxFRzOP-Uq^{%o&CHu7t>U{Tf&F~ z(xP}$*&=G>!tragg(rF2f)vbk7Kr@=+j)~!La(26Y7bt! z|LpCHeQudu3ZxWl$irxwXda&3IVHw|T&T3+mV>41g_O%W%muC$m#sRu`i>Q~Xh+=}%s+iwC{uqmXnn*l5ouiR_eWqxY)zG4EMC{}b~;^Lm0N-Rri z=Yqv64YfB6Zpr{-?Ct7!I-HhHLMF(00nrh&2>Sf#%?Bg|`2KwYn0HETpKo;~G*lfj zO|c2~A8p3Dkj7;34Lz8CDp;hJDP%&#b$Z)`slyT>T&0TA$!78v;d>OJ%jHb9{%pJl zy+mu{{yL+vs%-DW8?Ogj*A$JDZ+%18EDGgS)B6AXqsxRE0dNgh5thozKK1!#xz1Wa z-W&K!vmDaQB+PD_H96~sP{k&TF8VEnpJE1 z5@YWxvZFoK+P#x`INg)+m=(A5U^SbIvvT_Cz%Cbqkn_{0JN9&FmRF__9Yjm~YL;Y~ zwl>dsVI2BIc2uA$ukdtLsebA9myYsH$SM=eaMa=z8T+}3`Ekfm;0mSLYoJmCeoRzX zE(^YxhCXK4rsR6bpi%^$6Phg7&3RN4Vg)Gea*7{BgVJXrR(9IkY5bE0=PneEiou^a!5?=f(AjrQtMR>{-?uNU!Ws8!y6#Jz)24uJCm8P*j|d$W zZH2kO9`UA0N`avc$4OAU{dF(DxS&Rp;>-Ww?JeV?TKm6IN{O zMk!H{PDxR^yBk4?kq`xu&Y_1!rIA)<=osc)%YD1=|BL52=X1{aobzUndziIm&01If zzNKa6`-Y`CFlC% zVufpieq51Jv6j*Cvq#rmc6Y~%Jwdc-=YBpxt0mgT!DRCuGRoAdaW)^Z@VMvy)Q+)x zXPp`qF8fye7DBxZY)Q_!%qqwZ?hMtg$S;8I!Zb*_&mz|wT>Y~3kjD#?C?nV6JYT5N zbo_XFV|VJpDv|A@oRwrez4LheP1tG8NUXKZf5Ct!7EWX_qNibS5g0N#y(;Uemy8z{Dlh7f-$4E7}vQW9r?5_RaP@I;M%S zZnIT7%375wk@|8lKm`8$!f*|}CThTK(Z}G zY4kBW&QRra%Fi$O8%}G{rW78Jm$mq5770+SJ0UpMCp-{&L0%to3Rbc!6}W?hA0hz- zNUy~{z_sG3LZ*y$U+Vpr=)A6RmWO$!9mk@BBQjDR-d?&%z1cnno~5lWtZaj^N?QoJ5pC3Sgj{38%y@?;l(zWt&W z*0(MX!17-N7?eC4QXQMCx#7|k2j8!x+gJD33=pY^tTD!r<4|^B@=~M zHg=8Z=W^$bDYhPbSQ#v8ZQlFYAzQL=Y*Zjoo2!A#1XAnRVv~8(c4coIP2j1Ms}uT2 zt^RbAweGesjE9{;6!K#aoFRmFa_lbqSdfb|`pD$2*T?lqh>ATGHW^!ctjTWNG#j?m zQ%PiQ-LcT&yg-3FNUToo7vdIjcL7DtRyer{!(p=q%9 z#wFhZS%c zIg;Vq-FNS&_rRB`&V?N7PP90dT!UK@F8w~!b=B5MNgz_Y+48z4ul+qj_sIT(GjrVF zeGY_0>NpktyjqZh-9@>&zT*sYDbB8re#I_V8@&!SnVlmyAs!yRNj1$E4%+&p*{C;) zn|vQhi+Wd=6h$s9dwC2!OXhQ%C6){2b7!|+9J>Gu3AS^`c}^;aetx-Wyd__b-G}`~ zC8ZaN-#;_4<$ba!ofE$pM&07oA`Sz*d%;9%Lo3$E!KLlGqo~tECnvG9kl^4e>%#|^ESxt#uqvslhu&p zo+I+$e3|551P;F zVlU6kiB4`#UNv#bn9ANUddCrM-OpZ`Q~NOVWY?7Jm*LL92MN46>4leXyt^g8d+hhS zFP{x{D5cNxOjPCRs1hg!;$GkgqPj&%VcMT5(Ut7@zcLE^;~E$}7C_vI$Zn5#4T+NA zF|hhduL{c1jd`LEuC0?NMCd|$V~BJQj0oM=6`QIZZvWr>pLv~Xg?8GAHJo>;wRWUZ zPtjP!R`Xnw>qVH1Pnrm4P2ODsgYEfS58{P>S^NhrH{3c|#3|lhdeOX3OMI^IJK%CY z=Aidqnd!vUM24W=5ORi4F~b5f z$yPvz$bTzerlO+3dH6T;Xi^c8>qLw|v|!Spx!>7$(0LG5gPG`)FlbJ@zT1-tN|5Tv za%@{uKx2&ZUoB2~a$WenoHDjiilVzY$3OY*`!yYPXI?@THEyRIOrL`ktTL&~6YTDS zO*AOD&|L<*x&W6@CzDB8v&g8!|5jPvQv{}8Oatm_^Zpb1i5b@+Y1PqhA6N^A4qTt* zl5ZkQFi#p!5)U{&EiK)7$DAQlKa9$(a!wb&3f0dql^d24)n2i2kXm6?ijl7%eb>CP zV;lWYjRSyD*OxGqr(XYRhsvqgc{s`+;C9HX$u!c4@(DabKMFvGU!_J}r5^nW%K!*K zRqm9)mH_%;Ce!-o6EY8xJ;;U}V=2QKNy2}=5%LMOK#@mk;NXJbG*8moNKZW}qYtO! z5PE<7HXmr(CdV}zj{FXoHsbP`z{UMh_Ab;mQj#){m8=dV{;^w^`=55}Pr&{Bo%mll zm-8En8*_JCVTMZ^W9wt)Kjg_-OHmz;SA*zcw`4DW!A`*w|688gFY3fG-Noq+GNHqb zZ2W`&xklfpRLCa!X-CeCNyasrb z%N@Mgc}T=kV?SN}v$~J}`9GrDXL-We0D;aX5{#Lrhhnn^er7tFEsBu?{_~~j2f}|^ zUpxO;G7c%8$gb0XjpAh2D!@zR#^cxFefPpe^VBaOAVL-1YR!ek-!%cU~;+b;Jdh*?9u(k_0^zobbP zafLG6-W_1w7 z|B!#WvtkSB*Qp~c!xP`N&sL`pmtmV?C!l*7>u2zC>*qaIz}t`$>Prj3iNVE6Cj{_q zmt-!`=CXfJc$(<2^s)51UZ(vGf&FhlKKVX+vhqh#0G^)t=Gf4=`C<6Sby*(0a?Yht ztn{Pq{IaO!A;@sOpD)L7h5%2E_>b<@u)R6WBO&l=5edD}i=4Ak4h`C;%M_v-0JTC+mzra=iQ`-n2xz7=8v&cwi9)K6tz%O(;6CP1!vwPI?z;e-mSs= ze6$$Z_i%tYXvrch_@dPEQc-~kz?~Ltn}LcR(aJc33I1dB{|?nA6Yo|FHBcj8LSu=T zHYnv1LXEU()<`;(&CRy23DT0!-vD2$s~(&N!S@eOUgcKkfC1h{)OA8&``zrGGJvv!d9V?{>kgygjR05w|Ll)lpN};?qo4S9!JrAF zu=S3rX?UQh2VTNI+>j4~5TE0**{2KI&poL2&TMOlORb+sbbZ13^P=6%5JXp)7K8HG z?(J4IbF?Z@k1Fw(#Jh7}h+%1aW)yXweWT;(-uUnLo@f{Z2NiaTs^-cC;v(dvNDYJ- zt)mpct*Ma(-rolpOW6m1!TI^}`oeju-_L4*FU%r>Hug9$?Icn1&f?7rqC)r_OG41? z1bPallNbNqOY4zKh)a>U5iPHOT2OiSC^59EV3b$6o+KYVlu)He+>(tvJ$IIZzTsFS zA1DvvCV+hc$vykLS|DGl0T%;ee^~@qbx!d=eLAUf{eIYgKCUj$h4V1U?bZUPVFl4|*+t>ByE1 zR)qBe3f$V<|B!=TyhX@ncSUYlvJ{r%Y`38SV+M?|il#@`nbzI*^gNB?BdfbW{4zsO z7$~OC?af#{y9TvfVx5|PE`mj7;ZFN-=2d3PI;l|+E$c#QZ;|!%68jDK%sX;Qp^R|u zOu)=KpgeuOo?cqLITK*REx9`ZWl>Bpwevo{NB~Soh-}ESjXIU4fwbA{Cc7z39mG+< zcmO8Ev!##E;WO!Sge9qQC$8TDIzMjG-3qu3eLbB?%~&##pr(XVmwckVC;8%ldEZU_ zU0#lTed(7MIqpS6y64QSMnH9FJg4lAKrZZR2!I2JFZZ|KX>bM`H*TNGuv~v{tT#ZO_7UYU6koHszj5gQ=xzm^|*7qalK0ilng5ab`fs*yX1g`yfD zk)sVz-`hbcJ&!`~p8ock{E`7#u^x|=$b2-yO7HfIWI`f9aiD?hiw*ET!+w*b^qPB% z#=@O`L_Y7K(VC2V8mGv4FGS~UQk-y-8dbcS7G2NxK=yk#Yi<=>WzkVgJkkm$W>a8k zFUDdUC+l;6`wcd{%zZgnzq}9U5o*^3+WWrTM z$zHe|Y1o?UQZD-yJ0ui3w^pKYn_-LdcC=UDmfeS<>5e{m_%at0cQ$>Mf7kCZZHVU%Z$EJ z2;*0mw%%;JET9HexVl~GdU*lN>4*du4Qv z#gT{IC!<3FM3kd8%BPcy;i0*@iGR7`Z>cN3Ag#fp*L8PzaIBpgIDJ ziJa^={x1U35xMCyE>(j<>c{QlB~l-Y#{xhkEYcB}XV(Jw;b%jcbSR_GQwf0Ojsjpm z4Khlu9lm#2OO13Y07SBmvV_tn$bcluVkpXS9l*=?wg(5xCz>lx+P>8q5;Vq+^3GP& zbTO+2b_E#*JN8p*NFXRb`eRq&Z$h132|M#vbzHUUr(Kb^eJemqoTiI02w5CCcb_y(^}OU2l_y~a z?#Q(AlwC*LI!#&eB#~aN`<#BB){s>auj-*Cy#q;lXQkqv6Pz3aLNug{! z{bsg?dGThoo?ibwVK_Qp9P*r;=N&rVT>?>7uyf7E)^Fy)>0(j7M7wn z{Ne=QnAz72EO4!_q-9xbNVpNaMRic8SQ|CGhh;Y{d);oU@$KzK7gR1M!)vWN1m2<9 z01GBrKt@M)CEUz!fBX{1<6rfwgTiANfP6jFK4H8wPmomRy&euF+g|E^1>=Jf6h?uN zzoeXWwu&*k-!8t|EP>4!mCz+@V~d$m@6J?ciMi)$@CkX95+9!@2v-dyAz0x1&Jq(; zHq1@(X6|MrZ$b^z%dM*0*t6YLu_NcS-yjUQ-*^+qyI;x}9D&ea2?sE>+ktrH0ZQ-j zJIH0q-HyopI6stFOAjl>k-nL?^$9@cQ=F^-{w*7BnH@W_|N7P*a-;$v!(MS_zffKQK>#Esls3-kRV{kML8;Dw!vkJ0Dz8aQ&F*+ zTDRA`5;rdGw`{gE^mrcEGTIxGQ)=5r1}dqz>=xtkG?(Km5dz1^Ah=jKai2F$Su1)4tusXuleI-IcmwqIcRmk+L`?9@cAfDe zdA?bRPJQ_qbhAq!b4I)0Uk?Y}i%iD#U5dgLk_G6jlZRehaI{uif7zdR_VQOf$F7&# zP4Q9$Rk2BDzC~0eLaS*DW|(}#yEtoKz9s(#(UjKO#SOlick*#I`kk9zJ9nIjt0ks| znd+ytay^9C=RjKgGnW^uAdw)R(f??n(JufDpKN+lSxp>)?VxSt{%XdackuYCSuCzT zn9Ic+&dD~X1EvZ`5dnQ-_b^7q>|B1bn^U4sKw8RlYh;`GV(M7VHYR*{@?pXbAy&Cp~#SymQ6Q&B6ica0?HEH1n5BswZ?HJ$#- zW*}Q;1c97U#UAqW6vHeXXyv}^whB|n^Cn@HZ_u|0D@If8`>Ej-C$-=5y$Qf98tYxg zE8MeQ64D(M>qVjxnE-24d)^Y|+k5}LR}!mC&c63PYB^EktsO13URf3_5J>4dXlL$& z+~LF7j(UPc_wC8e$R21Tn~jc7b&X3OJ=X!n3&pa<w15oLlGMX#he&qw-pD&a(TI9D>r4|KD(X343rlMM?Jc8tKMn}0Fs@|T|98T{Z z;2?|7AnxWIv&e0_qM~t)ZP8jV1Fu&}+EVmQ-#Z}gnx&`9Z2j9*M}Bn8b%Mw>;05*)zRF_Vn@C-p^)o-4}0 zO@K>FgGf^ScbC4E?yFJ>T9~}orA)g{_EQ(+^?k?9*IV~gr@18^#!3cA2Usm&`QH7; z)>Y2}N9DwmT8B^Y8MxeYBuq90P3wL$DFGh>zij0)73@&JxhsE;?uSaPS`Nk}^3jON zX?Q|6X{g}wghKZDsD^CzCyZsbRr6p9;%c-@{UUTJp$g(8+%WluVNmE`mrW2`Nz#_s zf6cVdCNK+@p*g$ahb%c(ie*O%D+B#a_G7){sFy$d8~tNMLjxJ!{QU5uxLC|WT*lAS zy2zlE@``?LEElSQtxqkzy7_A!{M}$I`F}pA2&8BzxzN7JT zgbfF82X2BpV%TVGTk%43456gsVr_JmprWpG{J($o)pBR<4d-rFiyR6K_j)@tdEvMx zepxX+?ihC8H!%=Kg$%xmsP#hX`=?)*rM`-gkI@$sowiDJo3Sf#ZxSWnPj@=@9HQr6 zwp8QhL2{BctHBIAbq_g*EJNKV3`_KK$#nSuL(C4OnD&G+TEld#cO7d#0Xl6|zS$2Q zvmzv=u37r^=Ar~jUGNS6yH|4^Ob=Ll`KDDtzb^VlZo2{T_Z<~Vjxc~2q&9k~sA|;m zow#q8F9lO4(ql^k;R5K`Xedad7LDLpb-;k)kPtjDz4o}|QJc2T=g0_iWb2ly=mFv0 z@t6?Pt0yiiODbEwn&xKOR;M|l7mw~)CRcFhY$?7!$0Iu>My{d=54;{GGB<=@>(gQ<+=elkoZViLu_q0Y1my{7bZib`i{|6I z0jV%)5YSNvscF*FM5io*&sa*4GAo*lcSA@0?RV=4+*dy;t}Iw{w|^&3I;tp5C>whDv7Z9U^XXA|dZ)14!-m;0g*b4l@FjDGiGm|W&t0vabM zXyiL2iCJ+5xD{Y|&vr&};8GQFI`5B)s8VCR3P=(ra+|Ulox@RAWu1(HGHADBLiI@K zlFs$o#cFXe;1wV)8Q7h63znzyMg=C8wvp z=B&vl&!TaRq)aYHD|Ln%%^kfnFP#f}pUcUFXnv>HOrhJfr&zYvNvSk>g1Ir?_VD%- zMH8`bft({GWwgtGM-8?L54WWulGl&a?X)(@V&uXTkp;oehs2yzHO5YYSv41nYS-px zx|%zb?MBiUR?n*BTVmR#<~JUdu*~21ZrVyjgUc$|1TIam32r_#X%@>+%BhZT944fg zvsh59zFZd7qir&Ff-e;NnWovF;3j)SWCM2346D_A$Kg7d=LZ&ls5~cWBo;F3)RswN zih1MJ)BSn>lp-vRlXS)Q?0di%hfU}y?6A?U2AZaz?FB#q#GLIs9l~i)} z37f8SG`@~RQiv|e{%|H&Z-aS-!)wv3Y#J_$s%Buz!1Qh(7Q*yd{B|rfS_(NPD_w+P z5Fz>yB0%RUONgY7&P2T{(ZeI>d?d zYW5X5b4FAL2VZtiA{Y&fn*)R?`MZWNwjNCZZgbFN#qh=k^&vyWK^z854sW}Fwmte&ZCEZm~r>Sm4qUkObcvC|dkDt^9QMPC} zcT|td+W)n>6iiFm$C(FDjB<3ML82m=Tl=#1AHZ zdy+@xp2q&VF>?32tb$#k^?fGrs0w4>sb+-)>iM!Ulh|kMuqvrbh#0deNv|7##wYL@ zOVXq&n)5r?MatP{3u+JtG@l0Xf^TDa{448!B1mzAujbQt^mSiN2N{+V|t{X5*0}k?fFGsGLc8U77 z7|yn0XT@E-`xatEYH5Nj1CqZR?H1lpt4H$H8JPL@7}BVVr)1v&C+es3pQx0_fd$?0 z&3|(pA$kZ+zBvKs-jc+3ywV*AqFSPeKJbVies?W7{+TK8Fh@$fd-~x{Ok0#eG+TE} zn?b=hWOaRbeJjVqj3mc3KzZc=W^Aq=SB++vzT2}3J|eiCGS9nXX@ZJrdoV&@pTqDb z-qLn}j^J~BeR_S>G|=va4Ly85)(bMievU+8g7A*?UWXcYuGniInnAD zFBsJ9nXbO5q7cL@3<~VJR=Nl<&ORDCuyqLuNh}Tt4|H66jA!G_YC#Ys7khIUTd5qY zH#jZ~ofY&z3xWoy$^BY%-2D574;^@9(th41;?OaH;KVn4Bi5 z$}I3#=(wO?(1iZw=v%|zH*)TSV>HYe^#}j?nkYF>Xc#g*bNKQ14Gm~nR3Z?|WBbq7 z+|T<$bkrC1qcfoH<1g&C;5RcP(S9Pg3%Gs_hP6D&Pv2=t67zlCv7ELSzcdVz$O4X; z?#VO!xx#jNIrX4($0%e$J6B&dD+~-ZJykU}SMXfOk0y~Pj*j2gzJFiV{jm(>cET(< zrAGzeAJ+c5f8==+zhQD|VZ_uUJ+Ua^W^S_do>=G2Lsn)r#W#^pm%F{v&67jbz^lOe z^QwFyC3g{qza6i(Z$F<*gHF@dko?o1}TU@L)^txJ;TQ!sMP|-LOMa$ zp~~%~(!{QK6v1kYFl=TDx=Q`n1{xNryG{Yz(6ZQ`ZwT!;B0WL%Ox#&JH8B+@44+!6 zSZP7|Q`A4^ofAx-8!mFZ0p^|HU0T_t|Al#{Pr*(>%;HuQ`D$qS-^-XVT)02+&~)7E z#}Pu?Nasw#2*Jf?RKnrURZ?5JyzvygJk8EID$YU{B$O3GFYZ2zsV*v!DwQ!Q;ALVx z+#DRiUH||1z=T2G<|I!aH&DkDln`r3q9d^JuuL@nBuvAr@$+ILE$`3?hKM9&#KOC4 z=qRYg!q4hMh@=R^H;V!R%JCW|`P>4eQ9Zi72H>7^+egi{*#6L^smJc!$BwuQ{++rc zAPdjoqM~HdU}5*@>son7-nV0Gr>Zu%*EN&R)RUF4&WPctueM zHLL|12HCl;fi4ORw?kWA*xDC3+wm8_X|2Uy7LwF2G{GPz#Ok^DjeZ&j%x~0pz&?kk z9D|>#Wcy`{X+yNY+Ft;`)oXtnVR8zM6_GP}gxnY^KD=yEqF$nDKN_5P&osH=v?xZ_ z3`q9Y1rI>&S7ZmOP`<{OYDF4Zg7NvWHIjOXTuZq)uIt^F&-thy$`zhr;> zmPHwf&5}TMl-BxjJsSHy+|=9hIym6r(jtqs^QG3iYWFwiuDxr27ekiPHHU$x{%ZCb zl9c)PyI9nxX8t4E%ZR&0NyxD|bX5KWOm4N?=XU#nGsRutM_=7>5GuQ5P8!Jm@}um} z$WRh_d}h#v;ZLK@n;{d=&)ELYBBGLWvKajz0h!RqG#d7)Kj$JyPECN4Q%fKd&!LEO zkQa*mOsOOE zBv}J)f5QSoHjk<6z@2rlZtout^T_xhEAj`qDEaccN%BvTZ9lQmNy~_aR1XVT;H~pH zdaIuF+scf#x{IAm#hpFaiVZmjv7O1M8z7i8MbFSWS=|o;EB1hHM{FCMhL(7vS7Sfw zGc$A3Ok(m|RCp{0Mq<^}L73qNG(TUdjfZWl%4+PuHUb zfBhflK~h#EQqI+iLqlSyI}e}p=x$^geJ3G)kvaz&Rse5JHpOEUNqP+Y6(9BqH2a!G zS3mm#L`X<7J*etOigXzNDs0oClZ7#DXGr+F8wKs#k&Z;eG0 zL+-JM@Kol51>VTP;aj4^Sx7}mWcLWTTjBdB@hqv3y&YnX43_&0@T8aT&#SWCoj=B( zH5^%N!$-r(oLHi?!shN$h(YB-#OX`1n^v(m0gU!a9)ft>(JO1bs)w4{m;*~ z%gaYaJTJzNZB@5hQBA2ucLd*`b=to}1RRwF{YdXz%>hVEOyLexZ!vZ5q_P8#{^4c5 zTFqi8AviMyzyNz)qD@uWlVH6h{S|nns6+OTNT|T)t2YmYC#D1+0%elqHzd=HOws{% z+c7{@-_%{VVY}`dGMG#ztx&bD#Mj zLL`7{7WYC#8(BcrPtOjxHqZy=y5$#RpmJ(`Hc#c}Co>koS0oDDCk0Z1w#(p65|fYL z6{o0_RW>|(@!XCn^K~ebznC9T9VtUXSoFfs8)`E#bIF~@)Z9o!UG0nM=<~hk}&cN?9jgH+%)ap~hy#Co`B?15%&Ps16Ip z0$2m628=?AIf4VYS0|6~tOYyfDHhao)WOukRW{^{7yt%gp0wYhs6%aHHJ9O3o)fk4&ebm z+$W2H!Ei;m$TgCqKHeI&95wOfE`oDNf*34vLcHbxBBs63Q2KJlPXLm-0oP-j)kUCx zGcBp87IEJga|2M<&)($rxT)6qdHU{eK)tm^RO(-K4q<6E*_7&HET67O?*Wgq*i|3b z57%x~Yg5~{&Dvx-Ac5*G!wfiMx-DCaZ1l-Eu#x@(YRi|q9Ro#|*ujJGk|{j_pw56r z?g?t*g2U27{H)Kti5w*$Qua;-KuFdhiT(KezUm;0#t=Dz>>K)<^rWuC{^nkXyARRY7SRr1a(8adcK2-1nnfKhYLvqgzlJP z2C^siWk%-(lOp_XAzT?l&lPeT0gzX%9kjIDDc~>EOxv!WVXsik^DVyQ^D_G&nxR~CW5d>OR=k_34q1N(=7Ae zM?rkdyNlMg2zadWI{+PX*s8Gic#^Uw@Cj9GtPUN`-|W8C9;D?#2Ira|6!R8C}LS+>>LDpzzKKOZ2L)GV0wo5Hp(% z{fK2{qm%NM){t@0H1#yWeC@mHS0wRksY_J06;nR|lgw39mRa6#pZTEVCV!#+QInUKw&&+~t;~W<2l7G2o8<}#_DKiUhoE@>OR73gYI&+^Ug&~xS8)!~8UygMsk5{o^iOcE${tztS`wO>TH#r`q>v^B(mU(5i)s2^4!V>k!OhHCUkVp!}_kx+u zEM}`(uiL!=s&c;H)jJP}&x(Sjkz$~vbZL2=!*BdDBG&W@qi5C2!bxvk_E;gOz?Qi4 zJmKjJk5^fLrD$gm9 z4HPy=)AdUpD(Z*x3tr0cob~p86n?juOaRSQQXY^#6dL0-TOnNFpw~aM5q&1Co=!5G zMLqnQU2^2S1mNRt$1AC;*?8>rG+rjm**%klzFsdXeRIqyy-e^leAgG!oXmnv3H^)2 zyIYs8=)u*pv|uQ(z`HGbxOzr7)M+UfLU!e`E0`(zB>859;{B8KrRta%%e)2^6&X71 zcw&-}Jxg-)Q%*4~=w8;HwPj#^=O|Ot7Lm;?4t!d?9qeRn#a_Q#7Vky_i&CzK>B7a@ z_seAm@g~EcKZwhDy1dYD`f~f@I+((?NW5%Unq;AzXph;aB9gQOSvTk{_v~D2u^?_) zT$a6{S#P@k!nJ?`|M+p`u4)MYO6RYoN~nweTZ|DCB)1hLr{Yvmpwc%hLO|#{>vWry)DSENYbR+~_+&&NYU8b6M7K?N6X3t3D zpyhN~Mr9M?h0Z?l7HR@(ouA>?#g7WgE34RYj*`lHV?{0@y15=J!B;^go_e#V#@9<~ zVjkzIVY7YX@7TRODdH9i=8n6G-H+ueuk6p`taXG_*1Q;tJzzC=Mr2=Qe~d%~zrvLy z?dY_1kH(kJXwkpv>|-zu90i((R)7VZ67o>VtGM6wX;ot~#Dl5wC_-d_$r}!eR zbF7{)ek&`#TZTu;TC!>QrmD^ArK!BN0u>ZK&+nbFlSHN)RxMQNtA(Dr%HEOe2)r)W z!ygge<5Dncq*?Vo2J_;oFR{7xm=-$={hRkE${aJ~WZaojSD$>zvEAOf?UeFLjF5tj z+Ro+xqg5{?uxN@#FYrQn_qnzW-r7fS3%s>7 zIW9m@0=%zJsyEGp47vyHO;jl#eY7m^5cS(z7x?al@$|o!+1Dz4pSk4{7(e;LD~2a? zO_|9oTPF0ZpnQWYxoL}2<8Izrl7@H!i#iCtCD40Yu18g1mMn8jFm8-S+P--h2xm&< z<1wFQ)MV6I>29#ImEX4n_R5sjI-%Tth~kIzw>!iwsRmi2z@ksA`4tV5rOtYpbhW(q zGalzxXcZO4I>Y=_~tIeat+}xZ_PMLOz6ie|WWm z0A)#=K79x~SUxj#YQ1o5@_?7n5b{F1C9A)PTv40r88(Zq)M?R&;!NG01NYWd|EsHc9FX4S< zFL&JOk{nvt^8S(V8VhW=>^UM)240McNJo$>!JM^FHYq9e*Cc(ewQXeL2e0)tS*2Tv z^Y-XT7;h9`Sti;ko*POZWF2^a5F`0(&A0QBM;DSMQaIiIXM`)qibM;v6) zag?f|lsZB1XZ$EZg`@5VWBlCQ4JvoHG_8hZ7HaDr$}TaRt+rCB-p*>!2zqMTLtHyN znT~43CGEC^TX>pV0~_(2rzy>KR$xZ9vS`B5R8vqr-Z3Tv#deA3-}gx32o_ITM`NWH zwe-B>IZRQvL`?jaFNut<>PqQ-?xFZl7VPQET%wZ8_q;a&-Vjl8_kn0ibQBT+N3M<# z;cr3~HMnT4lyNqE8RG%&MBj0R6&|wpzT^0eOmmOhR>j4RPn7)FUClDD>6N!lSC;tq z^o6+P`_g5e*nKk*&dAf1vAyPXCFv9O-WB|0F4}Q@-;Y`cI(5hbWH4HSmy|J9e9@S$ zN=@$@0g5wKOx}6=RYdBAlk*;aN!F|j^A0z}vl5bJVy?|aGxvn-btYa}7~px2)Mu3F zScf|TNA=zG8(tdH`#SzV61#Z`tZwxMje*sxxTGq5f=+t1fcP}$eln1d-MHe1aDK`N zI?jOQtV*PA@I|?&!z0Xi8r2Vfw&S@;pkKG$|$Dm2AEM(vc<@aa1;jbmS- zgmHGbB{5-yrVNwrqO>nN4?_rnXkA4Bu>M(wi`^8sp~((ws%ZH}<7+GL-9v%69g9CT zJu)LZqxzVerkC}EwS?^@*%_bs9t+z{fDg_G`w+V)8ihgPF`o(bH>F#5IfnSbG z&`&QCmkbPk%S^i-8A}@L3Hh2^F?<~?t&Ur20JO))$9b&qg{w{>V&y$c*F0|O$f7^A ze!AxM`YnERv0pM7^ux7NUU_N0vI;GOqt!B@%5ja?r$IXW;ER{&mkuZ-p{&}-ts={c2IBJB9TZQO zyQMmHL$)G^Jg+zrh*b<)46$C_XnlF!h>smsAX|YG2p{*xY~_?;Fq$ce zDQ}7I+~A|z@6;AAD)XAwoMT#l5)9Wx&)oD9))Edv?<;2AYD(()bce{~| zw3s zKbqL|+#yQ3K}K-kN_bw(SnOw(yYwBm?ugiu1d=c;UXCp9(Uslv#%S$ZE{>|>H2CTV z+Rmf;;&z;$l`_d&uPDwj&H5a*5X!`P-UMqdS8_zG&NeUHnKw~tONr6;8WD`%SusZ^ zoVEKC{gDAhtddjGk>Xu*`DICpgrN83S7m2zh4S(2Ve(A`=M{9%;6&`tE@UU-h%6H& zRiM{7c9Pja5o4DE^^*kOJk$i#+z8ip*a-(2V~Cq+AP!lS!jH^5T6IyW+xq_Ha4%gq zz5O!8ZN~|6FZsF7P0xLs3i{_af=Ka59+j&ZIJlO+C=IIYVHQFT*UIpC=^@Ic(gBt| z9DNcj3Kv9=OK;@2yR>&Ya~?UH8d{6ksjo|V^@x*#O<5L=)8aSWwWlTbeG1%95V^Dr ze103se%_KnFmAPe;;o1ek8G*m^vZ@9Rt>f4kP0l~tmoQyR)=0q#e|7kFX)g?2#hQx zKiqPacIG`AMmhy=k?Cuo6-G*a&nF=a6Drr;2x6p8UT29dx10~PY7EhO_y5H=MzrRS z!5sCZ@xF9Tp^54DlYOGG$JdYdXD~bl5Baq?x+=_LHCyLnB8O7wy|wZ0WaD(v;VqWn#gh-tj{9^zK?%^NiuE%)Z0HpUog@2LO(Pgu{^tN)OxZV+w5&uL!YB+0c9$M0& z1pP-Ta8kpf7YlyLe*F>f)?B$eLk^4*l$@WY?$di+2=@ywv^%R01H5l#LJECl!G7HpIPARB$Y)PHv?y|c3yOJE^4W%yg}4b z_Fbgs7wp)0-&qx4YPL;1-b^?pFQtom@1<+O(w(PsaZ^LKQSS-m=pXpCG2jW4XCp0C z{tI?}ULj~`2L&_U4hts(Ydo;TLYL3|R=h;Lz-E%92l9`HFffcF<{m}~f{5)t0nHdg z2B^~B+fDm~xEUPjZ{1#Yv_qtM#X#33A>LOn<86u5riSM&m8{oVz4~;|&Z5jsW#27{ z0-x64e^C>oaJVDxz2obz*;!G_APl9~dq2Ng%&>U}2ESZM^H=e~{e$7>h=IH!`JJujYU;_WuDA6TYXJ%)3Lw zSsb-r(u~r4qW#8_%knHL_e6PGv?I1QY25=G?(W+7Z>4m7+FSP@pVo2U)0!;&=j_{G z0}!Z|_5a-YZyO2eXUFRnR2EN>0)LVjc~<&rtt#fQv7cUtJ`LATPsu`w_^$w;R?bt^ z^j~_wr&ZTamuYkas(i0m&YWDW4?iBbqaSdH#9_7gD;>iH(y`QPU8#R?WVx~v6)Fu0 z(5glQeu5&I>Gjcz5ah@_I5kd-(tgFq-)XJN6OcbNat)5?@1`~a|Qa@VZUf_?{5Rf}J-$8BkG=GbeM0xri zfIn*)aq02s@%h96p)iYGEiKOA^_1b$x|e@w2YLphP)Z}cg!_ihZ}!^7jW6-{E%wMQ z&MfkUAoLj2W!&lCjMU60guDW%YJQ$o`ePPm7;ePj(3MKtmUix*wtv1Nnq!OKOEh2d zM=JnhopLKGTr4R+zcaj)6xwRD+4aR4d@4!;k4`%;BDR5o+5m!ejhjEC_&Gp+);{tq zp8RtRI1dZxD0{=5PP%{KSMaet2yyn=j`%F|_tZW_;J!(_37Js+g^j<4fNL`Qa-AEWK-V3x`xcM}gzM~pdA!(6)7snDkA?WfQHq_^z|citw+tN@en#`jUly-TQRj2m zegCM`V_gu<;2&k&%!K>+Cbx+q2y^T^doN{mQ?~1+QZ7nyiEt24HuNWSQ|KousygI? z6L$dU>v`T;`@%(T{w)U}tk4zZf$iU3xg!8rXS}h%ydzC8sPFeMGq@>q1Yh{xrp@O9 z7VaJ}MG(bi+Oc~-{AEGT;RhfvoLKT>K${?K={(y1trm2F<$!XLIR5v!$jiN4P?x$p z00ax(u%OeH{Qrzio8|MzPym))>ji514RnPlE2_d) z;WrxX-Fo$nYLf&;Aw0L(H=Tba={ny^pBn`Ba+$wX6)#p&Jr*{FkYGgWI$#ZrJZe&d zK;IO!bwiT&|GPu=jgB?5i2uvADY)^4G_du>Q7c+!)^k#=$9X|&r1Fxv3f>4 z3_)V^ou6Bv#73(3=*5;WljJBsJt}SMI=b?`t+K5LQzCj2TN(WKkO@OeCCXrSwhA|z zq)P?MJdDSNrN3kMPdV-^iDK}js&WB932}9B{~d;Fx{8Vux3bm|e2=!ozf;32K?CSw#Z_iOuqcY@4D zhKzqT3;*$Gm4G~2O*r(sKQ#ezQF>F^BhTD1RCganL7Jfp+TmEnI+yW1y>nIG!U;)C z_+AsO9LYgj>Q#WymUz_31}zn2Sl&0~yA?&Kc410RF&t)>0p$+#Y7wzdGsM9T;`0gY zVZ_YEN^A-ZZrn*6Kho;_F_|~r#l}&s$fGaVeI$nZw|959t+)-@FIkhLv`WMmxWru!&aSs^WN%4Kzs)it76$p5WgiCJ^-X&De&lxfMI#Ul_rYQ-#}lJ zqAtBZ7DMk{=#9~tD4z!&iK`_L2$t>Bc~WLFz213p8CxAwFMmGD35`B)zW8;0o~C{6 zHVQK$HAw&%kZCdx1L%zBfUlV#b5Ipq3=xMhz>IQ;6pyln1B7_}5no^cqWb^};5!$p zNJ1gK68&)XgU z^M-DTK+`g3O%zNL0bh(RI#;ODs86^daG+~0?y6FDt^%W5VoO0J`i~ydNCMpdWPWmM#{XB&#a^!g3^aC+nLyO!RI@S*Y z){9dIV=hRN>=b+lv4dG+9S0!XQ~(29f_uCn9>xqX7C=Ilr?vgUeQwLT0fEW;#tW1A;yc=B8HYY`D%>hoL zNMAVsx()pSy0bPP$crnfW$yfuse2xvM}win0Np!?T7RU4+I1cHKlj{?`}VXj8ol4rDaPfVjzafI{2xokeu@${T)~X`_iQ1 zH_#92`n780zbAuY3)X?J?|`jG3%Rr#P%_T_0SaX0(f$x_Vm}65=a)r zU2O>?S%;l=B&TFO?d7O=9uu`#oVEAx-?CB0MVvcXZp)pw@iQ)pbr$kkD;^8;F&sre z*U6rK7gz(Ug%)5Tag<0)uS~FTqA<@hb{lqlv$94Y4?_Z$!hXlMYhvUi-wC$#FCZdW zCSdOD=FaH!Qrgnr0M9iEg>X(NM^8iF#92v3yR{<#@BxZ0QL?-3BwiUew_^{2`)xmm z6lJPV9VKTcy+?eni$MMSZRU%aDvg)UL{8+8U$GSKIjFd+0k>jH37~1Z>PYNV8NB&c zLWHYE#C6W^(7OBps60BXdKM%WKYe#mJ=rUf%`Us0bg-1S4K5@cKM(Xhhptx=g7QmJ z&ZRpb;`f2tGm!tWWI{Z(4csZ#AuG48Q2e)zSMFg1zV0Dwdu~R$ov^xVX&T>*l>*8y zlb16?@&@cC^cj#K^f;QxKCT(Skg8IfkR93 z4?xH$za*(xq)GE+%o)}B}&SgJ&Yww@!r$PdEe{3 z-oJi-zy7>k&peO&{?6mRzn|@gLu{`fYWYy}f2*4=%Gl*;`TNVjq;$%ixJQ6+l=pMlv8GUiP9~jvjqB`M`M| z7?Z_B*oMf2$X_=ksuDF|&=t?Kb~*J(rq_WB8RlL~o!Vz+%3sD*cNS+m)+9_@oDa48 zY~48QBYM5VQQb3|1%|Vf4tj#R`M0Fz#y;A|&ZXtFtwe$t<~vT`W;Iz3$@iIPp<)ll z?563xnS#}3KW~=1_WgPw+$`*M^3YF8>!Q`vSylmCwc2 z{JBpP0IbQ#sjl=fWqZpapS9@};(Sg~*8zWvc;7r?z?;llY@ntB+-*<&|oUCP0MQzA+}wHuXx04kdzcNq74WeUq?p4mdD*S#jX zkxc6oFb@{2qO0SayVc^$Ye#NryrcFqE2F<8cwUp8o&e21(&@htdst+t&my88>AeUT zdstv%(l(1bBx)`(e5YJ@1W_^AIUql_yWiPsA`X`qR^+fReUM*48eZO>QBOxn>Fu*l zLw@v1AgtaQ-V_}=TTPw$lM{0Mu)r+?TF~^vNM%FqoOuE`tL!DLVzX|LzRv(dObUTA zO)zaDi$&;%oXhW05y%|z?*sx_NrUz4r8S>*-=5Q+t+>=U3euPsaFP;-iCeo2X4M~a z%GA>xHUO9JLWD?&XUNwU(N=LTE1kp<(*Oa+acI^@v86=VG*ez;5q9Q^(#D6I+nOoh zK>JT8mcw?}0kA2KtT0CBZ@{DEk{vv*qJ8P8KaQNlQsNt+1A`X@u>5KE+0*t++Q%-l z=B0}YzEepLy3oxok_dLYmrokyo2vC-4(|#D3qXj>aNWquulFwL65H=xDkEn#UL=O| z*k$*s5?t1f|G8$}&tg0n@UR`*Li6C0{D$Fw6SIrZ`5^Ohw>O7lwvu{DkPg1#qC`Ej z-yL5V=3tN>4tetD%-;1Dt4}Ss^2%HYs*TcpGper{ za8GmEft$@pg_;hb<3M6zdQEsC5C3iG^M2Z=Nj0UT#jME4@ub6No{SMeifHw@sU)W! z@{}?azyOeDV@(A&)QysT*smq=lH?xlsYZ-lVX}sCNQfOAb73`uiIMh+x<9BMNeC~WfsjevA!vkR_7b6 z3^5(48QAF1t5E^yC6RPR{_^6V&)g9qi;?l1e)5{KG`PPbg~_K@P9-w)J>DzRRe(&W8}x=1AhHyQ^gtP5e5}UmyR`oF}#+EWJ-I zT|HlCyV03PN@GDO(ezo=)AajruBjbB*`1|4mbxlAF9kN~&+yU8N2>VWgj?<}F=mrm zR6oYdD`~h@mpeJC6w;6kTPV4LrxDzyTh<|{xsu{cGcp7-6K6^Bdm-2Yp*y`mTOpaF z#YOyCl|QW?9*gWw(p^E3?NY+{3fwT2jl+f<#9~ZZmw0rnMYvJQYAEIog26E%eXi6U zJ5E~1{s75tX^KWrvoIB-31NVlCs>NLc~>;#x0xlTBuv8&b$!9QtLSu-pHeq8j4MYQ zSAe_nz&p~!4+^JDQJol%^qQ}GN771KOo=Enuy1CUc*hWYfv&P={ZKSRyf1S}k>z5+ zl+c|#E5sotT%qXxgs8E(l>=MP4>jn&GvwOzW2uW;-Up&;(y#f;AB(0OU*M21@MHY7 z2aQPXSQmlw>XdY+EIYdAkIB-Eq`dMs4z~f3-7oU`Oi6&Ja4(yz%+OL&RL6n5TK{zW zEzb?XCP;Ox&anQTXq$44+VJCXiD|GYqyRqbBV}(jy&!NloK3J;I*JRke@Ko{JLdCZ z=#Z*T$h60XU69hoVJn`|5V0pT+X8}ViyYUB7qZdN$;CXWx~WDTh(bDuXj0b`nMKOH zTDnXr0-RwDZFcvPs*yK`H%G=_*Bd^e?p+W0*i|NkU-1_hm_=v?l3{2nE*UcI^xh6R zo^+OHO0K!>FL~v9bS{JJZxVF+utHxLu{7xHbi&m>3F zTNy52Hr|&ssWh@I8lqxwVOG%*7Km$&F2|$3#5?(8DQ4SWrA9jW-PIhGR)#ZHl8{fs z^EY}l0N_?2MFZpw-R^{?`}BwN;^C$;=zA+>$HJ7-0h!fAZf6g~IAlBiyI)CL+DTX|O z!rPuP&g$UOzbvGJFe4s*vj2yIT*9JcO3@iIgv3QM=u3FQbT~N{stN_#pDV!ngE;#R zKf_=@%Ml4zA6IJ~#!G*0Bp?|{LoF3B)11HvAxuk)i{dOJ#O-Q~d3A1@(~ES4W6YZ~ z+Gl?TzGfXVQcOluYuDS zM=w_U>mb|M^|=%dC)f-3V~RycLjb;QRo z@F+}PZon2*ifm3H>P7|9rC{vassdTX0)=zVZl_N861(KvG-fe9Tc?8~?XxSiyu5HS z(W+lh?=m=ICf;2icxs>ibOKbGH|j|MQ1pVR;mM6HumigfK`nLHj}0w; zF=@OxQ^L#_+DnL{Kq!Zxx4iAKbwPAF&4N6G=l%#Wc#C{dshvmN;poMjss~ik&%#jF zR}+eTE~u{RpPDls>bYAwJBCFUI8ofC!Zt9BJnpILh<(t1!MEL+liTETxZgpAOLoJwegHxAMUF%K&D3{2<2%XMhA&LH#s%M@*d?aiY*Y0Wo!bT~$Fg{i7H&y~(B8 z1WAeNFJw%<;{F*k_{r;hRBbWDO*{pigRn(#yZVezMJ^UAsHe3V^pUrxjE5pS%KRCV zn|YOQZW~8oDBnG;q!dqYRJP`tF~Szk2mJ8X zwm+VaeBjC>wX(2VRVttesbn11GQ9YwdHqrxt`#eSK?XJDt^+!B*5Y-1b_~KB;Tv|B zBy`*G!`b>}OTZm5!{_~5nF6>JcLPU!knd7Ezh+|kKRYg??OzsI-9OJrCw zyfng>>ZnfBh4U)NbEDDZ+O>8OWcGJvC#Ql5H0E)b{Y}o?k22Zl14jqCG<>t4R^8sJ zu6a>vAB>`w@ULU+N~)HvB%%!CzRzKM?^xm^Li>pk3#A+pDww*a@Qb~~rTt^WW{Yb# z60`QI5jCE}APVjsK3TZPcNw~icOg`^uc>m+1*4?dCU9cc)fln@5kC0=T0>{}U6%6Ny9gerKKb=aMhBni2UWXcL{L8b*GSVy3xtlePh zEy2Iv`c5AX#sMX>EYPJdQ=G8EAm#KiQPJsxnyM|_KQkre%Je5}G0C}12bATj8998~k@VYA^;j*2*wx%}ZyLnx;Y$K{bt*s^%U#agJVo)orm;x-)aov<)^Tm0jn z8ur|Q70->Sz8P%zxJ$3&JyeIDb@xsAEepZ*A{cLI0+q_=L6bTo+n)rV(5pTEiRc(z zbgJ-j-Ar)pA#Lp7)%Q|QAHK|)f3Q5ycl-Pum7+P`3iA&1>$?b?o}0Dy)nuU?_5dU9 zDmLKMnN2nL}15 zbn_l{P1{_}b2TBZ_ErZy{j$na|7>c;uwomB|EAa7K7-oMg+g~+69P`dWO2KUiQ)MR z2Spz#1Tjm4e@yZ`{?fvCWL09!;`#P+Y`-89hy?M~2+bWuvDPjd-)8X^tqNjcZ4pLI z@>QJl(jL*LF@_I!3yo?^vWF!0E2#kJXyB*c2I)!(AL|_+AC`2vCEiK(W?^r34;_zM zOfN?QS=GKj@e67|4D1+f^3xPMy0T@bXZ^1mQW|$b|5_t=5sWj^t^`TfD~vbI`cj*G<&CMm{`1m8=4Ogi-&kN<@qv+&=3 zpHCMBtWozsZ0ep}-XqOPp#`l;>EJ>1?3&Cme4;FoHUKZ|4DDXp#_skA7(e;3bPMP9 zFFsY-KJ>uj!@^+$B!>ehibO%nQ%Mh}4s~t3l}r>-^m1U5ZtOQ4b?Q4ay>=R?;)dS* z)~h{5jm%t%v#saK?XZaI=}APgD`oe*pQpaQp2WgR?$1jPe*f1h!S7daDh&ju(rT~J zpRD*@5x&0LA#}8lV3dg8>{|O~INb-x%>Zi^r?^}ypn%|1E2$xW8PVHuEFm^^^UMo5 zvH87&rgyYI&r3h;*xBDIm$t?q{#(m`7x$?{K0l{|k?H*o!{_K?hNFcsXIFPE${qE6 zHW=$Y2oHv`_-I~(r>r6)+X67;mLf8uzxtPltL`~2 zv3tu_Z8CJTH>W^j&3Weg_UO@J+4Ccg!2Squ6tHJ{wCP)CA3pDnEuMZ9nVBNVg3F)- zsEpUUN@Ks2u%C!a{fY-c1yVeaHMLX~UmB+8as8sbM;vN}bU6FUr`X8C?S=9Jafy+& zoEfxk1WQ4v7wF=muB~R%1oW=V?UdNHVfrXn%NWSXxeEkt@xBJYXh8k?SF0|=?WlXK)*?&2CvBQet123; zWdY1ayhFkjI91?~bG=Fx%N#@AZK$b|Nxzr-OO5CV@+3p|^xMfWPNy{I%nhRAhyUIW zZtM+&*%hW82|i8N`LNdFq46mAZtz#1fMk)lO^uY7mYjTg*R@XZO`E$IpF`0ReV^`&nJ7Gi+H#_N?y7y!tCxF!4>Z&QPEAv7t#w)c4%YsSReXB21I0T7q4D5xLPN=}mOHl^WC3^A zLTVg$21YqRQH_qM|CP3b>OW&q&A$x=(RK#@=3>=Et8duB+bpd(82(MG9z^X7BnyC- zNpjMwu~T4ze`(5r-UXa`anDP42E;^Jr6HQpLDJkI9Y}(UuJBxQ(fU20s=}IH6&0d# zzz$R4|0jmE-2dssWYY95{8KQh!trth12388LtuF#Ie-{&xy3i+;J@4s1&(8DvC+BO zw6Etu$?v!VoB-giKJpd!UU&FM#lx@!H8JEfS^l*i417sEg0;{`r 0 if there is data available or < 0 on error. When we've - reached EOF, `nread` will be set to ``UV_EOF``. When `nread` < 0, - the `buf` parameter might not point to a valid buffer; in that case - `buf.len` and `buf.base` are both set to 0. - - .. note:: - `nread` might be 0, which does *not* indicate an error or EOF. This - is equivalent to ``EAGAIN`` or ``EWOULDBLOCK`` under ``read(2)``. - - The callee is responsible for stopping closing the stream when an error happens - by calling :c:func:`uv_read_stop` or :c:func:`uv_close`. Trying to read - from the stream again is undefined. - - The callee is responsible for freeing the buffer, libuv does not reuse it. - The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on - error. - -.. c:type:: void (*uv_write_cb)(uv_write_t* req, int status) - - Callback called after data was written on a stream. `status` will be 0 in - case of success, < 0 otherwise. - -.. c:type:: void (*uv_connect_cb)(uv_connect_t* req, int status) - - Callback called after a connection started by :c:func:`uv_connect` is done. - `status` will be 0 in case of success, < 0 otherwise. - -.. c:type:: void (*uv_shutdown_cb)(uv_shutdown_t* req, int status) - - Callback called after s shutdown request has been completed. `status` will - be 0 in case of success, < 0 otherwise. - -.. c:type:: void (*uv_connection_cb)(uv_stream_t* server, int status) - - Callback called when a stream server has received an incoming connection. - The user can accept the connection by calling :c:func:`uv_accept`. - `status` will be 0 in case of success, < 0 otherwise. - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: size_t uv_stream_t.write_queue_size - - Contains the amount of queued bytes waiting to be sent. Readonly. - -.. c:member:: uv_stream_t* uv_connect_t.handle - - Pointer to the stream where this connection request is running. - -.. c:member:: uv_stream_t* uv_shutdown_t.handle - - Pointer to the stream where this shutdown request is running. - -.. c:member:: uv_stream_t* uv_write_t.handle - - Pointer to the stream where this write request is running. - -.. c:member:: uv_stream_t* uv_write_t.send_handle - - Pointer to the stream being sent using this write request.. - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) - - Shutdown the outgoing (write) side of a duplex stream. It waits for pending - write requests to complete. The `handle` should refer to a initialized stream. - `req` should be an uninitialized shutdown request struct. The `cb` is called - after shutdown is complete. - -.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) - - Start listening for incoming connections. `backlog` indicates the number of - connections the kernel might queue, same as :man:`listen(2)`. When a new - incoming connection is received the :c:type:`uv_connection_cb` callback is - called. - -.. c:function:: int uv_accept(uv_stream_t* server, uv_stream_t* client) - - This call is used in conjunction with :c:func:`uv_listen` to accept incoming - connections. Call this function after receiving a :c:type:`uv_connection_cb` - to accept the connection. Before calling this function the client handle must - be initialized. < 0 return value indicates an error. - - When the :c:type:`uv_connection_cb` callback is called it is guaranteed that - this function will complete successfully the first time. If you attempt to use - it more than once, it may fail. It is suggested to only call this function once - per :c:type:`uv_connection_cb` call. - - .. note:: - `server` and `client` must be handles running on the same loop. - -.. c:function:: int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) - - Read data from an incoming stream. The :c:type:`uv_read_cb` callback will - be made several times until there is no more data to read or - :c:func:`uv_read_stop` is called. - -.. c:function:: int uv_read_stop(uv_stream_t*) - - Stop reading data from the stream. The :c:type:`uv_read_cb` callback will - no longer be called. - - This function is idempotent and may be safely called on a stopped stream. - -.. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb) - - Write data to stream. Buffers are written in order. Example: - - :: - - uv_buf_t a[] = { - { .base = "1", .len = 1 }, - { .base = "2", .len = 1 } - }; - - uv_buf_t b[] = { - { .base = "3", .len = 1 }, - { .base = "4", .len = 1 } - }; - - uv_write_t req1; - uv_write_t req2; - - /* writes "1234" */ - uv_write(&req1, stream, a, 2); - uv_write(&req2, stream, b, 2); - -.. c:function:: int uv_write2(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_write_cb cb) - - Extended write function for sending handles over a pipe. The pipe must be - initialized with `ipc` == 1. - - .. note:: - `send_handle` must be a TCP socket or pipe, which is a server or a connection (listening - or connected state). Bound sockets or pipes will be assumed to be servers. - -.. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs) - - Same as :c:func:`uv_write`, but won't queue a write request if it can't be - completed immediately. - - Will return either: - - * > 0: number of bytes written (can be less than the supplied buffer size). - * < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent - immediately). - -.. c:function:: int uv_is_readable(const uv_stream_t* handle) - - Returns 1 if the stream is readable, 0 otherwise. - -.. c:function:: int uv_is_writable(const uv_stream_t* handle) - - Returns 1 if the stream is writable, 0 otherwise. - -.. c:function:: int uv_stream_set_blocking(uv_stream_t* handle, int blocking) - - Enable or disable blocking mode for a stream. - - When blocking mode is enabled all writes complete synchronously. The - interface remains unchanged otherwise, e.g. completion or failure of the - operation will still be reported through a callback which is made - asynchronously. - - .. warning:: - Relying too much on this API is not recommended. It is likely to change - significantly in the future. - - Currently only works on Windows for :c:type:`uv_pipe_t` handles. - On UNIX platforms, all :c:type:`uv_stream_t` handles are supported. - - Also libuv currently makes no ordering guarantee when the blocking mode - is changed after write requests have already been submitted. Therefore it is - recommended to set the blocking mode immediately after opening or creating - the stream. - - .. versionchanged:: 1.4.0 UNIX implementation added. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/tcp.rst b/outside/libuv-v1.7.5/docs/src/tcp.rst deleted file mode 100644 index dd18522d91..0000000000 --- a/outside/libuv-v1.7.5/docs/src/tcp.rst +++ /dev/null @@ -1,108 +0,0 @@ - -.. _tcp: - -:c:type:`uv_tcp_t` --- TCP handle -================================= - -TCP handles are used to represent both TCP streams and servers. - -:c:type:`uv_tcp_t` is a 'subclass' of :c:type:`uv_stream_t`. - - -Data types ----------- - -.. c:type:: uv_tcp_t - - TCP handle type. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_stream_t` members also apply. - - -API ---- - -.. c:function:: int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) - - Initialize the handle. No socket is created as of yet. - -.. c:function:: int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) - - Initialize the handle with the specified flags. At the moment the lower 8 bits - of the `flags` parameter are used as the socket domain. A socket will be created - for the given domain. If the specified domain is ``AF_UNSPEC`` no socket is created, - just like :c:func:`uv_tcp_init`. - - .. versionadded:: 1.7.0 - -.. c:function:: int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) - - Open an existing file descriptor or SOCKET as a TCP handle. - - .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. - - .. note:: - The passed file descriptor or SOCKET is not checked for its type, but - it's required that it represents a valid stream socket. - -.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable) - - Enable / disable Nagle's algorithm. - -.. c:function:: int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) - - Enable / disable TCP keep-alive. `delay` is the initial delay in seconds, - ignored when `enable` is zero. - -.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) - - Enable / disable simultaneous asynchronous accept requests that are - queued by the operating system when listening for new TCP connections. - - This setting is used to tune a TCP server for the desired performance. - Having simultaneous accepts can significantly improve the rate of accepting - connections (which is why it is enabled by default) but may lead to uneven - load distribution in multi-process setups. - -.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags) - - Bind the handle to an address and port. `addr` should point to an - initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``. - - When the port is already taken, you can expect to see an ``UV_EADDRINUSE`` - error from either :c:func:`uv_tcp_bind`, :c:func:`uv_listen` or - :c:func:`uv_tcp_connect`. That is, a successful call to this function does - not guarantee that the call to :c:func:`uv_listen` or :c:func:`uv_tcp_connect` - will succeed as well. - - `flags` can contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support - is disabled and only IPv6 is used. - -.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen) - - Get the current address to which the handle is bound. `addr` must point to - a valid and big enough chunk of memory, ``struct sockaddr_storage`` is - recommended for IPv4 and IPv6 support. - -.. c:function:: int uv_tcp_getpeername(const uv_tcp_t* handle, struct sockaddr* name, int* namelen) - - Get the address of the peer connected to the handle. `addr` must point to - a valid and big enough chunk of memory, ``struct sockaddr_storage`` is - recommended for IPv4 and IPv6 support. - -.. c:function:: int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, uv_connect_cb cb) - - Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle - and an uninitialized :c:type:`uv_connect_t`. `addr` should point to an - initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``. - - The callback is made when the connection has been established or when a - connection error happened. - -.. seealso:: The :c:type:`uv_stream_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/threading.rst b/outside/libuv-v1.7.5/docs/src/threading.rst deleted file mode 100644 index e876dde125..0000000000 --- a/outside/libuv-v1.7.5/docs/src/threading.rst +++ /dev/null @@ -1,160 +0,0 @@ - -.. _threading: - -Threading and synchronization utilities -======================================= - -libuv provides cross-platform implementations for multiple threading and -synchronization primitives. The API largely follows the pthreads API. - - -Data types ----------- - -.. c:type:: uv_thread_t - - Thread data type. - -.. c:type:: void (*uv_thread_cb)(void* arg) - - Callback that is invoked to initialize thread execution. `arg` is the same - value that was passed to :c:func:`uv_thread_create`. - -.. c:type:: uv_key_t - - Thread-local key data type. - -.. c:type:: uv_once_t - - Once-only initializer data type. - -.. c:type:: uv_mutex_t - - Mutex data type. - -.. c:type:: uv_rwlock_t - - Read-write lock data type. - -.. c:type:: uv_sem_t - - Semaphore data type. - -.. c:type:: uv_cond_t - - Condition data type. - -.. c:type:: uv_barrier_t - - Barrier data type. - - -API ---- - -Threads -^^^^^^^ - -.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg) - - .. versionchanged:: 1.4.1 returns a UV_E* error code on failure - -.. c:function:: uv_thread_t uv_thread_self(void) -.. c:function:: int uv_thread_join(uv_thread_t *tid) -.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) - -Thread-local storage -^^^^^^^^^^^^^^^^^^^^ - -.. note:: - The total thread-local storage size may be limited. That is, it may not be possible to - create many TLS keys. - -.. c:function:: int uv_key_create(uv_key_t* key) -.. c:function:: void uv_key_delete(uv_key_t* key) -.. c:function:: void* uv_key_get(uv_key_t* key) -.. c:function:: void uv_key_set(uv_key_t* key, void* value) - -Once-only initialization -^^^^^^^^^^^^^^^^^^^^^^^^ - -Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the -same guard will block all callers except one (it's unspecified which one). -The guard should be initialized statically with the UV_ONCE_INIT macro. - -.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void)) - -Mutex locks -^^^^^^^^^^^ - -Functions return 0 on success or an error code < 0 (unless the -return type is void, of course). - -.. c:function:: int uv_mutex_init(uv_mutex_t* handle) -.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle) -.. c:function:: void uv_mutex_lock(uv_mutex_t* handle) -.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle) -.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle) - -Read-write locks -^^^^^^^^^^^^^^^^ - -Functions return 0 on success or an error code < 0 (unless the -return type is void, of course). - -.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock) -.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock) -.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock) -.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) -.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) -.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock) -.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) -.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) - -Semaphores -^^^^^^^^^^ - -Functions return 0 on success or an error code < 0 (unless the -return type is void, of course). - -.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value) -.. c:function:: void uv_sem_destroy(uv_sem_t* sem) -.. c:function:: void uv_sem_post(uv_sem_t* sem) -.. c:function:: void uv_sem_wait(uv_sem_t* sem) -.. c:function:: int uv_sem_trywait(uv_sem_t* sem) - -Conditions -^^^^^^^^^^ - -Functions return 0 on success or an error code < 0 (unless the -return type is void, of course). - -.. note:: - Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` and - :c:func:`uv_cond_timedwait`. - -.. c:function:: int uv_cond_init(uv_cond_t* cond) -.. c:function:: void uv_cond_destroy(uv_cond_t* cond) -.. c:function:: void uv_cond_signal(uv_cond_t* cond) -.. c:function:: void uv_cond_broadcast(uv_cond_t* cond) -.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) -.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) - -Barriers -^^^^^^^^ - -Functions return 0 on success or an error code < 0 (unless the -return type is void, of course). - -.. note:: - :c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread - to facilitate cleanup, i.e. - - :: - - if (uv_barrier_wait(&barrier) > 0) - uv_barrier_destroy(&barrier); - -.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) -.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier) -.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier) diff --git a/outside/libuv-v1.7.5/docs/src/threadpool.rst b/outside/libuv-v1.7.5/docs/src/threadpool.rst deleted file mode 100644 index 18949507e7..0000000000 --- a/outside/libuv-v1.7.5/docs/src/threadpool.rst +++ /dev/null @@ -1,67 +0,0 @@ - -.. _threadpool: - -Thread pool work scheduling -=========================== - -libuv provides a threadpool which can be used to run user code and get notified -in the loop thread. This thread pool is internally used to run all filesystem -operations, as well as getaddrinfo and getnameinfo requests. - -Its default size is 4, but it can be changed at startup time by setting the -``UV_THREADPOOL_SIZE`` environment variable to any value (the absolute maximum -is 128). - -The threadpool is global and shared across all event loops. When a particular -function makes use of the threadpool (i.e. when using :c:func:`uv_queue_work`) -libuv preallocates and initializes the maximum number of threads allowed by -``UV_THREADPOOL_SIZE``. This causes a relatively minor memory overhead -(~1MB for 128 threads) but increases the performance of threading at runtime. - -.. note:: - Note that even though a global thread pool which is shared across all events - loops is used, the functions are not thread safe. - - -Data types ----------- - -.. c:type:: uv_work_t - - Work request type. - -.. c:type:: void (*uv_work_cb)(uv_work_t* req) - - Callback passed to :c:func:`uv_queue_work` which will be run on the thread - pool. - -.. c:type:: void (*uv_after_work_cb)(uv_work_t* req, int status) - - Callback passed to :c:func:`uv_queue_work` which will be called on the loop - thread after the work on the threadpool has been completed. If the work - was cancelled using :c:func:`uv_cancel` `status` will be ``UV_ECANCELED``. - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: uv_loop_t* uv_work_t.loop - - Loop that started this request and where completion will be reported. - Readonly. - -.. seealso:: The :c:type:`uv_req_t` members also apply. - - -API ---- - -.. c:function:: int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb) - - Initializes a work request which will run the given `work_cb` in a thread - from the threadpool. Once `work_cb` is completed, `after_work_cb` will be - called on the loop thread. - - This request can be cancelled with :c:func:`uv_cancel`. - -.. seealso:: The :c:type:`uv_req_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/timer.rst b/outside/libuv-v1.7.5/docs/src/timer.rst deleted file mode 100644 index 31d733efc3..0000000000 --- a/outside/libuv-v1.7.5/docs/src/timer.rst +++ /dev/null @@ -1,76 +0,0 @@ - -.. _timer: - -:c:type:`uv_timer_t` --- Timer handle -===================================== - -Timer handles are used to schedule callbacks to be called in the future. - - -Data types ----------- - -.. c:type:: uv_timer_t - - Timer handle type. - -.. c:type:: void (*uv_timer_cb)(uv_timer_t* handle) - - Type definition for callback passed to :c:func:`uv_timer_start`. - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) - - Initialize the handle. - -.. c:function:: int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat) - - Start the timer. `timeout` and `repeat` are in milliseconds. - - If `timeout` is zero, the callback fires on the next event loop iteration. - If `repeat` is non-zero, the callback fires first after `timeout` - milliseconds and then repeatedly after `repeat` milliseconds. - -.. c:function:: int uv_timer_stop(uv_timer_t* handle) - - Stop the timer, the callback will not be called anymore. - -.. c:function:: int uv_timer_again(uv_timer_t* handle) - - Stop the timer, and if it is repeating restart it using the repeat value - as the timeout. If the timer has never been started before it returns - UV_EINVAL. - -.. c:function:: void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) - - Set the repeat interval value in milliseconds. The timer will be scheduled - to run on the given interval, regardless of the callback execution - duration, and will follow normal timer semantics in the case of a - time-slice overrun. - - For example, if a 50ms repeating timer first runs for 17ms, it will be - scheduled to run again 33ms later. If other tasks consume more than the - 33ms following the first timer callback, then the callback will run as soon - as possible. - - .. note:: - If the repeat value is set from a timer callback it does not immediately take effect. - If the timer was non-repeating before, it will have been stopped. If it was repeating, - then the old repeat value will have been used to schedule the next timeout. - -.. c:function:: uint64_t uv_timer_get_repeat(const uv_timer_t* handle) - - Get the timer repeat value. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/tty.rst b/outside/libuv-v1.7.5/docs/src/tty.rst deleted file mode 100644 index 655dca9ca2..0000000000 --- a/outside/libuv-v1.7.5/docs/src/tty.rst +++ /dev/null @@ -1,93 +0,0 @@ - -.. _tty: - -:c:type:`uv_tty_t` --- TTY handle -================================= - -TTY handles represent a stream for the console. - -:c:type:`uv_tty_t` is a 'subclass' of :c:type:`uv_stream_t`. - - -Data types ----------- - -.. c:type:: uv_tty_t - - TTY handle type. - -.. c:type:: uv_tty_mode_t - - .. versionadded:: 1.2.0 - - TTY mode type: - - :: - - typedef enum { - /* Initial/normal terminal mode */ - UV_TTY_MODE_NORMAL, - /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */ - UV_TTY_MODE_RAW, - /* Binary-safe I/O mode for IPC (Unix-only) */ - UV_TTY_MODE_IO - } uv_tty_mode_t; - - - -Public members -^^^^^^^^^^^^^^ - -N/A - -.. seealso:: The :c:type:`uv_stream_t` members also apply. - - -API ---- - -.. c:function:: int uv_tty_init(uv_loop_t* loop, uv_tty_t* handle, uv_file fd, int readable) - - Initialize a new TTY stream with the given file descriptor. Usually the - file descriptor will be: - - * 0 = stdin - * 1 = stdout - * 2 = stderr - - `readable`, specifies if you plan on calling :c:func:`uv_read_start` with - this stream. stdin is readable, stdout is not. - - On Unix this function will try to open ``/dev/tty`` and use it if the passed - file descriptor refers to a TTY. This lets libuv put the tty in non-blocking - mode without affecting other processes that share the tty. - - .. note:: - If opening ``/dev/tty`` fails, libuv falls back to blocking writes for - non-readable TTY streams. - - .. versionchanged:: 1.5.0: trying to initialize a TTY stream with a file - descriptor that refers to a file returns `UV_EINVAL` - on UNIX. - -.. c:function:: int uv_tty_set_mode(uv_tty_t* handle, uv_tty_mode_t mode) - - .. versionchanged:: 1.2.0: the mode is specified as a - :c:type:`uv_tty_mode_t` value. - - Set the TTY using the specified terminal mode. - -.. c:function:: int uv_tty_reset_mode(void) - - To be called when the program exits. Resets TTY settings to default - values for the next process to take over. - - This function is async signal-safe on Unix platforms but can fail with error - code ``UV_EBUSY`` if you call it when execution is inside - :c:func:`uv_tty_set_mode`. - -.. c:function:: int uv_tty_get_winsize(uv_tty_t* handle, int* width, int* height) - - Gets the current Window size. On success it returns 0. - -.. seealso:: The :c:type:`uv_stream_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/udp.rst b/outside/libuv-v1.7.5/docs/src/udp.rst deleted file mode 100644 index dd46603394..0000000000 --- a/outside/libuv-v1.7.5/docs/src/udp.rst +++ /dev/null @@ -1,295 +0,0 @@ - -.. _udp: - -:c:type:`uv_udp_t` --- UDP handle -================================= - -UDP handles encapsulate UDP communication for both clients and servers. - - -Data types ----------- - -.. c:type:: uv_udp_t - - UDP handle type. - -.. c:type:: uv_udp_send_t - - UDP send request type. - -.. c:type:: uv_udp_flags - - Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`.. - - :: - - enum uv_udp_flags { - /* Disables dual stack mode. */ - UV_UDP_IPV6ONLY = 1, - /* - * Indicates message was truncated because read buffer was too small. The - * remainder was discarded by the OS. Used in uv_udp_recv_cb. - */ - UV_UDP_PARTIAL = 2, - /* - * Indicates if SO_REUSEADDR will be set when binding the handle in - * uv_udp_bind. - * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other - * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that - * multiple threads or processes can bind to the same address without error - * (provided they all set the flag) but only the last one to bind will receive - * any traffic, in effect "stealing" the port from the previous listener. - */ - UV_UDP_REUSEADDR = 4 - }; - -.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status) - - Type definition for callback passed to :c:func:`uv_udp_send`, which is - called after the data was sent. - -.. c:type:: void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) - - Type definition for callback passed to :c:func:`uv_udp_recv_start`, which - is called when the endpoint receives data. - - * `handle`: UDP handle - * `nread`: Number of bytes that have been received. - 0 if there is no more data to read. You may discard or repurpose - the read buffer. Note that 0 may also mean that an empty datagram - was received (in this case `addr` is not NULL). < 0 if a transmission - error was detected. - * `buf`: :c:type:`uv_buf_t` with the received data. - * `addr`: ``struct sockaddr*`` containing the address of the sender. - Can be NULL. Valid for the duration of the callback only. - * `flags`: One or more or'ed UV_UDP_* constants. Right now only - ``UV_UDP_PARTIAL`` is used. - - .. note:: - The receive callback will be called with `nread` == 0 and `addr` == NULL when there is - nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is - received. - -.. c:type:: uv_membership - - Membership type for a multicast address. - - :: - - typedef enum { - UV_LEAVE_GROUP = 0, - UV_JOIN_GROUP - } uv_membership; - - -Public members -^^^^^^^^^^^^^^ - -.. c:member:: size_t uv_udp_t.send_queue_size - - Number of bytes queued for sending. This field strictly shows how much - information is currently queued. - -.. c:member:: size_t uv_udp_t.send_queue_count - - Number of send requests currently in the queue awaiting to be processed. - -.. c:member:: uv_udp_t* uv_udp_send_t.handle - - UDP handle where this send request is taking place. - -.. seealso:: The :c:type:`uv_handle_t` members also apply. - - -API ---- - -.. c:function:: int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) - - Initialize a new UDP handle. The actual socket is created lazily. - Returns 0 on success. - -.. c:function:: int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) - - Initialize the handle with the specified flags. At the moment the lower 8 bits - of the `flags` parameter are used as the socket domain. A socket will be created - for the given domain. If the specified domain is ``AF_UNSPEC`` no socket is created, - just like :c:func:`uv_udp_init`. - - .. versionadded:: 1.7.0 - -.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) - - Opens an existing file descriptor or Windows SOCKET as a UDP handle. - - Unix only: - The only requirement of the `sock` argument is that it follows the datagram - contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc). - In other words, other datagram-type sockets like raw sockets or netlink - sockets can also be passed to this function. - - .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. - - .. note:: - The passed file descriptor or SOCKET is not checked for its type, but - it's required that it represents a valid datagram socket. - -.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags) - - Bind the UDP handle to an IP address and port. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param addr: `struct sockaddr_in` or `struct sockaddr_in6` - with the address and port to bind to. - - :param flags: Indicate how the socket will be bound, - ``UV_UDP_IPV6ONLY`` and ``UV_UDP_REUSEADDR`` are supported. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_getsockname(const uv_udp_t* handle, struct sockaddr* name, int* namelen) - - Get the local IP and port of the UDP handle. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init` and bound. - - :param name: Pointer to the structure to be filled with the address data. - In order to support IPv4 and IPv6 `struct sockaddr_storage` should be - used. - - :param namelen: On input it indicates the data of the `name` field. On - output it indicates how much of it was filled. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership) - - Set membership for a multicast address - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param multicast_addr: Multicast address to set membership for. - - :param interface_addr: Interface address. - - :param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) - - Set IP multicast loop flag. Makes multicast packets loop back to - local sockets. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param on: 1 for on, 0 for off. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) - - Set the multicast ttl. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param ttl: 1 through 255. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) - - Set the multicast interface to send or receive data on. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param interface_addr: interface address. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_set_broadcast(uv_udp_t* handle, int on) - - Set broadcast on or off. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param on: 1 for on, 0 for off. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_set_ttl(uv_udp_t* handle, int ttl) - - Set the time to live. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param ttl: 1 through 255. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, uv_udp_send_cb send_cb) - - Send data over the UDP socket. If the socket has not previously been bound - with :c:func:`uv_udp_bind` it will be bound to 0.0.0.0 - (the "all interfaces" IPv4 address) and a random port number. - - :param req: UDP request handle. Need not be initialized. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param bufs: List of buffers to send. - - :param nbufs: Number of buffers in `bufs`. - - :param addr: `struct sockaddr_in` or `struct sockaddr_in6` with the - address and port of the remote peer. - - :param send_cb: Callback to invoke when the data has been sent out. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr) - - Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't - be completed immediately. - - :returns: >= 0: number of bytes sent (it matches the given buffer size). - < 0: negative error code (``UV_EAGAIN`` is returned when the message - can't be sent immediately). - -.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb) - - Prepare for receiving data. If the socket has not previously been bound - with :c:func:`uv_udp_bind` it is bound to 0.0.0.0 (the "all interfaces" - IPv4 address) and a random port number. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :param alloc_cb: Callback to invoke when temporary storage is needed. - - :param recv_cb: Callback to invoke with received data. - - :returns: 0 on success, or an error code < 0 on failure. - -.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle) - - Stop listening for incoming datagrams. - - :param handle: UDP handle. Should have been initialized with - :c:func:`uv_udp_init`. - - :returns: 0 on success, or an error code < 0 on failure. - -.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/outside/libuv-v1.7.5/docs/src/version.rst b/outside/libuv-v1.7.5/docs/src/version.rst deleted file mode 100644 index e1715b2d3c..0000000000 --- a/outside/libuv-v1.7.5/docs/src/version.rst +++ /dev/null @@ -1,60 +0,0 @@ - -.. _version: - -Version-checking macros and functions -===================================== - -Starting with version 1.0.0 libuv follows the `semantic versioning`_ -scheme. This means that new APIs can be introduced throughout the lifetime of -a major release. In this section you'll find all macros and functions that -will allow you to write or compile code conditionally, in order to work with -multiple libuv versions. - -.. _semantic versioning: http://semver.org - - -Macros ------- - -.. c:macro:: UV_VERSION_MAJOR - - libuv version's major number. - -.. c:macro:: UV_VERSION_MINOR - - libuv version's minor number. - -.. c:macro:: UV_VERSION_PATCH - - libuv version's patch number. - -.. c:macro:: UV_VERSION_IS_RELEASE - - Set to 1 to indicate a release version of libuv, 0 for a development - snapshot. - -.. c:macro:: UV_VERSION_SUFFIX - - libuv version suffix. Certain development releases such as Release Candidates - might have a suffix such as "rc". - -.. c:macro:: UV_VERSION_HEX - - Returns the libuv version packed into a single integer. 8 bits are used for - each component, with the patch number stored in the 8 least significant - bits. E.g. for libuv 1.2.3 this would be 0x010203. - - .. versionadded:: 1.7.0 - - -Functions ---------- - -.. c:function:: unsigned int uv_version(void) - - Returns :c:macro:`UV_VERSION_HEX`. - -.. c:function:: const char* uv_version_string(void) - - Returns the libuv version number as a string. For non-release versions the - version suffix is included. diff --git a/outside/libuv-v1.7.5/gyp_uv.py b/outside/libuv-v1.7.5/gyp_uv.py deleted file mode 100755 index 0491ff873f..0000000000 --- a/outside/libuv-v1.7.5/gyp_uv.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -import os -import platform -import sys - -try: - import multiprocessing.synchronize - gyp_parallel_support = True -except ImportError: - gyp_parallel_support = False - - -CC = os.environ.get('CC', 'cc') -script_dir = os.path.dirname(__file__) -uv_root = os.path.normpath(script_dir) -output_dir = os.path.join(os.path.abspath(uv_root), 'out') - -sys.path.insert(0, os.path.join(uv_root, 'build', 'gyp', 'pylib')) -try: - import gyp -except ImportError: - print('You need to install gyp in build/gyp first. See the README.') - sys.exit(42) - - -def host_arch(): - machine = platform.machine() - if machine == 'i386': return 'ia32' - if machine == 'x86_64': return 'x64' - if machine.startswith('arm'): return 'arm' - if machine.startswith('mips'): return 'mips' - return machine # Return as-is and hope for the best. - - -def run_gyp(args): - rc = gyp.main(args) - if rc != 0: - print 'Error running GYP' - sys.exit(rc) - - -if __name__ == '__main__': - args = sys.argv[1:] - - # GYP bug. - # On msvs it will crash if it gets an absolute path. - # On Mac/make it will crash if it doesn't get an absolute path. - if sys.platform == 'win32': - args.append(os.path.join(uv_root, 'uv.gyp')) - common_fn = os.path.join(uv_root, 'common.gypi') - options_fn = os.path.join(uv_root, 'options.gypi') - # we force vs 2010 over 2008 which would otherwise be the default for gyp - if not os.environ.get('GYP_MSVS_VERSION'): - os.environ['GYP_MSVS_VERSION'] = '2010' - else: - args.append(os.path.join(os.path.abspath(uv_root), 'uv.gyp')) - common_fn = os.path.join(os.path.abspath(uv_root), 'common.gypi') - options_fn = os.path.join(os.path.abspath(uv_root), 'options.gypi') - - if os.path.exists(common_fn): - args.extend(['-I', common_fn]) - - if os.path.exists(options_fn): - args.extend(['-I', options_fn]) - - args.append('--depth=' + uv_root) - - # There's a bug with windows which doesn't allow this feature. - if sys.platform != 'win32': - if '-f' not in args: - args.extend('-f make'.split()) - if 'eclipse' not in args and 'ninja' not in args: - args.extend(['-Goutput_dir=' + output_dir]) - args.extend(['--generator-output', output_dir]) - - if not any(a.startswith('-Dhost_arch=') for a in args): - args.append('-Dhost_arch=%s' % host_arch()) - - if not any(a.startswith('-Dtarget_arch=') for a in args): - args.append('-Dtarget_arch=%s' % host_arch()) - - if not any(a.startswith('-Duv_library=') for a in args): - args.append('-Duv_library=static_library') - - if not any(a.startswith('-Dcomponent=') for a in args): - args.append('-Dcomponent=static_library') - - # Some platforms (OpenBSD for example) don't have multiprocessing.synchronize - # so gyp must be run with --no-parallel - if not gyp_parallel_support: - args.append('--no-parallel') - - gyp_args = list(args) - print gyp_args - run_gyp(gyp_args) diff --git a/outside/libuv-v1.7.5/img/banner.png b/outside/libuv-v1.7.5/img/banner.png deleted file mode 100644 index 7187daa2e574daa7aa84d81fbddcf6ec3e571d24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44102 zcmbUIby$?`_dS3DKCQ9s|`b^bhOF1?1DC+>UiwbxpEKe4)ZRf!4c2p|X|R##KjgCH#MB@B*-1Kw_@ zkX?W`d`~r#M-W6vf&LGJGTzWY5P^=9l9H~jqlb^jBS#NUW_2YcW>0SqdnZ>r2nv|W z(swY>U#F5eo;y&~dp(D@AtE625}L1M5$`G?}@^R zN)#EdAtSrHzAXIYmk%dk^MuIoY96vYy1WU4PC})nc~}v+tq?3=ln@U>XlEh>Z^WQT zHxyr+!{AXcgwLxxnt1T*kbK}v#Ue;v1qRPb=g^08u^_8HTbm_Fmk+Yy3|kq6;8`cH zgJ6(ZG7BXv_Z7rUVfR!Sa+HGJ4;nrD54tZ1UANcll7J@oAVGCwdo`%C0YVIr5mrNZ zM3CUUr_o#xRuE+M_2$h0DC#wIU1iT$`ZrHG*(x_!sn^xgO>7eXg`45=dEpux^E2KW zP^ad(E@q8kogvTP@%S~ZaJUF5a{n6y<-Vc>ce{TXFhEj1Fd+7_p2U)GqYVeeYGbo> zwLDnnDGxylKB2=`yaF|Ja48(P+tpk4Z7jzJgt@-Q&+V&8}UFv{AcZqsz1`})#7a<7-l8FBlhqN@rPE z&?~-o7Pgp2nw(_!eGrSs5VY6q(f<7w9wyu|a$(RPwIg?_n#&Hs?bQ>#An1WI8^1ws zja)Y#1S#i+b5|JcQryw&Hppp?K>_eWwQjU+Ojq-WN6+3mMJh2vu>e8r=%W|?{lvw3#^=1V;4*U={| z?P^%$&)JxJo?gGls`*M(O-S#V0kfeR!=8*chD40H%EwnyUm@X$izlB{g_6Uo@5y{8 zs#9uuCr%fo@|JMup^s2TJXLPykasPeOq^KW>QI>@=~TR|Qnw&tjRyC2m#ZNEmrlj1 zJG}TwwtZEs?}^I3&{Z0}$83&0v>mMS$085^4}mX+<*&$W&8VPuU+eze3AK03H`qk3 zP2r2TvysOt33E0jV5nCW z7>tmQsEoMl-CXA_$rMqeyP4E8_0XjnS0b60ndfWt&#a%FKX3n}|H-mvMv!GA?^ST3 zzj#Zp*I9#hnQU2P8OJVNSivwqLvQw7p20QIcvHm>dG&e~_hQ~ri1=nm^hZ*uYZiWZ zn=(r0NbPv+RI%ps@!D((2B)N>pPT4y^ASzc;{gtR}gA)8H;1msnw~YRB$i1%5v$` z7iL0R+L{1f78l~OC%)mLT^v>Ylfi!6&FPm6&Cg{@OY$U?Zfo2&uF>01wwJ?QO7}W> z<8v2(^;U7(e(1Bg>pNVFT=YdET1`TB<}RhFX{q zqR_3uY0jzY5I=yOwW>dQYFb*R1T{=3cy=p56KYo~`9kJomU| z_3TE7z@@>Z+gb6UD$#wM8X`8FX`%rd>Cd8G9?}c~-P6DCDOq&ND-~L&Sf?#Sy=oek z&L2~Gp+Xwx^u>IMZOQG6+n0O}91a!^P3;Zs?F>EbrXsE)DJ?0j?*4E6Z~K3|7R{6q z8WT+JNMoNur)4KU@ce^=jVr(XTjw8&(;{*!yOsf0=4eM3`=8kG-OAJ~61e`qeg zR@`(q>26u}4~Ndm-}OE9B@MKd%M&=$<@Ij$A=VBy)D8`w%R9G|T9QIOhP=3x!6lBF zBq?JsWe9y#>wR6)NOCS?;LWyN$mfI9bpeO_gJgpfx0mWE`nbBBvh*`YRUN1unjS^& zKYbpn8PUg|Cd;2m|7G@T%TEoTLobVkz>&kO%$m%Ot#{KE+hW^J+c7ga-$Zh_vQ2J3 z8tVM2guJ&rEJv7=BIq*zK2%3ZC)}ZK^`?NWz$@bqP z_=((0&!_k4hK15Z{fB3i9?dJCDW@vWWjYAyNL27?h;qx8@;ggUiGLLNDEEcm-sIcZ z{jB@yu9`O___@o)++ADeFShn$7PA%!mx8F%1-@E%KF%BHIEXH$D&Z&Rl}we_dV2Rx z@~#3I_dBXM_B{%J_Ll^YI~Y0~SOtc~hM!I-nR7GV-BaV%4ov*@>XYbWw$HZfX%TD9W=dvLW%x0>3Cl>f2t_8oO7K!FWzkNmci3=PvG?nHZx>yC_1XP-g8*X+ zZjVb%!h38JK7xA1qBR54TjSig)ed&X_HF&Ky%MQq**yJQ-)efN6U5)_kFS~8uKySUuk*oEKx1(^>~_Ki4vRVi4o3w>BeXE+-_q!Wn0E+<)JMcf!Z$N588Vp z+UsC0n}mi0%h4g5GviwpI`;)k=IgA_o@CL>QpP?jzdlW!Mj1A7YbIcsKE|WB?e$D@ zZAn>I)5Agg5&QL(IlgQ&lGM_)l{6A};>oF6;(4Rmt;3`LrUlaaZ%sEx)+;sTw@EjC zvMcTx=$Dc+C@?rMI5QC29+|DP9zSs(-lh-wbR_a?Y})M8@uh4}>$D-vPU>&N)>$Be|1Q+{zl?-y`Knfw?W7zCUZGxjo6GW9dg&1}p*>U@(O z{;@F^c%eGYMEXWV+T^juzCn-E)Oy5dlEdC$Tvkd}NGSj5jMenp`k+QtDat_Fm5!?sF1XD+wj?tzDgR^>27}0oKfCn?$Wd!*isi{ zf4okgEj}=N(DL{<73#-WwuH=V%YLB8@#o{id8*k^Z_dkszUE1P&g~DMbUs-g$Zsi3 zD$T}>$(dcvOzg~rIV1dY_lIXxk8z?S2d`co#*->x$G?v6dqVtVGy9ILgv6qp_vQLU zvC`nfL5^(dtG8Eu<3#No_}2Md{Plgw*#j zg{lXYsRx$^O+xEEiDX~n3(Aq8K%EEU}x+!GxVS22vDdF`Wal@%hxu0n&cO>2m&}h zl=|#h2vxQl`0T&)zt)0kOU5h} zB3aBo@wWYabv`8^fgr&6x1Q-xZY>++1BEtvE=c=GGC;_K_1l&Ad54_qDkoj9#4TZ- z?hhZHjIv>$`_3V+sOM0`5`i=q6qt&7h>n`1e@n#y-I`Q~Gu?gTIPB}=0|GN}z}nfF zAS9$kx5OYlJNrwWODDKF^6e2hVc}rz0jsv}^vE{uLaX_89~<}W?49Gz7*cgEEYxl~=9D;&SRL*r%#;~E$(a4Mp=lQLoq9U(_4(vNONT8Et zu=-X}aLZNdUHXIwiL0&=KP$HmHo=yA-9#pypQ^d_tD2 zp|gjOb4n9ETo8WFk|g{Te7 z%l|Sp3N=nnS65alYY(8~?S5!4qjjcYM|aOG`-Bc^ie?I(4H8%N*|0Y$y2f7 z3R*6;zkmOp3xc_&rKNQYLsClW_g-H&hP#ybD(x6G#+57Mq)vTlDfbQ8U_4xsfGZu( zGwA>OaPk99$Nf?+Y8;n~@bKvY6-OVrsodUdm;ZnsKYB;QzG zUUqbR*PW*n<8`u|r_7Co12ZpwHzEGDrRRSsg20mB=75NxR!Oh7*d2-Rh1!NTe29kT z1Ork`gpwI!NSRbZLS#soWUp5$Di9fc>VeBuhBNN;PkMy-kGN(Qu3gv*zafSxDF#aylJ-?nMer6BkymcLaC^ixo z+5z!90u}&7EDl0o+zJ;?x`jcNZgF~~IJm#MQ zuG!iyRn63qAUL7WN>ge9lMl~*XEMg$w-WM*Y ziS}d@dUJ>qaLodoyTLt#u+H>Fc6JTR%}Wc5SpW-bYinc-zvaTNFuvK}_Wy{Ll9sl# zoEE<@QDs|Ie#bv_v7 z=PxnP5M?);@lt`c#DU1%>)_$xu;AaHp<2@q9*^Y{vjH|NfkU(Oi9M;pK$7kr;8%L? z0O)g?G&xMZ1!_yi4_HX3E(DDDS zq@=yhW!y?Qq<;lYUZ_{H3qo}FY_p=Uvg81S35+`K8GsAwEqUWHPj-hY}{!5i9G?>$M$(J8EsSqwc?MOH*QY#r6B zHDtbSipQok6r?AY;_pQQy8X1Ro4P2LDyniLYStA70Wxi&r6Laq;uKk6C$ z7BPnubbnwr`%`<^75 zBRuE+hv$VeE`M@f3;JoZJCA8~1FrDvtf@%?y<-4%g!DX9#5j`hIg+@L{$a0D35Zrd zQ~N@2P@rPkt>8vw%dspVrttz}8>0vN$`|5i`6eBf zH-iG0mNNp zf-oPRoQ!?)B(N%T4GOjckwt*Kk%{#udfBOYpaRN^W5n$Z0lJI$7cZ6oc}XO?!X7Ut z2DoCNhKqX0w`Hua|ALTupwmilH|iBj@o4Oz>^bjLE!@A|`7gQTfT~4y#{mc~LCWK! zW}vz_aL(OhMZKK-=H}<>5N+n`*X@%vGBk8_1pX8Z(qmALr^o+x zhp!#g{8Vrw?DC8lY)ewT-K8G;oFN2R1qO0Eljjx{J>h(%h2Mvh4fd?5smW73D2)gE zPc0RKF&`t^zJm}Zx0bvJl6;pF|KpCfSXU{=+orI2szWh=T=?wNYLY7}D{l=kzqjiX z@A4m0{W&oO7M)UFvO>Dt>j+Mx z&BZix{)9hif)6!ep>_fz!z^}v6(eh(Qw!LCe%IE9G=#may3Y%sUTC(yurS&XGEuxg zC#;y?Cl)}5^~39bH_SYSm~ZvYHiXs@bz#c7i2DVf#i zy-Wb&FSt=TeIOHS4LSEGFKjU6o!i40;1y&=Kf@dy@j#T``|;uo_k8hrc)I(l=bd1E zoLW;it>ee*>|l@j0U^1YBOCepwbX*UH^}x+U0kq#0j$P;;<1l|@@*gI1J(1_BqI?C z$#Pe#U}is{oi78M7Z$87N9D8bQjgl!U@%KbWZgwW(knVFKg1}rZgp?@<#an#@dyfC2Y+B zB#a0LbKs4{3&43eFskK~xnPA>mj4UP5r&IS{XHh~r+5}uj|zXv-S|sBqeQUZWMn+) zdAN7!E=aSuu`MtocH#w&g+9>sHh(!4^P`SrI9?f+d9^9E+(P!h^=2MJuQwC3@Vw>y zIbO5oi|#)Angx(FG&H*+I6il7tZi)(H}+?G)OR1IkBy05s}QFlT3eUsW0R)>d#F*c zEIe=bNd6zH>Cs-$BWX`b@g+fl{5`C?`pCUCjJNf~1_Cqz9Eos^cy}dpOQ-@OBh9)S z^YW#C<5CT}4ytSr4#9LD$#cN|1YtU)=Da(9jsK)A^ipMD;5a^|-+rI(95*22w639{ z_}3{BPGp5ObI&y3^B@2y_?wJYwK2YX>HIJ4-Xl?o6TZ{}54uu#j2n{{(N+KKpiNuw zm8aawbTt8UP{0|+n{IGsVf;U=0qk^d1WMDUJuDd>#fsM;DesC8nSE;*TlX1S_nBER zNyY-D)28v*oGa;%Rs%fCRs3WJkNRTp+c!^6cA73yQc_Nzd8W`xNd8+3=7YdkO-%bt zkUxuypP#=-!}X{^8_mkb9a{k)&_R{{J9FvoJC?AaiHWBG zRaXgMCTPIB$qwTe`g@^T&`^CODqdDH9#pXH0=7n<61nne9c}INBGNSUmu)fZK6#Ks$W)nDx7amcY1_UZPJp*IPwH}To|5o#2w#|c3jn%x- zlMyE}99QwnTej77EM{~}02ydKQf*8Yn{+Tr}BrHr0lz`y2?%OtUGBT8-TOd1NrvCsD-F@bIl)Md@y?6+B)~{SmGb0t&anGXTiTs3NuB6GI)#tKF-a3 zr2Tcdu3&FJ6CJbFIxzom$KCl(q-E$_aE;8$G(ieh#C>|)Y{{|k_4W1i42q(RRzFJI z1D7G$wwD^0rU>8qXvK-NeJ_uCyqcuXl>)2#Sii}+Vakb6A=C=8)Gp=kB0i(!ffOTA zBv4v}Kn~zz@v>)69pa)QQAbA;6j1xkQyCeVYsJtBJq-LqIEW9=o4zy`KqYf3mXOH&bGZ=N#a?%K+2ZVTSz;RRdLF5Nz1@A zn$rH(5cn^mt4%1FTs1+S+-t)C_q((2w}v(lsmSAiA`(ckMnP%nL5^ZmwD?__F8X3d z#k`rRAGS`tVj;0m$QE}JGk~Hl^f^XfvJ$+1KqueY9#(R!87jZK<0JWd z(jlx5X^8_u#>Tl9)Rm!W`ib?n=4Pq9RaaN75DaL`+gZOUO~SDRFcR0;1`d#um0n760M`-2AcX5m9@ZWs`Sw zd)qhjX0bSz@h6=R=BKA|(V1#dJerqp8zf}mxd(J2NX7l>auUJXso`L6_O0{EkHgVN z<#vw86|27<`z-fT&U`%lFkzVX{>Oiq^G^THAdQYD1}`j#&Fk{=5}j%_lSDC{Kvu(Q zCgXsY5ru`4k#T5X5;Pu%&V%9cOU}5`n-9-#jJ?2t6AoI zuiKvv4Zb~w3NJy`C3D)Q%)?55XahVSU}srZP)DF1CU2CDl~#^t-5JKHGmV~`Yi*1O zShuMZ!{+EjS_xCv!gILC%?L3?B;?teIBQ%@5CbXS0l;-bW$G+}jfdppr^cc_=z20`X3+Nk|-`~H` zo5Evb>sHyFjFOcbhK`1f4zN6Do=ej!pGkB>qC%Phs zLM%7-xBdmEw|5D`tfBSu&``pJVNN9%GkU!M%bP{E5hI%0(`uH&{6^P(xEKyeNzN{} zW}B&HWLA+rl1fFmw?IDcn5Js$^0D!Z)QRLJ12SXn>T3S0RG>xw*`Iq$hZ1ymE0ofU z!hW6P%xV=?j2@YrZq32xU7Sk+CZg>fAOgrQ`n;NCK#EDqRoeL!Mrfh+AkY920{qy! z?DKa2;-fY=Huo{g^(>8Ex(q|Bc&!SP2~;Ko0TgpnMD0hiTd&v&HMk~p(9In(I|O3l z=|?Nmy#Mi;v32y{O5;Bj*~#(lL?Glf7{~3Kcg{^d7~yKc1Yc`4`nlaf9(91%%zEM2#Jc0sfU<9|GaoU8K#Z^se+aZp3@sD)I=YS3I=m>a`-y7hO^Rh z_!J96iHW-z-hHo7$eW3nPQjg4+?Zcf&0x&GqQw2ucF(r=eN>2qoXcP#T4)UAbpj)a zv~>f7cU9|Kn|XqHFZBAb8Jd{EkZuEqg%i{#g2XMio*y0^Jxl%RAyBpJN&rtV2lvR* z-j+9p#z>%XXUnDMpQ0{YuK}!d+zA8#SGx1~dM}@)F!LCAyWtcVH$b|*^g^GsCh#*{ z5MP-Au5)ttPq=eU|2|kB{VsFzk^#87!T7oTsOo=mjQ=z(pN^g$otOpEsr~j!#>Ndh z$JyD8=~^7%-@IK$we}~k4eJrjD>s1tE!Bje+RWRHz2Lv$7RXy7aeA~Itc8l?<|)G{ zEiLujHjke$YWeHHv>TGE94tL!|k0B;s`PZ8~GVUfUB)-0|SHc~lhy zs$BKFxP1+6OH0Vw_V(0~Z3wDG0(neG&5vb3bHgn(;>`GlI#Wmk-*ubZ3f_kgP_-tp zPBkOq#PS3;cfk#z*XpKrJP4Dx=A_T*VmvjAA!6d8!iNCCNlOR9)ZYAhrYHV+pe=}URgAGV*}VWIW&!yZ_(R%Vt;I}mEQ&y z<=Y_D!uCTiHC@XROQroD%Hi%Rfz_p>!>npjWYo1Ycn zjz?%c9th>3WVc1fQCk4=Y*q7zb!9{2<>33J_ay{0H*P2bM-i;_g#eXoSZI%&z~5Ap z->^^|N({Sw+usvN#K|_nXm3LF9t~BnOLvrUO)LAp2H%$_c)+>`S2A=fgan z^xIR&@SmCbYiRD;;$K}(rtJ#_)?II?*on#;<9{u2dSwV3wP*k0UOMXiO@Fy&@QP}6 z;84C$@6>X}zK*}%i~C=jAwkim5Cv=+z_F7LH#H1R8pysg4KH4JoYW}D8UaNKSo*F6V3yTAN6@bQ$d+ZM>~SN?7B*A< zDZN-&*+wjL7?_%jsp1Xns%XSY})`JH$MZMa4KUf78@lhDhdegJdT0DnvW!)$n92wxovH7 zR@OF2?SgrT-7N=g)T zbWRwJ04Spsgcb({P=Cy9u|lExFD83zL~_hyO~YTs?ziqop3}6IeA(J$7t--hhyXh2 zNhX2SyLS@~i#c>?q_@FfR!5VTh}4)w+x500*W3B~b#>?Bi&I8hSH2TWE8REL2yV6j zRQq<9>RjWjZjdv3&9iw=(9LM^N|EJP-)SY^byq3R>njK2B9gc1*fO7pz}nmH7I&_X zqQr{M>4

;+s0)O?4jMGXN_fjD^yY!L#d=Q=9Dh2|l}AL`Pw{cu#w0 zP`t01ks?AT=Kr1$H$$F-=byj>x~$lfEO2D0?02A}Y__+oFx@xbj#lhPEmGa%(73p_ zH;fxhqsbMWg;H-xoj7antxcLQD>M z9Kgy$cUQ!`TvYBMn`W%dZF1G*lg0E*b-t@++tN3M=TZ+5-qe~wIDW;U8;vj}J=C@N zDUzV#CnK=wJxOf!2KE$cz{nUSu$~t$6PQFe*oF|aEb@c=8htAI?vlS-QIIA%Ss8z( zWqZ4|XL&0Lj(9P>!y!)g-i!Dx!J72oFsi4b|7uUZmKDy4bp$SoXQZ4z8L$mE=XTML z+2OG7)Jbf`PQ*B-!ovYiY(ksT_G~xmpakWmPkF%e-q<+!e7hpr%7DwH%$D@xoE7EN z8I92aV&*N6V7kYo`MeB+U|amQ4rh32{%yeX8R-;rlX4!KlVYc8)Ncrwbt;$TBiZ9u z?EbjD6&{bUVN(*fELP-o#jXt}sD+)N7;ra4@w`2|UBavG_e< z>BBz}V~hFj}&?URH6l zVia6$65TV^@~%PZRC#T&<_@}s*}43`C&v8d<29LX^KPOaE{$Yv{ysnJuW03LlOB{G zDg;(6MoG$g?p>HE8?dVryvU{%R$Dy29mMfy5RTD=k$uwQ?eFh6T&{;jUiC!IFML8f zzG<_yRW$8Wi;ZurW_~g;{$53$%9+N^;Q#RekL0ss2A~crJ>Tq~*YBKE*R9Vd)IPS5 zz%Iq?HJ-Jvl$X>(I5QOKm3@v&vG$+_CjWTd762$taR9{*IjXlB_X$z=Y;*|V_!1ft zf&cLA!&6_?r7T*2OEhNfcFS*HA=lk4hO;((!(AiPUZ1hAqMiHr?i0hWW6h6_EjG9F zJ=1_s%r{&~ok92c37(49c(zKV4|*)ES-j&k8A^Xa$;;-|IP-C=IbZmarEnw#aYDq`ry#2OF>eKu+N}U?2k8{P_!v>J?=vMMMV#N9pka)aJ_Z4OBMtE_ ziLO8*k_?sLngXZb$sItZib^kQqeG2&Er=b?j{Z|IY$g>q$TMOf)Cd zp;=#pT?lP_+#loh7%t!^XZJ4r>FWgUhOW=@ZXU|qZ()bqt%>b9>`lN+JE0>^`bZ1L z7lVCD@gCoe>4V$FhGb<^a@Us3PZ>eC{f}u9)C-W#n#%~O&wX#|uX*VcTw#)TNO>{{ z1RH7}!Xl?e4q1o*npgO+ni###GBh;~-#Jfc%7p)&Am0CY> zv9ODINnHEeeH^^HF|EA7h`04P{^Q@rs|Bt#tC&1x*A?H6Ivf~DD0tv8w z<)7WcV+3XROLn#OzJ@@8YTw0WOkNqS$?9FElR%)I5~6Di?0#g#h^I%xhC@G19t2O? z926QBe?-r;f+#0-n@1QEdnl-p)$MEvL%M8t?d$nCH2rMlvZ z!ZtH_uw6l-qfqeZLkdDOjz|;s(1>_(8QOb(#(R&WY>9s#F_+>E6ZD4~O)__FudBBG z7Eh8k^=F`}zDHyktBZ3A4|q>G_X2bw@-AZT4L(nY zSX3MR!?NCj`456To9Nbw?1SxeqbZ%L&Yf|~N`&U3!LReFa%tht%%O~kItcodZ(fNp z#49Z2DLwoziITs5i;Zt0qYOdb66p`!I`lUHcIKHgdSsBr3wG8AvpH zUrs0GWlM67T4HO(7zF(QM3G674Ah~DkfMiBykAT)b2yn7k=M5U%hr01bm;ob34HO~ z8saCTxo4?UyRVUh;4|h)Zj?cC};Oq{FA>2|GSzS_pX%_eUAK!?| zPh4$hXIgS}gF4!U{uqw${uwKv<(>fkbkXM){Zl(qvdcal%AF2YyI8B*-krGH-Z#1? zdtDS|9mgANPYanyrfBk@dA@Fj#cUT%Y!_F>jxC>i=oxzx z1u50UvA)Rw>H-56(xW4-hUGzNe?E4f(c%6VUo}j*sL_f)u0xO!IL4ILn15sprf28R zh4W}xJ^(VTDGgI-=1cfVQafI|#3Cx%dk-QO) z^~gxbnFv3ji@8a;?Daq)Sud|$X1a@tO=vIaok@3nODK#yzJboOsWuT2 zt*<`+lW|=8m!4^8xH#?U-Z%fuY|k)><2^nq^xG{C&_7Vu`^pup+S2Nm2hGL5g3>YR zJt2AGDuK4VY8cS^&OADNSUKbeAf1YnJ<@XwlfB!*oYKYQHMcxkqsuyNLpyBN6T5cvbB-JV6TP^t|1Z6`^6g`_@Q&FwGZml#qq`f?vhOgmmO-) z`!n5Lx&XPVKHNW=caIIl1{2d+@N9S!Xy{(3MFI8UkLD^V_n;Ycn+NtunDT4&b-h{U zFI=q@3j*d%<54dubH-8g<33?!t%&`zr1Kr@SF^VoBEYI3*rg!M&)SYZr zsQp9gb;xs2JVEmr3B}97iyC1D<|lhdBUbb3yA``9OnwRL*acD>_cnbIPad%|b46eC zY{6Wip~|VFMW%}OhT_7umO+nALY-&7HU{bEm|Gi__D3u>$x40UDJQ5}4&!hx&&F$Z z&^8b>v7h>g(~&?a0#kM!WH#`w zwd_mBeUIFkGC1E_a@FD#{?llV?IvO=I`z4s91Q~uj!tE5`eHdTg35G}AuSyJu9%#o zIYN*)?S}A8OZksjaO0_}5wr3PV__Ip>jkDXp`e?+D&HJ;vW3JvN#m?75m;1DpjR(Qfm z!4YybwO+pTOG;G3_oeQqDrLWWw{&aoJwPt7iYWgIvDHPuj+%b2Vi*ay7s}FR+~wuE z&U>hLp^(<3`Al1N&lFRezH3!8tZcMB^n{5ksC3~DN7Of-AH{;$eGA4rf5kyH%{p?u zAyD@0kR(3yq3rFLEb~%BPoovh}*5;i8vkXNpCswDj zKFC=#ws?O1rANsyaiq_?bUq?$w^|l6cbGCxmy4+EwTh~q%y>l^YJ<5PN))XJu?f8y zArtaeMkG##BZk)tR$8Dj4@?PjFW36_yP08rVGOV+z%T)RqlwgiCqZsu1OHjvE%gOP-15@b8*A=NxK?6v0{oC= zUN`%t!4i;#24;JYF#Mz=I+T7=B(+o3}`_x8FvMK#7N>E1q%h>DVs@iGl^R|v* z_dNrPYcusWhTXEN5ZFZ=Ay`|@O#&#NqHS$XYt^@HBl%960p~net5wdBja{Z`i+_X0 zQ|?-U&mrOz2?A~LzaA6t$ibzVo>4t5KYlR`*p;#+7XLQBQQY|myC)<_bjdJxA`dGf zQ>70Eb*R#m4|a)HESNn1Yt&~;0q-2ZHX@21eLiMmk2 zckKIQ7bK$W_YH&TaD_MGyOTiNTObquzLJLK7arW!)9{hj`x@{h zJSQHR#eQII91o9P6Vz@Q?&F`jBCE^*oBaV878Y!om52!sIb!W)<)0c(jTUA9QP?>l zOwV0P@4F%e2}x0@r0(R?hEEVm-W&oRWs9ln)5x1ru{QA@L)%b3{F?mG^C;(nSU&5p z)K2}?+d7@R5NRvLyT>$s0o6HK?F%OMW_9@-t3E8&APgEBc?37Hu42qSs~0{F^3+nwBGEic-v`GyD>*oM@F8o0V^Sh7=L5^tL{+3 zpjiz%q&7s63RVq{xWi?g)vHng16w`y+=2RzMYCG@EsbPdPLj=2hv>`041Wa#rJM*M zNlaC}k`-BSf-<)_PO*v-7gj@aQ48um^*pqwMMVfEVs?`^UR`1paNv;(USz{f8D1yZ zFXq?di?Z_cuZ$5BZ*O!b+c?Tp-`py0Wrr4#B!<{F=tD4jIAOt^sg1M_kH+rAF~50Wu{DEHT~Y53Rgr%Q2P1;WtFPC)L@72Fw$A&AiG zWC49i3LAsn_+Vo_>)-hD#9G~px*M}&TH%MLUT&`K zvTbS=>pHs`6y56F2Z4A_3-w z*6rQewRmI_i6dj%M98r`CImk`UkJ}_bj5&t=loLb43iCjjysC5f|gP* zN;H`|Wt1GnHB!t=O%&TGO+xym#oIJZtha1%>B^47JM?Lj>)P#Ze?9Iq&9^wnY}S$g zY}}m)o}4g+tGhe0{|hDzdY;JmYOLj-n!ui&Uq^bYp@Zvu5_es-w(PvX7{Rscua3i4 zznF$HW_Tz|uxm^xLTHAl+wj+bKF>(S0MQUE=II)3Lg+REA&u9B4t6!GZ>_3ib87!M z(V|Z#Nya^(LMX-SK@;njNU<6OR8mt-B@A|I+*{GW@_7pJljId!Z9ZaYBGMf};dm3H zs*Q%HH}s172I{2OYr+OZu3#yIf84nD)!LVJd5mbNubgz zv7)9(M=YH=R?&HVCLm}~Hzz92$UoA5`Ru@SIDDVlGA~r}V>y^bzcGNlu-vamF7yVB z3e2vG0n-Es6k_k*avQh!TUSPE{_3L5o+LJ9 z_EChvr_;DO;_PG{uN!;KjZXkpqAE-$(6{=K-i~KOTEC-rw~@wf*!7+Z66`%wJ-Ye( z?SG%kT%Ga$3hAVLV(T8kCiNZqnv6qyZGGgsRZP3HB75%$McTP;b$bSE+_r;W)|8y< zE!8qHW@LuomkTjH`|@V~uFt&_8nn{wWyHG_L!7$jCM>Il+jk$)Y(FpX@{TVDsq3(L z5DcO1INS=}We^vPX^=B(UE>Sg?mK%O%x|1u`KF=e8BX3#4YJSAMi&zac)7p^{KXPC zcNA{jdl>4ZX& zZf8Na8Rccct-4bS@$O)BLtu5kvJe7AO`1iF;J3A3DHlIJoZ%|=;f!4Jh6U|*fj|1d zIzq%twY`{4XHE0-5-}Zs*t%~$;65FxrJ3mA;-NuL+yI;r9zDsJN}}ZUgxI;hwft;) z=ZATr%RInh#eSXe;O^x}@8Ta`&He#907AuYVQDqFJpX;_EE0;>qNJiyAP|SZI<8)~ z;QfDD(u8NEsF`rhlPl|Ec1NqfkEos}$*MsJp{iL)VXhh#!hYc{VhHv@$4hG0>R1%v z#*Ez(E`r27yD%@6X&k05+8Qcc!wC&`sbfjJxkz%GAccgrJGQSgX}Dj!{DU{@g7LnRQ@MCry;>IQw8HAr6$ z0)3>h*sR*=JeuJN!KcPG-_=nfAFN)HTw+V>mTQr+@?{dKA2DiCJ6~$k@iz{%&yL&T zZul0d=;!&cOn%^O_ke1&^=+yB4K|W-!+-;5e#^|cRyl3{oM}C<8O*k7o8CW8Z*iq2F4;FdhH&KG zYJT4bkaTW`SqPZ~mp&z7iN&@Bn)m@_rbk6aA2cb-(l5X#Ftif2$5ORMkiD!w(d??$ zMOi;HR!JZ3%|TO*P$uvVt>C#kVgbT9tSw^B2OB~ydlG5STUcmsC&8PG4b2jrb(Ef= zIu~)8DA?t7ZfASXl$p-7en$_W9k3DQyII4^yp1;&wdLlG`G-pz$4ZbbPyK~bLUnUb z|MRMhwBZ_7LJ;xOsN?)o*V6fwo_6@c@ORPUF00TZYOyZAn9K=KZbyRl|50c^5}`eG zVP09=X4}&=7kCygL1PImi>4zx_I`<(F=D`u zE?IT)hGweLZ@JfJmpuh>c+;k^1GGj6+3(e14}DZt@ls2lSL$R{XK{A(Bi1=P*1Dgx zdc9`joAg$C>g>aNuRz^=p6I@}?J{;vJGV_ET6pS#_-vK?#zYLhN=^Tr4ODvld!tU& z)uP);*t!&+{kH{!%OA5l-=DEpC(pdY@gI=;q?E5AtTo9&CP(*>V{d8)c>GRX&YEDw zjFuB7I#m)*Sdo5f!LJ}FVZp2>gP{QL=}N+A=D>t3L?vOJO;8VW6qGVqL5zDo-y*(caxTv~E7bU9#F%OYtzw!k zIS6;5qWPMgrbRc;^9!IfMn{&E4vmF|Mwn9r2>e$Gn!9-aLE_rK$)JfvON7a`Qli5o zu76}*rei(mCVD|$JYch#+;&a6c)o1yBE9hA@>b$C63^I9l%6}saJ)Tlp0fxL7OWhg zPeAyYY{x(6sWTQh3uQsL^h@(M;^kCxRdLp)L>+q4WcM*N{>TTof-&13t>}4NLwRHf zhd;Pqq*E7F9TKg_%G?YvBb&P6WCQ#J-Z*RUlsl0^l*wD-KKSgFGz?T4ZpqD!`GZZW z8@j4!TGF4r0te8Z87Oo<;+2t;HEdkq5G(#{HbUB3+?@fMgBSx-Sdu6qpZRXRPKeYS z`~A^sh|*8}+rW}S*+A~WAyI#wzzJ5N0mW9W_1^%n` zdm(yDkX}^GhJNRf#)X#Q1O{lQ-X`pU16r<#sq%JB&h5ZgbUyJKxMvwvQ|6 z{P%^yBus7z2~P}7M8=~kIAB-BI4-yYpmYvZ3`w4ALT9UAoTZwF@9kRN8N55RUX?R~ zz|Ao1XKI+kVMBpu`iTd!CRXFxR)@U#GE}Vimi0N*KH*KBzj#D)5C;OkB5)y~DcDm%qP zqvFoCrPGU(c8h=gKd!#TpXopTm!wrfB^Db~ic0J&g!hDE+VWVl=~&unOlfN?pR2v)VhAHb?gAT;&u1h_z1HPo(4b_v{eQF3>o@|`Q0brvG(%q1}B5Kz%EArGPA@%TjG^z(OQKBeV|}#&t=tN zMq9s-*N@QrWUj24YQA!)_SlVPA&SDv>yZm%nEdj_vmR@Gc$*0NAJ|Ne`n_Mp?36A-#_#tHc$`R(Y*n9*UdS_+Dnr2 z#0MA0if-d0imGQ=TXy&D22f|bT%9V(R#txwY4wMOscqzS!1e5H>Upv_tF04Hy6vJE z&e-WCayKAkL72nJjx#Y!Q}Ur+x$ZXu;E@X(K|)81sHmRaIYJKcN3gDcAhc(3bEMj< z(C*KToZ6|cOS`OnTP?M=z5QpUU6#&R71!)iO!)~-aVDNpng;FzUo9*XyWF}uoKac< zr*2FYuukTg0K@HmQo>P*4ydKGmJMAZdu2n6MC3CTsRX@5veMaPwndIOV&yNnU&Ek- zloG575(hG{lKbz2c6Tp5`1{YoLDjMcGKr}|8 zh;E4;kr0MyDcV1802CH9!@1@%OVk`p;r~**Um+B1>b*c6z@=j1%)}%+2+;^bNITMz zKlTh9G(%xfkp9j1^9Ow9UK+(Z!ntZg6?WjCU47Ss0~-O^^j`*rKSI+yyYpvQ_8_#* z-g15Y{3EO4JUt-zHfW_j!P6lF^!iuol~nHUHB~oJghEaKCHl}CUF|-~a7TS9e`ay_ z-Vf|Aw@JMx<72kFJGXgHq9u0c{Bl>DQ1_!k~c++?`5h8MoHg5`)TLNlWm~xG%fDCwjv^G>#Gm*nw2f~u?BrT z8N!~p_p?hRtDo%`2n%>CcKH&Cr?^`lS+G&R#mUZ(-DB`5S5_+ZyL7>_yi^g#FkeMS z*g|SL&jmcyPJYdcEupFF(e6obQ|)GqV{vW5GkJ)hORTdnZ?>|sKV6}=6GdG8Dcull z56D*98OfX%w_@YF5SNx%R#Oa&8vF|;?P3N&$!9jM@uw_;DdaK#UM(b%buyK_ucE>` zCCOfEwCuye(O6@IM!y+mNO;z9i44jZI_cFb&hsW4Yuk7PNdZvo)`fKyzCY`B_lJyu z$Yex7u5|+R4VtZdpP{KRE2}ya=5hW2X}2=4wxugb*1rz*|g*%3c>H` zT$(nPzZSgi%m+4Yr z=3b<|)G-KN*GA3$-K4)^j=C3WhuAXeS?*dcXInS8s@%n+kbZe(qtfRMEd+{+D7-6o?ZWUd|FeL7*IY2 z@F^DFH>;Kbi_5gE(+~75V?*f+>YHNp)_sW7yn61f{`LE7UDXqxAEM>eXYL^EZw1U^ z1dyHVy-?Am@1aJzme|JQ0l(7t!mXxRcLyv)!`iY}F-+dqSyU*L` zA_F?fhl+xOs171T+*8$!vuM3`g>;f4`uW0ZHN6?39f`7tm3AjEimznacNfl+iVY|h zkmf|twFR2NGvP~bfe<*1$zw+T6bYw-z`AO(9NHO29UzjSsltD$IRxNwMhEEWLpod^ z;p>QoF)({AT0R8qO_LIFI6Bq-7;MXaDv?N49c2sw$VsMHNwzZJ8S77i7{q`R(f4}e z@GL+rnz1LPmNF*G1pg0gCjgk?ny?B?;^mh6gjn@+U8)6`)Rkq&c1?Sp`A>CA( ziu_jPST^|N%<`FaU1qHiDH)}JIsm4jG*UigIk9;BPO*=D*6Z9KA)FBPAqv78H?y9@`rDz0x77gzoDv7Q-D)cH8}elcqT)MGylD|0`CP)a3IN`IA#FZkcq}> zjm@hK3rckV*XfAl!v!8}dzPG)c1e)1J+skXH6!7mR<`>(4*K%0Sf`WUuiA^F>gN*F zAx;H;6MAVHXSQ<2y+i%8?0mEM#ZT1Ii>t>*+>qVsGniG#y2wupdL2(|F>^issUCv; z5|VjD4~5)+&PLat-d$#sbJ`v_|ID(3N=e?7D0_e-~(*1o_s9v(BDl5l9YHC6>+A5;*85|X%9 z3ZJw|$4g=JRQ(;x)^e>NpNcGaLg4TMeh`yxD8lsLcS#X_T>%br_5FFE|CMqzkA(;e zX|=kJE`kK{`cI2U&Z>;N2C<3i5LUWGO(&yVe?tuVNSmNs(9e8`A+dmx*#jxT%Ugc$ zN_LN=si9~}+8dD#4KqnQzdc4DwGB{iU?Ki*+hPl#nz5VD>UAQ)e9q*x5q{RnmuQXl# z&XKX{4(Y>3==Ak}PiNoVvRt<-jX>B1sI>XHi^ob~K`o9^Dw7*mY6nhhZ0dJlAJp5Q% zIiW#_+XIZ7=(PnE@A;l7VH7WH>luUxy(6gd1i^W!M`6L#Yt zo%9DF({hNe-*xB81G?6*9kyX*Ha(LtXE$~<{Z7Yk0CnoJjMsRfM(6|{pT&b92-i@>Z^t$%l%`S}q3{`0-4-1fJtx)tb)O+#NF5PP$tA-SwnQLXkH2*^Yd z;zy12@3HGp=4f|AS6ZH9iA-tW(d>ux+0Cztqgs{S4YQTOD|`!hI6Ec3T$`GoN6#mr zP8&m!#NJi3ub|fe0eh5@VE2Jx-4gWT@leX)(cnvIjn_W}NA@A*Z)B~l$9+&Wh!rVV ze6_nEs_1rFF>68hmborR-@e{S50V-z1r2iwS-F55W9yrqP1A7D)9jUdZ8dhjckD{Q zZeBuDgcnn`u#eI%i)301tLue#eRo`H#-j2ed(8QDq1ctz829}^J-a`OA)|+r4Bj;S zS&vJu@K%H$u(IY4%jq*tW9`~M;2UNR8EhsAY>I$+TDm5Fors4#Cr-P9F15e4TgHGC z#N5}=tTXKs)MGW@tK%EAu@D7tFE@pwi3)m?v;CxD&c8|K{>lde7(~aN_E?TWxDpVp zb|b@|sS$y2MCa-YeQNJ6iEivqB3DMJh4~jZkR?~Mq3D_6j&3-*VT>cC3tRdwj>7;D z8EAH@BqjrVq$a{Z6zV?t&no(Xm}-eZs7zez_rU4hUE9cokLxncL&Xm}K6PN>gt-Eh zM1h}OIz1J6wyXVhyVV8f(`+sS3y@Lcnj9M#KC{r#=u259T%y5^p*_-L>BH3OI z6uRVX6FxLKJl5s)IhIX4%FO?uL&^LuRX%YB=q;gp@F#H$MJNkclP%X`Q;IT6tDh`4 zSZv9MuNSG5PNmJR`~KUq@blGQf%t7rTkJSt0Lj$`XeAWte%;sk>e%F`@7!-*BDJ;f zMFW>Bn^6ch?5commvot%7q5+wat(`F?YS6xm_r82{BS@7Aa&r)!-$=ebsLY`S`f8l z(`s_X`K&BAzKIYlE?S(9t8xsJo}9*3=Ri$EsS}GO-jzbu=^?8}87B|Zf4=WQpLbw9 z_)#|CQuRF4&%W5=`qGaWaBy92!dUKlwf5;bW3A!LzS-p-KjJGuFD3Mqcp$H_u=&-) zUc3EYA8mW%bNhPpo5G4&Ckk}+ekf=AlU=5GF7iXIznrH`1!7ONk!c8gz+*eLWd*Kw zTHyPOa#L-hOIu@Vph;+b+|A^l!EkNVZ&NxD4af*Q{-Q(-yIS7sweWz5y!>YU){_K# z$4BNL4BU=q>oVR-PQOq%HtaIp5KEE_i;&3@Tx^s~GKe6XD%Kl|#2kv>ca8TgVnBUc zo#nC0guc2L?Svpk!jVuzb*6qn4JXfeX7w`Cl`X_09v!_tgkTG6l}FC07;uP?bV_E) zBq#GE<8*@cMF#4|ZsO>#O}hUl5Ow5CI%lJ6w#Tl$sr_vYQyH>m66-Vn$^MNUS*ji% z-EqvOj;ar{zw-!?sZjOA7zCC@c?YGcYEi&Ty0faFIE;cXBXXty=1rEK^qv=k1XKG* zS|vHa%y}bhqDZ(Q79294a1kD)X3OR+#cw@Q1pcEm0DPqRv7%7CNl2tVaM~{_3R{&y z%NEM0NY-DeVQH_f(|me*7drr(Xm@FE&haDYu$wo^%5>%hS=TsyqO%(Ol+67edGR<( zhQx0B3(J=w-t<*A9U4ZhZI8jZbNrkuY4cZ9Y_P{v`ZLTk{d|vGr1u?xFGe<8c}vg` zv;%&4XSD|a8!4m}aSZR+9ki?4CpTW@px??J@X%&x04ZS=jyhk`~TeBw@&u^UNOK`m7A1rS`S?C_1qdqvtjZnwP#n)AI8`G^}R4? zloq;vcN{1YkHfw`HyJB-yk0j|RmcVIw`(Z&8oypc>qsc6!J;uHl2czD_}+#^X_+%HS_Y_#p0%K!M_`xXvZA*AdRq z>D<(dc6`kPWU z6oljENlG-yFgl>V{J&lSI5YB0+lb`h7H5B4DNzarC+u%;cX^Y3nzz(-NOuhn315f| z6bfM~d+wT8f&^pM@|J4Z{U(j*f<{7NrEhKfVb^;;nwaHsK|M1Q-9?FS+h&E9mw#07mXgs zF+9pB--LxN?XveyrY+a!MqB1;e!Y8E*qfFbA(+KFW4b=1qp~k?eV?8>i)5~erNQK) z`)A}y5+SUgDow<=d!D|R-kOGS-{+xf<^}+|*aR+ZYdCyO6T&rT(7$}ty`()akzLD- zna*%-%;O$0M;OmTKCTPu*5FHC>=Y`184Jgj&ac1Ua0#=4=mt84*&ujBN}aXCCl#F3 za$4MshE7lFno=x~2`XBwxpKqZZe65&z2{=k?!xqymC!$Exjvu3;OH#uge^SZF9Vx-EjbmNWW2?Q3`Ep{I}FY zdWWG0d)#blIK&scmRe?iyD=ZbXOF2p9C+~?{-Ay?c4GgGl;fI{TEf#}*l2IKfd5b% zBer+4xGq%V+Y?Jj810ly+0&Mg)x^f>@OZYlP2%MGW?Pdi+W7$ds3c&3t z#W+tS-1qlBGg;0^1WuoIa{US+7Kl*LD!1`Rm%H3l=)5keOPFaXg%B7o^R(CHvVMvp zIwQVfI1>|2Ajt?R)i4^jD_IFnq4vpFT8lxaPe*HW4=0;PsKMM>Dz(j^>CsjZQy`K} zVVxAAat^LGOU8DL#R^X2a|gs3{_T(k|ESK5?A zKXdqGCcLKelQqg0zJWns_GMkEV|GZ$-Pnz?66 z0o4-y)sgVn>GuO7!os>|dR94BI+T}|6I)X|nba4<1fPbvlC9tOSVS`!L0%R#68(`T zStedPg6I}Ra=s;c=ulRK)Dz1g*P*)vKC?DErsL3E$Vrz;icfP&UkWszi@Jg>C1mwl zZ^^18(XrejpB33HNCzYw6^`9TSs?tlOY-0D>z?V*dM3W1%ND12USis?Yb#g|9KE?N+1FiWZUxv-Y5onXh3}Qi-^x9b3za%$FAWz~~G% zYobCwN8QF6to7WfVN>1QWgb7qHom16axKXZe}oK7g#Y;qeShjieMIqsv#EJlWDYxK z%IAZ8Hu8r)#$6{j0lM=VCeVu0W0sb-4i*rCr5EOq^ncl1sR=;!BmHgIu& zS8?w#j$XW`A*u_og?H8J{(yCr5`u&b6xr=Z!SKtxk?z3zeI8xEB>PvEvoQ^A^z+l7 zoEXUvyg&ly)58jmMY5$MEW%;;%zaLKj3vB|N!%J~hai6a`iha6B+J&1vGcG;(Af}K zN7(cI&3nJaNGyXg3VB~hZh8^yI#5rS!)Pge_5G^~@Zl$@z$R4cG9Pb*^cJvRXl4$K zr>X$kpw5NVZj@En6JVB_N5l#()q!2{Nkt93!)yL%S>`k%$tXV-UcqtH-pm!e7&tsH zy_|NjZdN2TXar;DPYQPg?kmt+h}&ZdbG}*ztw#e8wm~zDWch~KIaNCjh1vxFO9p6f z19%dDq>%&=8FGx+UC;^gz^a|BE0l4L&;%UzF@KV5usI?l#hlh%dqx!=#%k^^eW*@U z-Lz}`tW$OTL6rHguE_o*T+JD{SYiV~1bICDCUSf>F03od3ccP1g*@_Tmg^eBlZw(S zY|?FOif)$KV4S)HQEMEy_As4J)5p?(#`aaL3;!jl=;w@%8nC2;k+ceKZrpB>FqJFV zjfz<)q+%-8zG0Npdb`&E1zam+$-2!C@Egn#T^JWe864in>oIepTphs0!u^BX&eZis zV-)yEC~<5)%rwbsV(lZV*ac11;eJW&h*QbZN!FeJcrQmYQ>0e!?xPj?9mb3EmA5M> zOZrmt;8rmN&=LC;2jFa5oMS|D4>JHboe@rL~=VmFqTeg!Ta`|4`r+ zo1L14vgCAs=(A+Eo!u%fq}9!tzTk{m9r<0OJ)b{~y!TqYK|Y~s3BSkyDi7(vXFl=n zN*whtVDgXQuy(X3fDr#h$n&GoC#9NTwNkEx%ssZzd@Lp+qh@U~8Y0Dm)3BkQrI z@EPRpF4t`ok=5DqbO*n1keO~^sEiKSO>`J{nX(dKa=Mp~*0Tkx z`hBv7650AQ3unESJ41)!E2ZV&Xx)*XK$EqT*rW~IE(KG%bj=hlz=Sa>5h}VvdIdGl zj?g0QUZ01n0NBo9lq7=8w{V69I%@l$Wp>}1#}tYUbXs+{(%#n5e1^RBT>R9b?mWqT zmuyxhvO@W~)NjjJg|rD4*=KOYjkLK@jTzsXwDEdrZ+>y=qI&Av{mjSz0aGB%)FAIr z%`@!cV~Z-B1>Px5`E8-OGhZ;4y~4R-J#sHQH0`mRDBL*UJvaldh`BBy-Y%fqyWtEE zyb)nYa563urmWBd+?%^^k=(u%Db)O5>rtMTYsq3%+Q*-EMa#=r=N{tNY{TQp2M`-= zcmg*gx8%@ccsi z#yBY~S?4Ltb-k8)Oa&g4;XQF^M?wM7y}r)@D;jd#6a+i6*J-iqr0`IpiF`mS4DVGw zh8Y7k1??>J?B8$y?YUPq`AOT495|Ga+=nHks@3Lp&u5fOy#r3JHVGs8yDr~N_IT?t zGRbwuh1vi3PG^OrccTwIqBQ=s(m6XaNC~|o-sQ~gU(E5(-j9e}_F6&gOa9=ae5C|5~}e)0xKUPWJKj_$gWD&FPnalHiGw zjg^#mX==xdu-y46P?=*aWk-%U`_%=IJ1K+l_+g2w!ss`AqQlzf8cvM%=ECdJH4wT^ z;9a%hR|Ibw@{9y`Kz+VjNF=NAnWRr`BWL=YgP8jKg%J+8p8Zyv1ic??*De!AqZ*@( z=^~k9BT@(llsA7K)HxOhM@2{+MPG`0{71ERgy{8ix+rW-DA_Y0I$EVWwmo-FAAMP% zbjl>>yq8jY$cUs}&=BNH`AwW|)K)F4QC6NJT^=pz+I4&Bq$w8O=q`Wp<7z}gB=VqM zYN(1AqocDWTDV16Ld^E<8Pcn1`|v<H0G~X?Z~I*Cj8>h$`-kn^ zg!+D}GIC(-_x&rs1LL{xqWWGP3-^vc8=Lgk&U0B-grLgQ^qR!G@J;S~-s}^)VEVTT z$YD2VO)=Q4@mKnM?l^P9adXXh#(1ZEVM@@56@tjcBW>82A)^+7YO zSJNV&mcP!F+O&6Neu?@x>eq73lh>;^`ils_iqlp!m6(dIE6~VUU5Lg2!h_kYlsMQop#B3dr?SxwFF>)oA$b zS-`BBKh>x&G8Q3GSJ`q_xvWdL4j&CkIi@YwXp?s*lNVGZyVKvP-^m(`wDO!&T~vmV z?%2TPQis=6@u0=>o6syn*Ot7LE6P$Kv+Z~c>6OO@{XLx7ts-M*$Gmo(UhdBvKZXsp;}8mw0+7Es@B2`QZQJVN zDByfhp0%4nRIeM$%h%`ef=gfM9bi?6Ljo>wviyO=m_wPu+VzXcz4^iCo00|_KP8-4 zWzL$zD`@?!R}h8iyOMT8$R$c_-?7O7@az?5-1-B)w|^wZ&Eq2o#_)GrNN(^^)Ow;1 zD(VzWYiJMt)%5vRK1rf64!hC`=xEBoGNL=8we>j3n9RX3wG44ta4?^hX|dZuZ$Cbs z<2G6mF3gy<+K0RH-0zJ7I{J%89f>pw|RT zs=;5e>RyVxuGzu0Gi`lXE{)VKFYKAWEe*nz3jsm;R1Rs9BK5wBNQ-Hk^tuP)3GN`Ix=~hX8 zne=X-J%6ylRKAj<=@vZ#fuG-G?8sw?BSO=GO6euUG#OPV+~8 z%6=5Y*9`NiqG-%29i@$%i57#SV*65eKHmYDuac};{ei`kOF#_YX#_?c@^h zJLj`5w2oOJyu9gz!*~U1c?+&XG_oqGiTx%GRQtXIJ-$3z55=?B_m`ocn!i2mhJYLR<>v8x0h$q7p>E5I< zhU=3Z z!F=h9$pGTP1MSiB)yet>W*GGEu@Izq)=}#3{V#4!eqE0`zH}LXlWBB5^Ar8QgXce! zQ|UPoE;_3UnbHcqGjd>P-tO7IG+)#DRo;Dy)1ApmW6HOEfAFSD+=)Pb;k3zvqy?cr z@ty1fy!Sa~6lLEsLJ2VuY?3~jD`vt5;qGn`qXbl z^s|IeVS$aL+RlFHrW8`RNjk$nbj+}bGa+7mYWmBoUr>lvd^MxXI)3v+_LIfwvNQ+u zZ-k@B=vod``ArOz0ej!O+jT8z@HvX2z0+f@7HT@iz8K7^eWci=UQkp@;C9|QR53uk z8r?un%kw*xH9Kk_qlt=_-rAY?-&z2as)vpyT1~}(F!UE@)(~#V1fWoHVjTsuQ>+3n zYa-J&%XAItslf}d51Rb8>Dteo*G!!fBkz0etG#2UGWHJJTlr{tRxEs}l@-&_V7bg3 z91&*5sc{FDulqZKG_;r|_aVuWLF{s${kV+=bAK>uG2doGPr9tE556^OGxwk22ygv-_M{ ztz;ZPAJ1;%AcG%!$_*ZuI3J)HQClWMi*KmAE*Um^Gedb(}FHX-i{M3qKCezfprpycwy;A)7!Am}Ep{T&!2zq+HZGO;|B?V;=?@ zv_rcZ`qxndr+^hZm|B3>T4UYz;iZ>#tj^Fq5L)Vk$ciujQ6}QioF?_Z3fq5WBIcE} z$iY`-u` zm!yB6pJ1rZ$7KF83Y;zIBgVX#^P(5n1{}vVY?4qmhHp1683t_6#h&fc+U-=07(Xy4 ztksPf*^K&&`{zlulYZ|nRdjZZG;-Y0Z&X_=FwF5QZznlojq93zJ4Va?N`b&SAbi~B zkLT45;s>3D9`Fwj1pZc?&}XW5B#OT8ZmIBkeFori@INDMy6x@5KfSussr%UdMZ%B3 z8TT(bfhpJ$d)WLNs07NXtoHR}XFCGsYO5!}Gdxg{IBT%2p()>{K7eHkoJ=-!e|yMk z-v3YFEXh$S<`q=SkvcWxIU6?_S~R(KR*x*NRq6X4e{ulm=iW?R=fGg$U^bPGi$+r; z(0nU9TU~Q7Loq-p?`gCor%iJ()pV454FbOu;m|-cVpG;X^?Wu~G6fh8tEf63#j?n% zo@$w{{wYR%q`*ItS%Qu}q?681dBFNb4498DVVFoZ%L39Ku=HoR3$IH$Eq9t@5gHUq zx(}QA2@|wYDWSz;4S%$X0K*0IhksciVo?5}H$WtGOMU+H&tCiOz1b;S`Nn-Zt%k}^ zsH7e1oT0-%ssFQ93DQkkX5_cQ6E~hqh^7!`O)1|J7ZJtQF{xwi_on}j0p!mDL{kQTK2XWJ{%ERH=4~l$r$Dl_l@a*Gt z>hmX}Ov)d>7#@=kO1FdAqtz0wnt;=b>Zk^jPSiP(x@DtkBDU3P@upBQR+#zqfNI#i zn&RENj}BXM{oh0`?j!ID17+T2{`37u`1(CCYCc^9ao@yalp&@uc;UhL^bZV9_Mhgm z)cQVm`fOsyj)AO@-TueM=$_Hu3qg+27FW*6g(t~}X_t7fV zH2NP{tXR97!^q7kzn0dqPWx-S%SA(hqJKKPOc8Rw>Ldd8a6H z#0BHIJN6*5|B2EizNq^z$T+Rl_jp63oj73&teRd$i!Aj@z?4y*lAn_GXa$i@`-%DmYWR?$gr04&g4T&xbSH}>nWNgh z&@55J^7?zQyp1C&F@xVP+b>Y(7`iY@lM;7jkyPM}b>XIHaUDRIkc8C`9M0}P4&1?? zJ&>IQWl1R@eX+WZ9g!F>iYX9b;4~xR-l42#NQc@FWV|E=3Qob>FwjjhV>Z;^^nL=c zJ!=R?&Vz(4^<$8b9wU{k=$MhS)uF??Dp5m!Y@7(+6a9{Wb-g(HlIw{7+u#U-CZ{K& zmGmksaPm}H*WD$d@Y2R_SyPXIzPDjRBg$5ff2T{E+?ICN8rweXRX!a4q?D(%92WV= zCWxHUYJMvJ++8r<6l<(8ENV^m_`7Qa4CsIa{$5odC7d&?@~8E(pO+)+I^#{{qZPizcY`!7D}ifs9SmDW4BPpbZyJvqKmdn%?JKkcD(m(O(*4x?9~(o#>9 zEsZ)mDa_2-6Br*oNZKYg`Ci=YO& zr)xT*nF5Y7@dO+MxGc1)2x!MhHg}tqMz)qeK7xS)!YDU;84(G)oNh}kd!D~5>#5YU zj4&hrnZ+w*?DxAgxh%^F$?Oj6Fc^m$X^J(d>KDn8O*O?dkx$Y2@jWw10w(~FuH%e^ zK_-VXqCFIwDzd6D;G$id@h2(VcFl2_$xl`rkB@^ z0lQy++HRxXikYf6Gvh3MKPd^mvmj~jK6}kE{70M2UWF4!Br#e^GFM8{E~uYzO;Qq4 zppheTNg(3Vi2|_2=9)=&iPWlg=3s$FeUmy<=UZ6 ztDSbqw2aFGX)H;3kEqWhasdo@HNi)kbAHkR<_AKzs+vXHGJ;q4+$^>2)rjDa@s z%y5LK?(Kh9i^M>)*rAFZ|ATwn2|9cj_@RuP@Z7Bz#xm))(n;^&xaVo_`1yAwodlES zf1mOU`T3aLB`KHf_X8*Z_{Fi@-s{&BELHkds8P1GB3yf_u0R+J8jI$%>txn5=2L4% zTtp;og4S&HW=@x40xJU&Fh~i*!1)Y`26lU(qbX{+&!guiT$@JzDe@T}wlvTJSMc!v z6MY_|fpTT*H(!>i<3<;V2LIZZv`QMf&Yzc>J`Mz-W+iQ(q$q{aO<_*0sX8qEMBxzH zD8L59bI)~|6iquhlB2|-9nON6F-T5~JR}0fpv0;31U%ETmt67buzvl@SZ(fWOWq95 zana-RBF!eb0G=vh8_>Vt(@e=vfVjG+10o=uCQEKOQ&f}~BoiP8(z@6Sp!r%hXv+(z z28h(-GyEg}PqxX3Y)cUay$F2fx0NLhLZp+XiqynRW8R$Zd}Vd}-rzm2_{pcGKMH;9 zuib0XE?~b)p1Nk85GxUwQh!U8_a`bUs?LAYxn|5A#{DAs&kVl!b%KM|%x|-v=vtE2 zmmcfgs+HE9b>R_O$YVuaf7XRx$MfnrS+>mGsKZ~h2R#bCL4PN!H?TJxcjxXbUW9FX zING?+DvfWNO^FGmDruzU4#jxpL1$O2Q!H}?;xv!8QsroF8RD@AK<+k;cT zwxLp36(W=NMQMrP@;-VewNF&6F0Ug-6abdzR7#*XrH&0+d#C!OM1{wS>8+FjMnnYC znGOTaVt%dJdp_YE6t2$fX%2DTm#eD^(h&9l?l7Z=tMtMhjAJb zvP3pbixyAULQ`V~NS>$%W>g5GA|*%Unzn3}JmnKfzef{G^_o8b&Cqa2zgzd#iVz2s z1aC8h#2pr2_x3Xiq?l4(T7^uq?5=ZBctMbcZ~%^=eEo75YDs@&7Bh5Ao~3b#G%qUo zI#Gx6L{cqe!|#|%Z8o+qA_Fdm@~?kzc5gQ^4?ekc7Dv(@iC^wifphcH#dZAh@>Mn$ zdO{)+;CdVKtm+tv83-JZJRaa)haKMh(Mfw%=Ov){rLrb^|8w~MKgovh>&UqvxfA~P zoHm>-j@>1un0DR?8#%Kt=2rJzyt9;N-gA8s+=;vXqp&ep^|g(J5m>w$@x4We*FJKm z-Um?`)FMuRj@8x}dI6DV$3c|0w`*Rs+$0E=xYrjihU#BXCd{~n$K$l|OZdL)tVs0( zZa-I^h_!7Hl}6?aw}0uLGIJsRGSNetHQ~f&b`p&eeU+v-#n2A_iF*xNE?w#M8xDLx z`vp$|>mfwlbf901O&nGvomD7pp!lAO$~;lRbD~8$AupfHIN7CLjOuCVpJaVVgmp_j zinc7T!O?)_wf)vFt46IJoXG5HJEV1RtvmTN)(ijjh5yu#LlwR0D79y(hY6CFs+OPw z>uSIt5&srl0TGn2ey4%N^L8o^Sa>~IWUqq?J_MSYX_t}rf7|tV>0?yGwQ%1@=8|$5 z4GSH(XIQu+U#o^>n|{7b$fHh~J=%$4&}ZsJT&Z3|x-bX5{&m?D{bps^y2_xL&TA04 zzYcJ~WHB7J_NJIs8vetwp*P7!gb|mbrbkW480ApJExR#{*B8N`VFLbd|1sF4Vn9XC zqD#_DBu=vde;()F|49U4lODVX%Ip((vubypN7pbe4_Uz%?8S!uX4nFzJ9TIEM`tLU zF{{CF&q%`Ub*?J zh?^{(^*<*h0al~h6LGx93SeO4I`F6Wd(V@5Mmtxv^PPdu2Ni5gRw}OFhUM#2++Nb( z0sr&+J?h?53l*>E$);+kZ`RT8vZ7j(w9q!BW7w5jP39#eEwa!gwlYsL6S_2hZTwN& zd4b|~c-MG3CwEy5UB!8lO31P!n)MzaX#YG5k)M)QbjJMHg6<_?oOR2;u3DfM)^N;k zzV@7dF4vK_SNysxGl z`h~5jZK6}w-wU;J4*RF?uZqOil*<%Jn`)h0i_qqDrdW7Va+Umjy=z7E2aVLzl{Sm> z61$w#XShZ{*`406;O=0fr2>IP7D@uHweT~NL`b@|L>0-&8IVFU0+?qBc~3QCtkIf7 zYY6UZ_oZvl^u~a~vm#8|>po^z9Q>$zg64Lw80puP5d;{>$6=~rA&K;nhHdb$#5vAbF!k?#u37iwi znO`{LlF@yxBzIP-M2J%Kbx6bgj5`W7LLfzWd`vi-WWB@r_@FWZ1_ywKBpnFXRp9XE zf#MhD3#j;s-zou@ERWy|Gv|pMLq#|6>W8lR@M3o_j;{BQE|sK3M5yt=x{*yc4D8uqHiCeWv+v@UB->d5TJUu9;E(%pY-T zS%jDc-X(7`eIpm&N2)7x8yK&6ivJqXT~PL|V#>XY?h^_M!n6!53UNkPqDq4Fl=V)e z5{+drItnR4EBceeOXd56~Y(hJtZlb29m5>{g#v{${8c0qEo z^CWmmP>ktaqrwTg)I?@Vi@O_p-Tq_GzAB$#$RG zg@2Re^KsPkXn5Hv=vXiFxJv2Hz@a+Ec?3&1Wan&*K&Bn9i}x(XotUsiGh_D#K1w~* zI>_%)JrU{4RYt^ku^OCk)fubwMSWb`<@sW6Z+*$z!BC zBOl=E*ZcVoPL$^KNCE$tMirSF5wP39b3&$Vt!*6RPNS;X!U3D z!`J)l8Q)6k9{ickhXy~air2-w*ix=$U-%MYY+l0tK4@}p;k)dV9r6Bl*+qu52kOVG zGRS+RjPE^R^~3%7B~vvxLsbPEx~Dw}4*-@yVHcl0 zX^ov8ko1qc8Tn&t>Rm!5Uq3g#q1?0EP82#{>i@3JwF(7sb#a}j_~2$ z6Zj?noOlIWV#;)1`P|KyNeX%DC?~N=lj0s!*1j9+tj*uRPCI-8>8r&yAF zkNnV2DDA3tOhCM~BhS9*d)LPLOLXKTN?FSzZBcClR-U|0`yM;wtL{HV>x-Kq!cSKS zTOsPbRQXHa=D+|^Q@{RDQNnBvO zxF0einIzG`>BqsJ4#>#6Q|M9-Z?y2U%e9xWF9gEBT57sMh7kB#oGI8FMOLno`8S;5 zYjgl!=E~&9Nv3o}zd}UFyhbnIb)iuh`}tqYJTDbMCY|M>x{ieQ@Jp1o)Qq-BjuJG8 zOa>45taNs$Tn6X{C-nK3L2QayccHST^LN4z&nwkB^%+@d)$ka2BZLB6C5wYm3I0TS zF9u#}U5BohLa_ZK@m8FH4k-sUMA?VLt~ImiRZbGMJfN;u38VlwHC;L*>BMz9!Z=hq zWS7zb4D)~4BxrZA3)or5Rk4=mZQ)D!j-sG|)v2a_>&{xu|2bIwl-1cU%lx;oV}9~| z6}bpPVLok8>a%ygVb<8%{Cu{11uN>r zeXYuS&t6c{TEB}`%$6VOvl2aVYiUi`fHQQzVmhc-s^fiS@E&*A;gZ%`xs%6F5!%W_ z(E4ilnn;JJOV(e#26H1*MWNQeRJ`~THA|Y+iPi+FBQ@H3`Zs~Hn(Ot?jg>;!$c%zb z`u6Hx0RZC_&iF)KlBycAXYUX*#SZSx6+>jheOZHZj;6z)aMlmOoyf2w>1N08@!7|V zdnS5+G?so0T&bSWEvaKwu{JT`0VvMcLw)27LP#}`d))6c+0GuUJ2YkRHd#P^;rtFt)ep5+0=RiVu7r->wYbHS0qcwAUr z01Hrx`GAsLj|uZT+&>#SkN(kje;y0LXP)ez>F?c(?UTnLxL!`=jj_M(i$12^e-<2oej+_QIu605?V)oYPBn_90LGHWA z&97tiTPw1G4uQ)xJD&?lFII!;HFITVpLh))r2^ews-Vl`IzD;|KyKhm&#>mRk~VuJ z6~yLEYUCa>n7X{T6iXsZCgA=qvwQ-9K)}A;5`Pr{v2ggKC2yaT5=|R@l5eiOshzVz zky5#4=^sa$#TcgA&e51eOdO|*j&2z!*McbBwW!v_fzdEh62iNXD~ z4{0v&`n1YDMErX04)=R zSyLweP&zlfHq(gD4qpRVgdb~mhQ-L(#=8>lA3m!$x~RYLRHRt!S|qU8!x|LCl-;+Qx8FZ7CTlOx233g!yXV9g{I()@G&3iLj_+_(3n^+ zcyGlDs<1~5vko{?B?kI|Fa$PA8iWb#H>c~pGlE+`unI7C+PmAKhs$qNn?YgQ& z9Aa&W<(1__2^ymIg8H_LwK4Lc7pC5NO?P7eSb=7zjrLRs_l5NIuE&susaH_~;328n z-g}-y_NslvZ!xh>Olz2*C7KD%mB-%#itGu0gBv<4=Y2rQu9&<_;xlYU#a2z=;J`EQZ9l zFP@w=gE1RDyH_i`hjL!rMEW}~%Pms7$E4F#*{rko)pms0Ot*z>v6<)rlCvxS zkoua9s%vBNH-k;W)~a}T5QW<*p-Wg0fpuWF#2p9XR4{JSyQEN>M_WN&2N^fzGC{vN z4O3u;Az&rD>%+-gJHHZmIL#$t{K9~l^_p;6&8V0ap9GTsUtFDuJCq9??<=7a&Pkcd zGL_im^v-WHic4I#%?eR3CS`=kt|awDqG0TjD2V@mN3@A3}c_oFq@e> z_qor#&%O6gc%SEe-uL_a{l4GNcl{u@|8SxY%f@Ux1*m7e@NuiQchD->BFdJbrUM)v zqba%lq^tLuFPq}o0F@7VhL%03UM?%jwJxc$tT=XXK*v-u9K4VP$wD_7y7(;7l;A8U z#Sf8($DIUxO1C1P+*9oX3y4tc0X!Ru!<6k;_laEkyZ`^+XI#kH&bvhIx_w-hi~VGq zuv&tF(+lBp%pGUpdkQaetwg{7_LmrLl|0=3?fTUlUshYb`>*+JGV9nwWq$WQOwJ|j zxR`USoVBOJu={H1j-j}h*|Q8M{`$0ovlKhMc=v+|n1&GHg$KNZm}n zPP2sxdf97O*vM9!sANDuWNy(B9eKTnAfg;VN`^JJj7Eggk+}4*i zL$bwmf;kUr<+sewz%cqz&C{G^KP`fEO<&z~31-O}pc$dWsQm_j$9H0b=9)TS;7A8n z&4oMVx%4B9PmO0?q#v9OG=h-t< z^u7AG?`CzJ|I1hYS5Ina_MoE5u}N zQ;TX*g_-rB(J(AnR=1%|zYI6zUU8{trmvu?^L2tI*rGL2p-m5T&wFNQ_9N7x^LW@} zR+&al*MX^p(CDaAwi0s;Js-PwlFpt!p|Q2XRkH!aQ0PD~zq`Pwas9Ot#MLvYAk;$@ z^g)je-8$DwdjUtJf!5_>SI6P5WmDnAS>v+v*DPg^uBDdW7^$viK9g1d|E=Uo&ExP0?kgrY#=K$9IFZluvS$9&m?C;vC?nvjxS*3M&>w$0^r-|C->QTqC{8yj6 zy(V)Ott9OX`RJGSA6Wkto&3cb=m*H{A>wEKoc@`8^4Fz?lk-lt{Z+o;r{Y0)cxTOm znpqNt^Q#)06A};nFz9^AX|1l zm}Ta7kh;Y&OIC#i1ub8B@bwFMP)SM^m1?S5^C;|Wy&1N7MmXWggt z-^5g15EC&2bUmXTG0&#ejO;ej9X_Du@@jvjiH z?UK9yA1q4mJO5X7t{wheOj|2)(!_CeDZHiW(Ns*H4zxpb zsp-hda?JX8!C{i|`wQ9?e_nnK)yqALXkYlJ>PoYh*4P_#b7lQ+C;;u9;TLa&x?iVo zn(&zKZY+tzt#;-uGIk{=FXWLdn>8@bVS-%^{?}Cc3h=WDD!!!sP;o+!TTGh$ZPP&Z z!|(A$g0ngW_L3RF9=g(W{9s*S;>bapGx%uw0aZ&7~x3x}P*vATe^jW=5uXKCGBTD-s#R+?HDhht3IP;x;___38NU3X%Yv`@ha@p@5 z{BQTx{~E3QzZze6et!GL7oUoIs}r0eW*#0{rK18`0=?yWz;!2AWpm{UBsG4 zirXKKBw^j^QMd1p)46}*IQ{ZFLZx4|d5ToYkBY2efj)8z_M`Ix@hToU)es&;4R<_6 z4Ik-cOZ4GiGq!6F0xsaTJG<7>fDpF4s4Z-@9%u&ybxwU}fhIXk4w98m?3rg2uU2ta&IRgW8bEuU zznyCFcY%y31_0g*+IP>OmeSwygl*9jyxO7OINxJ#T0A*@8cSc4y-D}K!91xv4 z9aR-fM_hFK{OH)6Vs6_nz1ojN+_?38Hn$@`4LV5(&A`90)v}`Q!-!wux-o%6jGQmH zoQwhTqm}T~`3}1&D^o4Ztof%|2RGJT)sE%AGqOlHon>~UB)V-pVEEmnraegDLAIz) z5p9OY+Xyl=BCL9spu8^QNFOfMa{KCqnfBca(Rpeht;hboH`iIQS`8_5%YeZPDb`Lt zO}1fl))$=1pc=JnCnXt-s>?@uZ+%d8T|O3T3U=W2J?x=to@F-g(26Fz)FXuYv?uk# z=TQ0MLI00EOtuP`>5NkLCv3;u+jU!hC@ikf6mx0lHw}u zj2+ac9=)+|ciElnWwRkcg-Hhr)j_nIck|!f5^wk2)2sm>zd;}o0>yd6NsM@48Dj3& z(1`x;dW1Hr_sZ%r6Tkd2eX)MxAvtSveDm)Tnz8JyY(QBv=HQ2|LJf0W{?McD$cg_Y z18(MT-24$^KNLZ266&Y}>=xSe!cN}eZiw-n*XtYsw^>8y!eG1pLT$Z3EwT`jzaevJ zF2ny;IfO~Z$>kr-O|kq%_P(>=asx*pLh#n~jARpcrbvC&KiXwws*dQ(_M$i98JqP@8<0&pf<1@bMCmoyp9q&5)dnc#;$6BT@yiAKqb zfM%?uBH+?i(S2IkxYIB$p+WMgI@u0A*Y2^&@N*SpQ%rqq9$7Dlq-=B16KH9et+dwek`co|jD^5)Rr|hc9b5tIy+M=GsnJG4Li+#XnkQ zrDjIRP8bny2DCG!p`-x~n7WZBM4L;7-7>NcJi@o8sLouC)W#`~^?iC5U z$v)^AIlB)VrwB*%=31mm3YGR`K*XFCnmll7Nw{KSd7-K=@Q>Lup{1M%! z+T{QHY7?(3_cUd{#Yy^|_Xlil{|H|EvaRs^Rd%T7j8G-uz!~jT$D%Rh-~Rir1P{F3 zQTqqV(O&T8{6FmnCHtQ)f9HS7a0u(z&*$?CDxbt|>TR2>Tsv0hQ$AUFufN{EFgke+ zl`?9cQew-ZO3Ic2MlG@;v{}7L(?<8_a=@>)tPvZ@L_lwXb4SQH0Q+RBdaa829d{4E znTB)iiYFvqZr5@R*@kzE7)sW+Ld+~lpIs#EpaQcf`qe12#)+B_Zs+-U=;U?5cYX#x z9kht{#F0ZND}$5m4;c@l^*u#T275mjnDPt6bdUKu1{9pmJw?8!=5MI5{q)M?f}o6W z-PTRXU`#tMp@^Wo~@_*`W>I^Eja5ePhd51=}o z3W`XooQbXGa_;mqjp)GE}oW?Ic zEY*Z>bpa2Km*N9WWTUsW#0yiql51p$UbO2_W)dE+)O!;tccF)~H#Z6OhL^;JWrc?O zT)6XQ6FO)RJ#v76xd+MgUxbTiYXmU>Y$LC8i_Hsek|#^c%I4N9mW=Ov)R_Yx8MfQ> zG-f}_)4v2X6y%lwx1wCMVW1xF`L+J>g-+>BhMu0UZ+7HI75ROk3bd@^lSL9$k$k~@5w!^ z1m2Y2M5(Fx!Ee9s`lH7G%V7L}Zk#H%3PRt_+y9JS9xpoiV*i&ax#dF2f6qrdM?D=M z{?>RNa@%F~*4f)Lk6ItMPPE@UaHsa>L!H;NKS&+3_D3K2VrFX0)#$~>;Eal z*UxMGDoAc0kw0p4B9RK0`o;<5_gAl-iu^CCSd`OH>k#3Gk5 z<{Wlr3tix&0YGs&I&yAjNxiEX?2rK}Fyrr0}yiSv0=vd`rJCAf~V15mrB8HeF#g}-7*GFwmU z4XbKKa1wD+_Yvp=_>}SH#J{Am9*XdT(t?-rt2|@D$26e7P__{`VQwJh{2L9%mA}5` z;$$1_)vZ|9CA#LhI_sh8pwSSp-UjC!F$z!Jsrssv|CtQ)AM?mHHxyK2ASDPMvl7ae zAw6c;y*R-l+gHjPqDew*sd2b#9K57cnN|efN?}*w(9JcAIzS%_^h|i$ri4Xt!qN#d z0$IXaxKe4O7+m*(l^NFPizMlzG1e^LRuh6O8{E@rt*G4f-x1HHGcw|c#u(rvK*B|rP1hFGk%rnXVkPn)lpJ~mDHog=^Vlborl z!tmJNwrjVMl{46*E*fTr+7>mA2_U&EVe17rcE(3Pb-`hBlxq7JtDmoBkg8JG(4N!K%FGt|h0FU7?{+3)hZ1*= z`qo6k2wu~4j}&bzg!y}*7VkE(=|~I7aH&0#fi)di8(_F6nMbIB9NXuN!SMdOz{(f4QXXmr5 zQ8zV$qba|1cNw0^`YZ5=cSiBTCvvmH`ZbR$+5VZA#Q!^4~|DYZY99W&WekPBXu zu6w1BBup643SLtZ!b+YRZj5B`Sxhm5{S_x9bl74Ta~_Nyv(PoyBP_mfW3D}>?XO&+ zcLvQEzLgj-riTAU>rx2fqGStuo3$>QoK%oOWRys5iC$&1q`eVIk_*zg5hBfvpZXTK zE@Q96z_K}STm;ivx1s9U(k;k;=4Y~bncs**W;y-?=5sf&g+u{XJ3}G_tF$@r3%EybPiX{Zy^Hj_ zY6#Yd*TX4?6A7U`E%Mk)wg_YF@HQBKA*dOM>^LGRzY=Hvho#$D)fWw>64tqEQQDTB z7SoXi2CF86+a)^bC(Wgk8Zzouq%M3O@(KJ`{Eqx9Q@06O;iB7sWQ*@nsl}uSh7fOva3sr2c5s)GJVYJnek}P zb?Ieyhn?$7G(C+i&(3nA_QB{3+~YCIu|hKRj8Pkrb#R#$(&wv*^H9R+NMvQcRt6Cr z{+=@nS4$SuLC(Q5F?O0=7KegiGK%FecB=EC(cn<%$WYhD3wv6(2NbAk!xOXl#-Jh@ zNx<`zgMY%8WC=)OyEla{OkoZ!-E|HJ)D_#SVvyR%{9^UGTv8%#wx=5;gS%q$wymmk>fmCGA=@dV1{JK z{#@%_0o>lzJbZqJ_iszr{d=`f-m*TGUIOxDl(yH#mNfDhPBRN72i$OB^7)l(6U#5b zxv`TM!PytG>yZM)&!B**l5<^xV_|Mi*)iCndZXoZIL{SEC@!k-8n^gldc;SFo>gi@ z%H%1OA5&1@X|fUf687NJ0gZYms%kIO^zxpa3`#5{Vj`pw)j$|k#;EiZnenx&IU>f=+&Ljy*(SLe zbxY_A({j!z!%|bI9L0aI3$H^R4A+rSOq{v7R&1ZT@wegqp=EcMPto013GHn9Xa{B33 z`K5ZxDTS-I*%w{;1M6y3<}7Y<>3dj0&m*f3=>c$~U10%ATC*6Tc#M&>UqE zfpeg+*6x}+#nEJ?irdR1Zsb9&H&Oh&*TmZ)GtuapCrBX@8SLt^t;+-~=uX=&4qE$Y z#SQXogia?FpuO8CfnC37lOB#+DQMfd){D;zr5y577;oI!Yj{3^S0f2wMvy4ZVau-c z?6KbrawYG1%OVu{)Mk6YaLwv3Xwo2%`yBsH4<-)sEUBCxtE0>`1TX0rYK9@{a*gEg z#_ofZ-s~r%yZqi?sB5#8?su27S4nMU^(po(6r`ybIQc(W{FtWd1g)N~a7$j)!$OeF z?V&!i{a#82br+yhf_TMOUC20)?}B$w-!m8;*Kl(#@yD4bZ||w>+`kvLdspYtrq!@1 zOEe=DqKQEYyq6O_*>{~5mP0}6|91H3KJXX(p(|KmZGCY@3AOxnw2x8#Xk$HC)3e-+qe_XN0qmtuCn`rtC9wt5O*58td=ohK0$;o?rj zkfH>U{bR9)y%KNjVJ&**mE?g1=kwYxX-K>!whdj)uDt(p9Wne$8o_mAiJfUx3WuI& z=ycwdO+WvH1c~QLB7e+9i4YOONhneE;$hu>9PhG$T;AYw*h74JvfXIgb8Vq-w z>b)RRx~buvb+ZnTbsGs*?1d(Bfrrc^1UuA|&lAI&0jskO=WspiYm#u5zLm?QpAfCj$jz-~1+rxJ!W5MzF%K~7?`~qa6aye7Mk;b0==y-~*E+2usm&9(% zl^l~?bOAF=EtSSiCzgi==zrWa6C1i(XE&plM?i+hIxCY2?|zEAl$}8d8jtEr$jX;0XJe8~^ zq~b&E#ht~42p^8`nKAJA7uDhlsFzk^rp+w>YvzU3z+<&nEt_|X^R)<^*T)5$3(73h#?Be9D*dWvmaQuf^LXvwnwWF&J|*~3=C{N@atJL%vpSY%MTf$x2LL&Gt9V{Mu~GYK#=+1b zaU5af#*C`o&*Fy-U092!t>Oy%#PTL^bAqT?G0<<0r z`TeOuXHK)`btL}|A55O?o7F&lJJ;_Xe`?EfKu=8+9%DJ?1QV2}8f<;QX`bBj`B*Xc zA?N}1QfOJgMOmr*y0_8b0IKXqZB3^Opx&?U!I#4D#2`|p*QS+uuc(AsOab7O7=CMS zM&m;4#KVIQK(n{@Whd~;yi1W93>uL2VQN48TQa-Mi%I|;TPY%nMrR0EsAyLdhcm0Y3kMWOelc{bVo zfeu!DuPUc0LTF~LFXZb-{M3DBxZ$pMy6jKah33}>Y{&RVdlx;+HD2I?KSRxcozuy< zj^=pCnes9to(2DuVV$5L8Az94HrC|D)rCc>;@&Ovz9SR=#kd^!`y=H~`7chN-$s0_ z#AYnD{ss?P7N-n9$@xzHt9YaA?d-Ke+CMrm`)$jjGR}XSe*9&ReC^@$yW+M*PxSDP zTU;?`(6e3Uw;GsCk(3#vySp~~g4Py+jM*A-Vs4>E#=M!8o02W`GML)e0%-JK-yZT3 z9FFv-N0~xqViJMSsUX(I90MY@BWXP4O7lQsUXDTpxyMVJlu|E9r2}vby~?s#+#Y2wLMQA$mZ7rZLlY zYByX4Sn>VW`-`{hi6ODyPIHw<7kWzU6L`%5X=w)`{Yd;^Lhr>1O{;dw^t;1UmnODH zuUv4=Q6thWRD~g1&JT5}{0ii3#WnWm*zG4v8#bGLIlM&GytGreM?rozS&52ux|lS$ zaL!sI5|E;(!h(xW>JQ~wf1hbTK%iu1$qkQLXpxhjZ@g!;gH+IE#Typ`#4(vhHWCCf z$oM(3<3V6lhp8la)no0RgmfEtcPgY^lmW-g!(ftrC5dS6O`5|=eC>=)w(TaS^vm3D zn}>t*Q?;$(t;n}WO1VHKrl#%#&f`A{aoiF5Pj`LC$Q84Q2#WqW|KT8w^QF8BTG#O8 z(B`ejR=QiUe;c_AZ?t+|5TI+aIOL zio_+$+^;oP)wd>y*(o8l`QSbGb(F(gQ6|ZOwQn^ z8E=>V&X)uT6DHO&%Y7<_V9Qyv2%m545*`b?H~dUiAMKa=3zaH&O!9J-#+ruYcV@lK zueX;_LN&%D`r^!VbQKZ(>k2PfFx;tT3b~yT?wYdh@^Y1g5fzi7dlYil)X3J}0@cF6Xv1XQ(7NTkm<-feS)i*r*({)krwZgF=|2^R*xW%4;C|QP*zo($ovuNh$ zBI2+61}<_0sFkmub}8H0CCqQ_*s%!tm6@pfZ>^TkieS`DE(z|oQNLPqHtpc*@s6|8 zfPd~Y!an!XE(K72I|%kj)2{xh0tBx3Or zt@QBcWXNg$TS{w2%<(#%_&C4^b~0$8dZN}#@R}+Gkg8p{$s|<*OSI(fgSJ&)B^P<&F<>y1s^e0+(P=HanVGkExn3!G?;v6_>M~mE!M*x5ETw!fPvw z&Ovirqp;C`^orF+sG+T#3n7{)VHIhfH$L{qSWRyn`65x1SrPp+{Z*x3lhttJF`t}} zBtOHN$Yg(Uz0u;awyvRwGgs7r8aGmXCD-o&nHG-ctEdbq3siw!}-h;mYG+4Stt;cL|eZoSGWtNnTzYPhu0 zY8?Hdb*zC~csfzA;OxMO{rjDZgND?4OON_{K#yR#p76TZVzZA(sAq;AEkk+S=a8zC zat>CQk`538`=dk(qnZDk1)yk?CGIM2(Ay*enZ|Ed_AE@zIfBBM180;0Ac!bL+JOJD z8W5YYygFez``1=b*(7vKA7qM5(4W_ZRbKfT^dG!85tn3?3J`BAF}}q|UnD%v9k9Z_ zURCyB*90`>c8{OgxP0(T#CLeb?t(tJ4I`#%WO=ci9nbVADUsh%O9}Sl-IB!p4Z}>; zl1h;a->Y`3ic`%0!A=VsNEw_Njb72Shs@~ubi0zqFSuukb7~{2_uPaNdIm6V648KJ z!yl^}hnuiIB1d5oZqFdx?3jba;`2Fss%Ul~V3|X0oZl2C2+G>^{(7*%+bKGs2lR6{ z#~lhPi)b;-@T*$4-AONa98UX`T4n-aMa)g|q7vLAWx7@qxs;#VGyI2XBR&bLMvl8xr6;3XlxKtKaos4P2DNfjscepG`c9*l4x5ifR5cmB|_%t8Jp3$5zBw)P~eNN~3Z z&E0xO^eU?E0p`07-)l(l@cXaE{F~lI9-YS*BEPz1BR-iRMT;C{o_^xv8LcFmT6p>$%PAEfLB|#Npa}p((D>ZzTLXnSH{pBkuPjV~wqp z3Rd8y(w=gdQdEYyX{6zs?rvJ0b~6l><^2r{v#t;vAb$%nlzkRV2vYXkH|%(21M7*` zX8!&h_)sUh>0JFVKuUo8~-Bo?i5P`1%*vmXc*V>RT;1c z56kZdnyc}<%M<3jae_7>Vj_VwzRcz8UdC+T-S@Kobn~OXOXlTgGNTBA=gkPbQ9qZV zVnvVsMw@=9s4!8{eljb&+<-V0_c*ehR=hKmKQ$5&n ztC7F?Gsa$4pgA3F@TE&Rp^Tr|XMpU|t&h;7xc5N8c^mTxT4|^_$t|FT_64HR*lVYS z5B?6S(R4k3Ip3}SkObr;?!-}*LYA}=ZSQ+(41Q9HGRoI zpcASYn1v1hHMo?>!Xs<>QZz5HHIlk$th<`!?H?S0lEa6b#c9`V4uQ7uEg+CNB9^XW zv4&i+EHop%HqMBmw7+p#;=Y~Q&zVssxTJlACfnN2Z|H-TvBx~Af7l?p^sxdi`AJUL z?`83Q@*M7-!*{Gv_C28M2R(}prM3`ZE!54ye06=UY5;V}bfoMTIl^ZyS)2F_^klD= zA?@{ht2#%(!&!FO`EH`AA)wrjO zEDSK06xiqHb}n*bQ{s0F&qpx@wWS53g~rstV|viecwq%H;I2PdgO3A6Zr*vekk-Ju zd@J?jKe4D+pX1EBhE!FvH!M#IPa+n{NB%9{`RJ^>q6#Kz?*|R+Vb584TZbYxD1w)l zCM%9r$WSTEBRVWB=0&%Cu-BeWD4ivF%6OZJj^o>76rTGy%x%ejXJ1fjk@ZN!Nduo*KU}+- z82`TRgcTRz*#lkAj9K8eMXooGzbR+-M2%i|4(eWA_%djON45GJ^OPW0j56M~oyS$t zdd3n=O)2jypQik|Q30Mu1d3nd>iK%Vv(9s4qk__o5tVI_n&aYwxb{CLD?ZL=9ekwh zMn$|Upr?U?krl7QV#1MCU4E-s)#|K1s{p#@1B1+v`zf+eaS*rp47(Yr8-RaNcY}ws}{4ETb|UP;z}OFr@RGb>a4tC zznQfD&B$s2K}JVl8$|M9>D0uX@#egg(SSS81;Oy*lUP?gFC4n6$7tN0K{&nQ z4xevpB#jp2)QCIHz+tt4n_46$T0ADWdv=kfuuYMFBn4cOZQOP%);jXB)?WO8T^MaF z=OYP=3@zCMa`VWO0jN0c-~SD1@O!l_ATN>wmF>Jg@RAdgds*ck4xO3ik$V$6fxf|( zU7S&qOQbhwGj&VdUnx6&C{a9!F0(i14d0vM0$0<5YQmR=Nt!mV?}@VbeW#(7?Imz= zRQOKSPOcv9qL~}R#vHlFTF}eb15L-i&KqQu`F3tY|IDp_XcnnpIhr4&6;qXZ_a{wB zYenW|3KIs;*aNXG!(%Dv^%q8E~Ji&{=$9jcgEs@9UCQh>{|DRh@rI#t}w ztfFaN-u6vi9;%z*7?XP>7V6G!-fn$${W3DO!w}!9D9@}r9$ls-T}VFV?8)Eu`>Kj& z!=Vp*kKuoIag?WH+Uy}`jgNMf>Zxx%<_A_^#Wi-8)vpaU8=?Z=9t`}a zjlutez)F={k1fF&MPZ?1o?Wswl(HCw-|TY`!C*>>6fuf%LKn`f0aGum>+BYP7}ty- zKLp-I3uuJ?Ek0S@l9E|(6*OXv_$O%7W&|zM=lyIAaCD+OcvhQ=j0R5CHvh9BuvqTpH<@L*fTwTgdF8y%Iy6g5 z>^TNg=}|`G>%)yC<(bv;KIQ#a*$RC02SfA*Gi-$FWUuXtt{S;4>FcU8S-HRUdk|^y z@nCk4i$9hr>!_|a;meM0Jqh)L*7U@w>8jAK8sF%!g4%!pMo10V%LoYFosb;D` zIot902T@@`fBN*0<*7*`m&oTh@O|Sa6)RmqUYWh0c)Aq}tnD?{Pl!PuIwUx}K#U%f z#7SpLPm#f18C_HjcPj7*H~_rG_A(@JHeo-l1uKIYI0Q*RS{3O7=ZqtJ!KPECkz_s5 zkR*e!UP}r?%?*ke+)m-w9j^0~AYAYUXN-yN54?mLl&Ur^qDc6<8+~w{H)Qv>t#_O( z=Q`${-{2ja@^j!h6|*<>>5PLX;d`izry~H3hODDG%LA>96kN$u{f^;?^YH<{k~LO3 zs(3$Q2~FX5+_qT)+dyP``{D8Ry6|aXr^d^t;Bq@?a8pIfM78n;w#S1; zNH&1)&aLRNl=vYE?FO7XElJ_%IZ0vkFHuIB#Ck zXgno_NO)aKxDIv>;N*{Ug4^PM=IMZc;j#y|e*(Iu3?aYR!XjN;D{{o~DykU)SH=CR zxP$1mR%sPRvJxP(aevKj8vT>nQ$1NO?v^K9SK_s`=t(-D$S5Y;UKY!IL8b5i+4cf& z947VYnH)i{D3cO%#kWbdUeelPk2Y)b)cc0-^D-ub+c``K*Evh@sQ8_7t;gT@bI1C^ zQ}+^VAX?)!MF|x~Rn3)MXD~CU`H6Yc(vKBc_Jjgr*yLOL=#XaNa*CkHIk zEnC2PT#57{GnRAyW$ZK$q>als8`QqwnjWtuhIwA(Y_`)P!{FvG_|7j~R@r5xdRhSCRwL2SIOFWCksV{~iLaQJYc=ifGB?DKyd2Nnunxa&vjA z7FooK!X6<8J`f%gops$Gp$zdLIhy)P=0Z+ap;FS|9z(T7p(j_eX`mB5RO)9!Etr*a z-E{d7)Z_Pcj~U%$z0Djr{y;Ht;I3@OxFet|Y4JvRRTq}Oy)O;C2DMMgg>)#CGIcw% z59ZlQAP`qO&h`a88N#LZTc~n}-pI43HGRg+-_89Wfmk$wC@GES(b!r z8#McH6|0=4oSb}2!(JbGq-K5bgYj~$DFzh21v;fStiQlOks)rm>yCtgTJ|T^&Ey(A zYpHko&0h2hhscZ^34E{>XG7>jsfQF?4QOG6(Nmb?bJfGyrWBjzUU8(B? z8DOl=g+&mzabjW89#WZ!?b(i-S<-}aJ{%&(+&ja%SkTWuMchVs21LUqR}f5+l+6)i zgr(`F;X@#hnJYq4&KShGI9M^1(uw@q7E3a6fr#;E*P>n_(X;l18veUhSP|cM4KAeE zrh8mvdXPnlq)aHPgOgy^;8(jo;zq@nwLa=NEoo8Y%dvjEw)i+%<~#eMq%8(GiR^Jp z(MBfR0Ji|8#;WY&UgG~2c9dypcuTWBN?wNzJB1Y_H>|#U4sl_4gL} z>+VI0KgLKO@42s`dIT4WeCDNZ=?)2OmZ?SI*wfSQD)z-qrB9k|O@mFc%fV-P6)#>5 zDF(KHQ04BI6#Y+@8O*a@C2Q7&p95U>qulE2U;B;|npfdXM0PlTHxXdVV11Xg?Blz7 zcoA$Dzs~?T`9CFF*m6zy=b+6g;iHfsK{yn-_9w1BA74wd4g0nAtNlwgtiLAwJlJg9 zM}@~YSY>)`T*3c-N>D_g3t4w4Vj0mfN7dxgeIGFpUoMn&Rc}0+d|1#IYa6ybI-eQW zx-h5MIJ`MKhSWUbolvm!n$gNP70T8vi=Bg7%ZAQ*X*u`C`9~aCc_b$y@gDYNAN$A0 zz09IKA)RPj)@Ou1?#Ds!4NW<-IM8uT8@jGr)k2nrRx44Jc9M9=5kGiC`iogss7$9G zPQV2Ex?aQYV-)4}X3*rW;P1sJ+xnp|D~nn6f0SzOXG&s3>40qR!*(k`qDM@6ylPje zNf_C;+5j%e%Zi9eFKFoR25MMC<88tn=*ghNHl{pdRsGo%OmFj;ed(C)M~LYM*I%L` z*7tTNSrrZz)8W?vUX|U3M-J2;^xje^J)4!1SW;VQwye;roPKJ~s~f%ABTH2`F@H;=_(67tDC9<8L!2 z^PXP~O3LB87QD$Nj;L*^r5D0S>l@};GeA;~FTikQvWmdfu@&Ep@Nl`pe>@q*Z{t;0 zk~vWdfh$ic^fwKUHRe)(+UJV1b3q0x8r!}Q;M+RSv45$;7Ki+@zCh7QIcD3fUuS59 zKh<(K7}cgFmp+dE+0b*nw~D~741$$&dh#p(z}B>ie97SxvnL2tF{nkG1PSq9W zOBp=}1~=re3$3jniRa*Z{slG6JmCGT<&{aJ+Xk1c{XYcV3F)|&8&lwT^a8l9lHHsL zDPI=%KUn>YGq7IhP;J9?pR+D2aL7jRT8Z%#y$g)7(uIxh{54q{`zQ<|>cH|zK+c{~ zXOMux8HM2AQ_^vdn}lVXG7st`z_rgbm9%B%LRb;-FFK=}^u=eYQOy(fCvNT~-Ghcl zpfV?E8Ci+aR2aG^a8X0z3+JeTFyP41FC-o?f*JUWhO4n&%7m3?`!6k$a%B`aFx#%w ztt5g7A0pFT$INzNOPS}UNqAvkQ}4NA+Q@I_Z>n$+x^8>37dZwPv5zI1kb#nQh;t}R z+>gJ97@y-!YTe!!M)K=`s?aZ~98fLrtEJD*bwKKVa0kOFtnOO>`5g@h7k=?I8)#K? zOJNPDQ4Du&?z3^|(DD}9ZLI{m(@msEARy@&(YLuc``%7ZO*=&GIsB4tT=hY1UXqug z-mr31*7AJ&#ZtlO+!7V#%s6A(tu)tLK9hf5Yh~3IncyaFE@m9D4i7eR3tOgG21*>&TPBxpX&Q`)y_=)T(omGxOd3h_ngV1ITHXAwZab%ud62B{U_`HUNIr2!|%tE5p>HJ*Zy`EJJ zubUqFctXWQ(^6we^GI2Yj32s?0D9f7hMOL^6GK_*od@Fifrz5JvuaM9cjjH3Xz>$b zZn?OFidf|=RA>)*0C6K#+74Nhx%IrBFBnl6`hM-|nw6|e-zZQ%3^mT zjZ`u<{4v9fwJXHznufV7ShaONdg_v4%I}G{ULN;->-;u(B$8xs(?GO*rQW`TeS?m1 ziw|q){U0>F`B##Q_rI-KTA5N=k+WsW>21n!2xqWNsZ2c`&&gRzElqKrPywe*%>k9l z3>D4NI!-yy^PD3&;XFWsVF`+cg!tw2to8f@_u_|pubaL1YhTx$sr8C+^G`Ez2E#8P zZchruD#$M#WRNdB+%~!bG*0erbkojtF#4WTXymz-@8<*1q~TnJv|#7 z5Q%<+|5N6G+6!r7N{iDJvBTjfEbo1(*?61$OU{;^E_>Kly#0|I+}%Gz>O2&@4Wkz? z5<^N+^kG>c?Y_L4roGVz*p(oSc7AGwi^AcX{$Gt#IT7zWtZDBZ{aQmB*ZwQX zYX9|mELc(t*aL9tAlMz$)NyhZ$z#143xmI?EqE8cV#Fge418^bWNJBrkKEoKc2u2N|iQmLraPR)0YC2PB?z)JDmt#V~9CEGVtuc!L0Y zY%%lFK5r@uGq~LYf>wfa3~g0@`FEn{sy)U6N3PFYBl1B}6@9_Jo1Y)M#0^`vbyq&+ zH%;FzH-x*Mw!YDaPr3PAJwjWR()Wg4ubrxHvK|_MyyUh2s@5OD! z3{XhxFnc5SwXHeP*%c`fIejQTUTm#X7Q1U;4q;D4=d8`eS_l7+i%v$M#`hm9sM@l{ z*5a_pjO zHaZSX{Ci*7svrJLZEx${E`)8zIsOQ7OIzy73H&k`LJM?pRztu*{(tA6WwwwMWYqbBG6HO=$Jxg)5LnJ|gr(&3u)}du0 zFqcpX-{>v(GwAky)6lyeGp87OJm52qw&wZEeqH&4?{?02PlC<7Fk=t*-_0}wZp>Je~OGOMy8c58?>(- z3|UwoHsv)l_7D8mecZ{zEN)&2v_Y;^f?%0vyI5V>V@T-E8D7@|le!#boj7*wa*VWu zY{q)6#G|#UO7%gBMXvdhnXOgLwOP~(A;eFRff9DyDZN1fN3DD*>`Jxb(%#fvaIne! zOj`qcZ^_}Oe>UE(d74{C5S{+BzqHm1(gpdpb1ur|Q-8%k>dgLr_fI6+`QB?!+6||m zOVDttTDxlfW@3h1^Y)+NffKVMQ$KR<<#BZSkGEF0Xcpz}ES9p^!wu&eH#u*5DtBMs zMvkE}vV&4`9z#F4{JuGpGT4J>QFl@d4K;4{+{)q$$^PD&TMqg~2*a3GV36+Wrc;dUss?W-_k5Gt#n^ z=%U+)l*OQsfj(YSZPfCpM?z7%`@{W#?{w!s)bwA4?%JKVOlt{^@;l!c^DFl#WX<>T z_+uvC@qhE7EYeo>PVn9Yca33JGFl7o8?xrGKIm?~!bN(aOI4^Xd0-8<@2W=-y*6=w z`DIR;VMz7cRh6WGbFj#&5Oi%l>Lgs((UtC=c~#<$0_v zotw!nzZA3gpgeiTDM&qOW-g&<{FOJZW^h6szP59MGK=R0p+idzvydV=B$ph@F^Fk#rr(07-_R zM>YM>N9gRYin5Ju5>N>9f2+F2{d@&WpA$E@ZPg`yJ6DJmU-W$JVP&Cw#M#@bO_vLc2u2Q)w|(wB zu&8nO61lG5aQ(A1j9Kb;`XVx2uco`X?gX%%We#$j^G}MCbn9}4pkF-wDO^lKOf zZxnvg-rtA6cA~P59MlY6MScb5Cd{yVfGs2o;1W62(r8EDq(C(|ow~I2fc))!~|#V?wE>)x+t@Hqm9K9;8%rdL&!y z*AkX!ILOgiNW~ zabGX;C50kC*u(b;vLN(2-sp4INLxYa}5JdF?P*OU9<*`(^qD|oCT)zih zFH0oZn$H(gzhqs0A~DkkQyQDA)UK4FHD2-`-p(LsxU}&{fqrGp()iR^_&-TAPrj-` zmUF?c)?aimPtQZviqiZFJ)br6Y9w{!7Y9P(C z&Z*0W67Re!X$${r$5GuB!ZG%{i$KS0+1nY7#-VyO3!&{P-Jp2B0xdJ3`^G7DtySf@ zR=83z`}uJ=f+7xT|1~MI`uxVu`A*BzSXEr$d3k4G z1reT-<~!N0pcZl0ZxcEA%E#LcHVBSDh`*HBXQ^P;qKC3fDFSAvM(&{XB?;679r~AM zgh-`_!UfW|w z4jR}wBpzKT0+`*cB|Z2lPL%tP^;U5%w{ZIe+i75e9uy98W@RIJ zN^lR?aZ&b4f%uQ~Mn{eipL1KZgG7+MK*}D$A}c~Xt4&33nG<|;^dNLm?#Wi(QRA=@ zD+Th+u(FF0YxhBXdYToNT7pZSYRFH{vPRyrB5pOVO8us4Ly_5T=oj*Oy>gui#2-xe zpZUTlA8yRW70z926Ig(1)OWf7@(yj9^mg>8PHmb+&7n37oZx7iLOkNP8AuS~i~)3z zl0iYX&}jofIHq5mY$D~x?!M~nQbz?!!lI>!1`(XjI_QcuDkW%c5CB`5@=y8{uh;|Q zAGI>x<+le%d3Ph0653U#_H2HrQ!zS6y9ce8B4!`FvmCgWeiVP>&i3CyT5*>;uE2QT zugDUi_SbL!Jy}p$R#v)8$#Rcij*BoiM0i{wOj)wi=EZx#aUUh~S~6qO#^~F(bQRaK zWPDoFSCiW4Meq#bKplP;2R-fRWdaD-n#;aD7c9i8{E(jj^I`W~$&x(s;lXxCAKys#^SHzETtzZ-bpbX`dbCq8%g4KI#u4ljNw4!AF<`;6S?tcBpG zM5STf{_h!Yn%67bMtH64*Fz;g(yH8sDm`**MD^CoD$@LPeM`@z$$-#|!s{KmoZ0B< z@3wm0-%C}hr6-I1m}UhJ8RTzp4o19HqV&V#;0o)WG}|_NHTij@qsWsVNwCe1!Sl_* zk8Q?aI@a5(QjE&}G-&uML?GwMjKSac3=Et_x>eU_lrc&5VXzaZ#U3Bn9}adIUL`oGTQB)9Eu5C?`rFWOzcjotxX?T;<;RD5r@9c<$BI)hYXyBa{`;2H)nyer!}qNP?5oC=qzbn_tffcEFVHjT#{KT^rj@nACB6 zPVW5Ebk5JXvv}yPNf_*v25i={fao-q_>KjlsRzYLv>R^O9yb|%yqUprIMh53$Ziu@ zX-puWw6hpDt2QZx)#19=59tfshMT+d^=oA}z87!seyQ^X3TJ)bgi2`DlG5kSt(Cc;1d7a%D7y!@2&{3Y1V(W;3(l$r11H1EgwB z!nX%5yd~q7n;^N|Z9>a4U7b++ZI{52leh$@Kr?_*zGA8+!D$<|0sBJ?TvDk+KtP^5p@{(c1lLExO&7uDNUn|Y>~@xwUNIKB^RhQva6p_XYYfa z_(TJaT0KyJ^#0Zak@S0UUAx{?VKbin-qJU6LlwhFV+)^dV#(6uNw=}fp5%SJ*= z71d=S=Ax6XnFRCFgJg>ATb1r@nCC>OmIXu!hdj**hw2UA=G}Gj!z#T!Mzy+)3iQIG$-tD z6PTOCtA4+FdNX!~YANQsVRlI`<`%+B=h$tfmZKNt^1)Y+*jk`bndt*1D(0E2r*T(s z7=wWdz)?(oAK@l3{wC2n`;@ekmUPa&CXS`*-lX*8K%a*}&8vI2^|;rNN-WQvD2b#v zWB$;ILh3WZLYe?ex%- z>M0m+`)-0Jp*A3JP*j@x9P;;O)phPpP$Um;Xt1x#ps-n18+DhutMJyP-E+=(SlW4u5|Jb@%KHdYOUedFc^GC_=gv% zwBh)OxQcR{Qa@iUwx~<&Yz0>H-=Ij5UML|=Y6fWjq8#~kUZHWVV91-waYV4H-K5&b zo_}JZg&-y73Tajy<)rV$oDWhJlsV1lF&ke$b?U-f-blk3qmcc%1GZmd{{+$glu!p+ zVVSkjOOwWzGZkUIC5Z(@GO!ib|97x0i^6cq9yVjxy+AA~8h%7^clLUh>w0YWtjqV6 ziR?P--u7=6B$7cwqO7!AJlv>lw!L367dacs|0xST?-4a)lJT}3H3e<*uQ8EaQ*2L# z_dW5ElHl{#HI@dx#Ax0hxB`RJZrA0B&>2|tZCuQ506is=LEpJ=|U9m4>x zog2gy10AlAtVs&`1`seV=`6o!SsLX&9lBo#7^t$$l7WV&XoMimFKn%*>kSm*3&GeI z5~*pN_Bwg#nx2=fH+enyn=t3iuVtlf9u^sZgR80YHbZ?Y_^gma2L;W2RvXGmseILf7x6M1SrbLA=rbJ8CdlDEaSFSVXDH( z%_ZaZFE`isxc^Ew6?&J^pt`*9510`Y%27z}Rm<2?ZM{`a^=z*g;AqF651nq<)L44e zUQwC#VozqD_Ln{?0MSY1bb5IE;O>b6{X`#)h!d0Ihynot27g@9+20$>pAa8s9V;H~ zU`eI&nU#2vQ^e5dYi%n7UxhPmjd*vQxF$s8CJ6kAmA`63F4As#2d-QJmEaOeA<#fB zdP2<8{&Pwhx>NXo`uPkYDk&+AvwllVa?)z9PNUPCS z5U+)W2hF?>yY{xd4|!<(^W?AVfvYqWBvc?d}We)>?llO8f7IC7}IP(?d3^0rJb?B9PowvryZD(mV%d-y%~-|tyU zESO|;>)YB{&{T1}(Fv@Z9#G1ixvk7--s4TWe)~@$M{zKuUf$`zux&I95|mwX&>L!2 z|C0${*sak0#sK3cpuLuXK@HSaUzfYf4} z^G^KRolJyD8_GVFwbQ*Y9JOz8$vc>zo^=se2Y;p z_8;aZsXBWdOc=E0>`&8H*MPc_2R3o8%KsPyN=3VHBb?Oy`Z_##0u9wl>oF2KUagp` z&D#8ev+MP>**eieI8#7JY9m2_=Q-~Z8e)n=C);eHgi8Kt|>a;HnI?wgo9a^)N*;P?X1(gW#*i{8Cj8r3ND0BOjq?ueL5Q9>@w%O?Oo2I+L5>Viq?uY6jeK@qB zBvS$I(J>2*{@R$Zqwp0d)EgVrS|zC!bM~~8Xj;mhOXH_xa;V2q>c9ietgy6`0g2UZ zW;-XawQW4Ho`3kYxRgkz979FhX}zJkCA-v-rcgJNujO$h;q_H}*%A@2x_!DyH(nE? zjWH2!031sAE!24~_~R}G@Z0};t+P+VKp&))l{zwBOHo!(YCmaQ83!0RW5?(cEMLVY zeb25;Jm~4C88Sj1=_ig}Ks`IGLkg;RG@wr@e2}N9&?l}SdGT;p&ViCj;0t=~;GbWH zGTyWYyQf6Rm!(#YY#QAOy|;VXr|)D1WpPfB08ZG^lp{DK6cqCz(GaT2q7kIN?=*H( zU*EurMy>N1drP_E;bKRWYo5C15@bGaK2d2=uOIOBP8-q#LWbn?Oq5{+ekDP|@625B zr~dY&crdlp8#P`k>py)9IN{LPAR`MIUf1CNc%xMhf)gIs21{%2%O7;ZfTBUBk9Zj( z0uU2NRg&v5LQU49D1`;>n2d5Xt14q`Pw{|`f&ZJ91~pg((xCdoO^!FsbjzhI0<~CA zcucC%V_&^IXaC{G7m~V?KQ;17`;~El)Q&!q`KajJ*5C8!z_yumtqJSH-EP~4CEkPO zCspk!zL|!E0k55jiHEzxo%&g9{bqXPkd^2D->|*41h>2Ma>8kGX|3Ovbh4ZY_X)w; z$0eCVAE|eOJP%&Bx;x(%2?V|V$&YQ!tgNhKJ+?9Awy?%4k)sE#gBr&6VWdEQas7|1 zw6hLYpX$$(TID+cx@Pa%!!4}GptSWh2Dq{0ZN-xN3T|xaSCOpse%Av;!pkF+wW4SO zaL|+}azWD*Qqe& zSUYyNdu44M>k@P*3p+~WnM~leRxRZ?LAm(wgm#+m?6#M_LQTt0D>!f9`bCVA z!K5de3dEX#6PH&LOvSgR7u1az-a4VvkV0@k0qLsfb*#@GU6S6P(2|J*T-gh`$D~Tx zvOlpRA3h!Z1Knvsd^b`-O)c-SRQMe4+pc7L@~uJT>LszuxT3P2!)}^}LY4PE*^)m{ z>Qfa1sv`**`g_hPp;0LW?An=T$Zg+&{(ic0LRK368=>xIapOmMnD$|BYTns>W|bvS zfV7X7Q>f|oVLcuhLl~JDWqVLxh2*7Nl9NaFsLJJj+DMXUVRx$_SSL~?uPaFzGm-hE z5=$tDoTvc<$~dfn`aLwE=ahaue8~7{apc5)>VlZaozrfylQca$F&QI;xVU~3MsAcjmhaaVTm}cc23zq9G%M@-BHb$6iDJvo5OSqW`LR?%l-J>uG`LM=FXe-t78HFR zXV7>#4#YC|6C4MJrOm)ngMQr}a}1hnX=;XeR$nDT4R?-`2m5SJ_mfNYUCfA= zYkp-E@9T}HEKAJ%0BNmN#XN3)dyMyHSETH3QqAmX!;S5+rop1?Jpo30G|`?OwS*mR ztKG&*R*3ELvEz|=i$+!r8p38bzmZ4u5gQ+AHoi4V3=2HdTAdbO{Q6lD#p2#3(>bSK zzBrGdzfTq=mZ{MDtYp(EWAybM`T)7{Y8;Wr%y>&s+onE`ng)lz58ZCS2*cNIo8nxL z;X$mwy(r!$oKet25wDRS;q6I=HF$=3Wj^v|*`kTd6SPM;srLf