Upgrade libuv to 179f475b2ad64729feb0422f06ce133cb364482a

This commit is contained in:
Brian Anderson 2011-10-22 17:37:18 -07:00
parent 81a44ccacf
commit bdbeb75bfb
150 changed files with 19569 additions and 1844 deletions

View File

@ -37,20 +37,19 @@ abs_obj := $(abspath $(obj))
# generated dependency rule Makefiles in one pass.
all_deps :=
# C++ apps need to be linked with g++. Not sure what's appropriate.
# C++ apps need to be linked with g++.
#
# Note, the flock is used to seralize linking. Linking is a memory-intensive
# Note: flock is used to seralize linking. Linking is a memory-intensive
# process so running parallel links can often lead to thrashing. To disable
# the serialization, override FLOCK via an envrionment variable as follows:
# the serialization, override LINK via an envrionment variable as follows:
#
# export FLOCK=
# export LINK=g++
#
# This will allow make to invoke N linker processes as specified in -jN.
FLOCK ?= ./gyp-mac-tool flock $(builddir)/linker.lock
LINK ?= ./gyp-mac-tool flock $(builddir)/linker.lock $(CXX)
LINK ?= $(FLOCK) $(CXX)
CC.target ?= $(CC)
CFLAGS.target ?= $(CFLAGS)
CXX.target ?= $(CXX)
@ -223,6 +222,23 @@ command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
# $| -- order-only dependencies
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
# Helper that executes all postbuilds, and deletes the output file when done
# if any of the postbuilds failed.
define do_postbuilds
@E=0;\
for p in $(POSTBUILDS); do\
eval $$p;\
F=$$?;\
if [ $$F -ne 0 ]; then\
E=$$F;\
fi;\
done;\
if [ $$E -ne 0 ]; then\
rm -rf "$@";\
exit $$E;\
fi
endef
# do_cmd: run a command via the above cmd_foo names, if necessary.
# Should always run for a given target to handle command-line changes.
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
@ -241,7 +257,7 @@ $(if $(or $(command_changed),$(prereq_changed)),
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
@$(if $(2),$(fixup_dep))
$(if $(and $(3), $(POSTBUILDS)),
@for p in $(POSTBUILDS); do eval $$p; done
$(call do_postbuilds)
)
)
endef

View File

@ -74,12 +74,14 @@ class MacTool(object):
if not plist:
return
# The format of PkgInfo is eight characters, representing the bundle type
# and bundle signature, each four characters. If either is missing, four
# '?' characters are used instead.
# Only create PkgInfo for executable types.
package_type = plist['CFBundlePackageType']
if len(package_type) != 4:
package_type = '?' * 4
if package_type != 'APPL':
return
# The format of PkgInfo is eight characters, representing the bundle type
# and bundle signature, each four characters. If that is missing, four
# '?' characters are used instead.
signature_code = plist['CFBundleSignature']
if len(signature_code) != 4:
signature_code = '?' * 4

View File

@ -2,11 +2,15 @@
TOOLSET := target
TARGET := run-benchmarks
DEFS_Default := '-D_GNU_SOURCE'
DEFS_Default := '-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144'
# Flags passed to all source files.
CFLAGS_Default := -fasm-blocks \
-mpascal-strings \
-Os \
-gdwarf-2 \
-arch i386
@ -31,9 +35,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ares.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pump.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-sizes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-tcp-write-batch.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-udp-packet-storm.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/dns-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-benchmarks.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o

View File

@ -2,11 +2,15 @@
TOOLSET := target
TARGET := run-tests
DEFS_Default := '-D_GNU_SOURCE'
DEFS_Default := '-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144'
# Flags passed to all source files.
CFLAGS_Default := -fasm-blocks \
-mpascal-strings \
-Os \
-gdwarf-2 \
-arch i386
@ -24,10 +28,13 @@ CFLAGS_OBJCC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-tests.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-loadavg.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-async.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-callback-stack.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-connection-fail.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-delayed-accept.o \
@ -35,11 +42,13 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs-event.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-currentexe.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-memory.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getsockname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-hrtime.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
@ -47,9 +56,13 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-stdio-over-pipes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-close.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-flags.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
@ -59,6 +72,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-dgram-too-big.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-ipv6.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-send-and-recv.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-multicast-join.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o
# Add to the list of files we specially track dependencies for.

View File

@ -2,17 +2,18 @@
TOOLSET := target
TARGET := uv
DEFS_Default := '-DHAVE_CONFIG_H' \
'-D_LARGEFILE_SOURCE' \
DEFS_Default := '-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144' \
'-DHAVE_CONFIG_H' \
'-DEV_CONFIG_H="config_darwin.h"' \
'-DEIO_CONFIG_H="config_darwin.h"'
# Flags passed to all source files.
CFLAGS_Default := -fasm-blocks \
-mpascal-strings \
-Os \
-gdwarf-2 \
-arch i386
@ -35,11 +36,8 @@ INCS_Default := -I$(srcdir)/src/rt/libuv/include \
-I$(srcdir)/src/rt/libuv/src/ares/config_darwin
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_cancel.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_data.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_destroy.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_name.o \
@ -49,6 +47,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyaddr.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getnameinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getopt.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getsock.o \
@ -58,8 +57,8 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_mkquery.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_nowarn.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_options.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_aaaa_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_mx_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ns_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ptr_reply.o \
@ -67,17 +66,20 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_txt_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_query.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_search.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_send.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strcasecmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strdup.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strerror.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_timeout.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_version.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_writev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/bitncmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_net_pton.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_ntop.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/windows_port.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/core.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/uv-eio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/fs.o \
@ -91,7 +93,8 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/eio/eio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/ev/ev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/darwin.o
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/darwin.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/kqueue.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)

View File

@ -37,20 +37,19 @@ abs_obj := $(abspath $(obj))
# generated dependency rule Makefiles in one pass.
all_deps :=
# C++ apps need to be linked with g++. Not sure what's appropriate.
# C++ apps need to be linked with g++.
#
# Note, the flock is used to seralize linking. Linking is a memory-intensive
# Note: flock is used to seralize linking. Linking is a memory-intensive
# process so running parallel links can often lead to thrashing. To disable
# the serialization, override FLOCK via an envrionment variable as follows:
# the serialization, override LINK via an envrionment variable as follows:
#
# export FLOCK=
# export LINK=g++
#
# This will allow make to invoke N linker processes as specified in -jN.
FLOCK ?= flock $(builddir)/linker.lock
LINK ?= flock $(builddir)/linker.lock $(CXX)
LINK ?= $(FLOCK) $(CXX)
CC.target ?= $(CC)
CFLAGS.target ?= $(CFLAGS)
CXX.target ?= $(CXX)
@ -213,6 +212,23 @@ command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
# $| -- order-only dependencies
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
# Helper that executes all postbuilds, and deletes the output file when done
# if any of the postbuilds failed.
define do_postbuilds
@E=0;\
for p in $(POSTBUILDS); do\
eval $$p;\
F=$$?;\
if [ $$F -ne 0 ]; then\
E=$$F;\
fi;\
done;\
if [ $$E -ne 0 ]; then\
rm -rf "$@";\
exit $$E;\
fi
endef
# do_cmd: run a command via the above cmd_foo names, if necessary.
# Should always run for a given target to handle command-line changes.
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
@ -231,7 +247,7 @@ $(if $(or $(command_changed),$(prereq_changed)),
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
@$(if $(2),$(fixup_dep))
$(if $(and $(3), $(POSTBUILDS)),
@for p in $(POSTBUILDS); do eval $$p; done
$(call do_postbuilds)
)
)
endef

View File

@ -2,7 +2,10 @@
TOOLSET := target
TARGET := run-benchmarks
DEFS_Default := '-D_GNU_SOURCE'
DEFS_Default := '-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144'
# Flags passed to all source files.
CFLAGS_Default :=
@ -22,9 +25,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ares.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pump.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-sizes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-tcp-write-batch.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-udp-packet-storm.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/dns-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-benchmarks.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o

View File

@ -2,7 +2,10 @@
TOOLSET := target
TARGET := run-tests
DEFS_Default := '-D_GNU_SOURCE'
DEFS_Default := '-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144'
# Flags passed to all source files.
CFLAGS_Default :=
@ -15,10 +18,13 @@ CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-tests.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-loadavg.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-async.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-callback-stack.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-connection-fail.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-delayed-accept.o \
@ -26,11 +32,13 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs-event.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-currentexe.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-memory.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getsockname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-hrtime.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
@ -38,9 +46,13 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-stdio-over-pipes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-close.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-flags.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
@ -50,6 +62,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-dgram-too-big.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-ipv6.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-send-and-recv.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-multicast-join.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-unix.o
# Add to the list of files we specially track dependencies for.

View File

@ -2,11 +2,11 @@
TOOLSET := target
TARGET := uv
DEFS_Default := '-DHAVE_CONFIG_H' \
'-D_LARGEFILE_SOURCE' \
DEFS_Default := '-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-D_GNU_SOURCE' \
'-DEIO_STACKSIZE=262144' \
'-DHAVE_CONFIG_H' \
'-DEV_CONFIG_H="config_linux.h"' \
'-DEIO_CONFIG_H="config_linux.h"'
@ -31,11 +31,8 @@ INCS_Default := -I$(srcdir)/src/rt/libuv/include \
-I$(srcdir)/src/rt/libuv/src/ares/config_linux
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_cancel.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_data.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_destroy.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_name.o \
@ -45,6 +42,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyaddr.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getnameinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getopt.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getsock.o \
@ -54,8 +52,8 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_mkquery.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_nowarn.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_options.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_aaaa_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_mx_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ns_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ptr_reply.o \
@ -63,17 +61,20 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_txt_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_query.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_search.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_send.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strcasecmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strdup.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strerror.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_timeout.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_version.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_writev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/bitncmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_net_pton.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_ntop.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/windows_port.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/core.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/uv-eio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/unix/fs.o \

View File

@ -37,20 +37,19 @@ abs_obj := $(abspath $(obj))
# generated dependency rule Makefiles in one pass.
all_deps :=
# C++ apps need to be linked with g++. Not sure what's appropriate.
# C++ apps need to be linked with g++.
#
# Note, the flock is used to seralize linking. Linking is a memory-intensive
# Note: flock is used to seralize linking. Linking is a memory-intensive
# process so running parallel links can often lead to thrashing. To disable
# the serialization, override FLOCK via an envrionment variable as follows:
# the serialization, override LINK via an envrionment variable as follows:
#
# export FLOCK=
# export LINK=g++
#
# This will allow make to invoke N linker processes as specified in -jN.
FLOCK ?= flock $(builddir)/linker.lock
LINK ?= flock $(builddir)/linker.lock $(CXX)
LINK ?= $(FLOCK) $(CXX)
CC.target ?= $(CC)
CFLAGS.target ?= $(CFLAGS)
CXX.target ?= $(CXX)
@ -213,6 +212,23 @@ command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
# $| -- order-only dependencies
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
# Helper that executes all postbuilds, and deletes the output file when done
# if any of the postbuilds failed.
define do_postbuilds
@E=0;\
for p in $(POSTBUILDS); do\
eval $$p;\
F=$$?;\
if [ $$F -ne 0 ]; then\
E=$$F;\
fi;\
done;\
if [ $$E -ne 0 ]; then\
rm -rf "$@";\
exit $$E;\
fi
endef
# do_cmd: run a command via the above cmd_foo names, if necessary.
# Should always run for a given target to handle command-line changes.
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
@ -231,7 +247,7 @@ $(if $(or $(command_changed),$(prereq_changed)),
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
@$(if $(2),$(fixup_dep))
$(if $(and $(3), $(POSTBUILDS)),
@for p in $(POSTBUILDS); do eval $$p; done
$(call do_postbuilds)
)
)
endef

View File

@ -22,9 +22,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-ares.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-pump.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-sizes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-tcp-write-batch.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/benchmark-udp-packet-storm.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/dns-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-benchmarks.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-win.o

View File

@ -15,10 +15,13 @@ CFLAGS_CC_Default :=
INCS_Default := -I$(srcdir)/src/rt/libuv/include
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/run-tests.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-loadavg.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-async.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-callback-stack.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-connection-fail.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-delayed-accept.o \
@ -26,11 +29,13 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-fs-event.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-currentexe.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-get-memory.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getaddrinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-getsockname.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-hrtime.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
@ -38,9 +43,13 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-stdio-over-pipes.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-bind6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-close.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-flags.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
@ -50,6 +59,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/echo-server.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-dgram-too-big.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-ipv6.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-send-and-recv.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/test-udp-multicast-join.o \
$(obj).target/$(TARGET)/src/rt/libuv/test/runner-win.o
# Add to the list of files we specially track dependencies for.

View File

@ -22,11 +22,8 @@ INCS_Default := -I$(srcdir)/src/rt/libuv/include \
-I$(srcdir)/src/rt/libuv/src/ares/config_win32
OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_cancel.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__close_sockets.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_data.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_destroy.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_expand_name.o \
@ -36,6 +33,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_free_string.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyaddr.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_gethostbyname.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__get_hostent.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getnameinfo.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getopt.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getsock.o \
@ -45,8 +43,8 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_mkquery.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_nowarn.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_options.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_aaaa_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_a_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_mx_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ns_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_ptr_reply.o \
@ -54,18 +52,22 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_parse_txt_reply.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_query.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__read_line.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_search.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_send.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strcasecmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strdup.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_strerror.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_timeout.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares__timeval.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_version.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_writev.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/bitncmp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_net_pton.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/inet_ntop.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/windows_port.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_getenv.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/ares/ares_platform.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/async.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/cares.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/core.o \
@ -78,7 +80,6 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/pipe.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/process.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/req.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/stdio.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/stream.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/tcp.o \
$(obj).target/$(TARGET)/src/rt/libuv/src/win/tty.o \

View File

@ -6,3 +6,5 @@
<alan@prettyrobots.com> <alan@blogometer.com>
San-Tai Hsu <vanilla@fatpipi.com>
Isaac Z. Schlueter <i@izs.me>
Saúl Ibarra Corretgé <saghul@gmail.com>
Yuki OKUMURA <mjt@cltn.org>

View File

@ -24,3 +24,10 @@ Matthew Sporleder <msporleder@gmail.com>
Erick Tryzelaar <erick.tryzelaar@gmail.com>
Isaac Z. Schlueter <i@izs.me>
Pieter Noordhuis <pcnoordhuis@gmail.com>
Marek Jelen <marek@jelen.biz>
Fedor Indutny <fedor.indutny@gmail.com>
Saúl Ibarra Corretgé <saghul@gmail.com>
Felix Geisendörfer <felix@debuggable.com>
Yuki OKUMURA <mjt@cltn.org>
Roman Shtylman <shtylman@gmail.com>
Frank DENIS <github@pureftpd.org>

View File

@ -77,10 +77,10 @@ else
include config-unix.mk
endif
TESTS=test/echo-server.c test/test-*.c
BENCHMARKS=test/echo-server.c test/dns-server.c test/benchmark-*.c
TESTS=test/blackhole-server.c test/echo-server.c test/test-*.c
BENCHMARKS=test/blackhole-server.c test/echo-server.c test/dns-server.c test/benchmark-*.c
all: uv.a test/run-tests$(E) test/run-benchmarks$(E)
all: uv.a
$(CARES_OBJS): %.o: %.c
$(CC) -o $*.o -c $(CFLAGS) $(CPPFLAGS) $< -DHAVE_CONFIG_H

View File

@ -8,8 +8,6 @@ http://nodejs.org/
## Features
Implemented:
* Non-blocking TCP sockets
* Non-blocking named pipes
@ -30,15 +28,13 @@ Implemented:
* Thread pool scheduling `uv_queue_work`
In-progress:
* ANSI escape code controlled TTY `uv_tty_t`
* File system events (Currently supports inotify, `ReadDirectoryChangesW`
and will support kqueue and event ports in the near future.)
* File system events Currently supports inotify, `ReadDirectoryChangesW`
and kqueue. Event ports in the near future.
`uv_fs_event_t`
* VT100 TTY `uv_tty_t`
* Socket sharing between processes `uv_ipc_t`
* IPC and socket sharing between processes `uv_write2`
## Documentation

View File

@ -32,6 +32,11 @@
'LinkIncremental': 2, # enable incremental linking
},
},
'conditions': [
['OS != "win"', {
'defines': [ 'EV_VERIFY=2' ],
}],
]
},
'Release': {
'defines': [ 'NDEBUG' ],

View File

@ -28,6 +28,7 @@ CFLAGS=$(CPPFLAGS) -g --std=gnu89 -D_WIN32_WINNT=0x0501 -Isrc/ares/config_win32
LINKFLAGS=-lm
CARES_OBJS += src/ares/windows_port.o
CARES_OBJS += src/ares/ares_platform.o
WIN_SRCS=$(wildcard src/win/*.c)
WIN_OBJS=$(WIN_SRCS:.c=.o)

View File

@ -18,8 +18,6 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
E=
CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
CFLAGS += -g
@ -44,7 +42,7 @@ ifeq (SunOS,$(uname_S))
EV_CONFIG=config_sunos.h
EIO_CONFIG=config_sunos.h
CPPFLAGS += -Isrc/ares/config_sunos -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
LINKFLAGS+=-lsocket -lnsl
LINKFLAGS+=-lsocket -lnsl -lkstat
OBJS += src/unix/sunos.o
endif
@ -54,6 +52,7 @@ EIO_CONFIG=config_darwin.h
CPPFLAGS += -Isrc/ares/config_darwin
LINKFLAGS+=-framework CoreServices
OBJS += src/unix/darwin.o
OBJS += src/unix/kqueue.o
endif
ifeq (Linux,$(uname_S))
@ -71,6 +70,7 @@ EIO_CONFIG=config_freebsd.h
CPPFLAGS += -Isrc/ares/config_freebsd
LINKFLAGS+=
OBJS += src/unix/freebsd.o
OBJS += src/unix/kqueue.o
endif
ifeq (NetBSD,$(uname_S))
@ -79,6 +79,16 @@ EIO_CONFIG=config_netbsd.h
CPPFLAGS += -Isrc/ares/config_netbsd
LINKFLAGS+=
OBJS += src/unix/netbsd.o
OBJS += src/unix/kqueue.o
endif
ifeq (OpenBSD,$(uname_S))
EV_CONFIG=config_openbsd.h
EIO_CONFIG=config_openbsd.h
CPPFLAGS += -Isrc/ares/config_openbsd
LINKFLAGS+=
OBJS += src/unix/openbsd.o
OBJS += src/unix/kqueue.o
endif
ifneq (,$(findstring CYGWIN,$(uname_S)))

View File

@ -1,6 +1,6 @@
/* Copyright 1998, 2009 by the Massachusetts Institute of Technology.
* Copyright (C) 2007-2010 by Daniel Stenberg
* Copyright (C) 2007-2011 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@ -96,10 +96,19 @@ typedef int ares_socklen_t;
# include <netinet/in.h>
# include <sys/socket.h>
# include <tcp.h>
#elif defined(_WIN32_WCE)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <winsock.h>
#elif defined(WIN32)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <winsock2.h>
# include <ws2tcpip.h>
# include <windows.h>
#else
# include <sys/socket.h>
# include <netinet/in.h>

View File

@ -7,11 +7,11 @@
#define ARES_VERSION_MAJOR 1
#define ARES_VERSION_MINOR 7
#define ARES_VERSION_PATCH 4
#define ARES_VERSION_PATCH 5
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
#define ARES_VERSION_STR "1.7.4"
#define ARES_VERSION_STR "1.7.5-DEV"
#if (ARES_VERSION >= 0x010700)
# define CARES_HAVE_ARES_LIBRARY_INIT 1

View File

@ -207,6 +207,7 @@ enum {
EV_NONE = 0x00, /* no events */
EV_READ = 0x01, /* ev_io detected read will not block */
EV_WRITE = 0x02, /* ev_io detected write will not block */
EV_LIBUV_KQUEUE_HACK = 0x40,
EV__IOFDSET = 0x80, /* internal use only */
EV_IO = EV_READ, /* alias for type-detection */
EV_TIMER = 0x00000100, /* timer timed out */

View File

@ -27,16 +27,13 @@
#include "ev.h"
#include "eio.h"
#if defined(__linux__)
#include "uv-private/uv-linux.h"
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <termios.h>
/* Note: May be cast to struct iovec. See writev(2). */
typedef struct {
@ -46,11 +43,6 @@ typedef struct {
typedef int uv_file;
/* Stub. Remove it once all platforms support the file watcher API. */
#ifndef UV_FS_EVENT_PRIVATE_FIELDS
#define UV_FS_EVENT_PRIVATE_FIELDS /* empty */
#endif
#define UV_LOOP_PRIVATE_FIELDS \
ares_channel channel; \
/* \
@ -99,8 +91,6 @@ typedef int uv_file;
#define UV_STREAM_PRIVATE_FIELDS \
uv_read_cb read_cb; \
uv_alloc_cb alloc_cb; \
uv_connect_t *connect_req; \
uv_shutdown_t *shutdown_req; \
ev_io read_watcher; \
@ -109,7 +99,8 @@ typedef int uv_file;
ngx_queue_t write_completed_queue; \
int delayed_error; \
uv_connection_cb connection_cb; \
int accepted_fd;
int accepted_fd; \
int blocking;
/* UV_TCP */
@ -183,6 +174,32 @@ typedef int uv_file;
#define UV_WORK_PRIVATE_FIELDS \
eio_req* eio;
#define UV_TTY_PRIVATE_FIELDS /* empty */
#define UV_TTY_PRIVATE_FIELDS \
struct termios orig_termios; \
int mode;
/* UV_FS_EVENT_PRIVATE_FIELDS */
#if defined(__linux__)
#define UV_FS_EVENT_PRIVATE_FIELDS \
ev_io read_watcher; \
uv_fs_event_cb cb; \
#elif (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) \
|| defined(__FreeBSD__) \
|| defined(__OpenBSD__) \
|| defined(__NetBSD__)
#define UV_FS_EVENT_PRIVATE_FIELDS \
ev_io event_watcher; \
uv_fs_event_cb cb; \
int fflags; \
#else
/* Stub for platforms where the file watcher isn't implemented yet. */
#define UV_FS_EVENT_PRIVATE_FIELDS
#endif
#endif /* UV_UNIX_H */

View File

@ -34,6 +34,98 @@
#define MAX_PIPENAME_LEN 256
/*
* 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);
#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);
/**
* It should be possible to cast uv_buf_t[] to WSABUF[]
* see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx
@ -75,9 +167,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
uv_idle_t* next_idle_handle; \
ares_channel ares_chan; \
int ares_active_sockets; \
uv_timer_t ares_polling_timer; \
/* Last error code */ \
uv_err_t last_error;
uv_timer_t ares_polling_timer;
#define UV_REQ_TYPE_PRIVATE \
/* TODO: remove the req suffix */ \
@ -100,7 +190,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \
/* empty */
int ipc_header; \
uv_buf_t write_buffer; \
HANDLE event_handle; \
HANDLE wait_handle;
#define UV_CONNECT_PRIVATE_FIELDS \
/* empty */
@ -117,12 +210,21 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
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;
} 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; \
@ -133,9 +235,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define UV_STREAM_PRIVATE_FIELDS \
unsigned int reqs_pending; \
uv_alloc_cb alloc_cb; \
uv_read_cb read_cb; \
uv_req_t read_req; \
uv_read_t read_req; \
union { \
struct { uv_stream_connection_fields }; \
struct { uv_stream_server_fields }; \
@ -143,14 +243,16 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define uv_tcp_server_fields \
uv_tcp_accept_t* accept_reqs; \
uv_tcp_accept_t* pending_accepts;
uv_tcp_accept_t* pending_accepts; \
LPFN_ACCEPTEX func_acceptex;
#define uv_tcp_connection_fields \
uv_buf_t read_buffer;
uv_buf_t read_buffer; \
LPFN_CONNECTEX func_connectex;
#define UV_TCP_PRIVATE_FIELDS \
SOCKET socket; \
uv_err_t bind_error; \
int bind_error; \
union { \
struct { uv_tcp_server_fields }; \
struct { uv_tcp_connection_fields }; \
@ -164,14 +266,21 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct sockaddr_storage recv_from; \
int recv_from_len; \
uv_udp_recv_cb recv_cb; \
uv_alloc_cb alloc_cb;
uv_alloc_cb alloc_cb; \
LPFN_WSARECV func_wsarecv; \
LPFN_WSARECVFROM func_wsarecvfrom;
#define uv_pipe_server_fields \
uv_pipe_accept_t accept_reqs[4]; \
uv_pipe_accept_t* pending_accepts;
uv_pipe_accept_t accept_reqs[4]; \
uv_pipe_accept_t* pending_accepts;
#define uv_pipe_connection_fields \
uv_timer_t* eof_timer;
uv_timer_t* eof_timer; \
uv_write_t ipc_header_write_req; \
int ipc_pid; \
uint64_t remaining_ipc_rawdata_bytes; \
WSAPROTOCOL_INFOW* pending_socket_info; \
uv_write_t* non_overlapped_writes_tail;
#define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \
@ -181,6 +290,33 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { uv_pipe_connection_fields }; \
};
/* 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; \
HANDLE read_line_handle; \
uv_buf_t read_line_buffer; \
HANDLE read_raw_wait; \
DWORD original_console_mode; \
/* Fields used for translating win */ \
/* keystrokes into vt100 characters */ \
char last_key[8]; \
unsigned char last_key_offset; \
unsigned char last_key_len; \
INPUT_RECORD last_input_record; \
WCHAR last_utf16_high_surrogate; \
/* utf8-to-utf16 conversion state */ \
unsigned char utf8_bytes_left; \
unsigned int utf8_codepoint; \
/* 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;
#define UV_TIMER_PRIVATE_FIELDS \
RB_ENTRY(uv_timer_s) tree_entry; \
int64_t due; \
@ -244,6 +380,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE close_handle;
#define UV_FS_PRIVATE_FIELDS \
wchar_t* pathw; \
int flags; \
int last_error; \
struct _stati64 stat; \
@ -270,11 +407,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
int req_pending; \
uv_fs_event_cb cb; \
wchar_t* filew; \
wchar_t* short_filew; \
int is_path_dir; \
char* buffer;
#define UV_TTY_PRIVATE_FIELDS /* empty */
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,

View File

@ -41,6 +41,98 @@ extern "C" {
typedef intptr_t ssize_t;
#endif
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
# include "uv-private/uv-unix.h"
#else
# include "uv-private/uv-win.h"
#endif
/* Expand this list if necessary. */
typedef enum {
UV_UNKNOWN = -1,
UV_OK = 0,
UV_EOF,
UV_EACCESS,
UV_EAGAIN,
UV_EADDRINUSE,
UV_EADDRNOTAVAIL,
UV_EAFNOSUPPORT,
UV_EALREADY,
UV_EBADF,
UV_EBUSY,
UV_ECONNABORTED,
UV_ECONNREFUSED,
UV_ECONNRESET,
UV_EDESTADDRREQ,
UV_EFAULT,
UV_EHOSTUNREACH,
UV_EINTR,
UV_EINVAL,
UV_EISCONN,
UV_EMFILE,
UV_EMSGSIZE,
UV_ENETDOWN,
UV_ENETUNREACH,
UV_ENFILE,
UV_ENOBUFS,
UV_ENOMEM,
UV_ENOTDIR,
UV_ENONET,
UV_ENOPROTOOPT,
UV_ENOTCONN,
UV_ENOTSOCK,
UV_ENOTSUP,
UV_ENOENT,
UV_ENOSYS,
UV_EPIPE,
UV_EPROTO,
UV_EPROTONOSUPPORT,
UV_EPROTOTYPE,
UV_ETIMEDOUT,
UV_ECHARSET,
UV_EAIFAMNOSUPPORT,
UV_EAINONAME,
UV_EAISERVICE,
UV_EAISOCKTYPE,
UV_ESHUTDOWN,
UV_EEXIST
} uv_err_code;
typedef enum {
UV_UNKNOWN_HANDLE = 0,
UV_TCP,
UV_UDP,
UV_NAMED_PIPE,
UV_TTY,
UV_FILE,
UV_TIMER,
UV_PREPARE,
UV_CHECK,
UV_IDLE,
UV_ASYNC,
UV_ARES_TASK,
UV_ARES_EVENT,
UV_PROCESS,
UV_FS_EVENT
} uv_handle_type;
typedef enum {
UV_UNKNOWN_REQ = 0,
UV_CONNECT,
UV_ACCEPT,
UV_READ,
UV_WRITE,
UV_SHUTDOWN,
UV_WAKEUP,
UV_UDP_SEND,
UV_FS,
UV_WORK,
UV_GETADDRINFO,
UV_REQ_TYPE_PRIVATE
} uv_req_type;
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_ares_task_s uv_ares_task_t;
typedef struct uv_err_s uv_err_t;
@ -69,12 +161,6 @@ typedef struct uv_fs_s uv_fs_t;
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_work_s uv_work_t;
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
# include "uv-private/uv-unix.h"
#else
# include "uv-private/uv-win.h"
#endif
/*
* This function must be called before any other functions in libuv.
@ -121,6 +207,13 @@ int64_t uv_now(uv_loop_t*);
*/
typedef uv_buf_t (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size);
typedef void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, uv_buf_t buf);
/*
* Just like the uv_read_cb except that if the pending parameter is true
* then you can use uv_accept() to pull the new handle into the process.
* If no handle is pending then pending will be UV_UNKNOWN_HANDLE.
*/
typedef void (*uv_read2_cb)(uv_pipe_t* pipe, ssize_t nread, uv_buf_t buf,
uv_handle_type pending);
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);
@ -148,88 +241,10 @@ typedef void (*uv_after_work_cb)(uv_work_t* req);
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename,
int events, int status);
/* Expand this list if necessary. */
typedef enum {
UV_UNKNOWN = -1,
UV_OK = 0,
UV_EOF,
UV_EACCESS,
UV_EAGAIN,
UV_EADDRINUSE,
UV_EADDRNOTAVAIL,
UV_EAFNOSUPPORT,
UV_EALREADY,
UV_EBADF,
UV_EBUSY,
UV_ECONNABORTED,
UV_ECONNREFUSED,
UV_ECONNRESET,
UV_EDESTADDRREQ,
UV_EFAULT,
UV_EHOSTUNREACH,
UV_EINTR,
UV_EINVAL,
UV_EISCONN,
UV_EMFILE,
UV_EMSGSIZE,
UV_ENETDOWN,
UV_ENETUNREACH,
UV_ENFILE,
UV_ENOBUFS,
UV_ENOMEM,
UV_ENONET,
UV_ENOPROTOOPT,
UV_ENOTCONN,
UV_ENOTSOCK,
UV_ENOTSUP,
UV_ENOENT,
UV_EPIPE,
UV_EPROTO,
UV_EPROTONOSUPPORT,
UV_EPROTOTYPE,
UV_ETIMEDOUT,
UV_ECHARSET,
UV_EAIFAMNOSUPPORT,
UV_EAINONAME,
UV_EAISERVICE,
UV_EAISOCKTYPE,
UV_ESHUTDOWN,
UV_EEXIST
} uv_err_code;
typedef enum {
UV_UNKNOWN_HANDLE = 0,
UV_TCP,
UV_UDP,
UV_NAMED_PIPE,
UV_TTY,
UV_FILE,
UV_TIMER,
UV_PREPARE,
UV_CHECK,
UV_IDLE,
UV_ASYNC,
UV_ARES_TASK,
UV_ARES_EVENT,
UV_PROCESS,
UV_FS_EVENT
} uv_handle_type;
typedef enum {
UV_UNKNOWN_REQ = 0,
UV_CONNECT,
UV_ACCEPT,
UV_READ,
UV_WRITE,
UV_SHUTDOWN,
UV_WAKEUP,
UV_UDP_SEND,
UV_FS,
UV_WORK,
UV_GETADDRINFO,
UV_REQ_TYPE_PRIVATE
} uv_req_type;
UV_LEAVE_GROUP = 0,
UV_JOIN_GROUP
} uv_membership;
struct uv_err_s {
@ -330,6 +345,9 @@ uv_buf_t uv_buf_init(char* base, size_t 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; \
uv_read2_cb read2_cb; \
/* private */ \
UV_STREAM_PRIVATE_FIELDS
@ -338,8 +356,8 @@ uv_buf_t uv_buf_init(char* base, size_t len);
*
* uv_stream is an abstract class.
*
* uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t
* and soon uv_file_t.
* uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t, and
* soon uv_file_t.
*/
struct uv_stream_s {
UV_HANDLE_FIELDS
@ -375,13 +393,12 @@ int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb);
int uv_read_stop(uv_stream_t*);
typedef enum {
UV_STDIN = 0,
UV_STDOUT,
UV_STDERR
} uv_std_type;
/*
* Extended read methods for receiving handles over a pipe. The pipe must be
* initialized with ipc == 1.
*/
int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read2_cb read_cb);
uv_stream_t* uv_std_handle(uv_loop_t*, uv_std_type type);
/*
* Write data to stream. Buffers are written in order. Example:
@ -404,10 +421,14 @@ uv_stream_t* uv_std_handle(uv_loop_t*, uv_std_type type);
int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb);
int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_stream_t* send_handle, uv_write_cb cb);
/* 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
};
@ -427,6 +448,15 @@ struct uv_tcp_s {
int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
/* Enable/disable Nagle's algorithm. */
int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
/* Enable/disable TCP keep-alive.
*
* `ms` is the initial delay in seconds, ignored when `enable` is zero.
*/
int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
@ -536,6 +566,21 @@ int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned flags);
int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags);
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen);
/*
* Set membership for a multicast address
*
* Arguments:
* handle UDP handle. Should have been initialized with `uv_udp_init`.
* multicast_addr multicast address to set membership for
* interface_addr interface address
* membership Should be UV_JOIN_GROUP or UV_LEAVE_GROUP
*
* Returns:
* 0 on success, -1 on error.
*/
int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
const char* interface_addr, uv_membership membership);
/*
* Send data. If the socket has not previously been bound with `uv_udp_bind`
* or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
@ -574,7 +619,7 @@ int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr_in6 addr, uv_udp_send_cb send_cb);
/*
* Send data. If the socket has not previously been bound with `uv_udp_bind`
* Receive data. If the socket has not previously been bound with `uv_udp_bind`
* or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
* and a random port number.
*
@ -612,13 +657,30 @@ struct uv_tty_s {
UV_TTY_PRIVATE_FIELDS
};
int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd);
/*
* Initialize a new TTY stream with the given file descriptor. Usually the
* file descriptor will be
* 0 = stdin
* 1 = stdout
* 2 = stderr
* The last argument, readable, specifies if you plan on calling
* uv_read_start with this stream. stdin is readable, stdout is not.
*
* TTY streams which are not readable have blocking writes.
*/
int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
/*
* Set mode. 0 for normal, 1 for raw.
*/
int uv_tty_set_mode(uv_tty_t*, int mode);
/*
* To be called when the program exits. Resets TTY settings to default
* values for the next process to take over.
*/
void uv_tty_reset_mode();
/*
* Gets the current Window size. On success zero is returned.
*/
@ -642,9 +704,14 @@ struct uv_pipe_s {
UV_HANDLE_FIELDS
UV_STREAM_FIELDS
UV_PIPE_PRIVATE_FIELDS
int ipc; /* non-zero if this pipe is used for passing handles */
};
int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle);
/*
* Initialize a pipe. The last argument is a boolean to indicate if
* this pipe will be used for handle passing between processes.
*/
int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
/*
* Opens an existing file descriptor or HANDLE as a pipe.
@ -807,6 +874,8 @@ struct uv_getaddrinfo_s {
*
* uv_freeaddrinfo() must be called after completion to free the addrinfo
* structure.
*
* On error NXDOMAIN the status code will be non-zero and UV_ENOENT returned.
*/
int uv_getaddrinfo(uv_loop_t*,
uv_getaddrinfo_t* handle,
@ -1003,7 +1072,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
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.
*/
@ -1038,6 +1107,13 @@ struct uv_fs_event_s {
};
/*
* Gets load avg
* See: http://en.wikipedia.org/wiki/Load_(computing)
* (Returns [0,0,0] for windows and cygwin)
*/
void uv_loadavg(double avg[3]);
/*
* If filename is a directory then we will watch for all events in that
* directory. If filename is a file - we will only get events from that
@ -1059,6 +1135,10 @@ int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
/* Gets the executable path */
int uv_exepath(char* buffer, size_t* size);
/* Gets memory info in bytes */
uint64_t uv_get_free_memory(void);
uint64_t uv_get_total_memory(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

View File

@ -1,5 +1,25 @@
Changelog for the c-ares project
Version 1.7.5 (August 16, 2011)
Fixed:
o detection of semicolon comments in resolv.conf
o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory
o replacement ares_inet_net_pton affected by the WLB-2008080064 advisory
o replacement ares_inet_ntop affected by potential out of bounds write
o added install target to Makefile.msvc
o only fall back to AF_INET searches when looking for AF_UNSPEC addresses
o fixed ares_parse_*_reply memory leaks
o Use correct sizeof in ares_getnameinfo()
o IPv6-on-windows: find DNS servers correctly
o man pages: docs for the c-ares utility programs
o getservbyport replacement for Win CE
o config_sortlist: (win32) missing else
o advance_tcp_send_queue: avoid NULL ptr dereference
o configure: fix a bashism
o ares_expand_name: Fix encoded length for indirect root
Version 1.7.4 (December 9, 2010)
Changed:

View File

@ -40,6 +40,30 @@
library version it is using.
How to install using MSVC from the command line
-----------------------------------------------
In order to allow easy usage of c-ares libraries it may be convenient to
install c-ares libraries and header files to a common subdirectory tree.
Once that c-ares libraries have been built using procedure described above,
use same command prompt window to define environment variable INSTALL_DIR
to designate the top subdirectory where installation of c-ares libraries and
header files will be done.
> set INSTALL_DIR=c:\c-ares
Afterwards, run following command to actually perform the installation:
> nmake -f Makefile.msvc install
Installation procedure will copy c-ares libraries to subdirectory 'lib' and
c-ares header files to subdirectory 'include' below the INSTALL_DIR subdir.
When environment variable INSTALL_DIR is not defined, installation is done
to c-ares source folder where Makefile.msvc file is located.
How to build using Visual Studio 6 IDE
--------------------------------------

View File

@ -1,25 +1,26 @@
c-ares version 1.7.4
Changed:
o local-bind: Support binding to local interface/IPs, see
ares_set_local_ip4, ares_set_local_ip6, ares_set_local_dev
c-ares version 1.7.5
Fixed:
o memory leak in ares_getnameinfo
o add missing break that caused get_ares_servers to fail
o ares_parse_a_reply: fix CNAME response parsing
o init_by_options: don't copy an empty sortlist
o Replaced uint32_t with unsigned int to fix broken builds
on a couple of platforms
o Fix lookup with HOSTALIASES set
o adig: fix NAPTR parsing
o compiler warning cleanups
o detection of semicolon comments in resolv.conf
o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory
o replacement ares_inet_net_pton affected by the WLB-2008080064 advisory
o replacement ares_inet_ntop affected by potential out of bounds write
o added install target to Makefile.msvc
o only fall back to AF_INET searches when looking for AF_UNSPEC addresses
o fixed ares_parse_*_reply memory leaks
o Use correct sizeof in ares_getnameinfo()
o IPv6-on-windows: find DNS servers correctly
o man pages: docs for the c-ares utility programs
o getservbyport replacement for Win CE
o config_sortlist: (win32) missing else
o advance_tcp_send_queue: avoid NULL ptr dereference
o configure: fix a bashism
o ares_expand_name: Fix encoded length for indirect root
Thanks go to these friendly people for their efforts and contributions:
Andrew C. Morrow, Ben Greear, Ben Noordhuis, Daniel Stenberg,
Guenter Knauf, Mike Crowe, Patrik Thunstrom, Yang Tse
Yang Tse, Jakub Hrozek, Gisle Vanem, Tom Hughes, David Stuart, Dima Tisnek,
Peter Pentchev, Stefan Buhler
Have fun!

View File

@ -87,7 +87,14 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
* Since this function strips trailing dots though, it becomes ""
*/
q[0] = '\0';
*enclen = 1; /* the caller should move one byte to get past this */
/* indirect root label (like 0xc0 0x0c) is 2 bytes long (stupid, but
valid) */
if ((*encoded & INDIR_MASK) == INDIR_MASK)
*enclen = 2;
else
*enclen = 1; /* the caller should move one byte to get past this */
return ARES_SUCCESS;
}

View File

@ -21,6 +21,7 @@
#endif
#include "ares.h"
#include "ares_nowarn.h"
#include "ares_private.h"
int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds)

View File

@ -28,6 +28,9 @@ void ares_free_hostent(struct hostent *host)
{
char **p;
if (!host)
return;
free((char *)(host->h_name));
for (p = host->h_aliases; *p; p++)
free(*p);

View File

@ -0,0 +1,30 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#include "ares_setup.h"
#include "ares_getenv.h"
#ifndef HAVE_GETENV
char *ares_getenv(const char *name)
{
#ifdef _WIN32_WCE
return NULL;
#endif
}
#endif

View File

@ -0,0 +1,26 @@
#ifndef HEADER_CARES_GETENV_H
#define HEADER_CARES_GETENV_H
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#include "ares_setup.h"
#ifndef HAVE_GETENV
extern char *ares_getenv(const char *name);
#endif
#endif /* HEADER_CARES_GETENV_H */

View File

@ -42,6 +42,7 @@
#include "ares.h"
#include "inet_net_pton.h"
#include "ares_platform.h"
#include "ares_private.h"
#ifdef WATT32
@ -186,7 +187,13 @@ static int file_lookup(struct ares_addr *addr, struct hostent **host)
#ifdef WIN32
char PATH_HOSTS[MAX_PATH];
if (IS_NT()) {
win_platform platform;
PATH_HOSTS[0] = '\0';
platform = ares__getplatform();
if (platform == WIN_NT) {
char tmp[MAX_PATH];
HKEY hkeyHosts;
@ -200,8 +207,10 @@ static int file_lookup(struct ares_addr *addr, struct hostent **host)
RegCloseKey(hkeyHosts);
}
}
else
else if (platform == WIN_9X)
GetWindowsDirectory(PATH_HOSTS, MAX_PATH);
else
return ARES_ENOTFOUND;
strcat(PATH_HOSTS, WIN_PATH_HOSTS);

View File

@ -48,6 +48,7 @@
#include "ares.h"
#include "inet_net_pton.h"
#include "bitncmp.h"
#include "ares_platform.h"
#include "ares_private.h"
#ifdef WATT32
@ -193,11 +194,11 @@ static void host_callback(void *arg, int status, int timeouts,
else if (hquery->sent_family == AF_INET6)
{
status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
if (status == ARES_ENODATA || status == ARES_EBADRESP) {
if ((status == ARES_ENODATA || status == ARES_EBADRESP) &&
hquery->want_family == AF_UNSPEC) {
/* The query returned something but either there were no AAAA
records (e.g. just CNAME) or the response was malformed. Try
looking up A instead. We should possibly limit this
attempt-next logic to AF_UNSPEC lookups only. */
looking up A instead. */
hquery->sent_family = AF_INET;
ares_search(hquery->channel, hquery->name, C_IN, T_A,
host_callback, hquery);
@ -209,11 +210,10 @@ static void host_callback(void *arg, int status, int timeouts,
end_hquery(hquery, status, host);
}
else if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
status == ARES_ETIMEOUT) && hquery->sent_family == AF_INET6)
status == ARES_ETIMEOUT) && (hquery->sent_family == AF_INET6 &&
hquery->want_family == AF_UNSPEC))
{
/* The AAAA query yielded no useful result. Now look up an A instead.
We should possibly limit this attempt-next logic to AF_UNSPEC lookups
only. */
/* The AAAA query yielded no useful result. Now look up an A instead. */
hquery->sent_family = AF_INET;
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
hquery);
@ -344,7 +344,13 @@ static int file_lookup(const char *name, int family, struct hostent **host)
#ifdef WIN32
char PATH_HOSTS[MAX_PATH];
if (IS_NT()) {
win_platform platform;
PATH_HOSTS[0] = '\0';
platform = ares__getplatform();
if (platform == WIN_NT) {
char tmp[MAX_PATH];
HKEY hkeyHosts;
@ -358,8 +364,10 @@ static int file_lookup(const char *name, int family, struct hostent **host)
RegCloseKey(hkeyHosts);
}
}
else
else if (platform == WIN_9X)
GetWindowsDirectory(PATH_HOSTS, MAX_PATH);
else
return ARES_ENOTFOUND;
strcat(PATH_HOSTS, WIN_PATH_HOSTS);

View File

@ -58,6 +58,7 @@
#include "ares.h"
#include "ares_ipv6.h"
#include "inet_ntop.h"
#include "ares_nowarn.h"
#include "ares_private.h"
struct nameinfo_query {
@ -187,7 +188,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
if (sa->sa_family == AF_INET)
{
niquery->family = AF_INET;
memcpy(&niquery->addr.addr4, addr, sizeof(addr));
memcpy(&niquery->addr.addr4, addr, sizeof(struct in_addr));
ares_gethostbyaddr(channel, &addr->sin_addr,
sizeof(struct in_addr), AF_INET,
nameinfo_callback, niquery);
@ -195,7 +196,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
else
{
niquery->family = AF_INET6;
memcpy(&niquery->addr.addr6, addr6, sizeof(addr6));
memcpy(&niquery->addr.addr6, addr6, sizeof(struct ares_in6_addr));
ares_gethostbyaddr(channel, &addr6->sin6_addr,
sizeof(struct ares_in6_addr), AF_INET6,
nameinfo_callback, niquery);

View File

@ -1,6 +1,6 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2007-2010 by Daniel Stenberg
* Copyright (C) 2007-2011 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@ -17,10 +17,6 @@
#include "ares_setup.h"
#ifdef USE_WINSOCK
#include <iphlpapi.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
@ -63,17 +59,19 @@
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
#include "ares.h"
#include "inet_net_pton.h"
#include "ares_library_init.h"
#include "ares_nowarn.h"
#include "ares_private.h"
#ifdef ANDROID
#include <sys/system_properties.h>
#endif
#include "ares.h"
#include "inet_net_pton.h"
#include "ares_library_init.h"
#include "ares_nowarn.h"
#include "ares_platform.h"
#include "inet_ntop.h"
#include "ares_private.h"
#ifdef WATT32
#undef WIN32 /* Redefined in MingW/MSVC headers */
#endif
@ -102,7 +100,7 @@ static int config_lookup(ares_channel channel, const char *str,
const char *bindch, const char *filech);
static int config_sortlist(struct apattern **sortlist, int *nsort,
const char *str);
static char *try_config(char *s, const char *opt);
static char *try_config(char *s, const char *opt, char scc);
#endif
#define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
@ -363,7 +361,7 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
ipv4_nservers++;
}
if (ipv4_nservers) {
options->servers = malloc(ipv4_nservers * sizeof(struct server_state));
options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
if (!options->servers)
return ARES_ENOMEM;
for (i = j = 0; i < channel->nservers; i++)
@ -595,73 +593,198 @@ static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
return 0;
}
/**
* The desired output for this method is that we set "ret_buf" to
* something like:
*
* 192.168.0.1,dns01.my.domain,fe80::200:f8ff:fe21:67cf
*
* The only ordering requirement is that primary servers are listed
* before secondary. There is no requirement that IPv4 addresses should
* necessarily be before IPv6.
*
* Note that ret_size should ideally be big enough to hold around
* 2-3 IPv4 and 2-3 IPv6 addresses.
*
* Finally, we need to return the total number of DNS servers located.
*/
static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
{
FIXED_INFO *fi, *newfi;
DWORD size = sizeof (*fi);
IP_ADDR_STRING *ipAddr;
int i, count = 0;
int debug = 0;
size_t ip_size = sizeof("255.255.255.255,")-1;
size_t left = ret_size;
char *ret = ret_buf;
HRESULT res;
const size_t ipv4_size = INET_ADDRSTRLEN + 1; /* +1 for ',' at end */
const size_t ipv6_size = INET6_ADDRSTRLEN + 12; /* +12 for "%0123456789," at end */
size_t left = ret_size;
char *ret = ret_buf;
int count = 0;
fi = malloc(size);
if (!fi)
return 0;
res = (*ares_fpGetNetworkParams) (fi, &size);
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
goto quit;
newfi = realloc(fi, size);
if (!newfi)
goto quit;
fi = newfi;
res = (*ares_fpGetNetworkParams) (fi, &size);
if (res != ERROR_SUCCESS)
goto quit;
if (debug)
/* Use the GetAdaptersAddresses method if it's available, otherwise
fall back to GetNetworkParams. */
if (ares_fpGetAdaptersAddresses != ZERO_NULL)
{
printf ("Host Name: %s\n", fi->HostName);
printf ("Domain Name: %s\n", fi->DomainName);
printf ("DNS Servers:\n"
" %s (primary)\n", fi->DnsServerList.IpAddress.String);
}
if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
left > ip_size)
{
ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
left -= ret - ret_buf;
count++;
}
const ULONG working_buf_size = 15000;
IP_ADAPTER_ADDRESSES *pFirstEntry = NULL;
IP_ADAPTER_ADDRESSES *pEntry = NULL;
ULONG bufSize = 0;
ULONG result = 0;
for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
ipAddr = ipAddr->Next, i++)
{
if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
/* According to MSDN, the recommended way to do this is to use a temporary
buffer of 15K, to "dramatically reduce the chance that the GetAdaptersAddresses
method returns ERROR_BUFFER_OVERFLOW" */
pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) malloc( working_buf_size );
bufSize = working_buf_size;
if( !pFirstEntry )
return 0;
/* Call the method one time */
result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
if( result == ERROR_BUFFER_OVERFLOW )
{
ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
left -= ret - ret_buf;
count++;
/* Reallocate, bufSize should now be set to the required size */
pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
if( !pFirstEntry )
return 0;
/* Call the method a second time */
result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
if( result == ERROR_BUFFER_OVERFLOW )
{
/* Reallocate, bufSize should now be set to the required size */
pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
if( !pFirstEntry )
return 0;
/* Call the method a third time. The maximum number of times we're going to do
this is 3. Three shall be the number thou shalt count, and the number of the
counting shall be three. Five is right out. */
result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
}
}
if (debug)
printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
/* Check the current result for failure */
if( result != ERROR_SUCCESS )
{
free( pFirstEntry );
return 0;
}
/* process the results */
for( pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next )
{
IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
for( ; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next )
{
struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
size_t stringlen = 0;
if( pGenericAddr->sa_family == AF_INET && left > ipv4_size )
{
/* Handle the v4 case */
struct sockaddr_in *pIPv4Addr = ( struct sockaddr_in * ) pGenericAddr;
ares_inet_ntop( AF_INET, &pIPv4Addr->sin_addr, ret, ipv4_size - 1 ); /* -1 for comma */
/* Append a comma to the end, THEN NULL. Should be OK because we
already tested the size at the top of the if statement. */
stringlen = strlen( ret );
ret[ stringlen ] = ',';
ret[ stringlen + 1 ] = '\0';
ret += stringlen + 1;
left -= ret - ret_buf;
++count;
}
else if( pGenericAddr->sa_family == AF_INET6 && left > ipv6_size )
{
/* Handle the v6 case */
struct sockaddr_in6 *pIPv6Addr = ( struct sockaddr_in6 * ) pGenericAddr;
ares_inet_ntop( AF_INET6, &pIPv6Addr->sin6_addr, ret, ipv6_size - 1 ); /* -1 for comma */
stringlen = strlen( ret );
/* Windows apparently always reports some IPv6 DNS servers that
prefixed with fec0:0:0:ffff. These ususally do not point to
working DNS servers, so we ignore them. */
if (strncmp(ret, "fec0:0:0:ffff:", 14) != 0) {
/* Append a comma to the end, THEN NULL. Should be OK because we
already tested the size at the top of the if statement. */
ret[ stringlen ] = ',';
ret[ stringlen + 1 ] = '\0';
ret += stringlen + 1;
left -= ret - ret_buf;
++count;
}
}
}
}
if( pFirstEntry )
free( pFirstEntry );
if (ret > ret_buf)
ret[-1] = '\0';
return count;
}
else
{
FIXED_INFO *fi, *newfi;
DWORD size = sizeof (*fi);
IP_ADDR_STRING *ipAddr;
int i;
int debug = 0;
HRESULT res;
fi = malloc(size);
if (!fi)
return 0;
res = (*ares_fpGetNetworkParams) (fi, &size);
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
goto quit;
newfi = realloc(fi, size);
if (!newfi)
goto quit;
fi = newfi;
res = (*ares_fpGetNetworkParams) (fi, &size);
if (res != ERROR_SUCCESS)
goto quit;
if (debug)
{
printf ("Host Name: %s\n", fi->HostName);
printf ("Domain Name: %s\n", fi->DomainName);
printf ("DNS Servers:\n"
" %s (primary)\n", fi->DnsServerList.IpAddress.String);
}
if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
left > ipv4_size)
{
ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
left -= ret - ret_buf;
++count;
}
for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
ipAddr = ipAddr->Next, i++)
{
if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
{
ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
left -= ret - ret_buf;
++count;
}
if (debug)
printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
}
quit:
if (fi)
free(fi);
if (fi)
free(fi);
if (debug && left <= ip_size)
printf ("Too many nameservers. Truncating to %d addressess", count);
if (ret > ret_buf)
ret[-1] = '\0';
return count;
if (debug && left <= ipv4_size)
printf ("Too many nameservers. Truncating to %d addressess", count);
if (ret > ret_buf)
ret[-1] = '\0';
return count;
}
}
#endif
@ -704,7 +827,8 @@ DhcpNameServer
DWORD data_type;
DWORD bytes;
DWORD result;
char buf[256];
char buf[512];
win_platform platform;
if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
return ARES_SUCCESS;
@ -716,7 +840,9 @@ DhcpNameServer
goto okay;
}
if (IS_NT())
platform = ares__getplatform();
if (platform == WIN_NT)
{
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
@ -750,7 +876,7 @@ DhcpNameServer
RegCloseKey(mykey);
}
}
else
else if (platform == WIN_9X)
{
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
@ -832,7 +958,10 @@ DhcpNameServer
return ARES_ENOMEM;
for (i = 0; def_nameservers[i]; i++)
servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
{
servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
servers[i].addr.family = AF_INET;
}
status = ARES_EOF;
#elif defined(ANDROID)
@ -856,17 +985,19 @@ DhcpNameServer
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
if ((p = try_config(line, "domain")))
if ((p = try_config(line, "domain", ';')))
status = config_domain(channel, p);
else if ((p = try_config(line, "lookup")) && !channel->lookups)
else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
status = config_lookup(channel, p, "bind", "file");
else if ((p = try_config(line, "search")))
else if ((p = try_config(line, "search", ';')))
status = set_search(channel, p);
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
else if ((p = try_config(line, "nameserver", ';')) &&
channel->nservers == -1)
status = config_nameserver(&servers, &nservers, p);
else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
else if ((p = try_config(line, "sortlist", ';')) &&
channel->nsort == -1)
status = config_sortlist(&sortlist, &nsort, p);
else if ((p = try_config(line, "options")))
else if ((p = try_config(line, "options", ';')))
status = set_options(channel, p);
else
status = ARES_SUCCESS;
@ -896,8 +1027,9 @@ DhcpNameServer
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
if ((p = try_config(line, "hosts:")) && !channel->lookups)
status = config_lookup(channel, p, "dns", "files");
if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
/* ignore errors */
(void)config_lookup(channel, p, "dns", "files");
}
fclose(fp);
}
@ -923,8 +1055,9 @@ DhcpNameServer
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
if ((p = try_config(line, "order")) && !channel->lookups)
status = config_lookup(channel, p, "bind", "hosts");
if ((p = try_config(line, "order", '\0')) && !channel->lookups)
/* ignore errors */
(void)config_lookup(channel, p, "bind", "hosts");
}
fclose(fp);
}
@ -950,8 +1083,9 @@ DhcpNameServer
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
if ((p = try_config(line, "hosts=")) && !channel->lookups)
status = config_lookup(channel, p, "bind", "local");
if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
/* ignore errors */
(void)config_lookup(channel, p, "bind", "local");
}
fclose(fp);
}
@ -1042,10 +1176,13 @@ static int init_by_defaults(ares_channel channel)
channel->nservers = 1;
}
#ifdef ENAMETOOLONG
#define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
#if defined(USE_WINSOCK)
#define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
#elif defined(ENAMETOOLONG)
#define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
(SOCKERRNO == EINVAL))
#else
#define toolong(x) (x == -1) && (EINVAL == errno)
#define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
#endif
if (channel->ndomains == -1) {
@ -1287,9 +1424,9 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
if (!sortlist_alloc(sortlist, nsort, &pat))
return ARES_ENOMEM;
}
if (ipbufpfx[0] &&
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
sizeof(pat.addrV4))) > 0)
else if (ipbufpfx[0] &&
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
sizeof(pat.addrV4))) > 0)
{
pat.type = PATTERN_CIDR;
pat.mask.bits = (unsigned short)bits;
@ -1426,7 +1563,7 @@ static const char *try_option(const char *p, const char *q, const char *opt)
}
#if !defined(WIN32) && !defined(WATT32)
static char *try_config(char *s, const char *opt)
static char *try_config(char *s, const char *opt, char scc)
{
size_t len;
char *p;
@ -1436,10 +1573,17 @@ static char *try_config(char *s, const char *opt)
/* no line or no option */
return NULL;
/* Hash '#' character is always used as primary comment char, additionally
a not-NUL secondary comment char will be considered when specified. */
/* trim line comment */
p = s;
while (*p && (*p != '#'))
p++;
if(scc)
while (*p && (*p != '#') && (*p != scc))
p++;
else
while (*p && (*p != '#'))
p++;
*p = '\0';
/* trim trailing whitespace */

View File

@ -0,0 +1,221 @@
#ifndef HEADER_CARES_IPHLPAPI_H
#define HEADER_CARES_IPHLPAPI_H
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2004 - 2011 by Daniel Stenberg et al
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#if defined(USE_WINSOCK)
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 22
#endif
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 65
#endif
/* ---------------------------------- */
#if !defined(_WS2DEF_) && \
!defined(__CSADDR_DEFINED__) && \
!defined(__CSADDR_T_DEFINED)
/* ---------------------------------- */
typedef struct _SOCKET_ADDRESS {
LPSOCKADDR lpSockaddr;
INT iSockaddrLength;
} SOCKET_ADDRESS, *PSOCKET_ADDRESS;
typedef struct _CSADDR_INFO {
SOCKET_ADDRESS LocalAddr;
SOCKET_ADDRESS RemoteAddr;
INT iSocketType;
INT iProtocol;
} CSADDR_INFO, *PCSADDR_INFO;
/* --------------------------------- */
#endif /* ! _WS2DEF_ && \ */
/* ! __CSADDR_DEFINED__ && \ */
/* ! __CSADDR_T_DEFINED */
/* --------------------------------- */
/* ------------------------------- */
#if !defined(IP_ADAPTER_DDNS_ENABLED)
/* ------------------------------- */
#define IP_ADAPTER_ADDRESS_DNS_ELIGIBLE 0x0001
#define IP_ADAPTER_ADDRESS_TRANSIENT 0x0002
#define IP_ADAPTER_DDNS_ENABLED 0x0001
#define IP_ADAPTER_REGISTER_ADAPTER_SUFFIX 0x0002
#define IP_ADAPTER_DHCP_ENABLED 0x0004
#define IP_ADAPTER_RECEIVE_ONLY 0x0008
#define IP_ADAPTER_NO_MULTICAST 0x0010
#define IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG 0x0020
#define GAA_FLAG_SKIP_UNICAST 0x0001
#define GAA_FLAG_SKIP_ANYCAST 0x0002
#define GAA_FLAG_SKIP_MULTICAST 0x0004
#define GAA_FLAG_SKIP_DNS_SERVER 0x0008
#define GAA_FLAG_INCLUDE_PREFIX 0x0010
#define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020
typedef enum {
IpPrefixOriginOther = 0,
IpPrefixOriginManual,
IpPrefixOriginWellKnown,
IpPrefixOriginDhcp,
IpPrefixOriginRouterAdvertisement
} IP_PREFIX_ORIGIN;
typedef enum {
IpSuffixOriginOther = 0,
IpSuffixOriginManual,
IpSuffixOriginWellKnown,
IpSuffixOriginDhcp,
IpSuffixOriginLinkLayerAddress,
IpSuffixOriginRandom
} IP_SUFFIX_ORIGIN;
typedef enum {
IpDadStateInvalid = 0,
IpDadStateTentative,
IpDadStateDuplicate,
IpDadStateDeprecated,
IpDadStatePreferred
} IP_DAD_STATE;
typedef enum {
IfOperStatusUp = 1,
IfOperStatusDown,
IfOperStatusTesting,
IfOperStatusUnknown,
IfOperStatusDormant,
IfOperStatusNotPresent,
IfOperStatusLowerLayerDown
} IF_OPER_STATUS;
typedef enum {
ScopeLevelInterface = 0x0001,
ScopeLevelLink = 0x0002,
ScopeLevelSubnet = 0x0003,
ScopeLevelAdmin = 0x0004,
ScopeLevelSite = 0x0005,
ScopeLevelOrganization = 0x0008,
ScopeLevelGlobal = 0x000E
} SCOPE_LEVEL;
typedef struct _IP_ADAPTER_UNICAST_ADDRESS {
union {
ULONGLONG Alignment;
struct {
ULONG Length;
DWORD Flags;
} s;
} u;
struct _IP_ADAPTER_UNICAST_ADDRESS *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, *PIP_ADAPTER_UNICAST_ADDRESS;
typedef struct _IP_ADAPTER_ANYCAST_ADDRESS {
union {
ULONGLONG Alignment;
struct {
ULONG Length;
DWORD Flags;
} s;
} u;
struct _IP_ADAPTER_ANYCAST_ADDRESS *Next;
SOCKET_ADDRESS Address;
} IP_ADAPTER_ANYCAST_ADDRESS, *PIP_ADAPTER_ANYCAST_ADDRESS;
typedef struct _IP_ADAPTER_MULTICAST_ADDRESS {
union {
ULONGLONG Alignment;
struct {
ULONG Length;
DWORD Flags;
} s;
} u;
struct _IP_ADAPTER_MULTICAST_ADDRESS *Next;
SOCKET_ADDRESS Address;
} IP_ADAPTER_MULTICAST_ADDRESS, *PIP_ADAPTER_MULTICAST_ADDRESS;
typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS {
union {
ULONGLONG Alignment;
struct {
ULONG Length;
DWORD Reserved;
} s;
} u;
struct _IP_ADAPTER_DNS_SERVER_ADDRESS *Next;
SOCKET_ADDRESS Address;
} IP_ADAPTER_DNS_SERVER_ADDRESS, *PIP_ADAPTER_DNS_SERVER_ADDRESS;
typedef struct _IP_ADAPTER_PREFIX {
union {
ULONGLONG Alignment;
struct {
ULONG Length;
DWORD Flags;
} s;
} u;
struct _IP_ADAPTER_PREFIX *Next;
SOCKET_ADDRESS Address;
ULONG PrefixLength;
} IP_ADAPTER_PREFIX, *PIP_ADAPTER_PREFIX;
typedef struct _IP_ADAPTER_ADDRESSES {
union {
ULONGLONG Alignment;
struct {
ULONG Length;
DWORD IfIndex;
} s;
} u;
struct _IP_ADAPTER_ADDRESSES *Next;
PCHAR AdapterName;
PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress;
PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress;
PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress;
PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
PWCHAR DnsSuffix;
PWCHAR Description;
PWCHAR FriendlyName;
BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD PhysicalAddressLength;
DWORD Flags;
DWORD Mtu;
DWORD IfType;
IF_OPER_STATUS OperStatus;
DWORD Ipv6IfIndex;
DWORD ZoneIndices[16];
PIP_ADAPTER_PREFIX FirstPrefix;
} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;
/* -------------------------------- */
#endif /* ! IP_ADAPTER_DDNS_ENABLED */
/* -------------------------------- */
#endif /* USE_WINSOCK */
#endif /* HEADER_CARES_IPHLPAPI_H */

View File

@ -26,6 +26,7 @@
#ifdef USE_WINSOCK
fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL;
fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL;
fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL;
#endif
/* library-private global vars with source visibility restricted to this file */
@ -56,6 +57,15 @@ static int ares_win32_init(void)
return ARES_EADDRGETNETWORKPARAMS;
}
ares_fpGetAdaptersAddresses = (fpGetAdaptersAddresses_t)
GetProcAddress(hnd_iphlpapi, "GetAdaptersAddresses");
if (!ares_fpGetAdaptersAddresses)
{
/* This can happen on clients before WinXP, I don't
think it should be an error, unless we don't want to
support Windows 2000 anymore */
}
/*
* When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036,
* also known as RtlGenRandom, which is the case for Windows versions prior

View File

@ -3,7 +3,7 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2004-2009 by Daniel Stenberg
* Copyright (C) 2004-2011 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@ -23,15 +23,18 @@
#ifdef USE_WINSOCK
#include <iphlpapi.h>
#include "ares_iphlpapi.h"
typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* );
/* Forward-declaration of variables defined in ares_library_init.c */
/* that are global and unique instances for whole c-ares library. */
extern fpGetNetworkParams_t ares_fpGetNetworkParams;
extern fpSystemFunction036_t ares_fpSystemFunction036;
extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses;
#endif /* USE_WINSOCK */

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2010 by Daniel Stenberg
/* Copyright (C) 2010-2011 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@ -17,13 +17,44 @@
#include "ares_setup.h"
#ifdef HAVE_ASSERT_H
# include <assert.h>
#endif
#if defined(__INTEL_COMPILER) && defined(__unix__)
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#endif /* __INTEL_COMPILER && __unix__ */
#define BUILDING_ARES_NOWARN_C 1
#include "ares_nowarn.h"
#define CARES_MASK_UINT (~(unsigned int) 0)
#define CARES_MASK_SINT (CARES_MASK_UINT >> 1)
#if (SIZEOF_INT == 2)
# define CARES_MASK_SINT 0x7FFF
# define CARES_MASK_UINT 0xFFFF
#elif (SIZEOF_INT == 4)
# define CARES_MASK_SINT 0x7FFFFFFF
# define CARES_MASK_UINT 0xFFFFFFFF
#elif (SIZEOF_INT == 8)
# define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFF
# define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFF
#elif (SIZEOF_INT == 16)
# define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
# define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
#endif
/*
** size_t to signed int
** unsigned size_t to signed int
*/
int aresx_uztosi(size_t uznum)
@ -51,9 +82,100 @@ int aresx_sltosi(long slnum)
# pragma warning(disable:810) /* conversion may lose significant bits */
#endif
DEBUGASSERT(slnum >= 0);
return (int)(slnum & (long) CARES_MASK_SINT);
#ifdef __INTEL_COMPILER
# pragma warning(pop)
#endif
}
/*
** signed ssize_t to signed int
*/
int aresx_sztosi(ssize_t sznum)
{
#ifdef __INTEL_COMPILER
# pragma warning(push)
# pragma warning(disable:810) /* conversion may lose significant bits */
#endif
DEBUGASSERT(sznum >= 0);
return (int)(sznum & (ssize_t) CARES_MASK_SINT);
#ifdef __INTEL_COMPILER
# pragma warning(pop)
#endif
}
/*
** signed ssize_t to unsigned int
*/
unsigned int aresx_sztoui(ssize_t sznum)
{
#ifdef __INTEL_COMPILER
# pragma warning(push)
# pragma warning(disable:810) /* conversion may lose significant bits */
#endif
DEBUGASSERT(sznum >= 0);
return (unsigned int)(sznum & (ssize_t) CARES_MASK_UINT);
#ifdef __INTEL_COMPILER
# pragma warning(pop)
#endif
}
#if defined(__INTEL_COMPILER) && defined(__unix__)
int aresx_FD_ISSET(int fd, fd_set *fdset)
{
#pragma warning(push)
#pragma warning(disable:1469) /* clobber ignored */
return FD_ISSET(fd, fdset);
#pragma warning(pop)
}
void aresx_FD_SET(int fd, fd_set *fdset)
{
#pragma warning(push)
#pragma warning(disable:1469) /* clobber ignored */
FD_SET(fd, fdset);
#pragma warning(pop)
}
void aresx_FD_ZERO(fd_set *fdset)
{
#pragma warning(push)
#pragma warning(disable:593) /* variable was set but never used */
FD_ZERO(fdset);
#pragma warning(pop)
}
unsigned short aresx_htons(unsigned short usnum)
{
#if (__INTEL_COMPILER == 910) && defined(__i386__)
return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
#else
#pragma warning(push)
#pragma warning(disable:810) /* conversion may lose significant bits */
return htons(usnum);
#pragma warning(pop)
#endif
}
unsigned short aresx_ntohs(unsigned short usnum)
{
#if (__INTEL_COMPILER == 910) && defined(__i386__)
return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
#else
#pragma warning(push)
#pragma warning(disable:810) /* conversion may lose significant bits */
return ntohs(usnum);
#pragma warning(pop)
#endif
}
#endif /* __INTEL_COMPILER && __unix__ */

View File

@ -2,7 +2,7 @@
#define HEADER_CARES_NOWARN_H
/* Copyright (C) 2010 by Daniel Stenberg
/* Copyright (C) 2010-2011 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@ -21,4 +21,35 @@ int aresx_uztosi(size_t uznum);
int aresx_sltosi(long slnum);
int aresx_sztosi(ssize_t sznum);
unsigned int aresx_sztoui(ssize_t sznum);
#if defined(__INTEL_COMPILER) && defined(__unix__)
int aresx_FD_ISSET(int fd, fd_set *fdset);
void aresx_FD_SET(int fd, fd_set *fdset);
void aresx_FD_ZERO(fd_set *fdset);
unsigned short aresx_htons(unsigned short usnum);
unsigned short aresx_ntohs(unsigned short usnum);
#ifndef BUILDING_ARES_NOWARN_C
# undef FD_ISSET
# define FD_ISSET(a,b) aresx_FD_ISSET((a),(b))
# undef FD_SET
# define FD_SET(a,b) aresx_FD_SET((a),(b))
# undef FD_ZERO
# define FD_ZERO(a) aresx_FD_ZERO((a))
# undef htons
# define htons(a) aresx_htons((a))
# undef ntohs
# define ntohs(a) aresx_ntohs((a))
#endif
#endif /* __INTEL_COMPILER && __unix__ */
#endif /* HEADER_CARES_NOWARN_H */

View File

@ -1,6 +1,6 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2008-2010 by Daniel Stenberg
* Copyright (C) 2008-2011 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@ -135,12 +135,10 @@ int ares_set_servers(ares_channel channel,
int ares_set_servers_csv(ares_channel channel,
const char* _csv)
{
int i;
size_t i;
char* csv = NULL;
char* ptr;
char* start_host;
long port;
bool found_port;
int rv = ARES_SUCCESS;
struct ares_addr_node *servers = NULL;
struct ares_addr_node *last = NULL;
@ -165,7 +163,6 @@ int ares_set_servers_csv(ares_channel channel,
}
start_host = csv;
found_port = false;
for (ptr = csv; *ptr; ptr++) {
if (*ptr == ',') {
char* pp = ptr - 1;
@ -186,9 +183,8 @@ int ares_set_servers_csv(ares_channel channel,
pp--;
}
if ((pp != start_host) && ((pp + 1) < ptr)) {
/* Found it. */
found_port = true;
port = strtol(pp + 1, NULL, 10);
/* Found it. Parse over the port number */
(void)strtol(pp + 1, NULL, 10);
*pp = 0; /* null terminate host */
}
/* resolve host, try ipv4 first, rslt is in network byte order */
@ -233,7 +229,6 @@ int ares_set_servers_csv(ares_channel channel,
}
/* Set up for next one */
found_port = false;
start_host = ptr + 1;
}
}

View File

@ -132,6 +132,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
aptr += len;
if (aptr + RRFIXEDSZ > abuf + alen)
{
free(rr_name);
status = ARES_EBADRESP;
break;
}
@ -149,6 +150,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
{
if (aptr + sizeof(struct in_addr) > abuf + alen)
{
free(rr_name);
status = ARES_EBADRESP;
break;
}
@ -159,6 +161,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
struct ares_addrttl * const at = &addrttls[naddrs];
if (aptr + sizeof(struct in_addr) > abuf + alen)
{
free(rr_name);
status = ARES_EBADRESP;
break;
}

View File

@ -132,6 +132,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
aptr += len;
if (aptr + RRFIXEDSZ > abuf + alen)
{
free(rr_name);
status = ARES_EBADRESP;
break;
}
@ -149,6 +150,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
{
if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
{
free(rr_name);
status = ARES_EBADRESP;
break;
}
@ -159,6 +161,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
struct ares_addr6ttl * const at = &addrttls[naddrs];
if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
{
free(rr_name);
status = ARES_EBADRESP;
break;
}

View File

@ -47,7 +47,7 @@
int
ares_parse_mx_reply (const unsigned char *abuf, int alen,
struct ares_mx_reply **mx_out)
struct ares_mx_reply **mx_out)
{
unsigned int qdcount, ancount, i;
const unsigned char *aptr, *vptr;
@ -134,7 +134,7 @@ ares_parse_mx_reply (const unsigned char *abuf, int alen,
mx_last = mx_curr;
vptr = aptr;
mx_curr->priority = ntohs (*((unsigned short *)vptr));
mx_curr->priority = DNS__16BIT(vptr);
vptr += sizeof(unsigned short);
status = ares_expand_name (vptr, abuf, alen, &mx_curr->host, &len);

View File

@ -1,5 +1,3 @@
/* $Id */
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
@ -105,6 +103,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
if ( aptr + RRFIXEDSZ > abuf + alen )
{
status = ARES_EBADRESP;
free(rr_name);
break;
}
rr_type = DNS_RR_TYPE( aptr );
@ -119,6 +118,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
&len);
if ( status != ARES_SUCCESS )
{
free(rr_name);
break;
}

View File

@ -99,6 +99,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
aptr += len;
if (aptr + RRFIXEDSZ > abuf + alen)
{
free(rr_name);
status = ARES_EBADRESP;
break;
}
@ -114,13 +115,17 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len);
if (status != ARES_SUCCESS)
break;
{
free(rr_name);
break;
}
if (hostname)
free(hostname);
hostname = rr_data;
aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char *));
aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char));
if (!aliases[aliascnt])
{
free(rr_name);
status = ARES_ENOMEM;
break;
}
@ -131,6 +136,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
alias_alloc *= 2;
ptr = realloc(aliases, alias_alloc * sizeof(char *));
if(!ptr) {
free(rr_name);
status = ARES_ENOMEM;
break;
}
@ -144,7 +150,10 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len);
if (status != ARES_SUCCESS)
break;
{
free(rr_name);
break;
}
free(ptrname);
ptrname = rr_data;
}

View File

@ -139,11 +139,11 @@ ares_parse_srv_reply (const unsigned char *abuf, int alen,
srv_last = srv_curr;
vptr = aptr;
srv_curr->priority = ntohs (*((unsigned short *)vptr));
srv_curr->priority = DNS__16BIT(vptr);
vptr += sizeof(unsigned short);
srv_curr->weight = ntohs (*((unsigned short *)vptr));
srv_curr->weight = DNS__16BIT(vptr);
vptr += sizeof(unsigned short);
srv_curr->port = ntohs (*((unsigned short *)vptr));
srv_curr->port = DNS__16BIT(vptr);
vptr += sizeof(unsigned short);
status = ares_expand_name (vptr, abuf, alen, &srv_curr->host, &len);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
#ifndef HEADER_CARES_PLATFORM_H
#define HEADER_CARES_PLATFORM_H
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2004 - 2011 by Daniel Stenberg et al
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#include "ares_setup.h"
#if defined(WIN32) && !defined(MSDOS)
typedef enum {
WIN_UNKNOWN,
WIN_3X,
WIN_9X,
WIN_NT,
WIN_CE
} win_platform;
win_platform ares__getplatform(void);
#endif
#if defined(_WIN32_WCE)
struct servent *getservbyport(int port, const char *proto);
#endif
#endif /* HEADER_CARES_PLATFORM_H */

View File

@ -52,7 +52,6 @@
#if defined(WIN32) && !defined(WATT32)
#define IS_NT() ((int)GetVersion() > 0)
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
#define NAMESERVER "NameServer"
@ -89,6 +88,11 @@
#include "ares_ipv6.h"
#include "ares_llist.h"
#ifndef HAVE_GETENV
# include "ares_getenv.h"
# define getenv(ptr) ares_getenv(ptr)
#endif
#ifndef HAVE_STRDUP
# include "ares_strdup.h"
# define strdup(ptr) ares_strdup(ptr)
@ -199,7 +203,7 @@ struct query {
void *arg;
/* Query status */
int try; /* Number of times we tried this query already. */
int try_count; /* Number of times we tried this query already. */
int server; /* Server this query has last been sent to. */
struct query_server_info *server_info; /* per-server state */
int using_tcp;

View File

@ -63,10 +63,10 @@
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include "ares.h"
#include "ares_dns.h"
#include "ares_nowarn.h"
#include "ares_private.h"
@ -300,29 +300,28 @@ static void advance_tcp_send_queue(ares_channel channel, int whichserver,
{
struct send_request *sendreq;
struct server_state *server = &channel->servers[whichserver];
while (num_bytes > 0)
{
sendreq = server->qhead;
if ((size_t)num_bytes >= sendreq->len)
{
num_bytes -= sendreq->len;
server->qhead = sendreq->next;
if (server->qhead == NULL)
{
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
server->qtail = NULL;
}
if (sendreq->data_storage != NULL)
free(sendreq->data_storage);
free(sendreq);
}
else
{
sendreq->data += num_bytes;
sendreq->len -= num_bytes;
num_bytes = 0;
}
while (num_bytes > 0) {
sendreq = server->qhead;
if ((size_t)num_bytes >= sendreq->len) {
num_bytes -= sendreq->len;
server->qhead = sendreq->next;
if (sendreq->data_storage)
free(sendreq->data_storage);
free(sendreq);
if (server->qhead == NULL) {
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
server->qtail = NULL;
/* qhead is NULL so we cannot continue this loop */
break;
}
}
else {
sendreq->data += num_bytes;
sendreq->len -= num_bytes;
num_bytes = 0;
}
}
}
/* If any TCP socket selects true for reading, read some data,
@ -686,7 +685,7 @@ static void next_server(ares_channel channel, struct query *query,
* servers to try. In total, we need to do channel->nservers * channel->tries
* attempts. Use query->try to remember how many times we already attempted
* this query. Use modular arithmetic to find the next server to try. */
while (++(query->try) < (channel->nservers * channel->tries))
while (++(query->try_count) < (channel->nservers * channel->tries))
{
struct server_state *server;
@ -791,7 +790,7 @@ void ares__send_query(ares_channel channel, struct query *query,
return;
}
}
timeplus = channel->timeout << (query->try / channel->nservers);
timeplus = channel->timeout << (query->try_count / channel->nservers);
timeplus = (timeplus * (9 + (rand () & 7))) / 16;
query->timeout = *now;
ares__timeadd(&query->timeout,

View File

@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
@ -292,7 +291,7 @@ static int single_domain(ares_channel channel, const char *name, char **s)
}
else
{
error = errno;
error = ERRNO;
switch(error)
{
case ENOENT:

View File

@ -96,7 +96,7 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
query->arg = arg;
/* Initialize query status. */
query->try = 0;
query->try_count = 0;
/* Choose the server to send the query to. If rotation is enabled, keep track
* of the next server we want to use. */

View File

@ -1,7 +1,6 @@
#ifndef HEADER_CARES_SETUP_H
#define HEADER_CARES_SETUP_H
/* $Id$ */
/* Copyright (C) 2004 - 2009 by Daniel Stenberg et al
*
@ -31,6 +30,12 @@
#ifdef HAVE_CONFIG_H
#include "ares_config.h"
#else
#ifdef WIN32
#include "config-win32.h"
#endif
#endif /* HAVE_CONFIG_H */
/* ================================================================ */
@ -70,7 +75,7 @@
/* please, do it beyond the point further indicated in this file. */
/* ================================================================ */
#if 0 /* libuv disabled */
#if 0 /* libuv hack */
/*
* c-ares external interface definitions are also used internally,
* and might also include required system header files to define them.
@ -83,7 +88,7 @@
*/
#include <ares_rules.h>
#endif
#endif /* libuv hack */
/* ================================================================= */
/* No system header file shall be included in this file before this */
@ -102,6 +107,10 @@
*/
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# ifdef HAVE_WS2TCPIP_H
@ -112,7 +121,6 @@
# include <winsock.h>
# endif
# endif
# include <windows.h>
#endif
/*

View File

@ -508,3 +508,5 @@
/* the signed version of size_t */
/* #undef ssize_t */
#define HAVE_GETENV 1

View File

@ -508,3 +508,5 @@
/* the signed version of size_t */
/* #undef ssize_t */
#define HAVE_GETENV 1

View File

@ -508,3 +508,5 @@
/* the signed version of size_t */
/* #undef ssize_t */
#define HAVE_GETENV 1

View File

@ -508,3 +508,5 @@
/* the signed version of size_t */
/* #undef ssize_t */
#define HAVE_GETENV 1

View File

@ -508,3 +508,5 @@
/* the signed version of size_t */
/* #undef ssize_t */
#define HAVE_GETENV 1

View File

@ -508,3 +508,5 @@
/* the signed version of size_t */
/* #undef ssize_t */
#define HAVE_GETENV 1

View File

@ -508,3 +508,5 @@
/* the signed version of size_t */
/* #undef ssize_t */
#define HAVE_GETENV 1

View File

@ -108,6 +108,9 @@
/* Define if you have the strcasecmp function. */
/* #define HAVE_STRCASECMP 1 */
/* Define if you have the getenv function. */
#define HAVE_GETENV 1
/* Define if you have the strdup function. */
#define HAVE_STRDUP 1

View File

@ -37,20 +37,20 @@
#endif
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ares.h"
#include "ares_ipv6.h"
#include "ares_nowarn.h"
#include "inet_net_pton.h"
const struct ares_in6_addr ares_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
#if !defined(HAVE_INET_NET_PTON) || !defined(HAVE_INET_NET_PTON_IPV6)
#ifndef HAVE_INET_NET_PTON
/*
* static int
@ -83,16 +83,17 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
&& ISASCII(src[1])
&& ISXDIGIT(src[1])) {
/* Hexadecimal: Eat nybble string. */
if (!size)
goto emsgsize;
dirty = 0;
src++; /* skip x or X. */
while ((ch = *src++) != '\0' && ISXDIGIT(ch)) {
while ((ch = *src++) != '\0' && ISASCII(ch) && ISXDIGIT(ch)) {
if (ISUPPER(ch))
ch = tolower(ch);
n = (int)(strchr(xdigits, ch) - xdigits);
n = aresx_sztosi(strchr(xdigits, ch) - xdigits);
if (dirty == 0)
tmp = n;
else
@ -109,18 +110,18 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
goto emsgsize;
*dst++ = (unsigned char) (tmp << 4);
}
} else if (ISDIGIT(ch)) {
} else if (ISASCII(ch) && ISDIGIT(ch)) {
/* Decimal: eat dotted digit string. */
for (;;) {
tmp = 0;
do {
n = (int)(strchr(digits, ch) - digits);
n = aresx_sztosi(strchr(digits, ch) - digits);
tmp *= 10;
tmp += n;
if (tmp > 255)
goto enoent;
} while ((ch = *src++) != '\0' &&
ISDIGIT(ch));
ISASCII(ch) && ISDIGIT(ch));
if (!size--)
goto emsgsize;
*dst++ = (unsigned char) tmp;
@ -129,27 +130,27 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
if (ch != '.')
goto enoent;
ch = *src++;
if (!ISDIGIT(ch))
if (!ISASCII(ch) || !ISDIGIT(ch))
goto enoent;
}
} else
goto enoent;
bits = -1;
if (ch == '/' &&
if (ch == '/' && ISASCII(src[0]) &&
ISDIGIT(src[0]) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */
ch = *src++; /* Skip over the /. */
bits = 0;
do {
n = (int)(strchr(digits, ch) - digits);
n = aresx_sztosi(strchr(digits, ch) - digits);
bits *= 10;
bits += n;
} while ((ch = *src++) != '\0' && ISDIGIT(ch));
if (bits > 32)
goto enoent;
} while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch));
if (ch != '\0')
goto enoent;
if (bits > 32)
goto emsgsize;
}
/* Firey death and destruction unless we prefetched EOS. */
@ -173,7 +174,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
bits = 8;
/* If imputed mask is narrower than specified octets, widen. */
if (bits < ((dst - odst) * 8))
bits = (int)(dst - odst) * 8;
bits = aresx_sztosi(dst - odst) * 8;
/*
* If there are no additional bits specified for a class D
* address adjust bits to 4.
@ -216,7 +217,7 @@ getbits(const char *src, int *bitsp)
if (n++ != 0 && val == 0) /* no leading zeros */
return (0);
val *= 10;
val += (pch - digits);
val += aresx_sztosi(pch - digits);
if (val > 128) /* range */
return (0);
continue;
@ -248,7 +249,7 @@ getv4(const char *src, unsigned char *dst, int *bitsp)
if (n++ != 0 && val == 0) /* no leading zeros */
return (0);
val *= 10;
val += (pch - digits);
val += aresx_sztoui(pch - digits);
if (val > 255) /* range */
return (0);
continue;
@ -269,8 +270,8 @@ getv4(const char *src, unsigned char *dst, int *bitsp)
return (0);
if (dst - odst > 3) /* too many octets? */
return (0);
*dst++ = (unsigned char)val;
return (1);
*dst = (unsigned char)val;
return 1;
}
static int
@ -308,7 +309,7 @@ inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
val |= aresx_sztoui(pch - xdigits);
if (++digits > 4)
goto enoent;
saw_xdigit = 1;
@ -425,7 +426,7 @@ ares_inet_net_pton(int af, const char *src, void *dst, size_t size)
}
}
#endif
#endif /* HAVE_INET_NET_PTON */
#ifndef HAVE_INET_PTON
int ares_inet_pton(int af, const char *src, void *dst)

View File

@ -1,8 +1,7 @@
#ifndef __ARES_INET_NET_PTON_H
#define __ARES_INET_NET_PTON_H
#ifndef HEADER_CARES_INET_NET_PTON_H
#define HEADER_CARES_INET_NET_PTON_H
/* Copyright (C) 2005 by Daniel Stenberg
/* Copyright (C) 2005-2010 by Daniel Stenberg et al
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@ -22,10 +21,11 @@
#else
int ares_inet_pton(int af, const char *src, void *dst);
#endif
#if defined(HAVE_INET_NET_PTON) && defined(HAVE_INET_NET_PTON_IPV6)
#ifdef HAVE_INET_NET_PTON
#define ares_inet_net_pton(w,x,y,z) inet_net_pton(w,x,y,z)
#else
int ares_inet_net_pton(int af, const char *src, void *dst, size_t size);
#endif
#endif /* __ARES_INET_NET_PTON_H */
#endif /* HEADER_CARES_INET_NET_PTON_H */

View File

@ -1,18 +1,18 @@
/* Copyright (c) 1996 by Internet Software Consortium.
/*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
* 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 "ares_setup.h"
@ -36,7 +36,6 @@
#endif
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -48,12 +47,6 @@
#ifndef HAVE_INET_NTOP
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
@ -68,32 +61,31 @@ static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size);
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* note:
* On Windows we store the error in the thread errno, not
* in the winsock error code. This is to avoid loosing the
* actual last winsock error. So use macro ERRNO to fetch the
* errno this funtion sets when returning NULL, not SOCKERRNO.
* On Windows we store the error in the thread errno, not
* in the winsock error code. This is to avoid loosing the
* actual last winsock error. So use macro ERRNO to fetch the
* errno this funtion sets when returning NULL, not SOCKERRNO.
* author:
* Paul Vixie, 1996.
*/
const char *
ares_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:
SET_ERRNO(EAFNOSUPPORT);
return (NULL);
}
switch (af) {
case AF_INET:
return (inet_ntop4(src, dst, size));
case AF_INET6:
return (inet_ntop6(src, dst, size));
default:
SET_ERRNO(EAFNOSUPPORT);
return (NULL);
}
/* NOTREACHED */
}
/* const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address, more or less like inet_ntoa()
* format an IPv4 address
* return:
* `dst' (as a const)
* notes:
@ -106,22 +98,21 @@ static const char *
inet_ntop4(const unsigned char *src, char *dst, size_t size)
{
static const char fmt[] = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
char tmp[sizeof("255.255.255.255")];
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size)
{
SET_ERRNO(ENOSPC);
return (NULL);
}
strcpy(dst, tmp);
return (dst);
if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size) {
SET_ERRNO(ENOSPC);
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(const unsigned char *src, char *dst, size_t size)
@ -135,11 +126,8 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
*/
char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
char *tp;
struct {
long base;
long len;
} best, cur;
unsigned long words[NS_IN6ADDRSZ / NS_INT16SZ];
struct { int base, len; } best, cur;
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
int i;
/*
@ -149,37 +137,29 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
*/
memset(words, '\0', sizeof(words));
for (i = 0; i < NS_IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
best.len = 0;
cur.base = -1;
cur.len = 0;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
{
if (words[i] == 0)
{
if (cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
}
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
if (words[i] == 0) {
if (cur.base == -1)
cur.base = i, cur.len = 1;
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;
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;
@ -187,46 +167,42 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
* Format the result.
*/
tp = tmp;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); 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)
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); 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++ = ':';
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
{
if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
return (NULL);
tp += strlen(tp);
break;
}
tp += SPRINTF((tp, "%lx", words[i]));
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))) {
if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
return (NULL);
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) == (NS_IN6ADDRSZ / NS_INT16SZ))
if (best.base != -1 && (best.base + best.len) ==
(NS_IN6ADDRSZ / NS_INT16SZ))
*tp++ = ':';
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((size_t)(tp - tmp) > size)
{
SET_ERRNO(ENOSPC);
return (NULL);
}
if ((size_t)(tp - tmp) > size) {
SET_ERRNO(ENOSPC);
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
#endif

View File

@ -18,7 +18,6 @@
*/
#ifdef HAVE_INET_NTOP
#include <arpa/inet.h>
#define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z)
#else
const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size);

View File

@ -75,6 +75,11 @@ typedef enum __ns_type {
ns_t_sink = 40, /* Kitchen sink (experimentatl) */
ns_t_opt = 41, /* EDNS0 option (meta-RR) */
ns_t_apl = 42, /* Address prefix list (RFC3123) */
ns_t_ds = 43, /* Delegation Signer (RFC4034) */
ns_t_sshfp = 44, /* SSH Key Fingerprint (RFC4255) */
ns_t_rrsig = 46, /* Resource Record Signature (RFC4034) */
ns_t_nsec = 47, /* Next Secure (RFC4034) */
ns_t_dnskey = 48, /* DNS Public Key (RFC4034) */
ns_t_tkey = 249, /* Transaction key */
ns_t_tsig = 250, /* Transaction signature. */
ns_t_ixfr = 251, /* Incremental zone transfer. */
@ -181,6 +186,11 @@ typedef enum __ns_rcode {
#define T_SRV ns_t_srv
#define T_ATMA ns_t_atma
#define T_NAPTR ns_t_naptr
#define T_DS ns_t_ds
#define T_SSHFP ns_t_sshfp
#define T_RRSIG ns_t_rrsig
#define T_NSEC ns_t_nsec
#define T_DNSKEY ns_t_dnskey
#define T_TSIG ns_t_tsig
#define T_IXFR ns_t_ixfr
#define T_AXFR ns_t_axfr

View File

@ -2,7 +2,7 @@
#define __SETUP_ONCE_H
/* Copyright (C) 2004 - 2010 by Daniel Stenberg et al
/* Copyright (C) 2004 - 2011 by Daniel Stenberg et al
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
@ -35,7 +35,10 @@
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@ -248,6 +251,7 @@ struct timeval {
#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
#define ISLOWER(x) (islower((int) ((unsigned char)x)))
#define ISASCII(x) (isascii((int) ((unsigned char)x)))
#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \
(((unsigned char)x) == '\t'))
@ -366,7 +370,7 @@ typedef int sig_atomic_t;
* (or equivalent) on this platform to hide platform details to code using it.
*/
#ifdef WIN32
#if defined(WIN32) && !defined(WATT32)
#define ERRNO ((int)GetLastError())
#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
#else
@ -455,6 +459,18 @@ typedef int sig_atomic_t;
#endif
/*
* System error codes for Windows CE
*/
#if defined(WIN32) && !defined(HAVE_ERRNO_H)
#define ENOENT ERROR_FILE_NOT_FOUND
#define ESRCH ERROR_PATH_NOT_FOUND
#define ENOMEM ERROR_NOT_ENOUGH_MEMORY
#define ENOSPC ERROR_INVALID_PARAMETER
#endif
/*
* Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid()
*/

View File

@ -67,6 +67,7 @@ static uv_ares_task_t* uv__ares_task_create(int fd) {
if (h == NULL) {
uv_fatal_error(ENOMEM, "malloc");
return NULL;
}
h->sock = fd;
@ -146,7 +147,7 @@ int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
/* only allow single init at a time */
if (loop->channel != NULL) {
uv_err_new_artificial(loop, UV_EALREADY);
uv__set_artificial_error(loop, UV_EALREADY);
return -1;
}

View File

@ -172,7 +172,7 @@ void uv_loop_delete(uv_loop_t* loop) {
uv_loop_t* uv_default_loop() {
if (!default_loop_ptr) {
default_loop_ptr = &default_loop_struct;
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
#if HAVE_KQUEUE
default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE);
#else
default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO);
@ -563,7 +563,7 @@ int uv_timer_stop(uv_timer_t* timer) {
int uv_timer_again(uv_timer_t* timer) {
if (!ev_is_active(&timer->timer_watcher)) {
uv_err_new(timer->loop, EINVAL);
uv__set_sys_error(timer->loop, EINVAL);
return -1;
}
@ -595,7 +595,7 @@ static int uv_getaddrinfo_done(eio_req* req) {
if (handle->retcode != 0) {
/* TODO how to display gai error strings? */
uv_err_new(handle->loop, handle->retcode);
uv__set_sys_error(handle->loop, handle->retcode);
}
handle->cb(handle, handle->retcode, res);
@ -626,7 +626,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
if (handle == NULL || cb == NULL ||
(hostname == NULL && service == NULL)) {
uv_err_new_artificial(loop, UV_EINVAL);
uv__set_artificial_error(loop, UV_EINVAL);
return -1;
}
@ -639,7 +639,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
if (hints) {
handle->hints = malloc(sizeof(struct addrinfo));
memcpy(&handle->hints, hints, sizeof(struct addrinfo));
memcpy(handle->hints, hints, sizeof(struct addrinfo));
}
else {
handle->hints = NULL;
@ -667,7 +667,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
void uv_freeaddrinfo(struct addrinfo* ai) {
freeaddrinfo(ai);
if (ai)
freeaddrinfo(ai);
}
@ -790,10 +791,3 @@ size_t uv__strlcpy(char* dst, const char* src, size_t size) {
return src - org;
}
uv_stream_t* uv_std_handle(uv_loop_t* loop, uv_std_type type) {
assert(0 && "implement me");
return NULL;
}

View File

@ -36,6 +36,11 @@ uint64_t uv_hrtime() {
return (ts.tv_sec * NANOSEC + ts.tv_nsec);
}
void uv_loadavg(double avg[3]) {
/* Unsupported as of cygwin 1.7.7 */
avg[0] = avg[1] = avg[2] = 0;
}
int uv_exepath(char* buffer, size_t* size) {
uint32_t usize;
@ -53,12 +58,19 @@ int uv_exepath(char* buffer, size_t* size) {
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_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv_err_new(loop, ENOSYS);
uv__set_sys_error(loop, ENOSYS);
return -1;
}

View File

@ -29,6 +29,9 @@
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <unistd.h> /* sysconf */
uint64_t uv_hrtime() {
@ -68,16 +71,38 @@ int uv_exepath(char* buffer, size_t* size) {
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);
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv_err_new(loop, ENOSYS);
return -1;
if (host_statistics(mach_host_self(), HOST_VM_INFO,
(host_info_t)&info, &count) != KERN_SUCCESS) {
return -1;
}
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);
void uv__fs_event_destroy(uv_fs_event_t* handle) {
assert(0 && "implement me");
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
return -1;
}
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;
}

View File

@ -0,0 +1,137 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* fallocate(2) is available */
/* #undef HAVE_FALLOCATE */
/* fdatasync(2) is available */
/* #undef HAVE_FDATASYNC */
/* futimes(2) is available */
#define HAVE_FUTIMES 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* posix_fadvise(2) is available */
/* #undef HAVE_POSIX_FADVISE */
/* posix_madvise(2) is available */
#define HAVE_POSIX_MADVISE 1
/* prctl(PR_SET_NAME) is available */
/* #undef HAVE_PRCTL_SET_NAME */
/* pread(2) and pwrite(2) are available */
#define HAVE_PREADWRITE 1
/* readahead(2) is available (linux) */
/* #undef HAVE_READAHEAD */
/* sendfile(2) is available and supported */
/* #undef HAVE_SENDFILE */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* sync_file_range(2) is available */
/* #undef HAVE_SYNC_FILE_RANGE */
/* Define to 1 if you have the <sys/prctl.h> header file. */
/* #undef HAVE_SYS_PRCTL_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* syscall(__NR_syncfs) is available */
/* #undef HAVE_SYS_SYNCFS */
/* Define to 1 if you have the <sys/syscall.h> header file. */
#define HAVE_SYS_SYSCALL_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* utimes(2) is available */
#define HAVE_UTIMES 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libeio"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Version number of package */
#define VERSION "1.0"
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */

View File

@ -11,7 +11,7 @@
#define HAVE_UTIMES 1
/* futimes(2) is available */
/* #undef HAVE_FUTIMES */
#define HAVE_FUTIMES 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

View File

@ -108,6 +108,10 @@ static void eio_destroy (eio_req *req);
#define EIO_ENOSYS() EIO_ERRNO (ENOSYS, -1)
#ifdef __sun
# define futimes(fd, times) futimesat (fd, NULL, times)
#endif
#ifdef _WIN32
#include <direct.h>

View File

@ -56,19 +56,37 @@ void uv_fatal_error(const int errorno, const char* syscall) {
}
uv_err_t uv_last_error(uv_loop_t* loop) {
return loop->last_err;
}
static int uv__translate_lib_error(int code) {
switch (code) {
case UV_ENOSYS: return ENOSYS;
case UV_ENOENT: return ENOENT;
case UV_EACCESS: return EACCES;
case UV_EBADF: return EBADF;
case UV_EPIPE: return EPIPE;
case UV_EAGAIN: return EAGAIN;
case UV_ECONNRESET: return ECONNRESET;
case UV_EFAULT: return EFAULT;
case UV_EMFILE: return EMFILE;
case UV_EMSGSIZE: return EMSGSIZE;
case UV_EINVAL: return EINVAL;
case UV_ECONNREFUSED: return ECONNREFUSED;
case UV_EADDRINUSE: return EADDRINUSE;
case UV_EADDRNOTAVAIL: return EADDRNOTAVAIL;
case UV_ENOTDIR: return ENOTDIR;
case UV_ENOTCONN: return ENOTCONN;
case UV_EEXIST: return EEXIST;
default: return -1;
}
char* uv_strerror(uv_err_t err) {
return strerror(err.sys_errno_);
assert(0 && "unreachable");
return -1;
}
uv_err_code uv_translate_sys_error(int sys_errno) {
switch (sys_errno) {
case 0: return UV_OK;
case ENOSYS: return UV_ENOSYS;
case ENOENT: return UV_ENOENT;
case EACCES: return UV_EACCESS;
case EBADF: return UV_EBADF;
@ -82,8 +100,10 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ECONNREFUSED: return UV_ECONNREFUSED;
case EADDRINUSE: return UV_EADDRINUSE;
case EADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
case ENOTDIR: return UV_ENOTDIR;
case ENOTCONN: return UV_ENOTCONN;
case EEXIST: return UV_EEXIST;
case EAI_NONAME: return UV_ENOENT;
default: return UV_UNKNOWN;
}
@ -92,19 +112,20 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
}
uv_err_t uv_err_new_artificial(uv_loop_t* loop, int code) {
uv_err_t err;
err.sys_errno_ = 0;
err.code = code;
loop->last_err = err;
return err;
}
/* TODO Pull in error messages so we don't have to
* a) rely on what the system provides us
* b) reverse-map the error codes
*/
char* uv_strerror(uv_err_t err) {
int errorno;
if (err.sys_errno_)
errorno = err.sys_errno_;
else
errorno = uv__translate_lib_error(err.code);
uv_err_t uv_err_new(uv_loop_t* loop, int sys_error) {
uv_err_t err;
err.sys_errno_ = sys_error;
err.code = uv_translate_sys_error(sys_error);
loop->last_err = err;
return err;
if (errorno == -1)
return "Unknown error";
else
return strerror(errorno);
}

View File

@ -0,0 +1,126 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `clock_gettime' function. */
#define HAVE_CLOCK_GETTIME 1
/* "use syscall interface for clock_gettime" */
/* #undef HAVE_CLOCK_SYSCALL */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `epoll_ctl' function. */
/* #undef HAVE_EPOLL_CTL */
/* Define to 1 if you have the `eventfd' function. */
/* #undef HAVE_EVENTFD */
/* Define to 1 if you have the `inotify_init' function. */
/* #undef HAVE_INOTIFY_INIT */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `kqueue' function. */
#define HAVE_KQUEUE 1
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define to 1 if you have the `rt' library (-lrt). */
/* #undef HAVE_LIBRT */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `nanosleep' function. */
#define HAVE_NANOSLEEP 1
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
/* Define to 1 if you have the <poll.h> header file. */
#define HAVE_POLL_H 1
/* Define to 1 if you have the `port_create' function. */
/* #undef HAVE_PORT_CREATE */
/* Define to 1 if you have the <port.h> header file. */
/* #undef HAVE_PORT_H */
/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1
/* Define to 1 if you have the `signalfd' function. */
/* #undef HAVE_SIGNALFD */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/epoll.h> header file. */
/* #undef HAVE_SYS_EPOLL_H */
/* Define to 1 if you have the <sys/eventfd.h> header file. */
/* #undef HAVE_SYS_EVENTFD_H */
/* Define to 1 if you have the <sys/event.h> header file. */
#define HAVE_SYS_EVENT_H 1
/* Define to 1 if you have the <sys/inotify.h> header file. */
/* #undef HAVE_SYS_INOTIFY_H */
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/signalfd.h> header file. */
/* #undef HAVE_SYS_SIGNALFD_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libev"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "4.04"

View File

@ -2663,7 +2663,8 @@ ev_io_start (EV_P_ ev_io *w)
return;
assert (("libev: ev_io_start called with negative fd", fd >= 0));
assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
assert (("libev: ev_io_start called with illegal event mask",
!(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE | EV_LIBUV_KQUEUE_HACK))));
EV_FREQUENT_CHECK;

View File

@ -43,6 +43,9 @@
#include <string.h>
#include <errno.h>
extern void
uv__kqueue_hack (EV_P_ int fflags, ev_io *w);
void inline_speed
kqueue_change (EV_P_ int fd, int filter, int flags, int fflags)
{
@ -80,6 +83,10 @@ kqueue_modify (EV_P_ int fd, int oev, int nev)
if (nev & EV_WRITE)
kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, NOTE_EOF);
if (nev & EV_LIBUV_KQUEUE_HACK)
kqueue_change (EV_A_ fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE);
}
static void
@ -114,6 +121,13 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
{
int fd = kqueue_events [i].ident;
if (kqueue_events [i].filter == EVFILT_VNODE)
{
/* pass kqueue filter flags to libuv */
ev_io *w = (ev_io *)(anfds [fd].head);
uv__kqueue_hack (EV_A_ kqueue_events [i].fflags, w);
}
if (expect_false (kqueue_events [i].flags & EV_ERROR))
{
int err = kqueue_events [i].data;
@ -140,6 +154,7 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
fd,
kqueue_events [i].filter == EVFILT_READ ? EV_READ
: kqueue_events [i].filter == EVFILT_WRITE ? EV_WRITE
: kqueue_events [i].filter == EVFILT_VNODE ? EV_LIBUV_KQUEUE_HACK
: 0
);
}

View File

@ -25,8 +25,11 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <vm/vm_param.h> /* VM_LOADAVG */
#include <time.h>
#include <unistd.h> /* sysconf */
#undef NANOSEC
#define NANOSEC 1000000000
@ -67,16 +70,39 @@ int uv_exepath(char* buffer, size_t* size) {
return 0;
}
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) == -1){
return -1;
}
return (uint64_t) freecount * sysconf(_SC_PAGESIZE);
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv_err_new(loop, ENOSYS);
return -1;
}
uint64_t uv_get_total_memory(void) {
unsigned long info;
int which[] = {CTL_HW, HW_PHYSMEM};
void uv__fs_event_destroy(uv_fs_event_t* handle) {
assert(0 && "implement me");
size_t size = sizeof(info);
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
return -1;
}
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;
}

View File

@ -46,7 +46,7 @@
/* async */ \
req->eio = eiofunc(args, EIO_PRI_DEFAULT, uv__fs_after, req); \
if (!req->eio) { \
uv_err_new(loop, ENOMEM); \
uv__set_sys_error(loop, ENOMEM); \
return -1; \
} \
uv_ref(loop); \
@ -54,7 +54,7 @@
/* sync */ \
req->result = func(args); \
if (req->result) { \
uv_err_new(loop, errno); \
uv__set_sys_error(loop, errno); \
} \
return req->result; \
} \
@ -85,8 +85,7 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
switch (req->fs_type) {
case UV_FS_READDIR:
assert((req->result == -1 && req->ptr == NULL)
|| (req->result >= 0 && req->ptr != NULL));
assert(req->result > 0 ? (req->ptr != NULL) : (req->ptr == NULL));
free(req->ptr);
req->ptr = NULL;
break;
@ -116,9 +115,6 @@ static int uv__fs_after(eio_req* eio) {
switch (req->fs_type) {
case UV_FS_READDIR:
if (req->eio->result == -1)
break; /* opendir() or readdir() operation failed. */
/*
* XXX This is pretty bad.
* We alloc and copy the large null terminated string list from libeio.
@ -128,16 +124,21 @@ static int uv__fs_after(eio_req* eio) {
*/
buflen = 0;
name = req->eio->ptr2;
for (i = 0; i < req->result; i++) {
namelen = strlen(name);
buflen += namelen + 1;
/* TODO check ENOMEM */
name += namelen;
assert(*name == '\0');
name++;
}
req->ptr = malloc(buflen);
memcpy(req->ptr, req->eio->ptr2, buflen);
if (buflen) {
if ((req->ptr = malloc(buflen)))
memcpy(req->ptr, req->eio->ptr2, buflen);
else
uv__set_sys_error(req->loop, ENOMEM);
}
break;
case UV_FS_STAT:
@ -149,19 +150,20 @@ static int uv__fs_after(eio_req* eio) {
case UV_FS_READLINK:
if (req->result == -1) {
req->ptr = NULL;
} else {
assert(req->result > 0);
if ((name = realloc(req->eio->ptr2, req->result + 1)) == NULL) {
/* Not enough memory. Reuse buffer, chop off last byte. */
name = req->eio->ptr2;
req->result--;
}
break;
}
assert(req->result > 0);
/* Make zero-terminated copy of req->eio->ptr2 */
if ((req->ptr = name = malloc(req->result + 1))) {
memcpy(name, req->eio->ptr2, req->result);
name[req->result] = '\0';
req->ptr = name;
req->result = 0;
}
else {
req->errorno = ENOMEM;
req->result = -1;
}
break;
default:
@ -191,7 +193,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_ref(loop);
req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -199,7 +201,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
/* sync */
req->result = open(path, flags, mode);
if (req->result < 0) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
return -1;
}
@ -223,7 +225,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
uv__fs_after, req);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -234,7 +236,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
pread(fd, buf, length, offset);
if (req->result < 0) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
return -1;
}
@ -260,7 +262,7 @@ int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT,
uv__fs_after, req);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -271,7 +273,7 @@ int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
pwrite(file, buf, length, offset);
if (req->result < 0) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
return -1;
}
@ -307,7 +309,7 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_ref(loop);
req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -315,7 +317,7 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
/* sync */
DIR* dir = opendir(path);
if (!dir) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
req->result = -1;
return -1;
}
@ -344,7 +346,7 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
r = closedir(dir);
if (r) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
req->result = -1;
return -1;
}
@ -380,7 +382,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -391,7 +393,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup);
if (req->result < 0) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
return -1;
}
@ -412,7 +414,7 @@ int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
req->eio = eio_fstat(file, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -421,7 +423,7 @@ int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
req->result = fstat(file, &req->statbuf);
if (req->result < 0) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
return -1;
}
@ -447,8 +449,11 @@ int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
char* path = NULL;
#ifdef __FreeBSD__
/* freebsd doesn't have fdatasync, do a full fsync instead. */
#if defined(__FreeBSD__) \
|| (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060)
/* freebsd and pre-10.6 darwin don't have fdatasync,
* do a full fsync instead.
*/
WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fsync, ARGS1(file))
#else
WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fdatasync, ARGS1(file))
@ -491,7 +496,7 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
}
#if defined(HAVE_FUTIMES)
#if HAVE_FUTIMES
static int _futime(const uv_file file, double atime, double mtime) {
struct timeval tv[2];
@ -502,21 +507,25 @@ static int _futime(const uv_file file, double atime, double mtime) {
tv[1].tv_sec = mtime;
tv[1].tv_usec = (unsigned long)(mtime * 1000000) % 1000000;
#ifdef __sun
return futimesat(file, NULL, tv);
#else
return futimes(file, tv);
#endif
}
#endif
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
double mtime, uv_fs_cb cb) {
#if defined(HAVE_FUTIMES)
#if HAVE_FUTIMES
const char* path = NULL;
uv_fs_req_init(loop, req, UV_FS_FUTIME, path, cb);
WRAP_EIO(UV_FS_FUTIME, eio_futime, _futime, ARGS3(file, atime, mtime))
#else
uv_err_new(loop, ENOSYS);
uv__set_sys_error(loop, ENOSYS);
return -1;
#endif
}
@ -546,7 +555,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -557,7 +566,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup);
if (req->result < 0) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
return -1;
}
@ -584,11 +593,8 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
ssize_t size;
int status;
char* buf;
status = -1;
uv_fs_req_init(loop, req, UV_FS_READLINK, path, cb);
if (cb) {
@ -596,7 +602,7 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_ref(loop);
return 0;
} else {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
} else {
@ -612,7 +618,7 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
}
if ((buf = malloc(size + 1)) == NULL) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}
@ -689,7 +695,7 @@ int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
req->eio = eio_custom(uv__work, EIO_PRI_DEFAULT, uv__after_work, req);
if (!req->eio) {
uv_err_new(loop, ENOMEM);
uv__set_sys_error(loop, ENOMEM);
return -1;
}

View File

@ -32,33 +32,33 @@
#include <linux/version.h>
#include <features.h>
#undef HAVE_FUTIMES
#undef HAVE_PIPE2
#undef HAVE_ACCEPT4
/* futimes() requires linux >= 2.6.22 and glib >= 2.6 */
#if LINUX_VERSION_CODE >= 0x20616 && __GLIBC_PREREQ(2, 6)
#define HAVE_FUTIMES
#define HAVE_FUTIMES 1
#endif
/* pipe2() requires linux >= 2.6.27 and glibc >= 2.9 */
#if LINUX_VERSION_CODE >= 0x2061B && __GLIBC_PREREQ(2, 9)
#define HAVE_PIPE2
#define HAVE_PIPE2 1
#endif
/* accept4() requires linux >= 2.6.28 and glib >= 2.10 */
#if LINUX_VERSION_CODE >= 0x2061C && __GLIBC_PREREQ(2, 10)
#define HAVE_ACCEPT4
#define HAVE_ACCEPT4 1
#endif
#endif /* __linux__ */
#ifdef __APPLE__
# define HAVE_FUTIMES
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
# define HAVE_FUTIMES 1
#endif
#ifdef __FreeBSD__
# define HAVE_FUTIMES
/* FIXME exact copy of the #ifdef guard in uv-unix.h */
#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) \
|| defined(__FreeBSD__) \
|| defined(__OpenBSD__) \
|| defined(__NetBSD__)
# define HAVE_KQUEUE 1
#endif
#define container_of(ptr, type, member) \
@ -74,13 +74,15 @@
/* flags */
enum {
UV_CLOSING = 0x00000001, /* uv_close() called but not finished. */
UV_CLOSED = 0x00000002, /* close(2) finished. */
UV_READING = 0x00000004, /* uv_read_start() called. */
UV_SHUTTING = 0x00000008, /* uv_shutdown() called but not complete. */
UV_SHUT = 0x00000010, /* Write side closed. */
UV_READABLE = 0x00000020, /* The stream is readable */
UV_WRITABLE = 0x00000040 /* The stream is writable */
UV_CLOSING = 0x01, /* uv_close() called but not finished. */
UV_CLOSED = 0x02, /* close(2) finished. */
UV_READING = 0x04, /* uv_read_start() called. */
UV_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */
UV_SHUT = 0x10, /* Write side closed. */
UV_READABLE = 0x20, /* The stream is readable */
UV_WRITABLE = 0x40, /* The stream is writable */
UV_TCP_NODELAY = 0x080, /* Disable Nagle. */
UV_TCP_KEEPALIVE = 0x100 /* Turn on keep-alive. */
};
size_t uv__strlcpy(char* dst, const char* src, size_t size);
@ -96,8 +98,6 @@ int uv__socket(int domain, int type, int protocol);
/* error */
uv_err_code uv_translate_sys_error(int sys_errno);
uv_err_t uv_err_new(uv_loop_t* loop, int sys_error);
uv_err_t uv_err_new_artificial(uv_loop_t* loop, int code);
void uv_fatal_error(const int errorno, const char* syscall);
/* stream */
@ -113,6 +113,8 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
/* tcp */
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
int uv__tcp_nodelay(uv_tcp_t* handle, int enable);
int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);
/* pipe */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);

View File

@ -0,0 +1,141 @@
/* 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 <assert.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#if HAVE_KQUEUE
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/event.h>
#include <fcntl.h>
#include <time.h>
static void uv__fs_event(EV_P_ ev_io* w, int revents);
static void uv__fs_event_start(uv_fs_event_t* handle) {
ev_io_init(&handle->event_watcher,
uv__fs_event,
handle->fd,
EV_LIBUV_KQUEUE_HACK);
ev_io_start(handle->loop->ev, &handle->event_watcher);
}
static void uv__fs_event_stop(uv_fs_event_t* handle) {
ev_io_stop(handle->loop->ev, &handle->event_watcher);
}
static void uv__fs_event(EV_P_ ev_io* w, int revents) {
uv_fs_event_t* handle;
int events;
assert(revents == EV_LIBUV_KQUEUE_HACK);
handle = container_of(w, uv_fs_event_t, event_watcher);
if (handle->fflags & (NOTE_ATTRIB | NOTE_EXTEND))
events = UV_CHANGE;
else
events = UV_RENAME;
handle->cb(handle, NULL, events, 0);
uv__fs_event_stop(handle);
/* File watcher operates in one-shot mode, re-arm it. */
if (handle->fd != -1)
uv__fs_event_start(handle);
}
/* Called by libev, don't touch. */
void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) {
uv_fs_event_t* handle;
handle = container_of(w, uv_fs_event_t, event_watcher);
handle->fflags = fflags;
}
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
int fd;
if (cb == NULL) {
uv__set_sys_error(loop, EINVAL);
return -1;
}
/* TODO open asynchronously - but how do we report back errors? */
if ((fd = open(filename, O_RDONLY)) == -1) {
uv__set_sys_error(loop, errno);
return -1;
}
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
handle->filename = strdup(filename);
handle->fflags = 0;
handle->cb = cb;
handle->fd = fd;
uv__fs_event_start(handle);
return 0;
}
void uv__fs_event_destroy(uv_fs_event_t* handle) {
free(handle->filename);
uv__close(handle->fd);
handle->fd = -1;
}
#else /* !HAVE_KQUEUE */
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv__set_sys_error(loop, ENOSYS);
return -1;
}
void uv__fs_event_destroy(uv_fs_event_t* handle) {
assert(0 && "unreachable");
}
/* Called by libev, don't touch. */
void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) {
assert(0 && "unreachable");
}
#endif /* HAVE_KQUEUE */

View File

@ -28,6 +28,7 @@
#include <errno.h>
#include <sys/inotify.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <time.h>
@ -52,6 +53,16 @@ uint64_t uv_hrtime() {
return (ts.tv_sec * NANOSEC + ts.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) {
if (!buffer || !size) {
@ -64,6 +75,13 @@ int uv_exepath(char* buffer, size_t* size) {
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);
}
static int new_inotify_fd(void) {
#if defined(IN_NONBLOCK) && defined(IN_CLOEXEC)
@ -126,6 +144,9 @@ static void uv__inotify_read(EV_P_ ev_io* w, int revents) {
filename = e->len ? e->name : basename_r(handle->filename);
handle->cb(handle, filename, events, 0);
if (handle->fd == -1)
break;
}
}
while (handle->fd != -1); /* handle might've been closed by callback */
@ -145,7 +166,7 @@ int uv_fs_event_init(uv_loop_t* loop,
* keep creating new inotify fds.
*/
if ((fd = new_inotify_fd()) == -1) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
return -1;
}
@ -158,7 +179,7 @@ int uv_fs_event_init(uv_loop_t* loop,
| IN_MOVED_TO;
if (inotify_add_watch(fd, filename, flags) == -1) {
uv_err_new(loop, errno);
uv__set_sys_error(loop, errno);
uv__close(fd);
return -1;
}
@ -180,4 +201,5 @@ void uv__fs_event_destroy(uv_fs_event_t* handle) {
uv__close(handle->fd);
handle->fd = -1;
free(handle->filename);
handle->filename = NULL;
}

View File

@ -24,6 +24,7 @@
#include <string.h>
#include <errno.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/sysctl.h>
@ -40,6 +41,17 @@ uint64_t uv_hrtime(void) {
return (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) {
uint32_t usize;
@ -70,16 +82,31 @@ int uv_exepath(char* buffer, size_t* size) {
return 0;
}
uint64_t uv_get_free_memory(void) {
struct uvmexp info;
size_t size = sizeof(info);
int which[] = {CTL_VM, VM_UVMEXP};
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv_err_new(loop, ENOSYS);
return -1;
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
return -1;
}
return (uint64_t) info.free * psysconf(_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);
void uv__fs_event_destroy(uv_fs_event_t* handle) {
assert(0 && "implement me");
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
return -1;
}
return (uint64_t) info;
}

View File

@ -0,0 +1,123 @@
/* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/sysctl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#undef NANOSEC
#define NANOSEC 1000000000
uint64_t uv_hrtime(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (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 status = -1;
if (!buffer || !size) {
goto out;
}
mypid = getpid();
for (;;) {
if ((argsbuf_tmp = realloc(argsbuf, argsbuf_size)) == 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) {
goto out;
}
argsbuf_size *= 2U;
}
if (argsbuf[0] == NULL) {
goto out;
}
exepath_size = strlen(argsbuf[0]);
if (exepath_size >= *size) {
goto out;
}
memcpy(buffer, argsbuf[0], exepath_size + 1U);
*size = exepath_size;
status = 0;
out:
free(argsbuf);
return status;
}
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) < 0) {
return -1;
}
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) < 0) {
return -1;
}
return (uint64_t) info;
}

View File

@ -29,10 +29,12 @@
#include <unistd.h>
#include <stdlib.h>
int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle) {
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);
loop->counters.pipe_init++;
handle->pipe_fname = NULL;
handle->ipc = ipc;
return 0;
}
@ -53,13 +55,13 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
/* Already bound? */
if (handle->fd >= 0) {
uv_err_new_artificial(handle->loop, UV_EINVAL);
uv__set_artificial_error(handle->loop, UV_EINVAL);
goto out;
}
/* Make a copy of the file name, it outlives this function's scope. */
if ((pipe_fname = strdup(name)) == NULL) {
uv_err_new(handle->loop, ENOMEM);
uv__set_sys_error(handle->loop, ENOMEM);
goto out;
}
@ -67,7 +69,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
name = NULL;
if ((sockfd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
goto out;
}
@ -88,7 +90,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|| unlink(pipe_fname) == -1
|| bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr) == -1) {
/* Convert ENOENT to EACCES for compatibility with Windows. */
uv_err_new(handle->loop, (errno == ENOENT) ? EACCES : errno);
uv__set_sys_error(handle->loop, (errno == ENOENT) ? EACCES : errno);
goto out;
}
}
@ -125,13 +127,13 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
status = -1;
if (handle->fd == -1) {
uv_err_new_artificial(handle->loop, UV_EINVAL);
uv__set_artificial_error(handle->loop, UV_EINVAL);
goto out;
}
assert(handle->fd >= 0);
if ((status = listen(handle->fd, backlog)) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
} else {
handle->connection_cb = cb;
ev_io_init(&handle->read_watcher, uv__pipe_accept, handle->fd, EV_READ);
@ -190,7 +192,7 @@ int uv_pipe_connect(uv_connect_t* req,
status = -1;
if ((sockfd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
goto out;
}
@ -207,7 +209,7 @@ int uv_pipe_connect(uv_connect_t* req,
while (r == -1 && errno == EINTR);
if (r == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
uv__close(sockfd);
goto out;
}
@ -257,7 +259,7 @@ void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
assert(0 && "EAGAIN on uv__accept(pipefd)");
} else {
uv_err_new(pipe->loop, errno);
uv__set_sys_error(pipe->loop, errno);
}
} else {
pipe->accepted_fd = sockfd;

View File

@ -1,4 +1,3 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@ -63,6 +62,34 @@ static void uv__chld(EV_P_ ev_child* watcher, int revents) {
}
}
/*
* Used for initializing stdio streams like options.stdin_stream. Returns
* zero on success.
*/
static int uv__process_init_pipe(uv_pipe_t* handle, int fds[2]) {
if (handle->type != UV_NAMED_PIPE) {
errno = EINVAL;
return -1;
}
if (handle->ipc) {
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
return -1;
}
} else {
if (pipe(fds) < 0) {
return -1;
}
}
uv__cloexec(fds[0], 1);
uv__cloexec(fds[1], 1);
return 0;
}
#ifndef SPAWN_WAIT_EXEC
# define SPAWN_WAIT_EXEC 1
#endif
@ -83,49 +110,26 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
#endif
int status;
pid_t pid;
int flags;
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
loop->counters.process_init++;
process->exit_cb = options.exit_cb;
if (options.stdin_stream) {
if (options.stdin_stream->type != UV_NAMED_PIPE) {
errno = EINVAL;
goto error;
}
if (pipe(stdin_pipe) < 0) {
goto error;
}
uv__cloexec(stdin_pipe[0], 1);
uv__cloexec(stdin_pipe[1], 1);
if (options.stdin_stream &&
uv__process_init_pipe(options.stdin_stream, stdin_pipe)) {
goto error;
}
if (options.stdout_stream) {
if (options.stdout_stream->type != UV_NAMED_PIPE) {
errno = EINVAL;
goto error;
}
if (pipe(stdout_pipe) < 0) {
goto error;
}
uv__cloexec(stdout_pipe[0], 1);
uv__cloexec(stdout_pipe[1], 1);
if (options.stdout_stream &&
uv__process_init_pipe(options.stdout_stream, stdout_pipe)) {
goto error;
}
if (options.stderr_stream) {
if (options.stderr_stream->type != UV_NAMED_PIPE) {
errno = EINVAL;
goto error;
}
if (pipe(stderr_pipe) < 0) {
goto error;
}
uv__cloexec(stderr_pipe[0], 1);
uv__cloexec(stderr_pipe[1], 1);
if (options.stderr_stream &&
uv__process_init_pipe(options.stderr_stream, stderr_pipe)) {
goto error;
}
/* This pipe is used by the parent to wait until
@ -154,7 +158,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
goto error;
}
# else
if (pipe(signal_pipe) < 0) {
if (socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe) < 0) {
goto error;
}
uv__cloexec(signal_pipe[0], 1);
@ -232,13 +236,8 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
}
while (status == -1 && (errno == EINTR || errno == ENOMEM));
assert((status == 1) && "poll() on pipe read end failed");
uv__close(signal_pipe[0]);
uv__close(signal_pipe[1]);
assert((status == 1)
&& "poll() on pipe read end failed");
assert((pfd.revents & POLLHUP) == POLLHUP
&& "no POLLHUP on pipe read end");
#endif
process->pid = pid;
@ -252,8 +251,9 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
assert(stdin_pipe[0] >= 0);
uv__close(stdin_pipe[0]);
uv__nonblock(stdin_pipe[1], 1);
flags = UV_WRITABLE | (options.stdin_stream->ipc ? UV_READABLE : 0);
uv__stream_open((uv_stream_t*)options.stdin_stream, stdin_pipe[1],
UV_WRITABLE);
flags);
}
if (stdout_pipe[0] >= 0) {
@ -261,8 +261,9 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
assert(stdout_pipe[1] >= 0);
uv__close(stdout_pipe[1]);
uv__nonblock(stdout_pipe[0], 1);
flags = UV_READABLE | (options.stdout_stream->ipc ? UV_WRITABLE : 0);
uv__stream_open((uv_stream_t*)options.stdout_stream, stdout_pipe[0],
UV_READABLE);
flags);
}
if (stderr_pipe[0] >= 0) {
@ -270,14 +271,15 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
assert(stderr_pipe[1] >= 0);
uv__close(stderr_pipe[1]);
uv__nonblock(stderr_pipe[0], 1);
flags = UV_READABLE | (options.stderr_stream->ipc ? UV_WRITABLE : 0);
uv__stream_open((uv_stream_t*)options.stderr_stream, stderr_pipe[0],
UV_READABLE);
flags);
}
return 0;
error:
uv_err_new(process->loop, errno);
uv__set_sys_error(process->loop, errno);
uv__close(stdin_pipe[0]);
uv__close(stdin_pipe[1]);
uv__close(stdout_pipe[0]);
@ -292,7 +294,7 @@ int uv_process_kill(uv_process_t* process, int signum) {
int r = kill(process->pid, signum);
if (r) {
uv_err_new(process->loop, errno);
uv__set_sys_error(process->loop, errno);
return -1;
} else {
return 0;

View File

@ -29,6 +29,8 @@
#include <string.h>
#include <sys/uio.h>
#include <stdio.h>
static void uv__stream_connect(uv_stream_t*);
static void uv__write(uv_stream_t* stream);
@ -51,6 +53,7 @@ void uv__stream_init(uv_loop_t* loop,
uv_stream_t* stream,
uv_handle_type type) {
uv__handle_init(loop, (uv_handle_t*)stream, type);
loop->counters.stream_init++;
stream->alloc_cb = NULL;
stream->close_cb = NULL;
@ -81,14 +84,26 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
assert(fd >= 0);
stream->fd = fd;
((uv_handle_t*)stream)->flags |= flags;
stream->flags |= flags;
/* Reuse the port address if applicable. */
yes = 1;
if (stream->type == UV_TCP
&& setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
uv_err_new(stream->loop, errno);
return -1;
if (stream->type == UV_TCP) {
/* Reuse the port address if applicable. */
yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
uv__set_sys_error(stream->loop, errno);
return -1;
}
if ((stream->flags & UV_TCP_NODELAY) &&
uv__tcp_nodelay((uv_tcp_t*)stream, 1)) {
return -1;
}
/* TODO Use delay the user passed in. */
if ((stream->flags & UV_TCP_KEEPALIVE) &&
uv__tcp_keepalive((uv_tcp_t*)stream, 1, 60)) {
return -1;
}
}
/* Associate the fd with each ev_io watcher. */
@ -118,7 +133,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
free(req->bufs);
if (req->cb) {
uv_err_new_artificial(req->handle->loop, UV_EINTR);
uv__set_artificial_error(req->handle->loop, UV_EINTR);
req->cb(req, -1);
}
}
@ -129,7 +144,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
req = ngx_queue_data(q, uv_write_t, queue);
if (req->cb) {
uv_err_new_artificial(stream->loop, req->error);
uv__set_artificial_error(stream->loop, req->error);
req->cb(req, req->error ? -1 : 0);
}
}
@ -167,7 +182,7 @@ void uv__server_io(EV_P_ ev_io* watcher, int revents) {
/* TODO special trick. unlock reserved socket, accept, close. */
return;
} else {
uv_err_new(stream->loop, errno);
uv__set_sys_error(stream->loop, errno);
stream->connection_cb((uv_stream_t*)stream, -1);
}
} else {
@ -199,15 +214,15 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
streamClient = (uv_stream_t*)client;
if (streamServer->accepted_fd < 0) {
uv_err_new(server->loop, EAGAIN);
uv__set_sys_error(server->loop, EAGAIN);
goto out;
}
if (uv__stream_open(streamClient, streamServer->accepted_fd,
UV_READABLE | UV_WRITABLE)) {
/* TODO handle error */
streamServer->accepted_fd = -1;
uv__close(streamServer->accepted_fd);
streamServer->accepted_fd = -1;
goto out;
}
@ -272,12 +287,12 @@ static void uv__drain(uv_stream_t* stream) {
if (shutdown(stream->fd, SHUT_WR)) {
/* Error. Report it. User should call uv_close(). */
uv_err_new(stream->loop, errno);
uv__set_sys_error(stream->loop, errno);
if (req->cb) {
req->cb(req, -1);
}
} else {
uv_err_new(stream->loop, 0);
uv__set_sys_error(stream->loop, 0);
((uv_handle_t*) stream)->flags |= UV_SHUT;
if (req->cb) {
req->cb(req, 0);
@ -349,14 +364,43 @@ static void uv__write(uv_stream_t* stream) {
* inside the iov each time we write. So there is no need to offset it.
*/
do {
if (iovcnt == 1) {
n = write(stream->fd, iov[0].iov_base, iov[0].iov_len);
} else {
n = writev(stream->fd, iov, iovcnt);
if (req->send_handle) {
struct msghdr msg;
char scratch[64];
struct cmsghdr *cmsg;
int fd_to_send = req->send_handle->fd;
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_LEN(sizeof(fd_to_send));
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = msg.msg_controllen;
*(int*) CMSG_DATA(cmsg) = fd_to_send;
do {
n = sendmsg(stream->fd, &msg, 0);
}
while (n == -1 && errno == EINTR);
} else {
do {
if (iovcnt == 1) {
n = write(stream->fd, iov[0].iov_base, iov[0].iov_len);
} else {
n = writev(stream->fd, iov, iovcnt);
}
}
while (n == -1 && errno == EINTR);
}
while (n == -1 && errno == EINTR);
if (n < 0) {
if (errno != EAGAIN) {
@ -428,7 +472,7 @@ static void uv__write_callbacks(uv_stream_t* stream) {
/* NOTE: call callback AFTER freeing the request data. */
if (req->cb) {
uv_err_new_artificial(stream->loop, req->error);
uv__set_artificial_error(stream->loop, req->error);
req->cb(req, req->error ? -1 : 0);
}
@ -447,12 +491,16 @@ static void uv__write_callbacks(uv_stream_t* stream) {
static void uv__read(uv_stream_t* stream) {
uv_buf_t buf;
ssize_t nread;
struct msghdr msg;
struct cmsghdr* cmsg;
char cmsg_space[64];
struct ev_loop* ev = stream->loop->ev;
/* XXX: Maybe instead of having UV_READING we just test if
* tcp->read_cb is NULL or not?
*/
while (stream->read_cb && ((uv_handle_t*)stream)->flags & UV_READING) {
while ((stream->read_cb || stream->read2_cb) &&
stream->flags & UV_READING) {
assert(stream->alloc_cb);
buf = stream->alloc_cb((uv_handle_t*)stream, 64 * 1024);
@ -460,10 +508,29 @@ static void uv__read(uv_stream_t* stream) {
assert(buf.base);
assert(stream->fd >= 0);
do {
nread = read(stream->fd, buf.base, buf.len);
if (stream->read_cb) {
do {
nread = read(stream->fd, buf.base, buf.len);
}
while (nread < 0 && errno == EINTR);
} else {
assert(stream->read2_cb);
/* read2_cb 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 = 64;
msg.msg_control = (void *) cmsg_space;
do {
nread = recvmsg(stream->fd, &msg, 0);
}
while (nread < 0 && errno == EINTR);
}
while (nread < 0 && errno == EINTR);
if (nread < 0) {
/* Error */
@ -472,25 +539,85 @@ static void uv__read(uv_stream_t* stream) {
if (stream->flags & UV_READING) {
ev_io_start(ev, &stream->read_watcher);
}
uv_err_new(stream->loop, EAGAIN);
stream->read_cb(stream, 0, buf);
uv__set_sys_error(stream->loop, EAGAIN);
if (stream->read_cb) {
stream->read_cb(stream, 0, buf);
} else {
stream->read2_cb((uv_pipe_t*)stream, 0, buf, UV_UNKNOWN_HANDLE);
}
return;
} else {
/* Error. User should call uv_close(). */
uv_err_new(stream->loop, errno);
stream->read_cb(stream, -1, buf);
uv__set_sys_error(stream->loop, errno);
if (stream->read_cb) {
stream->read_cb(stream, -1, buf);
} else {
stream->read2_cb((uv_pipe_t*)stream, -1, buf, UV_UNKNOWN_HANDLE);
}
assert(!ev_is_active(&stream->read_watcher));
return;
}
} else if (nread == 0) {
/* EOF */
uv_err_new_artificial(stream->loop, UV_EOF);
uv__set_artificial_error(stream->loop, UV_EOF);
ev_io_stop(ev, &stream->read_watcher);
stream->read_cb(stream, -1, buf);
if (stream->read_cb) {
stream->read_cb(stream, -1, buf);
} else {
stream->read2_cb((uv_pipe_t*)stream, -1, buf, UV_UNKNOWN_HANDLE);
}
return;
} else {
/* Successful read */
stream->read_cb(stream, nread, buf);
ssize_t buflen = buf.len;
if (stream->read_cb) {
stream->read_cb(stream, nread, buf);
} else {
assert(stream->read2_cb);
/*
* XXX: Some implementations can send multiple file descriptors in a
* single message. We should be using CMSG_NXTHDR() to walk the
* chain to get at them all. This would require changing the API to
* hand these back up the caller, is a pain.
*/
for (cmsg = CMSG_FIRSTHDR(&msg);
msg.msg_controllen > 0 && cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_type == SCM_RIGHTS) {
if (stream->accepted_fd != -1) {
fprintf(stderr, "(libuv) ignoring extra FD received\n");
}
stream->accepted_fd = *(int *) CMSG_DATA(cmsg);
} else {
fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n",
cmsg->cmsg_type);
}
}
if (stream->accepted_fd >= 0) {
stream->read2_cb((uv_pipe_t*)stream, nread, buf, UV_TCP);
} else {
stream->read2_cb((uv_pipe_t*)stream, nread, buf, UV_UNKNOWN_HANDLE);
}
}
/* Return if we didn't fill the buffer, there is no more data to read. */
if (nread < buflen) {
return;
}
}
}
}
@ -505,7 +632,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
stream->flags & UV_SHUT ||
stream->flags & UV_CLOSED ||
stream->flags & UV_CLOSING) {
uv_err_new(stream->loop, EINVAL);
uv__set_sys_error(stream->loop, EINVAL);
return -1;
}
@ -593,7 +720,7 @@ static void uv__stream_connect(uv_stream_t* stream) {
return;
} else {
/* Error */
uv_err_new(stream->loop, error);
uv__set_sys_error(stream->loop, error);
stream->connect_req = NULL;
if (req->cb) {
@ -610,7 +737,7 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
if (stream->fd <= 0) {
if ((sockfd = uv__socket(addr->sa_family, SOCK_STREAM, 0)) == -1) {
uv_err_new(stream->loop, errno);
uv__set_sys_error(stream->loop, errno);
return -1;
}
@ -627,12 +754,12 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
ngx_queue_init(&req->queue);
if (stream->connect_req) {
uv_err_new(stream->loop, EALREADY);
uv__set_sys_error(stream->loop, EALREADY);
return -1;
}
if (stream->type != UV_TCP) {
uv_err_new(stream->loop, ENOTSOCK);
uv__set_sys_error(stream->loop, ENOTSOCK);
return -1;
}
@ -656,7 +783,7 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
break;
default:
uv_err_new(stream->loop, errno);
uv__set_sys_error(stream->loop, errno);
return -1;
}
}
@ -672,11 +799,8 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
}
/* 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* stream, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) {
int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
uv_stream_t* send_handle, uv_write_cb cb) {
int empty_queue;
assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
@ -684,10 +808,17 @@ int uv_write(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
"uv_write (unix) does not yet support other types of streams");
if (stream->fd < 0) {
uv_err_new(stream->loop, EBADF);
uv__set_sys_error(stream->loop, EBADF);
return -1;
}
if (send_handle) {
if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) {
uv__set_sys_error(stream->loop, EOPNOTSUPP);
return -1;
}
}
empty_queue = (stream->write_queue_size == 0);
/* Initialize the req */
@ -695,6 +826,7 @@ int uv_write(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
req->cb = cb;
req->handle = stream;
req->error = 0;
req->send_handle = send_handle;
req->type = UV_WRITE;
ngx_queue_init(&req->queue);
@ -737,12 +869,22 @@ int uv_write(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
}
int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
/* 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* stream, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) {
return uv_write2(req, stream, bufs, bufcnt, NULL, cb);
}
int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb,
uv_read_cb read_cb, uv_read2_cb read2_cb) {
assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
stream->type == UV_TTY);
if (stream->flags & UV_CLOSING) {
uv_err_new(stream->loop, EINVAL);
uv__set_sys_error(stream->loop, EINVAL);
return -1;
}
@ -759,6 +901,7 @@ int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
assert(alloc_cb);
stream->read_cb = read_cb;
stream->read2_cb = read2_cb;
stream->alloc_cb = alloc_cb;
/* These should have been set by uv_tcp_init. */
@ -769,14 +912,24 @@ int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
}
int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
return uv__read_start_common(stream, alloc_cb, read_cb, NULL);
}
int uv_read2_start(uv_stream_t* stream, uv_alloc_cb alloc_cb,
uv_read2_cb read_cb) {
return uv__read_start_common(stream, alloc_cb, NULL, read_cb);
}
int uv_read_stop(uv_stream_t* stream) {
uv_tcp_t* tcp = (uv_tcp_t*)stream;
((uv_handle_t*)tcp)->flags &= ~UV_READING;
ev_io_stop(tcp->loop->ev, &tcp->read_watcher);
tcp->read_cb = NULL;
tcp->alloc_cb = NULL;
ev_io_stop(stream->loop->ev, &stream->read_watcher);
stream->flags &= ~UV_READING;
stream->read_cb = NULL;
stream->read2_cb = NULL;
stream->alloc_cb = NULL;
return 0;
}

View File

@ -19,6 +19,7 @@
*/
#include "uv.h"
#include "internal.h"
#include <stdio.h>
#include <stdint.h>
@ -26,7 +27,9 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/loadavg.h>
#include <unistd.h>
#include <kstat.h>
uint64_t uv_hrtime() {
@ -63,11 +66,26 @@ int uv_exepath(char* buffer, size_t* size) {
}
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);
}
int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_t* handle,
const char* filename,
uv_fs_event_cb cb) {
uv_err_new(loop, ENOSYS);
uv__set_sys_error(loop, ENOSYS);
return -1;
}

View File

@ -33,10 +33,10 @@ int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
}
static int uv__tcp_bind(uv_tcp_t* tcp,
int domain,
struct sockaddr* addr,
int addrsize) {
static int uv__bind(uv_tcp_t* tcp,
int domain,
struct sockaddr* addr,
int addrsize) {
int saved_errno;
int status;
@ -45,7 +45,7 @@ static int uv__tcp_bind(uv_tcp_t* tcp,
if (tcp->fd < 0) {
if ((tcp->fd = uv__socket(domain, SOCK_STREAM, 0)) == -1) {
uv_err_new(tcp->loop, errno);
uv__set_sys_error(tcp->loop, errno);
goto out;
}
@ -64,7 +64,7 @@ static int uv__tcp_bind(uv_tcp_t* tcp,
if (errno == EADDRINUSE) {
tcp->delayed_error = errno;
} else {
uv_err_new(tcp->loop, errno);
uv__set_sys_error(tcp->loop, errno);
goto out;
}
}
@ -76,29 +76,19 @@ out:
}
int uv_tcp_bind(uv_tcp_t* tcp, struct sockaddr_in addr) {
if (addr.sin_family != AF_INET) {
uv_err_new(tcp->loop, EFAULT);
return -1;
}
return uv__tcp_bind(tcp,
AF_INET,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in));
int uv__tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
return uv__bind(handle,
AF_INET,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in));
}
int uv_tcp_bind6(uv_tcp_t* tcp, struct sockaddr_in6 addr) {
if (addr.sin6_family != AF_INET6) {
uv_err_new(tcp->loop, EFAULT);
return -1;
}
return uv__tcp_bind(tcp,
AF_INET6,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in6));
int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
return uv__bind(handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in6));
}
@ -112,13 +102,13 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
saved_errno = errno;
if (handle->delayed_error) {
uv_err_new(handle->loop, handle->delayed_error);
uv__set_sys_error(handle->loop, handle->delayed_error);
rv = -1;
goto out;
}
if (handle->fd < 0) {
uv_err_new(handle->loop, EINVAL);
uv__set_sys_error(handle->loop, EINVAL);
rv = -1;
goto out;
}
@ -127,7 +117,7 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
socklen = (socklen_t)*namelen;
if (getsockname(handle->fd, name, &socklen) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
rv = -1;
} else {
*namelen = (int)socklen;
@ -149,13 +139,13 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
saved_errno = errno;
if (handle->delayed_error) {
uv_err_new(handle->loop, handle->delayed_error);
uv__set_sys_error(handle->loop, handle->delayed_error);
rv = -1;
goto out;
}
if (handle->fd < 0) {
uv_err_new(handle->loop, EINVAL);
uv__set_sys_error(handle->loop, EINVAL);
rv = -1;
goto out;
}
@ -164,7 +154,7 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
socklen = (socklen_t)*namelen;
if (getpeername(handle->fd, name, &socklen) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
rv = -1;
} else {
*namelen = (int)socklen;
@ -180,13 +170,13 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
int r;
if (tcp->delayed_error) {
uv_err_new(tcp->loop, tcp->delayed_error);
uv__set_sys_error(tcp->loop, tcp->delayed_error);
return -1;
}
if (tcp->fd < 0) {
if ((tcp->fd = uv__socket(AF_INET, SOCK_STREAM, 0)) == -1) {
uv_err_new(tcp->loop, errno);
uv__set_sys_error(tcp->loop, errno);
return -1;
}
@ -201,7 +191,7 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
r = listen(tcp->fd, backlog);
if (r < 0) {
uv_err_new(tcp->loop, errno);
uv__set_sys_error(tcp->loop, errno);
return -1;
}
@ -216,65 +206,116 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
}
int uv_tcp_connect(uv_connect_t* req,
int uv__tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in address,
uv_connect_cb cb) {
int saved_errno;
int saved_errno = errno;
int status;
saved_errno = errno;
status = -1;
if (handle->type != UV_TCP) {
uv_err_new(handle->loop, EINVAL);
goto out;
}
if (address.sin_family != AF_INET) {
uv_err_new(handle->loop, EINVAL);
goto out;
}
status = uv__connect(req,
(uv_stream_t*)handle,
(struct sockaddr*)&address,
sizeof address,
cb);
out:
errno = saved_errno;
return status;
}
int uv_tcp_connect6(uv_connect_t* req,
int uv__tcp_connect6(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in6 address,
uv_connect_cb cb) {
int saved_errno;
int saved_errno = errno;
int status;
saved_errno = errno;
status = -1;
if (handle->type != UV_TCP) {
uv_err_new(handle->loop, EINVAL);
goto out;
}
if (address.sin6_family != AF_INET6) {
uv_err_new(handle->loop, EINVAL);
goto out;
}
status = uv__connect(req,
(uv_stream_t*)handle,
(struct sockaddr*)&address,
sizeof address,
cb);
out:
errno = saved_errno;
return status;
}
int uv__tcp_nodelay(uv_tcp_t* handle, int enable) {
if (setsockopt(handle->fd,
IPPROTO_TCP,
TCP_NODELAY,
&enable,
sizeof enable) == -1) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
return 0;
}
int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
if (setsockopt(handle->fd,
SOL_SOCKET,
SO_KEEPALIVE,
&enable,
sizeof enable) == -1) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
#ifdef TCP_KEEPIDLE
if (enable && setsockopt(handle->fd,
IPPROTO_TCP,
TCP_KEEPIDLE,
&delay,
sizeof delay) == -1) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
#endif
#ifdef TCP_KEEPALIVE
if (enable && setsockopt(handle->fd,
IPPROTO_TCP,
TCP_KEEPALIVE,
&delay,
sizeof delay) == -1) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
#endif
return 0;
}
int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
if (handle->fd != -1 && uv__tcp_nodelay(handle, enable))
return -1;
if (enable)
handle->flags |= UV_TCP_NODELAY;
else
handle->flags &= ~UV_TCP_NODELAY;
return 0;
}
int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
if (handle->fd != -1 && uv__tcp_keepalive(handle, enable, delay))
return -1;
if (enable)
handle->flags |= UV_TCP_KEEPALIVE;
else
handle->flags &= ~UV_TCP_KEEPALIVE;
/* TODO Store delay if handle->fd == -1 but don't want to enlarge
* uv_tcp_t with an int that's almost never used...
*/
return 0;
}

View File

@ -29,43 +29,75 @@
#include <sys/ioctl.h>
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd) {
uv__nonblock(fd, 1);
static int orig_termios_fd = -1;
static struct termios orig_termios;
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE | UV_WRITABLE);
if (readable) {
uv__nonblock(fd, 1);
uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE);
} else {
/* Note: writable tty we set to blocking mode. */
uv__nonblock(fd, 0);
uv__stream_open((uv_stream_t*)tty, fd, UV_WRITABLE);
tty->blocking = 1;
}
loop->counters.tty_init++;
tty->mode = 0;
return 0;
}
int uv_tty_set_mode(uv_tty_t* tty, int mode) {
int fd = tty->fd;
struct termios orig_termios; /* in order to restore at exit */
struct termios raw;
if (tcgetattr(fd, &orig_termios) == -1) goto fatal;
if (mode && tty->mode == 0) {
/* on */
raw = orig_termios; /* modify the original mode */
/* input modes: no break, no CR to NL, no parity check, no strip char,
* no start/stop output control. */
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
/* output modes */
raw.c_oflag |= (ONLCR);
/* control modes - set 8 bit chars */
raw.c_cflag |= (CS8);
/* local modes - echoing off, canonical off, no extended functions,
* no signal chars (^Z,^C) */
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
/* control chars - set return condition: min number of bytes and timer.
* We want read to return every single byte, without timeout. */
raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
if (tcgetattr(fd, &tty->orig_termios)) {
goto fatal;
}
/* put terminal in raw mode after flushing */
if (tcsetattr(fd, TCSAFLUSH, &raw) < 0) goto fatal;
return 0;
/* This is used for uv_tty_reset_mode() */
if (orig_termios_fd == -1) {
orig_termios = tty->orig_termios;
orig_termios_fd = fd;
}
raw = tty->orig_termios;
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag |= (ONLCR);
raw.c_cflag |= (CS8);
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
raw.c_cc[VMIN] = 1;
raw.c_cc[VTIME] = 0;
/* Put terminal in raw mode after flushing */
if (tcsetattr(fd, TCSAFLUSH, &raw)) {
goto fatal;
}
tty->mode = 1;
return 0;
} else if (mode == 0 && tty->mode) {
/* off */
/* Put terminal in original mode after flushing */
if (tcsetattr(fd, TCSAFLUSH, &tty->orig_termios)) {
goto fatal;
}
tty->mode = 0;
return 0;
}
fatal:
uv_err_new(tty->loop, ENOTTY);
uv__set_sys_error(tty->loop, errno);
return -1;
}
@ -74,7 +106,7 @@ int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
struct winsize ws;
if (ioctl(tty->fd, TIOCGWINSZ, &ws) < 0) {
uv_err_new(tty->loop, errno);
uv__set_sys_error(tty->loop, errno);
return -1;
}
@ -89,7 +121,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
struct stat s;
if (file < 0) {
uv_err_new(NULL, EINVAL); /* XXX Need loop? */
uv__set_sys_error(NULL, EINVAL); /* XXX Need loop? */
return -1;
}
@ -98,7 +130,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
}
if (fstat(file, &s)) {
uv_err_new(NULL, errno); /* XXX Need loop? */
uv__set_sys_error(NULL, errno); /* XXX Need loop? */
return -1;
}
@ -108,3 +140,10 @@ uv_handle_type uv_guess_handle(uv_file file) {
return UV_NAMED_PIPE;
}
void uv_tty_reset_mode() {
if (orig_termios_fd >= 0) {
tcsetattr(orig_termios_fd, TCSANOW, &orig_termios);
}
}

View File

@ -34,8 +34,6 @@ static void uv__udp_run_pending(uv_udp_t* handle);
static void uv__udp_recvmsg(uv_udp_t* handle);
static void uv__udp_sendmsg(uv_udp_t* handle);
static void uv__udp_io(EV_P_ ev_io* w, int events);
static int uv__udp_bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
socklen_t len, unsigned flags);
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain);
static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr* addr, socklen_t addrlen, uv_udp_send_cb send_cb);
@ -84,7 +82,7 @@ void uv__udp_destroy(uv_udp_t* handle) {
req = ngx_queue_data(q, uv_udp_send_t, queue);
if (req->send_cb) {
/* FIXME proper error code like UV_EABORTED */
uv_err_new_artificial(handle->loop, UV_EINTR);
uv__set_artificial_error(handle->loop, UV_EINTR);
req->send_cb(req, -1);
}
}
@ -187,7 +185,7 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
req->send_cb(req, 0);
}
else {
uv_err_new(handle->loop, -req->status);
uv__set_sys_error(handle->loop, -req->status);
req->send_cb(req, -1);
}
}
@ -223,11 +221,11 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
if (nread == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
uv_err_new(handle->loop, EAGAIN);
uv__set_sys_error(handle->loop, EAGAIN);
handle->recv_cb(handle, 0, buf, NULL, 0);
}
else {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
handle->recv_cb(handle, -1, buf, NULL, 0);
}
}
@ -289,11 +287,11 @@ static void uv__udp_io(EV_P_ ev_io* w, int events) {
}
static int uv__udp_bind(uv_udp_t* handle,
int domain,
struct sockaddr* addr,
socklen_t len,
unsigned flags) {
static int uv__bind(uv_udp_t* handle,
int domain,
struct sockaddr* addr,
socklen_t len,
unsigned flags) {
int saved_errno;
int status;
int yes;
@ -301,27 +299,28 @@ static int uv__udp_bind(uv_udp_t* handle,
saved_errno = errno;
status = -1;
fd = -1;
/* Check for bad flags. */
if (flags & ~UV_UDP_IPV6ONLY) {
uv_err_new(handle->loop, EINVAL);
uv__set_sys_error(handle->loop, EINVAL);
goto out;
}
/* Cannot set IPv6-only mode on non-IPv6 socket. */
if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
uv_err_new(handle->loop, EINVAL);
uv__set_sys_error(handle->loop, EINVAL);
goto out;
}
/* Check for already active socket. */
if (handle->fd != -1) {
uv_err_new_artificial(handle->loop, UV_EALREADY);
uv__set_artificial_error(handle->loop, UV_EALREADY);
goto out;
}
if ((fd = uv__socket(domain, SOCK_DGRAM, 0)) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
goto out;
}
@ -329,17 +328,17 @@ static int uv__udp_bind(uv_udp_t* handle,
#ifdef IPV6_V6ONLY
yes = 1;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
goto out;
}
#else
uv_err_new((uv_handle_t*)handle, ENOTSUP);
uv__set_sys_error((uv_handle_t*)handle, ENOTSUP);
goto out;
#endif
}
if (bind(fd, addr, len) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
goto out;
}
@ -388,7 +387,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) {
abort();
}
return uv__udp_bind(handle, domain, (struct sockaddr*)&taddr, addrlen, 0);
return uv__bind(handle, domain, (struct sockaddr*)&taddr, addrlen, 0);
}
@ -416,7 +415,7 @@ static int uv__udp_send(uv_udp_send_t* req,
req->bufs = req->bufsml;
}
else if ((req->bufs = malloc(bufcnt * sizeof(bufs[0]))) == NULL) {
uv_err_new(handle->loop, ENOMEM);
uv__set_sys_error(handle->loop, ENOMEM);
return -1;
}
memcpy(req->bufs, bufs, bufcnt * sizeof(bufs[0]));
@ -442,21 +441,57 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
}
int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned flags) {
return uv__udp_bind(handle,
AF_INET,
(struct sockaddr*)&addr,
sizeof addr,
flags);
int uv__udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned flags) {
return uv__bind(handle,
AF_INET,
(struct sockaddr*)&addr,
sizeof addr,
flags);
}
int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags) {
return uv__udp_bind(handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof addr,
flags);
int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags) {
return uv__bind(handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof addr,
flags);
}
int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
const char* interface_addr, uv_membership membership) {
int optname;
struct ip_mreq mreq;
memset(&mreq, 0, sizeof mreq);
if (interface_addr) {
mreq.imr_interface.s_addr = inet_addr(interface_addr);
} else {
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
}
mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
switch (membership) {
case UV_JOIN_GROUP:
optname = IP_ADD_MEMBERSHIP;
break;
case UV_LEAVE_GROUP:
optname = IP_DROP_MEMBERSHIP;
break;
default:
uv__set_sys_error(handle->loop, EFAULT);
return -1;
}
if (setsockopt(handle->fd, IPPROTO_IP, optname, (void*) &mreq, sizeof mreq) == -1) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
return 0;
}
@ -470,7 +505,7 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
saved_errno = errno;
if (handle->fd < 0) {
uv_err_new(handle->loop, EINVAL);
uv__set_sys_error(handle->loop, EINVAL);
rv = -1;
goto out;
}
@ -479,7 +514,7 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
socklen = (socklen_t)*namelen;
if (getsockname(handle->fd, name, &socklen) == -1) {
uv_err_new(handle->loop, errno);
uv__set_sys_error(handle->loop, errno);
rv = -1;
} else {
*namelen = (int)socklen;
@ -527,12 +562,12 @@ int uv_udp_recv_start(uv_udp_t* handle,
uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) {
if (alloc_cb == NULL || recv_cb == NULL) {
uv_err_new_artificial(handle->loop, UV_EINVAL);
uv__set_artificial_error(handle->loop, UV_EINVAL);
return -1;
}
if (ev_is_active(&handle->read_watcher)) {
uv_err_new_artificial(handle->loop, UV_EALREADY);
uv__set_artificial_error(handle->loop, UV_EALREADY);
return -1;
}

View File

@ -76,12 +76,14 @@ const char* uv_err_name(uv_err_t err) {
case UV_ENFILE: return "ENFILE";
case UV_ENOBUFS: return "ENOBUFS";
case UV_ENOMEM: return "ENOMEM";
case UV_ENOTDIR: return "ENOTDIR";
case UV_ENONET: return "ENONET";
case UV_ENOPROTOOPT: return "ENOPROTOOPT";
case UV_ENOTCONN: return "ENOTCONN";
case UV_ENOTSOCK: return "ENOTSOCK";
case UV_ENOTSUP: return "ENOTSUP";
case UV_ENOENT: return "ENOENT";
case UV_ENOSYS: return "ENOSYS";
case UV_EPIPE: return "EPIPE";
case UV_EPROTO: return "EPROTO";
case UV_EPROTONOSUPPORT: return "EPROTONOSUPPORT";
@ -95,6 +97,29 @@ const char* uv_err_name(uv_err_t err) {
}
void uv__set_error(uv_loop_t* loop, uv_err_code code, int sys_error) {
loop->last_err.code = code;
loop->last_err.sys_errno_ = sys_error;
}
void uv__set_sys_error(uv_loop_t* loop, int sys_error) {
loop->last_err.code = uv_translate_sys_error(sys_error);
loop->last_err.sys_errno_ = sys_error;
}
void uv__set_artificial_error(uv_loop_t* loop, uv_err_code code) {
loop->last_err.code = code;
loop->last_err.sys_errno_ = 0;
}
uv_err_t uv_last_error(uv_loop_t* loop) {
return loop->last_err;
}
struct sockaddr_in uv_ip4_addr(const char* ip, int port) {
struct sockaddr_in addr;
@ -183,3 +208,65 @@ void uv_remove_ares_handle(uv_ares_task_t* handle) {
int uv_ares_handles_empty(uv_loop_t* loop) {
return loop->uv_ares_handles_ ? 0 : 1;
}
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
if (handle->type != UV_TCP || addr.sin_family != AF_INET) {
uv__set_artificial_error(handle->loop, UV_EFAULT);
return -1;
}
return uv__tcp_bind(handle, addr);
}
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
if (handle->type != UV_TCP || addr.sin6_family != AF_INET6) {
uv__set_artificial_error(handle->loop, UV_EFAULT);
return -1;
}
return uv__tcp_bind6(handle, addr);
}
int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
unsigned int flags) {
if (handle->type != UV_UDP || addr.sin_family != AF_INET) {
uv__set_artificial_error(handle->loop, UV_EFAULT);
return -1;
}
return uv__udp_bind(handle, addr, flags);
}
int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
unsigned int flags) {
if (handle->type != UV_UDP || addr.sin6_family != AF_INET6) {
uv__set_artificial_error(handle->loop, UV_EFAULT);
return -1;
}
return uv__udp_bind6(handle, addr, flags);
}
int uv_tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in address,
uv_connect_cb cb) {
if (handle->type != UV_TCP || address.sin_family != AF_INET) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
return -1;
}
return uv__tcp_connect(req, handle, address, cb);
}
int uv_tcp_connect6(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in6 address,
uv_connect_cb cb) {
if (handle->type != UV_TCP || address.sin6_family != AF_INET6) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
return -1;
}
return uv__tcp_connect6(req, handle, address, cb);
}

View File

@ -48,5 +48,26 @@ void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle);
int uv_ares_handles_empty(uv_loop_t* loop);
uv_err_code uv_translate_sys_error(int sys_errno);
void uv__set_error(uv_loop_t* loop, uv_err_code code, int sys_error);
void uv__set_sys_error(uv_loop_t* loop, int sys_error);
void uv__set_artificial_error(uv_loop_t* loop, uv_err_code code);
int uv__tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr);
int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr);
int uv__udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned flags);
int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags);
int uv__tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in address,
uv_connect_cb cb);
int uv__tcp_connect6(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in6 address,
uv_connect_cb cb);
#endif /* UV_COMMON_H_ */

View File

@ -48,6 +48,9 @@ static void uv_init(void) {
/* Initialize FS */
uv_fs_init();
/* Initialize console */
uv_console_init();
}
@ -79,7 +82,7 @@ static void uv_loop_init(uv_loop_t* loop) {
loop->ares_active_sockets = 0;
loop->ares_chan = NULL;
loop->last_error = uv_ok_;
loop->last_err = uv_ok_;
}

View File

@ -67,11 +67,6 @@ void uv_fatal_error(const int errorno, const char* syscall) {
}
uv_err_t uv_last_error(uv_loop_t* loop) {
return loop->last_error;
}
/* TODO: thread safety */
static char* last_err_str_ = NULL;
@ -110,6 +105,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
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 WSAEFAULT: return UV_EFAULT;
case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
@ -132,26 +129,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_PIPE_BUSY: return UV_EBUSY;
case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
case ERROR_ALREADY_EXISTS: return UV_EEXIST;
case WSAHOST_NOT_FOUND: return UV_ENOENT;
default: return UV_UNKNOWN;
}
}
uv_err_t uv_new_sys_error(int sys_errno) {
uv_err_t e;
e.code = uv_translate_sys_error(sys_errno);
e.sys_errno_ = sys_errno;
return e;
}
void uv_set_sys_error(uv_loop_t* loop, int sys_errno) {
loop->last_error.code = uv_translate_sys_error(sys_errno);
loop->last_error.sys_errno_ = sys_errno;
}
void uv_set_error(uv_loop_t* loop, uv_err_code code, int sys_errno) {
loop->last_error.code = code;
loop->last_error.sys_errno_ = sys_errno;
}

Some files were not shown because too many files have changed in this diff Show More