libevent: Import libevent 2.1.12

MFC after:	2 weeks

Merge commit '5223d1d95fddcef6f9a36e264a5800bd907ade8b' into main
This commit is contained in:
Cy Schubert 2023-11-14 15:04:28 -08:00
commit b50261e21f
165 changed files with 18205 additions and 6234 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,316 @@
Changes in version 2.1.12-stable (05 Jul 2020)
This release contains mostly bug fixes (I decided not to port some features
that can be ported even without ABI breakage, if you cannot find feature that
you are interested in, please give us a note!)
Since 2.1.12 libevent will use github actions as main CI, since
it recommends itself better then travis/appveyor (and had been removed from
upstream).
Look carefully at "slightly touches the behaviour" section.
Below you will find some of changes (this list has been cleaned up from the
patches that touches only tests and similar):
CI:
o Backport github actions to 2.1 (be3acd7c Azat Khuzhin)
o Merge branch 'event_rpcgen.py-cleanup' (f0ded5f3, 48e04887 Enji Cooper)
o Add API/ABI checker (using LVC) (709210d4, 2af1f6cc yuangongji)
test:
o tinytest: support timeout on Windows (794e8f75 yuangongji)
o Merge branch 'osx-clock' (e85afbe3 Azat Khuzhin)
o test-ratelim: calculate timers bias (for slow CPUs) to avoid false-positive (8ad26d0b Azat Khuzhin)
fixes:
o buffer: do not pass NULL to memcpy() from evbuffer_pullup() (5b063049 Azat Khuzhin)
o http: fix undefined-shift in EVUTIL_IS*_ helpers (6b8d02a7 Azat Khuzhin)
o Check error code of evhttp_add_header_internal() in evhttp_parse_query_impl() (97e28f09 Azat Khuzhin)
o http: fix EVHTTP_CON_AUTOFREE in case of timeout (and some else) (1be25938 Azat Khuzhin)
o evdns: Add additional validation for values of dns options (c2972453 ayuseleznev)
o There is typo in GetAdaptersAddresses windows library. It should be iphlpapi.dll (891adda9 Aleksandr-Melnikov)
o Merge branch 'EV_CLOSED-and-EV_ET-fixes' (db2efdf5 Azat Khuzhin)
o Fix memory corruption in EV_CLOSURE_EVENT_FINALIZE with debug enabled (8ccd8f56 Jan Kasiak)
o increase segment refcnt only if evbuffer_add_file_segment() succeeds (30662a3c yuangongji)
o evdns: fix a crash when evdns_base with waiting requests is freed (6f8e0e97 ayuseleznev)
o event_base_once: fix potential null pointer threat (2e9ceb16 chenguolong)
o http: do not assume body for CONNECT (1b42270b Azat Khuzhin)
o evbuffer_add_file: fix freeing of segment in the error path (5f017bde Azat Khuzhin)
o Fix checking return value of the evdns_base_resolv_conf_parse() (fc51bf2c Azat Khuzhin)
o Merge branch 'fix-signal-leak' (poll/select now needs reinit) (1c9cc07b Azat Khuzhin)
improvements:
o evutil_time: improve evutil_gettimeofday on Windows (a8219143 Nick Grifka)
o Support EV_CLOSED on linux for poll(2) (2530e7c6 Azat Khuzhin)
o Parse IPv6 scope IDs. (f602211f Philip Homburg)
o evutil_time: Implements usleep() using wait funtion on Windows (d42240d1 yuangongji)
o evutil_time: detect and use _gmtime64_s()/_gmtime64() (f4a6152c yuangongji)
slightly touches the behaviour:
o bufferevent: allow setting priority on socket and openssl type (4dd3acdd Nicolas J. Bouliane)
o Fix EV_CLOSED detection/reporting (epoll only) (1df324d4 Azat Khuzhin) (XXX)
o Revert "Warn if forked from the event loop during event_reinit()" (71f5c0d3 Azat Khuzhin)
samples:
o https-client: load certificates from the system cert store on Windows (e9478640 yuangongji)
build fixes:
o Do not use sysctl.h on linux (it had been deprecated) (d2871a37 Azat Khuzhin)
o cmake: avoid problems from use of CMAKE_USE_PTHREADS_INIT (a62ec765 Paul Osborne)
o Update list of cmake files for autotools dist archive (2016f017 Azat Khuzhin)
o LibeventConfig.cmake: restore CMAKE_FIND_LIBRARY_SUFFIXES and LIBEVENT_STATIC_LINK default (640f9cf6 Mario Emmenlauer)
o cmake: fix getaddrinfo checking error (dea51c2e yuangongji)
o autoconf: fix getaddrinfo checking errors on mingw (b9bf7fa7 yuangongji)
o Do not use shared global structures on CYGWIN (8a9b5655 Azat Khuzhin)
o Added uninstall target check to cmakelists (3f1fb1f9 Dimo Markov)
o Fix compilation without OPENSSL_API_COMPAT (921bdcdd Azat Khuzhin)
o cmake: improve package config file (1c047618, baec84f2 yuangongji)
o Link with iphlpapi only on windows (976f7d34 Azat Khuzhin)
o autotools: fails build when need but can not find openssl (93174bb5 yuangongji)
o Merge branch 'http-connect' (e2424229 Azat Khuzhin)
o Fix compat with NetBSD >= 10 (5febb4e1 Kamil Rytarowski)
o cmake: fix getrandom() detection (e0e5f3bd Azat Khuzhin)
o arc4random: replace sysctl() with getrandom (on linux) (66ec78fd Azat Khuzhin)
o Upgrade autoconf (after upgrading minimum required to 2.67) (45da7d9d yuangongji)
o eliminate some C4267 warnings in Windows (9e468c77 yuangongji)
o autotools: attach doxygen target into all target (5d1e8570 yuangongji)
o cmake: attach doxygen target into all target (7a85300a yuangongji)
o Change the minimum version of automake to 1.13 and autoconf to 2.67 (fdb8fb66 ygj6)
o Add Uninstall.cmake.in into dist archive (877f2355 Azat Khuzhin)
Changes in version 2.1.11-stable (01 Aug 2019)
This release contains one ABI breakage fix (that had been introduced in
2.1.10, and strictly speaking this release breaks ABI again to make it
compatible with 2.1.9 and less, please take a look at 18104973 for more
details). Apart from that it contains some bug fixes, that grouped below.
And even though the return value for evbuffer_setcb() had been changed it
should ABI compatible (anyway that function is in -compat.h header).
There is also one patch that introduce new functionality, this is 546a366c,
to tune SO_RCVBUF/SO_SNDBUF in evdns, but one can count it as a bug-fix on
the application level, since before you cannot tune this settings and hence
you could stumble on problems.
ABI breakage:
o Protect min_heap_push_ against integer overflow. (8c899768 Tobias Stoeckmann)
o Revert "Protect min_heap_push_ against integer overflow." (18104973 Azat Khuzhin)
functionality:
o evdns: add new options -- so-rcvbuf/so-sndbuf (546a366c Azat Khuzhin)
build:
o Change autoconf version to 2.62 and automake version to 1.11.2 (2a333008 yuangongji)
o cmake: install shared library only if it was requested (596855f7 Azat Khuzhin)
o Missing <winerror.h> on win7/MinGW(MINGW32_NT-6.1)/MSYS (9559349c yuangongji)
o cmake: set library names to be the same as with autotools (305251b9 yuangongji)
o Enable _GNU_SOURCE for Android (f013fc7d Keith Smiley)
o Enable kqueue for APPLE targets (3aa68a82 Keith Smiley)
o autotools: do not install bufferevent_ssl.h under --disable-openssl (5349a07e Azat Khuzhin)
o cmake: link against shell32.lib/advapi32.lib (c9ce638c Azat Khuzhin)
o Add README.md into dist archive (3660a4cc Azat Khuzhin)
o cmake: add missing autotools targets (doxygen, uninstall, event_rpcgen.py) (2d65071c yuangongji)
o m4/libevent_openssl.m4: fix detection of openssl (d4056e59 Fabrice Fontaine)
o Fix detection of the __has_attribute() for apple clang [ci skip] (7fd7c5ef Azat Khuzhin)
lib:
o buffer: fix possible NULL dereference in evbuffer_setcb() on ENOMEM (598f247d Azat Khuzhin)
o Warn if forked from the event loop during event_reinit() (b75922ae Azat Khuzhin)
o evutil: set the have_checked_interfaces in evutil_check_interfaces()
(ef498aa2, a09265ac jeremyerb)
samples:
o https-client: correction error checking (a8a04565 wenyg)
Changes in version 2.1.10-stable (26 May 2019)
This release contains mostly fixes (some evbuffer oddity, AF_UNIX handling in
http server, some UB fixes and others) but also some new functionality
(without ABI breakage as usual) and now dist archive can be used for building
on windows (getopt had been added into it).
Above you will find changelog for this particular release (but with some
trivial fixes pruned out from it - to make it a little bit more informative).
To view full changelog please use git:
git log --format=' o %s (%h %aN)' release-2.1.9-beta...release-2.1.10-stable
dist:
o Add getopt into dist archive (7042ff24 Azat Khuzhin)
functionality:
o evdns: add DNS_OPTION_NAMESERVERS_NO_DEFAULT/EVDNS_BASE_NAMESERVERS_NO_DEFAULT
(58e81106 Azat Khuzhin)
o Add support for EV_TIMEOUT to event_base_active_by_fd (3f893f0a John Ohl)
fixes:
o Merge branch 'evbuffer-fixes-806-v2' (2fea04b3 Azat Khuzhin)
o Merge branch 'issue-807-accept4-getnameinfo-AF_UNIX' (7c4da937, e2790a7f
Azat Khuzhin)
o kqueue: Avoid undefined behaviour. (e70e18e9 Tobias Stoeckmann)
o Prevent integer overflow in kq_build_changes_list. (43a55a23 Tobias Stoeckmann)
o evdns: fix lock/unlock mismatch in evdns_close_server_port() (54103883 zhuizhuhaomeng)
o Merge remote-tracking branch 'official/pr/804' -- Enforce limit of NSIG
signals (87fa93a8 Tobias Stoeckmann)
o Protect min_heap_push_ against integer overflow. (0b46bb8c Tobias Stoeckmann)
o le-proxy: initiate use of the Winsock DLL (2a1e1530 linxiaohui)
o Fix leaks in error path of the bufferevent_init_common_() (bb0f8fe7 Azat Khuzhin)
o buffer: make evbuffer_prepend() of zero-length array no-op (61fa7b7d Azat Khuzhin)
o Merge branch 'evbuffer-empty-chain-handling' (6a3dd717 Azat Khuzhin)
o Don't loose top error in SSL (3d1a7a1d Yury Korzhetsky)
o Remove needless check for arc4_seeded_ok (6602a97d Seong-Joong Kim)
o Merge pull request #769 from sungjungk/fix-return-handling (91084140 Nathan French)
build:
o Define `_GNU_SOURCE` properly/consistently per autoconf (00ba9fa2 Enji Cooper)
o signal: guard __cdecl definition with #ifdef (d89045a6 Azat Khuzhin)
o Link test/regress with event_core/event_extra over event (22380996 Azat Khuzhin)
tests:
o Use kill() over raise() for raising the signal (fixes osx 10.14 with
kqueue) (3db5296b, a45f6733 Azat Khuzhin)
o tinytest: implement per-test timeout (via alarm() under !win32 only)
(b64dbfb6, 75d7e1ff Azat Khuzhin)
Changes in version 2.1.9-beta (10 February 2019)
This changelog will differs from other releases in the next few clauses:
- contains only highlighted changes (so now it will not contains a lot of
patches that fixes some stuff in regression tests, typos, leaks fixes in
samples and so forth)
- no authors (since merge commits breaks them anyway, but AUTHORS sections in
README will be kept up to date)
- group name trimmed from commit subjects trimmed
- it's been 2 years since the previoius release, so it is pretty huge
And I think that this is more useful, so from now on it will always has the
same look (until there will too many objections of course).
To view full changelog please use git:
git log --format=' o %s (%h %aN)' release-2.1.8-stable...release-2.1.9-beta
dist archive:
o Add cmake rules into dist archive (bf3a67cf)
o Add missing print-winsock-errors.c into dist archive (822d6462)
o Include openssl-compat.h into dist archive (08658136)
core:
o Merge branch 'check-O_NONBLOCK-in-debug' (a39898f3, a8155c62)
o Merge branch 'event-ET-#636-v2' (ca4b6404)
o Fix visibility issues under (mostly on win32)
(349081e1g, 802be13ag, a1f28e2f)
o Define __EXT_POSIX2 for QNX (a2176f2c)
o Cleanup __func__ detection (b3af7bdd)
o Add convenience macros for user-triggered events (06ec5de6)
o Notify event base if there are no more events, so it can exit without delay (d9d1c09e)
o Fix base unlocking in event_del() if event_base_set() runned in another thread (4f0f40e3)
o If precise_time is false, we should not set EVENT_BASE_FLAG_PRECISE_TIMER (27dee54d)
o Fix race in access to ev_res from event loop with event_active() (43d92a6d)
o Return from event_del() after the last event callback termination (876c7ac7)
http:
o Merge branch 'http-EVHTTP_CON_READ_ON_WRITE_ERROR-fixes-v2' (eb7b472b)
o Preserve socket error from listen across closesocket cleanup (2ccd00a6)
o fix connection retries when there more then one request for connection (d30e7bba)
o improve error path for bufferevent_{setfd,enable,disable}() (a8cc449e)
o Fix conceivable UAF of the bufferevent in evhttp_connection_free() (6ac2ec25)
o Merge branch 'http-request-line-parsing' (cdcfbafe)
o Fix evhttp_connection_get_addr() fox incomming http connections (4215c003)
o fix leaks in evhttp_uriencode() (123362e9)
o CONNECT method only takes an authority (7d1ffe64)
o Allow bodies for GET/DELETE/OPTIONS/CONNECT (23eb38b9)
o Do not crash when evhttp_send_reply_start() is called after a timeout. (826f1134)
o Fix crashing http server when callback do not reply in place (5b40744d, b2581380)
o fix handling of close_notify (ssl) in http with openssl bufferevents (7e91622b)
evrpc:
o use *_new_with_arg() to match function prototype (a95cc9e3)
o avoid NULL dereference on request is not EVHTTP_REQ_POST (e05136c7)
regression tests:
o Merge branch 'TT_RETRIABLE' (6ea1ec68, f9b592aa)
bufferevent:
o Merge branch 'iocp-fixes' (6bfac964)
o Merge branch 'be-wm-overrun-v2' (3f692fff)
o bufferevent_socket_connect{,_hostname}() missing event callback and use ret code (1dde74ef)
o don't fail be_null_filter if bytes are copied (b92b0792)
o Call underlying bev ctrl GET_FD on filtered bufferevents (ebfac517)
bufferevent_openssl/openssl:
o Merge branch 'ssl_bufferevent_wm_filter-fix' (30020a35)
o be_openssl: avoid leaking of SSL structure (e86ccfe5)
o Fix build with LibreSSL 2.7 (894ca48a)
o Add missing includes into openssl-compat.h (01bc36c1)
o Explicitly call SSL_clear when reseting the fd. (29b7a516)
o Unbreak build with LibreSSL after openssl 1.1 support added (230af9f0)
samples:
o Merge branch 'sample-http-server' (b6309bcc)
o sample/https-client: use host SSL certificate store by default (5c0132f3)
listener:
o ipv6only socket bind support (ba148796)
o Merge branch 'listener-immediate-close' (df2ed13f)
o Merge branch 'evconnlistener-do-not-close-client-fd' (42e851bb)
evdns:
o evdns: handle NULL filename explicitly (0033f5cc)
o Merge branch 'evdns_getaddrinfo-race-fix' (3237d697)
o Generating evdns_base_config_windows_nameservers docs on all platforms (3bd2ce43)
utils:
o Merge branch 'evutil_found_ifaddr-dev' (b07e43e6)
o Avoid possible SEGVs in select() (in unit tests) (8818c86c)
o Port `event_rpcgen.py` and `test/check-dumpevents.py` to Python 3. (532a8cc3)
buffer:
o Fix assert() condition in evbuffer_drain() for IOCP (d6326104)
o fix incorrect unlock of the buffer mutex (for deferred callbacks) (2b4d127d)
o Fix wrong assert in evbuffer_drain() (9f4d0dce)
cmake:
o fix checking of devpoll backend (like in autotools, by devpoll.h existence) (7f161902)
o support static runtime (MSVC) (c8b3ec17, 61fb055a)
o do not build both (SHARED and STATIC) for MSVC/win32 (bc7f2fd9)
o introduce EVENT__LIBRARY_TYPE option (eb10a738)
o ensure windows dll's are installed as well as lib files (29590718)
o Fix generation of LibeventConfig.cmake for the installation tree (7fa08c4b)
o fix pkgconfig generation (copy-paste typo) (cc554d87)
o Merge branch 'cmake-missing-bits' (9806b126)
o Fix detection of timerfd_create() in CMake. (e50af331)
o Merge branch 'cmake-configure-fixes-v2' (a0bfe2c4)
o Do not add epoll_sub (syscall wrappers) for epoll in cmake (cea61de6)
o Fix RPATH for APPLE (45b1f379)
autotools:
o include win32 specific headers for socklen_t detection on win32/mingw (d7579fb9)
o Ignore evconfig-private.h for autotools (37423849)
o config.h can't be prefixed unconditionally (63a054f8)
o Merge branch 'pull-628' (7e56c8b2)
o Provide Makefile variables LIBEVENT_{CFLAGS,CPPFLAGS,LDFLAGS} (2f060c5f)
o confirm openssl is working before using (b39ccf8e)
o pass $(OPENSSL_INCS) for samples (FTBFS macOS) (c2495265)
o Add configure check for midipix (d433201e)
o Fix tests with detached builds (c46ff439)
build:
o Fix arc4random_addrandom() detecting and fallback (regression) (303d6d77)
o Merge branch 'win32-fixes' (ebd12e6d)
o Merge branch 'fix-openssl-linking' (e7bd9e03)
o Merge branch 'fix-struct-linger' (8567f2f5)
CI:
o travis-ci/appveyor now uses fast_finish+allow_failures
(5e97b6e6, dd472e7d, dfb5fc167)
o Merge branch 'travis-ci-osx-fixes' (9f02b39c)
o Merge branch 'win64-fixes' (aee0fcd5)
Changes in version 2.1.8-stable (22 January 2017)
Libevent 2.1.8-stable, it contains openssl fixes for resetting fd and using

View File

@ -175,7 +175,7 @@ Changes in 1.4.1-beta:
o support for 32-bit tag numbers in rpc structures; this is wire compatible, but changes the API slightly.
o prefix {encode,decode}_tag functions with evtag to avoid collisions
o Correctly handle DNS replies with no answers set (Fixes bug 1846282)
o The configure script now takes an --enable-gcc-warnigns option that turns on many optional gcc warnings. (Nick has been building with these for a while, but they might be useful to other developers.)
o The configure script now takes an --enable-gcc-warnings option that turns on many optional gcc warnings. (Nick has been building with these for a while, but they might be useful to other developers.)
o When building with GCC, use the "format" attribute to verify type correctness of calls to printf-like functions.
o removed linger from http server socket; reported by Ilya Martynov
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.

View File

@ -1143,7 +1143,7 @@ Changes in 2.0.1-alpha (17 Apr 2009):
o Check return value of event_add in signal.c
o Add a more powerful evbuffer_readln as a replacement for evbuffer_readline. The new function handles more newline styles, and is more useful with buffers that may contain a nul characters.
o Do not mangle socket handles on 64-bit windows.
o The configure script now takes an --enable-gcc-warnigns option that turns on many optional gcc warnings. (Nick has been building with these for a while, but they might be useful to other developers.)
o The configure script now takes an --enable-gcc-warnings option that turns on many optional gcc warnings. (Nick has been building with these for a while, but they might be useful to other developers.)
o move EV_PERSIST handling out of the event backends
o small improvements to evhttp documentation
o always generate Date and Content-Length headers for HTTP/1.1 replies

View File

@ -17,11 +17,11 @@
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = libevent
PROJECT_NAME = $(PROJECT)-$(VERSION)
# Place all output under 'doxygen/'
OUTPUT_DIRECTORY = doxygen/
OUTPUT_DIRECTORY = $(DOCDIR)
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
@ -64,24 +64,24 @@ STRIP_FROM_PATH = include/
# with spaces.
INPUT = \
include/event2/buffer.h \
include/event2/buffer_compat.h \
include/event2/bufferevent.h \
include/event2/bufferevent_compat.h \
include/event2/bufferevent_ssl.h \
include/event2/dns.h \
include/event2/dns_compat.h \
include/event2/event.h \
include/event2/event_compat.h \
include/event2/http.h \
include/event2/http_compat.h \
include/event2/listener.h \
include/event2/rpc.h \
include/event2/rpc_compat.h \
include/event2/tag.h \
include/event2/tag_compat.h \
include/event2/thread.h \
include/event2/util.h
$(SRCDIR)/include/event2/buffer.h \
$(SRCDIR)/include/event2/buffer_compat.h \
$(SRCDIR)/include/event2/bufferevent.h \
$(SRCDIR)/include/event2/bufferevent_compat.h \
$(SRCDIR)/include/event2/bufferevent_ssl.h \
$(SRCDIR)/include/event2/dns.h \
$(SRCDIR)/include/event2/dns_compat.h \
$(SRCDIR)/include/event2/event.h \
$(SRCDIR)/include/event2/event_compat.h \
$(SRCDIR)/include/event2/http.h \
$(SRCDIR)/include/event2/http_compat.h \
$(SRCDIR)/include/event2/listener.h \
$(SRCDIR)/include/event2/rpc.h \
$(SRCDIR)/include/event2/rpc_compat.h \
$(SRCDIR)/include/event2/tag.h \
$(SRCDIR)/include/event2/tag_compat.h \
$(SRCDIR)/include/event2/thread.h \
$(SRCDIR)/include/event2/util.h
#---------------------------------------------------------------------------
# configuration options related to the HTML output
@ -90,7 +90,7 @@ INPUT = \
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
GENERATE_HTML = $(GENERATE_HTML)
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
@ -99,7 +99,7 @@ GENERATE_HTML = YES
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = YES
GENERATE_LATEX = $(GENERATE_LATEX)
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
@ -175,7 +175,7 @@ LATEX_HIDE_INDICES = NO
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
GENERATE_MAN = $(GENERATE_MAN)
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)

View File

@ -5,8 +5,8 @@
# See LICENSE for copying information.
# 'foreign' means that we're not enforcing GNU package rules strictly.
# '1.9' means that we need automake 1.9 or later (and we do).
AUTOMAKE_OPTIONS = foreign 1.9 subdir-objects
# '1.13' means that we need automake 1.13 or later (and we do).
AUTOMAKE_OPTIONS = foreign 1.13 subdir-objects
ACLOCAL_AMFLAGS = -I m4
@ -38,7 +38,7 @@ RELEASE = -release 2.1
#
# Once an RC is out, DO NOT MAKE ANY ABI-BREAKING CHANGES IN THAT SERIES
# UNLESS YOU REALLY REALLY HAVE TO.
VERSION_INFO = 6:2:0
VERSION_INFO = 7:1:0
# History: RELEASE VERSION_INFO
# 2.0.1-alpha -- 2.0 1:0:0
@ -71,7 +71,11 @@ VERSION_INFO = 6:2:0
# 2.1.5-beta -- 2.1 5:0:0 (ABI changed slightly)
# 2.1.6-beta -- 2.1 6:0:0 (ABI changed slightly)
# 2.1.7-beta -- 2.1 6:1:0 (ABI changed slightly)
# 2.1.8-stable-- 2.1 6:2:0 (ABI changed slightly)
# 2.1.8-stable-- 2.1 6:2:0 (No ABI change)
# 2.1.9-beta-- 2.1 6:3:0 (No ABI change)
# 2.1.10-stable-- 2.1 6:4:0 (No ABI change, WRONG)
# 2.1.11-stable-- 2.1 7:0:0 (ABI changed)
# 2.1.12-stable-- 2.1 7:1:0 (No ABI change)
# ABI version history for this package effectively restarts every time
# we change RELEASE. Version 1.4.x had RELEASE of 1.4.
@ -104,6 +108,29 @@ PLATFORM_DEPENDENT_SRC = \
arc4random.c \
epoll_sub.c
CMAKE_FILES = \
cmake/AddCompilerFlags.cmake \
cmake/AddEventLibrary.cmake \
cmake/CheckConstExists.cmake \
cmake/CheckFileOffsetBits.c \
cmake/CheckFileOffsetBits.cmake \
cmake/CheckFunctionKeywords.cmake \
cmake/CheckPrototypeDefinition.c.in \
cmake/CheckPrototypeDefinition.cmake \
cmake/CheckWorkingKqueue.cmake \
cmake/CodeCoverage.cmake \
cmake/COPYING-CMAKE-SCRIPTS \
cmake/Copyright.txt \
cmake/LibeventConfig.cmake.in \
cmake/LibeventConfigVersion.cmake.in \
cmake/Macros.cmake \
cmake/Uninstall.cmake.in \
cmake/UseDoxygen.cmake \
cmake/VersionViaGit.cmake \
event-config.h.cmake \
evconfig-private.h.cmake \
CMakeLists.txt
EXTRA_DIST = \
ChangeLog-1.4 \
ChangeLog-2.0 \
@ -116,6 +143,8 @@ EXTRA_DIST = \
make-event-config.sed \
whatsnew-2.0.txt \
whatsnew-2.1.txt \
README.md \
$(CMAKE_FILES) \
$(PLATFORM_DEPENDENT_SRC)
LIBEVENT_LIBS_LA = libevent.la libevent_core.la libevent_extra.la
@ -148,6 +177,7 @@ include test/include.am
if BUILD_WIN32
SYS_CORE_LIBS = -liphlpapi
SYS_LIBS = -lws2_32 -lshell32 -ladvapi32
SYS_SRC = win32select.c buffer_iocp.c event_iocp.c \
bufferevent_async.c
@ -159,6 +189,7 @@ endif
else
SYS_CORE_LIBS =
SYS_LIBS =
SYS_SRC =
SYS_INCLUDES =
@ -228,14 +259,18 @@ NO_UNDEFINED =
MAYBE_CORE =
endif
GENERIC_LDFLAGS = -version-info $(VERSION_INFO) $(RELEASE) $(NO_UNDEFINED)
AM_CFLAGS = $(LIBEVENT_CFLAGS)
AM_CPPFLAGS = -I$(srcdir)/compat -I./include -I$(srcdir)/include $(SYS_INCLUDES) $(LIBEVENT_CPPFLAGS)
AM_LDFLAGS = $(LIBEVENT_LDFLAGS)
GENERIC_LDFLAGS = -version-info $(VERSION_INFO) $(RELEASE) $(NO_UNDEFINED) $(AM_LDFLAGS)
libevent_la_SOURCES = $(CORE_SRC) $(EXTRAS_SRC)
libevent_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS)
libevent_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS) $(SYS_CORE_LIBS)
libevent_la_LDFLAGS = $(GENERIC_LDFLAGS)
libevent_core_la_SOURCES = $(CORE_SRC)
libevent_core_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS)
libevent_core_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS) $(SYS_CORE_LIBS)
libevent_core_la_LDFLAGS = $(GENERIC_LDFLAGS)
if PTHREADS
@ -258,14 +293,16 @@ endif
noinst_HEADERS += \
WIN32-Code/nmake/evconfig-private.h \
WIN32-Code/nmake/event2/event-config.h \
WIN32-Code/getopt.h \
WIN32-Code/getopt.c \
WIN32-Code/getopt_long.c \
WIN32-Code/tree.h \
bufferevent-internal.h \
changelist-internal.h \
bufferevent-internal.h \
changelist-internal.h \
compat/sys/queue.h \
defer-internal.h \
epolltable-internal.h \
epolltable-internal.h \
evbuffer-internal.h \
evconfig-private.h \
event-internal.h \
evmap-internal.h \
evrpc-internal.h \
@ -283,7 +320,7 @@ noinst_HEADERS += \
ratelim-internal.h \
strlcpy-internal.h \
time-internal.h \
util-internal.h \
util-internal.h \
openssl-compat.h
EVENT1_HDRS = \
@ -299,13 +336,9 @@ else
noinst_HEADERS += $(EVENT1_HDRS)
endif
AM_CPPFLAGS = -I$(srcdir)/compat -I$(srcdir)/include -I./include $(SYS_INCLUDES)
verify: check
doxygen: FORCE
doxygen $(srcdir)/Doxyfile
FORCE:
include doxygen.am
DISTCLEANFILES += *~ libevent.pc libevent_core.pc libevent_extra.pc ./include/event2/event-config.h

File diff suppressed because it is too large Load Diff

487
contrib/libevent/README.md Normal file
View File

@ -0,0 +1,487 @@
<p align="center">
<img src="https://strcpy.net/libevent3.png" alt="libevent logo"/>
</p>
[![Appveyor Win32 Build Status](https://ci.appveyor.com/api/projects/status/ng3jg0uhy44mp7ik?svg=true)](https://ci.appveyor.com/project/libevent/libevent)
[![Travis Build Status](https://travis-ci.org/libevent/libevent.svg?branch=master)](https://travis-ci.org/libevent/libevent)
[![Coverage Status](https://coveralls.io/repos/github/libevent/libevent/badge.svg)](https://coveralls.io/github/libevent/libevent)
[![Join the chat at https://gitter.im/libevent/libevent](https://badges.gitter.im/libevent/libevent.svg)](https://gitter.im/libevent/libevent?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# 0. BUILDING AND INSTALLATION (Briefly)
## Autoconf
$ ./configure
$ make
$ make verify # (optional)
$ sudo make install
## CMake (General)
The following Libevent specific CMake variables are as follows (the values being
the default).
```
# Type of the library to build (SHARED or STATIC)
# Default is: SHARED for MSVC, otherwise BOTH
EVENT__LIBRARY_TYPE:STRING=DEFAULT
# Installation directory for CMake files
EVENT_INSTALL_CMAKE_DIR:PATH=lib/cmake/libevent
# Enable running gcov to get a test coverage report (only works with
# GCC/CLang). Make sure to enable -DCMAKE_BUILD_TYPE=Debug as well.
EVENT__COVERAGE:BOOL=OFF
# Defines if Libevent should build without the benchmark executables
EVENT__DISABLE_BENCHMARK:BOOL=OFF
# Define if Libevent should build without support for a debug mode
EVENT__DISABLE_DEBUG_MODE:BOOL=OFF
# Define if Libevent should not allow replacing the mm functions
EVENT__DISABLE_MM_REPLACEMENT:BOOL=OFF
# Define if Libevent should build without support for OpenSSL encryption
EVENT__DISABLE_OPENSSL:BOOL=OFF
# Disable the regress tests
EVENT__DISABLE_REGRESS:BOOL=OFF
# Disable sample files
EVENT__DISABLE_SAMPLES:BOOL=OFF
# If tests should be compiled or not
EVENT__DISABLE_TESTS:BOOL=OFF
# Define if Libevent should not be compiled with thread support
EVENT__DISABLE_THREAD_SUPPORT:BOOL=OFF
# Enables verbose debugging
EVENT__ENABLE_VERBOSE_DEBUG:BOOL=OFF
# When cross compiling, forces running a test program that verifies that Kqueue
# works with pipes. Note that this requires you to manually run the test program
# on the the cross compilation target to verify that it works. See CMake
# documentation for try_run for more details
EVENT__FORCE_KQUEUE_CHECK:BOOL=OFF
```
__More variables can be found by running `cmake -LAH <sourcedir_path>`__
## CMake (Windows)
Install CMake: <https://www.cmake.org>
$ md build && cd build
$ cmake -G "Visual Studio 10" .. # Or whatever generator you want to use cmake --help for a list.
$ start libevent.sln
## CMake (Unix)
$ mkdir build && cd build
$ cmake .. # Default to Unix Makefiles.
$ make
$ make verify # (optional)
# 1. BUILDING AND INSTALLATION (In Depth)
## Autoconf
To build Libevent, type
$ ./configure && make
(If you got Libevent from the git repository, you will
first need to run the included "autogen.sh" script in order to
generate the configure script.)
You can run the regression tests by running
$ make verify
Install as root via
$ make install
Before reporting any problems, please run the regression tests.
To enable low-level tracing, build the library as:
$ CFLAGS=-DUSE_DEBUG ./configure [...]
Standard configure flags should work. In particular, see:
--disable-shared Only build static libraries.
--prefix Install all files relative to this directory.
The configure script also supports the following flags:
--enable-gcc-warnings Enable extra compiler checking with GCC.
--disable-malloc-replacement
Don't let applications replace our memory
management functions.
--disable-openssl Disable support for OpenSSL encryption.
--disable-thread-support Don't support multithreaded environments.
## CMake (Windows)
(Note that autoconf is currently the most mature and supported build
environment for Libevent; the CMake instructions here are new and
experimental, though they _should_ be solid. We hope that CMake will
still be supported in future versions of Libevent, and will try to
make sure that happens.)
First of all install <https://www.cmake.org>.
To build Libevent using Microsoft Visual studio open the "Visual Studio Command prompt" and type:
```
$ cd <libevent source dir>
$ mkdir build && cd build
$ cmake -G "Visual Studio 10" .. # Or whatever generator you want to use cmake --help for a list.
$ start libevent.sln
```
In the above, the ".." refers to the dir containing the Libevent source code.
You can build multiple versions (with different compile time settings) from the same source tree
by creating other build directories.
It is highly recommended to build "out of source" when using
CMake instead of "in source" like the normal behaviour of autoconf for this reason.
The "NMake Makefiles" CMake generator can be used to build entirely via the command line.
To get a list of settings available for the project you can type:
```
$ cmake -LH ..
```
### GUI
CMake also provides a GUI that lets you specify the source directory and output (binary) directory
that the build should be placed in.
# 2. USEFUL LINKS:
For the latest released version of Libevent, see the official website at
<http://libevent.org/> .
There's a pretty good work-in-progress manual up at
<http://www.wangafu.net/~nickm/libevent-book/> .
For the latest development versions of Libevent, access our Git repository
via
```
$ git clone https://github.com/libevent/libevent.git
```
You can browse the git repository online at:
<https://github.com/libevent/libevent>
To report bugs, issues, or ask for new features:
__Patches__: https://github.com/libevent/libevent/pulls
> OK, those are not really _patches_. You fork, modify, and hit the "Create Pull Request" button.
> You can still submit normal git patches via the mailing list.
__Bugs, Features [RFC], and Issues__: https://github.com/libevent/libevent/issues
> Or you can do it via the mailing list.
There's also a libevent-users mailing list for talking about Libevent
use and development:
<http://archives.seul.org/libevent/users/>
# 3. ACKNOWLEDGMENTS
The following people have helped with suggestions, ideas, code or
fixing bugs:
* Samy Al Bahra
* Antony Antony
* Jacob Appelbaum
* Arno Bakker
* Weston Andros Adamson
* William Ahern
* Ivan Andropov
* Sergey Avseyev
* Avi Bab
* Joachim Bauch
* Andrey Belobrov
* Gilad Benjamini
* Stas Bekman
* Denis Bilenko
* Julien Blache
* Kevin Bowling
* Tomash Brechko
* Kelly Brock
* Ralph Castain
* Adrian Chadd
* Lawnstein Chan
* Shuo Chen
* Ka-Hing Cheung
* Andrew Cox
* Paul Croome
* George Danchev
* Andrew Danforth
* Ed Day
* Christopher Davis
* Mike Davis
* Frank Denis
* Antony Dovgal
* Mihai Draghicioiu
* Alexander Drozdov
* Mark Ellzey
* Shie Erlich
* Leonid Evdokimov
* Juan Pablo Fernandez
* Christophe Fillot
* Mike Frysinger
* Remi Gacogne
* Artem Germanov
* Alexander von Gernler
* Diego Giagio
* Artur Grabowski
* Diwaker Gupta
* Kuldeep Gupta
* Sebastian Hahn
* Dave Hart
* Greg Hazel
* Nicholas Heath
* Michael Herf
* Savg He
* Mark Heily
* Maxime Henrion
* Michael Herf
* Greg Hewgill
* Andrew Hochhaus
* Aaron Hopkins
* Tani Hosokawa
* Jamie Iles
* Xiuqiang Jiang
* Claudio Jeker
* Evan Jones
* Marcin Juszkiewicz
* George Kadianakis
* Makoto Kato
* Phua Keat
* Azat Khuzhin
* Alexander Klauer
* Kevin Ko
* Brian Koehmstedt
* Marko Kreen
* Ondřej Kuzník
* Valery Kyholodov
* Ross Lagerwall
* Scott Lamb
* Christopher Layne
* Adam Langley
* Graham Leggett
* Volker Lendecke
* Philip Lewis
* Zhou Li
* David Libenzi
* Yan Lin
* Moshe Litvin
* Simon Liu
* Mitchell Livingston
* Hagne Mahre
* Lubomir Marinov
* Abilio Marques
* Nicolas Martyanoff
* Abel Mathew
* Nick Mathewson
* James Mansion
* Nicholas Marriott
* Andrey Matveev
* Caitlin Mercer
* Dagobert Michelsen
* Andrea Montefusco
* Mansour Moufid
* Mina Naguib
* Felix Nawothnig
* Trond Norbye
* Linus Nordberg
* Richard Nyberg
* Jon Oberheide
* John Ohl
* Phil Oleson
* Alexey Ozeritsky
* Dave Pacheco
* Derrick Pallas
* Tassilo von Parseval
* Catalin Patulea
* Patrick Pelletier
* Simon Perreault
* Dan Petro
* Pierre Phaneuf
* Amarin Phaosawasdi
* Ryan Phillips
* Dimitre Piskyulev
* Pavel Plesov
* Jon Poland
* Roman Puls
* Nate R
* Robert Ransom
* Balint Reczey
* Bert JW Regeer
* Nate Rosenblum
* Peter Rosin
* Maseeb Abdul Qadir
* Wang Qin
* Alex S
* Gyepi Sam
* Hanna Schroeter
* Ralf Schmitt
* Mike Smellie
* Steve Snyder
* Nir Soffer
* Dug Song
* Dongsheng Song
* Hannes Sowa
* Joakim Soderberg
* Joseph Spadavecchia
* Kevin Springborn
* Harlan Stenn
* Andrew Sweeney
* Ferenc Szalai
* Brodie Thiesfield
* Jason Toffaletti
* Brian Utterback
* Gisle Vanem
* Bas Verhoeven
* Constantine Verutin
* Colin Watt
* Zack Weinberg
* Jardel Weyrich
* Jay R. Wren
* Zack Weinberg
* Mobai Zhang
* Alejo
* Alex
* Taral
* propanbutan
* masksqwe
* mmadia
* yangacer
* Andrey Skriabin
* basavesh.as
* billsegall
* Bill Vaughan
* Christopher Wiley
* David Paschich
* Ed Schouten
* Eduardo Panisset
* Jan Heylen
* jer-gentoo
* Joakim Söderberg
* kirillDanshin
* lzmths
* Marcus Sundberg
* Mark Mentovai
* Mattes D
* Matyas Dolak
* Neeraj Badlani
* Nick Mathewson
* Rainer Keller
* Seungmo Koo
* Thomas Bernard
* Xiao Bao Clark
* zeliard
* Zonr Chang
* Kurt Roeckx
* Seven
* Simone Basso
* Vlad Shcherban
* Tim Hentenaar
* Breaker
* johnsonlee
* Philip Prindeville
* Vis Virial
* Andreas Gustafsson
* Andrey Okoshkin
* an-tao
* baixiangcpp
* Bernard Spil
* Bogdan Harjoc
* Carlo Marcelo Arenas Belón
* David Benjamin
* David Disseldorp
* Dmitry Alimov
* Dominic Chen
* dpayne
* ejurgensen
* Fredrik Strupe
* Gonçalo Ribeiro
* James Synge
* Jan Beich
* Jesse Fang
* Jiri Luznicky
* José Luis Millán
* Kiyoshi Aman
* Leo Zhang
* lightningkay
* Luke Dashjr
* Marcin Szewczyk
* Maximilian Brunner
* Maya Rashish
* Murat Demirten
* Nathan French
* Nikolay Edigaryev
* Philip Herron
* Redfoxmoon
* stenn
* SuckShit
* The Gitter Badger
* tim-le
* Vincent JARDIN
* Xiang Zhang
* Xiaozhou Liu
* yongqing.jiao
* Enji Cooper
* linxiaohui
* Seong-Joong Kim
* Tobias Stoeckmann
* Yury Korzhetsky
* zhuizhuhaomeng
* Pierce Lopez
* yuangongji
* Keith Smiley
* jeremyerb
* Fabrice Fontaine
* wenyg
* Aleksandr-Melnikov
* ayuseleznev
* chenguolong
* Dimo Markov
* dota17
* fanquake
* Jan Kasiak
* Kamil Rytarowski
* Mario Emmenlauer
* Michael Davidsaver
* mohuang
* Nick Grifka
* Nicolas J. Bouliane
* Paul Osborne
* Philip Homburg
* Wataru Ashihara
* William A Rowe Jr
* yangyongsheng
If we have forgotten your name, please contact us.

View File

@ -0,0 +1,149 @@
/* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */
/*
* Copyright (c) 1987, 1993, 1994, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if 0
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
#endif
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define __P(x) x
#define _DIAGASSERT(x) assert(x)
#ifdef __weak_alias
__weak_alias(getopt,_getopt);
#endif
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
static char * _progname __P((char *));
int getopt_internal __P((int, char * const *, const char *));
static char *
_progname(nargv0)
char * nargv0;
{
char * tmp;
_DIAGASSERT(nargv0 != NULL);
tmp = strrchr(nargv0, '/');
if (tmp)
tmp++;
else
tmp = nargv0;
return(tmp);
}
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char * const nargv[];
const char *ostr;
{
static char *__progname = 0;
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
__progname = __progname?__progname:_progname(*nargv);
_DIAGASSERT(nargv != NULL);
_DIAGASSERT(ostr != NULL);
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-' /* found "--" */
&& place[1] == '\0') {
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname, optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__progname, optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}

View File

@ -0,0 +1,33 @@
#ifndef __GETOPT_H__
#define __GETOPT_H__
#ifdef __cplusplus
extern "C" {
#endif
extern int opterr; /* if error message should be printed */
extern int optind; /* index into parent argv vector */
extern int optopt; /* character checked for validity */
extern int optreset; /* reset getopt */
extern char *optarg; /* argument associated with option */
struct option
{
const char *name;
int has_arg;
int *flag;
int val;
};
#define no_argument 0
#define required_argument 1
#define optional_argument 2
int getopt(int, char**, const char*);
int getopt_long(int, char**, const char*, const struct option*, int*);
#ifdef __cplusplus
}
#endif
#endif /* __GETOPT_H__ */

View File

@ -0,0 +1,234 @@
/*
* Copyright (c) 1987, 1993, 1994, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
extern int opterr; /* if error message should be printed */
extern int optind; /* index into parent argv vector */
extern int optopt; /* character checked for validity */
extern int optreset; /* reset getopt */
extern char *optarg; /* argument associated with option */
#define __P(x) x
#define _DIAGASSERT(x) assert(x)
static char * __progname __P((char *));
int getopt_internal __P((int, char * const *, const char *));
static char *
__progname(nargv0)
char * nargv0;
{
char * tmp;
_DIAGASSERT(nargv0 != NULL);
tmp = strrchr(nargv0, '/');
if (tmp)
tmp++;
else
tmp = nargv0;
return(tmp);
}
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt_internal(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
_DIAGASSERT(nargv != NULL);
_DIAGASSERT(ostr != NULL);
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
/* ++optind; */
place = EMSG;
return (-2);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname(nargv[0]), optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
} else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if ((opterr) && (*ostr != ':'))
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__progname(nargv[0]), optopt);
return (BADARG);
} else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}
#if 0
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt2(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
int retval;
if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) {
retval = -1;
++optind;
}
return(retval);
}
#endif
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(nargc, nargv, options, long_options, index)
int nargc;
char ** nargv;
const char * options;
const struct option * long_options;
int * index;
{
int retval;
_DIAGASSERT(nargv != NULL);
_DIAGASSERT(options != NULL);
_DIAGASSERT(long_options != NULL);
/* index may be NULL */
if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
char *current_argv = nargv[optind++] + 2, *has_equal;
int i, match = -1;
size_t current_argv_len;
if (*current_argv == '\0') {
return(-1);
}
if ((has_equal = strchr(current_argv, '=')) != NULL) {
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
if (strncmp(current_argv, long_options[i].name, current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
match = i;
break;
}
if (match == -1)
match = i;
}
if (match != -1) {
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else
optarg = nargv[optind++];
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument, leading :
* indicates no error should be generated
*/
if ((opterr) && (*options != ':'))
(void)fprintf(stderr,
"%s: option requires an argument -- %s\n",
__progname(nargv[0]), current_argv);
return (BADARG);
}
} else { /* No matching argument */
if ((opterr) && (*options != ':'))
(void)fprintf(stderr,
"%s: illegal option -- %s\n", __progname(nargv[0]), current_argv);
return (BADCH);
}
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
retval = 0;
} else
retval = long_options[match].val;
if (index)
*index = match;
}
return(retval);
}

View File

@ -192,9 +192,6 @@
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1
/* Define to 1 if you have the <sys/devpoll.h> header file. */
/* #undef EVENT__HAVE_SYS_DEVPOLL_H */
/* Define to 1 if you have the <sys/epoll.h> header file. */
/* #undef EVENT__HAVE_SYS_EPOLL_H */
@ -274,7 +271,7 @@
/* #undef EVENT__HAVE_WORKING_KQUEUE */
/* Numeric representation of the version */
#define EVENT__NUMERIC_VERSION 0x02010800
#define EVENT__NUMERIC_VERSION 0x02010c00
/* Name of package */
#define EVENT__PACKAGE "libevent"
@ -324,29 +321,22 @@
#define EVENT__SIZEOF_VOID_P 4
#endif
/* Define to 1 if you have the ANSI C header files. */
#define EVENT__STDC_HEADERS 1
/* The size of `time_t`, as computed by sizeof. */
#ifdef _WIN64
#define EVENT__SIZEOF_TIME_T 8
#else
#define EVENT__SIZEOF_TIME_T 4
#endif
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define EVENT__TIME_WITH_SYS_TIME 1
/* Version number of package */
#define EVENT__VERSION "2.1.8-stable"
/* Define to appropriate substitue if compiler doesnt have __func__ */
#define EVENT____func__ __FUNCTION__
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef EVENT__const */
#define EVENT__VERSION "2.1.12-stable"
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef _EVENT___cplusplus
#define EVENT__inline __inline
#endif
/* Define to `int' if <sys/types.h> does not define. */
/* #undef EVENT__pid_t */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef EVENT__size_t */

View File

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15 -*- Autoconf -*-
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.15'
[am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.15], [],
m4_if([$1], [1.16.2], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.15])dnl
[AM_AUTOMAKE_VERSION([1.16.2])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -332,13 +332,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@ -346,49 +345,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
*\'*) eval set x "$CONFIG_FILES" ;;
*) set x $CONFIG_FILES ;;
esac
# TODO: see whether this extra hack can be removed once we start
# requiring Autoconf 2.70 or later.
AS_CASE([$CONFIG_FILES],
[*\'*], [eval set x "$CONFIG_FILES"],
[*], [set x $CONFIG_FILES])
shift
for mf
# Used to flag and report bootstrapping failures.
am_rc=0
for am_mf
do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile which includes
# dependency-tracking related rules and includes.
# Grep'ing the whole file directly is not great: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
|| continue
am_dirpart=`AS_DIRNAME(["$am_mf"])`
am_filepart=`AS_BASENAME(["$am_mf"])`
AM_RUN_LOG([cd "$am_dirpart" \
&& sed -e '/# am--include-marker/d' "$am_filepart" \
| $MAKE -f - am--depfiles]) || am_rc=$?
done
if test $am_rc -ne 0; then
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. If GNU make was not used, consider
re-running the configure script with MAKE="gmake" (or whatever is
necessary). You can also try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).])
fi
AS_UNSET([am_dirpart])
AS_UNSET([am_filepart])
AS_UNSET([am_mf])
AS_UNSET([am_rc])
rm -f conftest-deps.mk
}
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
@ -397,18 +390,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each '.P' file that we will
# need in order to bootstrap the dependency handling code.
# This code is only required when automatic dependency tracking is enabled.
# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
# order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
[AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -495,8 +487,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# For better backward compatibility. To be removed once Automake 1.9.x
# dies out for good. For more background, see:
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target (and possibly the TAP driver). The
# system "awk" is bad on some platforms.
@ -563,7 +555,7 @@ END
Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation
that behaves properly: <http://www.gnu.org/software/coreutils/>.
that behaves properly: <https://www.gnu.org/software/coreutils/>.
If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@ -605,7 +597,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -626,7 +618,7 @@ if test x"${install_sh+set}" != xset; then
fi
AC_SUBST([install_sh])])
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
# Copyright (C) 2003-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -647,7 +639,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -655,49 +647,42 @@ AC_SUBST([am__leading_dot])])
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
# Check whether make has an 'include' directive that can support all
# the idioms we need for our automatic dependency tracking code.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
cat > confinc.mk << 'END'
am__doit:
@echo this is the am__doit target
@echo this is the am__doit target >confinc.out
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
am__quote=
_am_result=GNU
;;
esac
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=.include
am__quote="\""
_am_result=BSD
;;
esac
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# BSD make does it like this.
echo '.include "confinc.mk" # ignored' > confmf.BSD
# Other make implementations (GNU, Solaris 10, AIX) do it like this.
echo 'include confinc.mk # ignored' > confmf.GNU
_am_result=no
for s in GNU BSD; do
AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
AS_CASE([$?:`cat confinc.out 2>/dev/null`],
['0:this is the am__doit target'],
[AS_CASE([$s],
[BSD], [am__include='.include' am__quote='"'],
[am__include='include' am__quote=''])])
if test "$am__include" != "#"; then
_am_result="yes ($s style)"
break
fi
done
rm -f confinc.* confmf.*
AC_MSG_RESULT([${_am_result}])
AC_SUBST([am__include])])
AC_SUBST([am__quote])])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -736,7 +721,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -765,7 +750,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -812,7 +797,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -831,7 +816,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -912,7 +897,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
# Copyright (C) 2009-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -972,7 +957,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1000,7 +985,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1019,7 +1004,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004-2014 Free Software Foundation, Inc.
# Copyright (C) 2004-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1152,6 +1137,8 @@ AC_SUBST([am__untar])
m4_include([m4/ac_backport_259_ssizet.m4])
m4_include([m4/acx_pthread.m4])
m4_include([m4/ax_check_funcs_ex.m4])
m4_include([m4/ax_prog_doxygen.m4])
m4_include([m4/libevent_openssl.m4])
m4_include([m4/libtool.m4])
m4_include([m4/ltoptions.m4])

View File

@ -54,6 +54,7 @@
#ifdef _WIN32
#include <wincrypt.h>
#include <process.h>
#include <winerror.h>
#else
#include <fcntl.h>
#include <unistd.h>
@ -62,6 +63,9 @@
#ifdef EVENT__HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#ifdef EVENT__HAVE_SYS_RANDOM_H
#include <sys/random.h>
#endif
#endif
#include <limits.h>
#include <stdlib.h>
@ -89,7 +93,6 @@ static int rs_initialized;
static struct arc4_stream rs;
static pid_t arc4_stir_pid;
static int arc4_count;
static int arc4_seeded_ok;
static inline unsigned char arc4_getbyte(void);
@ -163,22 +166,15 @@ arc4_seed_win32(void)
return -1;
arc4_addrandom(buf, sizeof(buf));
evutil_memclear_(buf, sizeof(buf));
arc4_seeded_ok = 1;
return 0;
}
#endif
#if defined(EVENT__HAVE_SYS_SYSCTL_H) && defined(EVENT__HAVE_SYSCTL)
#if EVENT__HAVE_DECL_CTL_KERN && EVENT__HAVE_DECL_KERN_RANDOM && EVENT__HAVE_DECL_RANDOM_UUID
#define TRY_SEED_SYSCTL_LINUX
#if defined(EVENT__HAVE_GETRANDOM)
#define TRY_SEED_GETRANDOM
static int
arc4_seed_sysctl_linux(void)
arc4_seed_getrandom(void)
{
/* Based on code by William Ahern, this function tries to use the
* RANDOM_UUID sysctl to get entropy from the kernel. This can work
* even if /dev/urandom is inaccessible for some reason (e.g., we're
* running in a chroot). */
int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
unsigned char buf[ADD_ENTROPY];
size_t len, n;
unsigned i;
@ -189,7 +185,7 @@ arc4_seed_sysctl_linux(void)
for (len = 0; len < sizeof(buf); len += n) {
n = sizeof(buf) - len;
if (0 != sysctl(mib, 3, &buf[len], &n, NULL, 0))
if (0 == getrandom(&buf[len], n, 0))
return -1;
}
/* make sure that the buffer actually got set. */
@ -201,11 +197,11 @@ arc4_seed_sysctl_linux(void)
arc4_addrandom(buf, sizeof(buf));
evutil_memclear_(buf, sizeof(buf));
arc4_seeded_ok = 1;
return 0;
}
#endif
#endif /* EVENT__HAVE_GETRANDOM */
#if defined(EVENT__HAVE_SYS_SYSCTL_H) && defined(EVENT__HAVE_SYSCTL)
#if EVENT__HAVE_DECL_CTL_KERN && EVENT__HAVE_DECL_KERN_ARND
#define TRY_SEED_SYSCTL_BSD
static int
@ -241,7 +237,6 @@ arc4_seed_sysctl_bsd(void)
arc4_addrandom(buf, sizeof(buf));
evutil_memclear_(buf, sizeof(buf));
arc4_seeded_ok = 1;
return 0;
}
#endif
@ -287,7 +282,6 @@ arc4_seed_proc_sys_kernel_random_uuid(void)
}
evutil_memclear_(entropy, sizeof(entropy));
evutil_memclear_(buf, sizeof(buf));
arc4_seeded_ok = 1;
return 0;
}
#endif
@ -311,7 +305,6 @@ static int arc4_seed_urandom_helper_(const char *fname)
return -1;
arc4_addrandom(buf, sizeof(buf));
evutil_memclear_(buf, sizeof(buf));
arc4_seeded_ok = 1;
return 0;
}
@ -347,6 +340,10 @@ arc4_seed(void)
if (0 == arc4_seed_win32())
ok = 1;
#endif
#ifdef TRY_SEED_GETRANDOM
if (0 == arc4_seed_getrandom())
ok = 1;
#endif
#ifdef TRY_SEED_URANDOM
if (0 == arc4_seed_urandom())
ok = 1;
@ -356,12 +353,6 @@ arc4_seed(void)
0 == arc4_seed_proc_sys_kernel_random_uuid())
ok = 1;
#endif
#ifdef TRY_SEED_SYSCTL_LINUX
/* Apparently Linux is deprecating sysctl, and spewing warning
* messages when you try to use it. */
if (!ok && 0 == arc4_seed_sysctl_linux())
ok = 1;
#endif
#ifdef TRY_SEED_SYSCTL_BSD
if (0 == arc4_seed_sysctl_bsd())
ok = 1;
@ -379,8 +370,7 @@ arc4_stir(void)
rs_initialized = 1;
}
arc4_seed();
if (!arc4_seeded_ok)
if (0 != arc4_seed())
return -1;
/*

View File

@ -95,6 +95,7 @@
#include "evthread-internal.h"
#include "evbuffer-internal.h"
#include "bufferevent-internal.h"
#include "event-internal.h"
/* some systems do not have MAP_FAILED */
#ifndef MAP_FAILED
@ -522,8 +523,8 @@ evbuffer_invoke_callbacks_(struct evbuffer *buffer)
evbuffer_incref_and_lock_(buffer);
if (buffer->parent)
bufferevent_incref_(buffer->parent);
EVBUFFER_UNLOCK(buffer);
}
EVBUFFER_UNLOCK(buffer);
}
evbuffer_run_callbacks(buffer, 0);
@ -703,13 +704,17 @@ static int
advance_last_with_data(struct evbuffer *buf)
{
int n = 0;
struct evbuffer_chain **chainp = buf->last_with_datap;
ASSERT_EVBUFFER_LOCKED(buf);
if (!*buf->last_with_datap)
if (!*chainp)
return 0;
while ((*buf->last_with_datap)->next && (*buf->last_with_datap)->next->off) {
buf->last_with_datap = &(*buf->last_with_datap)->next;
while ((*chainp)->next) {
chainp = &(*chainp)->next;
if ((*chainp)->off)
buf->last_with_datap = chainp;
++n;
}
return n;
@ -1146,7 +1151,7 @@ evbuffer_drain(struct evbuffer *buf, size_t len)
}
buf->first = chain;
EVUTIL_ASSERT(chain && remaining <= chain->off);
EVUTIL_ASSERT(remaining <= chain->off);
chain->misalign += remaining;
chain->off -= remaining;
}
@ -1298,7 +1303,7 @@ evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst,
chain = chain->next;
}
if (nread) {
if (chain != src->first) {
/* we can remove the chain */
struct evbuffer_chain **chp;
chp = evbuffer_free_trailing_empty_chains(dst);
@ -1416,9 +1421,11 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
for (; chain != NULL && (size_t)size >= chain->off; chain = next) {
next = chain->next;
memcpy(buffer, chain->buffer + chain->misalign, chain->off);
size -= chain->off;
buffer += chain->off;
if (chain->buffer) {
memcpy(buffer, chain->buffer + chain->misalign, chain->off);
size -= chain->off;
buffer += chain->off;
}
if (chain == last_with_data)
removed_last_with_data = 1;
if (&chain->next == buf->last_with_datap)
@ -1534,11 +1541,11 @@ evbuffer_find_eol_char(struct evbuffer_ptr *it)
return (-1);
}
static inline int
static inline size_t
evbuffer_strspn(
struct evbuffer_ptr *ptr, const char *chrset)
{
int count = 0;
size_t count = 0;
struct evbuffer_chain *chain = ptr->internal_.chain;
size_t i = ptr->internal_.pos_in_chain;
@ -1824,6 +1831,10 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen)
EVBUFFER_LOCK(buf);
if (datlen == 0) {
result = 0;
goto done;
}
if (buf->freeze_start) {
goto done;
}
@ -1877,7 +1888,7 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen)
if ((tmp = evbuffer_chain_new(datlen)) == NULL)
goto done;
buf->first = tmp;
if (buf->last_with_datap == &buf->first)
if (buf->last_with_datap == &buf->first && chain->off)
buf->last_with_datap = &tmp->next;
tmp->next = chain;
@ -2227,11 +2238,13 @@ evbuffer_read_setup_vecs_(struct evbuffer *buf, ev_ssize_t howmuch,
so_far = 0;
/* Let firstchain be the first chain with any space on it */
firstchainp = buf->last_with_datap;
EVUTIL_ASSERT(*firstchainp);
if (CHAIN_SPACE_LEN(*firstchainp) == 0) {
firstchainp = &(*firstchainp)->next;
}
chain = *firstchainp;
EVUTIL_ASSERT(chain);
for (i = 0; i < n_vecs_avail && so_far < (size_t)howmuch; ++i) {
size_t avail = (size_t) CHAIN_SPACE_LEN(chain);
if (avail > (howmuch - so_far) && exact)
@ -2465,7 +2478,7 @@ evbuffer_write_sendfile(struct evbuffer *buffer, evutil_socket_t dest_fd,
ev_off_t len = chain->off;
#elif defined(SENDFILE_IS_LINUX) || defined(SENDFILE_IS_SOLARIS)
ev_ssize_t res;
ev_off_t offset = chain->misalign;
off_t offset = chain->misalign;
#endif
ASSERT_EVBUFFER_LOCKED(buffer);
@ -3198,7 +3211,6 @@ evbuffer_add_file_segment(struct evbuffer *buf,
}
}
}
++seg->refcnt;
EVLOCK_UNLOCK(seg->lock, 0);
if (buf->freeze_end)
@ -3262,6 +3274,9 @@ evbuffer_add_file_segment(struct evbuffer *buf,
chain->off = length;
}
EVLOCK_LOCK(seg->lock, 0);
++seg->refcnt;
EVLOCK_UNLOCK(seg->lock, 0);
extra->segment = seg;
buf->n_add_for_cb += length;
evbuffer_chain_insert(buf, chain);
@ -3293,7 +3308,7 @@ evbuffer_add_file(struct evbuffer *buf, int fd, ev_off_t offset, ev_off_t length
return r;
}
void
int
evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg)
{
EVBUFFER_LOCK(buffer);
@ -3304,10 +3319,15 @@ evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg)
if (cb) {
struct evbuffer_cb_entry *ent =
evbuffer_add_cb(buffer, NULL, cbarg);
if (!ent) {
EVBUFFER_UNLOCK(buffer);
return -1;
}
ent->cb.cb_obsolete = cb;
ent->flags |= EVBUFFER_CB_OBSOLETE;
}
EVBUFFER_UNLOCK(buffer);
return 0;
}
struct evbuffer_cb_entry *

View File

@ -44,6 +44,7 @@
#include "mm-internal.h"
#include <winsock2.h>
#include <winerror.h>
#include <windows.h>
#include <stdio.h>

View File

@ -306,6 +306,13 @@ extern const struct bufferevent_ops bufferevent_ops_pair;
#define BEV_IS_FILTER(bevp) ((bevp)->be_ops == &bufferevent_ops_filter)
#define BEV_IS_PAIR(bevp) ((bevp)->be_ops == &bufferevent_ops_pair)
#if defined(EVENT__HAVE_OPENSSL)
extern const struct bufferevent_ops bufferevent_ops_openssl;
#define BEV_IS_OPENSSL(bevp) ((bevp)->be_ops == &bufferevent_ops_openssl)
#else
#define BEV_IS_OPENSSL(bevp) 0
#endif
#ifdef _WIN32
extern const struct bufferevent_ops bufferevent_ops_async;
#define BEV_IS_ASYNC(bevp) ((bevp)->be_ops == &bufferevent_ops_async)
@ -314,13 +321,16 @@ extern const struct bufferevent_ops bufferevent_ops_async;
#endif
/** Initialize the shared parts of a bufferevent. */
EVENT2_EXPORT_SYMBOL
int bufferevent_init_common_(struct bufferevent_private *, struct event_base *, const struct bufferevent_ops *, enum bufferevent_options options);
/** For internal use: temporarily stop all reads on bufev, until the conditions
* in 'what' are over. */
EVENT2_EXPORT_SYMBOL
void bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what);
/** For internal use: clear the conditions 'what' on bufev, and re-enable
* reading if there are no conditions left. */
EVENT2_EXPORT_SYMBOL
void bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what);
/** For internal use: temporarily stop all writes on bufev, until the conditions
@ -347,16 +357,19 @@ void bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend
@return 0 if successful, or -1 if an error occurred
@see bufferevent_disable()
*/
EVENT2_EXPORT_SYMBOL
int bufferevent_disable_hard_(struct bufferevent *bufev, short event);
/** Internal: Set up locking on a bufferevent. If lock is set, use it.
* Otherwise, use a new lock. */
EVENT2_EXPORT_SYMBOL
int bufferevent_enable_locking_(struct bufferevent *bufev, void *lock);
/** Internal: backwards compat macro for the now public function
* Increment the reference count on bufev. */
#define bufferevent_incref_(bufev) bufferevent_incref(bufev)
/** Internal: Lock bufev and increase its reference count.
* unlocking it otherwise. */
EVENT2_EXPORT_SYMBOL
void bufferevent_incref_and_lock_(struct bufferevent *bufev);
/** Internal: backwards compat macro for the now public function
* Decrement the reference count on bufev. Returns 1 if it freed
@ -365,17 +378,21 @@ void bufferevent_incref_and_lock_(struct bufferevent *bufev);
/** Internal: Drop the reference count on bufev, freeing as necessary, and
* unlocking it otherwise. Returns 1 if it freed the bufferevent. */
EVENT2_EXPORT_SYMBOL
int bufferevent_decref_and_unlock_(struct bufferevent *bufev);
/** Internal: If callbacks are deferred and we have a read callback, schedule
* a readcb. Otherwise just run the readcb. Ignores watermarks. */
EVENT2_EXPORT_SYMBOL
void bufferevent_run_readcb_(struct bufferevent *bufev, int options);
/** Internal: If callbacks are deferred and we have a write callback, schedule
* a writecb. Otherwise just run the writecb. Ignores watermarks. */
EVENT2_EXPORT_SYMBOL
void bufferevent_run_writecb_(struct bufferevent *bufev, int options);
/** Internal: If callbacks are deferred and we have an eventcb, schedule
* it to run with events "what". Otherwise just run the eventcb.
* See bufferevent_trigger_event for meaning of "options". */
EVENT2_EXPORT_SYMBOL
void bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options);
/** Internal: Run or schedule (if deferred or options contain
@ -399,6 +416,7 @@ bufferevent_trigger_nolock_(struct bufferevent *bufev, short iotype, int options
/** Internal: Add the event 'ev' with timeout tv, unless tv is set to 0, in
* which case add ev with no timeout. */
EVENT2_EXPORT_SYMBOL
int bufferevent_add_event_(struct event *ev, const struct timeval *tv);
/* =========
@ -408,19 +426,33 @@ int bufferevent_add_event_(struct event *ev, const struct timeval *tv);
/** Internal use: Set up the ev_read and ev_write callbacks so that
* the other "generic_timeout" functions will work on it. Call this from
* the constructor function. */
EVENT2_EXPORT_SYMBOL
void bufferevent_init_generic_timeout_cbs_(struct bufferevent *bev);
/** Internal use: Add or delete the generic timeout events as appropriate.
* (If an event is enabled and a timeout is set, we add the event. Otherwise
* we delete it.) Call this from anything that changes the timeout values,
* that enabled EV_READ or EV_WRITE, or that disables EV_READ or EV_WRITE. */
EVENT2_EXPORT_SYMBOL
int bufferevent_generic_adj_timeouts_(struct bufferevent *bev);
EVENT2_EXPORT_SYMBOL
int bufferevent_generic_adj_existing_timeouts_(struct bufferevent *bev);
EVENT2_EXPORT_SYMBOL
enum bufferevent_options bufferevent_get_options_(struct bufferevent *bev);
EVENT2_EXPORT_SYMBOL
const struct sockaddr*
bufferevent_socket_get_conn_address_(struct bufferevent *bev);
EVENT2_EXPORT_SYMBOL
void
bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, evutil_socket_t fd);
EVENT2_EXPORT_SYMBOL
void
bufferevent_socket_set_conn_address_(struct bufferevent *bev, struct sockaddr *addr, size_t addrlen);
/** Internal use: We have just successfully read data into an inbuf, so
* reset the read timeout (if any). */
#define BEV_RESET_GENERIC_READ_TIMEOUT(bev) \
@ -465,11 +497,15 @@ bufferevent_socket_get_conn_address_(struct bufferevent *bev);
/* ==== For rate-limiting. */
EVENT2_EXPORT_SYMBOL
int bufferevent_decrement_write_buckets_(struct bufferevent_private *bev,
ev_ssize_t bytes);
EVENT2_EXPORT_SYMBOL
int bufferevent_decrement_read_buckets_(struct bufferevent_private *bev,
ev_ssize_t bytes);
EVENT2_EXPORT_SYMBOL
ev_ssize_t bufferevent_get_read_max_(struct bufferevent_private *bev);
EVENT2_EXPORT_SYMBOL
ev_ssize_t bufferevent_get_write_max_(struct bufferevent_private *bev);
int bufferevent_ratelim_init_(struct bufferevent_private *bev);

View File

@ -66,8 +66,7 @@ static void bufferevent_finalize_cb_(struct event_callback *evcb, void *arg_);
void
bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
if (!bufev_private->read_suspended)
bufev->be_ops->disable(bufev, EV_READ);
@ -78,8 +77,7 @@ bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags w
void
bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
bufev_private->read_suspended &= ~what;
if (!bufev_private->read_suspended && (bufev->enabled & EV_READ))
@ -90,8 +88,7 @@ bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags
void
bufferevent_suspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
if (!bufev_private->write_suspended)
bufev->be_ops->disable(bufev, EV_WRITE);
@ -102,8 +99,7 @@ bufferevent_suspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags
void
bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
bufev_private->write_suspended &= ~what;
if (!bufev_private->write_suspended && (bufev->enabled & EV_WRITE))
@ -111,6 +107,28 @@ bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend_flag
BEV_UNLOCK(bufev);
}
/**
* Sometimes bufferevent's implementation can overrun high watermarks
* (one of examples is openssl) and in this case if the read callback
* will not handle enough data do over condition above the read
* callback will never be called again (due to suspend above).
*
* To avoid this we are scheduling read callback again here, but only
* from the user callback to avoid multiple scheduling:
* - when the data had been added to it
* - when the data had been drained from it (user specified read callback)
*/
static void bufferevent_inbuf_wm_check(struct bufferevent *bev)
{
if (!bev->wm_read.high)
return;
if (!(bev->enabled & EV_READ))
return;
if (evbuffer_get_length(bev->input) < bev->wm_read.high)
return;
bufferevent_trigger(bev, EV_READ, BEV_OPT_DEFER_CALLBACKS);
}
/* Callback to implement watermarks on the input buffer. Only enabled
* if the watermark is set. */
@ -147,6 +165,7 @@ bufferevent_run_deferred_callbacks_locked(struct event_callback *cb, void *arg)
if (bufev_private->readcb_pending && bufev->readcb) {
bufev_private->readcb_pending = 0;
bufev->readcb(bufev, bufev->cbarg);
bufferevent_inbuf_wm_check(bufev);
}
if (bufev_private->writecb_pending && bufev->writecb) {
bufev_private->writecb_pending = 0;
@ -187,6 +206,7 @@ bufferevent_run_deferred_callbacks_unlocked(struct event_callback *cb, void *arg
void *cbarg = bufev->cbarg;
bufev_private->readcb_pending = 0;
UNLOCKED(readcb(bufev, cbarg));
bufferevent_inbuf_wm_check(bufev);
}
if (bufev_private->writecb_pending && bufev->writecb) {
bufferevent_data_cb writecb = bufev->writecb;
@ -221,8 +241,7 @@ void
bufferevent_run_readcb_(struct bufferevent *bufev, int options)
{
/* Requires that we hold the lock and a reference */
struct bufferevent_private *p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *p = BEV_UPCAST(bufev);
if (bufev->readcb == NULL)
return;
if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) {
@ -230,6 +249,7 @@ bufferevent_run_readcb_(struct bufferevent *bufev, int options)
SCHEDULE_DEFERRED(p);
} else {
bufev->readcb(bufev, bufev->cbarg);
bufferevent_inbuf_wm_check(bufev);
}
}
@ -237,8 +257,7 @@ void
bufferevent_run_writecb_(struct bufferevent *bufev, int options)
{
/* Requires that we hold the lock and a reference */
struct bufferevent_private *p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *p = BEV_UPCAST(bufev);
if (bufev->writecb == NULL)
return;
if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) {
@ -266,8 +285,7 @@ void
bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options)
{
/* Requires that we hold the lock and a reference */
struct bufferevent_private *p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *p = BEV_UPCAST(bufev);
if (bufev->errorcb == NULL)
return;
if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) {
@ -297,14 +315,12 @@ bufferevent_init_common_(struct bufferevent_private *bufev_private,
if (!bufev->input) {
if ((bufev->input = evbuffer_new()) == NULL)
return -1;
goto err;
}
if (!bufev->output) {
if ((bufev->output = evbuffer_new()) == NULL) {
evbuffer_free(bufev->input);
return -1;
}
if ((bufev->output = evbuffer_new()) == NULL)
goto err;
}
bufev_private->refcnt = 1;
@ -316,7 +332,8 @@ bufferevent_init_common_(struct bufferevent_private *bufev_private,
bufev->be_ops = ops;
bufferevent_ratelim_init_(bufev_private);
if (bufferevent_ratelim_init_(bufev_private))
goto err;
/*
* Set to EV_WRITE so that using bufferevent_write is going to
@ -327,20 +344,14 @@ bufferevent_init_common_(struct bufferevent_private *bufev_private,
#ifndef EVENT__DISABLE_THREAD_SUPPORT
if (options & BEV_OPT_THREADSAFE) {
if (bufferevent_enable_locking_(bufev, NULL) < 0) {
/* cleanup */
evbuffer_free(bufev->input);
evbuffer_free(bufev->output);
bufev->input = NULL;
bufev->output = NULL;
return -1;
}
if (bufferevent_enable_locking_(bufev, NULL) < 0)
goto err;
}
#endif
if ((options & (BEV_OPT_DEFER_CALLBACKS|BEV_OPT_UNLOCK_CALLBACKS))
== BEV_OPT_UNLOCK_CALLBACKS) {
event_warnx("UNLOCK_CALLBACKS requires DEFER_CALLBACKS");
return -1;
goto err;
}
if (options & BEV_OPT_UNLOCK_CALLBACKS)
event_deferred_cb_init_(
@ -361,6 +372,17 @@ bufferevent_init_common_(struct bufferevent_private *bufev_private,
evbuffer_set_parent_(bufev->output, bufev);
return 0;
err:
if (bufev->input) {
evbuffer_free(bufev->input);
bufev->input = NULL;
}
if (bufev->output) {
evbuffer_free(bufev->output);
bufev->output = NULL;
}
return -1;
}
void
@ -459,8 +481,7 @@ bufferevent_read_buffer(struct bufferevent *bufev, struct evbuffer *buf)
int
bufferevent_enable(struct bufferevent *bufev, short event)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
short impl_events = event;
int r = 0;
@ -474,6 +495,8 @@ bufferevent_enable(struct bufferevent *bufev, short event)
if (impl_events && bufev->be_ops->enable(bufev, impl_events) < 0)
r = -1;
if (r)
event_debug(("%s: cannot enable 0x%hx on %p", __func__, event, bufev));
bufferevent_decref_and_unlock_(bufev);
return r;
@ -533,8 +556,7 @@ int
bufferevent_disable_hard_(struct bufferevent *bufev, short event)
{
int r = 0;
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
bufev->enabled &= ~event;
@ -557,6 +579,8 @@ bufferevent_disable(struct bufferevent *bufev, short event)
if (bufev->be_ops->disable(bufev, event) < 0)
r = -1;
if (r)
event_debug(("%s: cannot disable 0x%hx on %p", __func__, event, bufev));
BEV_UNLOCK(bufev);
return r;
@ -570,8 +594,7 @@ void
bufferevent_setwatermark(struct bufferevent *bufev, short events,
size_t lowmark, size_t highmark)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
if (events & EV_WRITE) {
@ -656,8 +679,7 @@ bufferevent_flush(struct bufferevent *bufev,
void
bufferevent_incref_and_lock_(struct bufferevent *bufev)
{
struct bufferevent_private *bufev_private =
BEV_UPCAST(bufev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
++bufev_private->refcnt;
}
@ -683,8 +705,7 @@ bufferevent_transfer_lock_ownership_(struct bufferevent *donor,
int
bufferevent_decref_and_unlock_(struct bufferevent *bufev)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
int n_cbs = 0;
#define MAX_CBS 16
struct event_callback *cbs[MAX_CBS];
@ -727,8 +748,7 @@ bufferevent_finalize_cb_(struct event_callback *evcb, void *arg_)
{
struct bufferevent *bufev = arg_;
struct bufferevent *underlying;
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
underlying = bufferevent_get_underlying(bufev);
@ -794,8 +814,7 @@ bufferevent_free(struct bufferevent *bufev)
void
bufferevent_incref(struct bufferevent *bufev)
{
struct bufferevent_private *bufev_private =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
/* XXX: now that this function is public, we might want to
* - return the count from this function
@ -851,6 +870,8 @@ bufferevent_setfd(struct bufferevent *bev, evutil_socket_t fd)
BEV_LOCK(bev);
if (bev->be_ops->ctrl)
res = bev->be_ops->ctrl(bev, BEV_CTRL_SET_FD, &d);
if (res)
event_debug(("%s: cannot set fd for %p to "EV_SOCK_FMT, __func__, bev, fd));
BEV_UNLOCK(bev);
return res;
}
@ -864,6 +885,8 @@ bufferevent_getfd(struct bufferevent *bev)
BEV_LOCK(bev);
if (bev->be_ops->ctrl)
res = bev->be_ops->ctrl(bev, BEV_CTRL_GET_FD, &d);
if (res)
event_debug(("%s: cannot get fd for %p", __func__, bev));
BEV_UNLOCK(bev);
return (res<0) ? -1 : d.fd;
}
@ -871,8 +894,7 @@ bufferevent_getfd(struct bufferevent *bev)
enum bufferevent_options
bufferevent_get_options_(struct bufferevent *bev)
{
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
enum bufferevent_options options;
BEV_LOCK(bev);
@ -948,8 +970,7 @@ int
bufferevent_generic_adj_timeouts_(struct bufferevent *bev)
{
const short enabled = bev->enabled;
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
int r1=0, r2=0;
if ((enabled & EV_READ) && !bev_p->read_suspended &&
evutil_timerisset(&bev->timeout_read))

View File

@ -46,6 +46,7 @@
#ifdef _WIN32
#include <winsock2.h>
#include <winerror.h>
#include <ws2tcpip.h>
#endif
@ -100,11 +101,32 @@ const struct bufferevent_ops bufferevent_ops_async = {
be_async_ctrl,
};
static inline void
be_async_run_eventcb(struct bufferevent *bev, short what, int options)
{ bufferevent_run_eventcb_(bev, what, options|BEV_TRIG_DEFER_CALLBACKS); }
static inline void
be_async_trigger_nolock(struct bufferevent *bev, short what, int options)
{ bufferevent_trigger_nolock_(bev, what, options|BEV_TRIG_DEFER_CALLBACKS); }
static inline int
fatal_error(int err)
{
switch (err) {
/* We may have already associated this fd with a port.
* Let's hope it's this port, and that the error code
* for doing this neer changes. */
case ERROR_INVALID_PARAMETER:
return 0;
}
return 1;
}
static inline struct bufferevent_async *
upcast(struct bufferevent *bev)
{
struct bufferevent_async *bev_a;
if (bev->be_ops != &bufferevent_ops_async)
if (!BEV_IS_ASYNC(bev))
return NULL;
bev_a = EVUTIL_UPCAST(bev, struct bufferevent_async, bev.bev);
return bev_a;
@ -217,7 +239,7 @@ bev_async_consider_writing(struct bufferevent_async *beva)
&beva->write_overlapped)) {
bufferevent_decref_(bev);
beva->ok = 0;
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
be_async_run_eventcb(bev, BEV_EVENT_ERROR, 0);
} else {
beva->write_in_progress = at_most;
bufferevent_decrement_write_buckets_(&beva->bev, at_most);
@ -270,7 +292,7 @@ bev_async_consider_reading(struct bufferevent_async *beva)
bufferevent_incref_(bev);
if (evbuffer_launch_read_(bev->input, at_most, &beva->read_overlapped)) {
beva->ok = 0;
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
be_async_run_eventcb(bev, BEV_EVENT_ERROR, 0);
bufferevent_decref_(bev);
} else {
beva->read_in_progress = at_most;
@ -381,10 +403,10 @@ be_async_destruct(struct bufferevent *bev)
bev_async_del_write(bev_async);
fd = evbuffer_overlapped_get_fd_(bev->input);
if (fd != (evutil_socket_t)INVALID_SOCKET &&
if (fd != (evutil_socket_t)EVUTIL_INVALID_SOCKET &&
(bev_p->options & BEV_OPT_CLOSE_ON_FREE)) {
evutil_closesocket(fd);
evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET);
evbuffer_overlapped_set_fd_(bev->input, EVUTIL_INVALID_SOCKET);
}
}
@ -428,8 +450,7 @@ connect_complete(struct event_overlapped *eo, ev_uintptr_t key,
else
bev_async_set_wsa_error(bev, eo);
bufferevent_run_eventcb_(bev,
ok? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0);
be_async_run_eventcb(bev, ok ? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0);
event_base_del_virtual_(bev->ev_base);
@ -459,16 +480,16 @@ read_complete(struct event_overlapped *eo, ev_uintptr_t key,
if (bev_a->ok) {
if (ok && nbytes) {
BEV_RESET_GENERIC_READ_TIMEOUT(bev);
bufferevent_trigger_nolock_(bev, EV_READ, 0);
be_async_trigger_nolock(bev, EV_READ, 0);
bev_async_consider_reading(bev_a);
} else if (!ok) {
what |= BEV_EVENT_ERROR;
bev_a->ok = 0;
bufferevent_run_eventcb_(bev, what, 0);
be_async_run_eventcb(bev, what, 0);
} else if (!nbytes) {
what |= BEV_EVENT_EOF;
bev_a->ok = 0;
bufferevent_run_eventcb_(bev, what, 0);
be_async_run_eventcb(bev, what, 0);
}
}
@ -502,16 +523,16 @@ write_complete(struct event_overlapped *eo, ev_uintptr_t key,
if (bev_a->ok) {
if (ok && nbytes) {
BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
bufferevent_trigger_nolock_(bev, EV_WRITE, 0);
be_async_trigger_nolock(bev, EV_WRITE, 0);
bev_async_consider_writing(bev_a);
} else if (!ok) {
what |= BEV_EVENT_ERROR;
bev_a->ok = 0;
bufferevent_run_eventcb_(bev, what, 0);
be_async_run_eventcb(bev, what, 0);
} else if (!nbytes) {
what |= BEV_EVENT_EOF;
bev_a->ok = 0;
bufferevent_run_eventcb_(bev, what, 0);
be_async_run_eventcb(bev, what, 0);
}
}
@ -532,11 +553,7 @@ bufferevent_async_new_(struct event_base *base,
return NULL;
if (fd >= 0 && event_iocp_port_associate_(iocp, fd, 1)<0) {
int err = GetLastError();
/* We may have alrady associated this fd with a port.
* Let's hope it's this port, and that the error code
* for doing this neer changes. */
if (err != ERROR_INVALID_PARAMETER)
if (fatal_error(GetLastError()))
return NULL;
}
@ -580,7 +597,6 @@ bufferevent_async_set_connected_(struct bufferevent *bev)
{
struct bufferevent_async *bev_async = upcast(bev);
bev_async->ok = 1;
bufferevent_init_generic_timeout_cbs_(bev);
/* Now's a good time to consider reading/writing */
be_async_enable(bev, bev->enabled);
}
@ -654,25 +670,29 @@ be_async_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
data->fd = evbuffer_overlapped_get_fd_(bev->input);
return 0;
case BEV_CTRL_SET_FD: {
struct bufferevent_async *bev_a = upcast(bev);
struct event_iocp_port *iocp;
if (data->fd == evbuffer_overlapped_get_fd_(bev->input))
return 0;
if (!(iocp = event_base_get_iocp_(bev->ev_base)))
return -1;
if (event_iocp_port_associate_(iocp, data->fd, 1) < 0)
return -1;
if (event_iocp_port_associate_(iocp, data->fd, 1) < 0) {
if (fatal_error(GetLastError()))
return -1;
}
evbuffer_overlapped_set_fd_(bev->input, data->fd);
evbuffer_overlapped_set_fd_(bev->output, data->fd);
bev_a->ok = data->fd >= 0;
return 0;
}
case BEV_CTRL_CANCEL_ALL: {
struct bufferevent_async *bev_a = upcast(bev);
evutil_socket_t fd = evbuffer_overlapped_get_fd_(bev->input);
if (fd != (evutil_socket_t)INVALID_SOCKET &&
if (fd != (evutil_socket_t)EVUTIL_INVALID_SOCKET &&
(bev_a->bev.options & BEV_OPT_CLOSE_ON_FREE)) {
closesocket(fd);
evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET);
evbuffer_overlapped_set_fd_(bev->input, EVUTIL_INVALID_SOCKET);
}
bev_a->ok = 0;
return 0;

View File

@ -118,11 +118,11 @@ static inline struct bufferevent_filtered *
upcast(struct bufferevent *bev)
{
struct bufferevent_filtered *bev_f;
if (bev->be_ops != &bufferevent_ops_filter)
if (!BEV_IS_FILTER(bev))
return NULL;
bev_f = (void*)( ((char*)bev) -
evutil_offsetof(struct bufferevent_filtered, bev.bev));
EVUTIL_ASSERT(bev_f->bev.bev.be_ops == &bufferevent_ops_filter);
EVUTIL_ASSERT(BEV_IS_FILTER(&bev_f->bev.bev));
return bev_f;
}
@ -160,7 +160,7 @@ be_null_filter(struct evbuffer *src, struct evbuffer *dst, ev_ssize_t lim,
enum bufferevent_flush_mode state, void *ctx)
{
(void)state;
if (evbuffer_remove_buffer(src, dst, lim) == 0)
if (evbuffer_remove_buffer(src, dst, lim) >= 0)
return BEV_OK;
else
return BEV_ERROR;
@ -605,6 +605,7 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
data->ptr = bevf->underlying;
return 0;
case BEV_CTRL_SET_FD:
case BEV_CTRL_GET_FD:
bevf = upcast(bev);
if (bevf->underlying &&
@ -612,9 +613,10 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
bevf->underlying->be_ops->ctrl) {
return (bevf->underlying->be_ops->ctrl)(bevf->underlying, op, data);
}
EVUTIL_FALLTHROUGH;
case BEV_CTRL_GET_FD:
case BEV_CTRL_CANCEL_ALL:
EVUTIL_FALLTHROUGH;
default:
return -1;
}

View File

@ -63,7 +63,6 @@
#include "bufferevent-internal.h"
#include "log-internal.h"
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "openssl-compat.h"
@ -155,7 +154,7 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
return r;
}
/* Called to write data info the BIO */
/* Called to write data into the BIO */
static int
bio_bufferevent_write(BIO *b, const char *in, int inlen)
{
@ -251,7 +250,7 @@ BIO_s_bufferevent(void)
/* Create a new BIO to wrap communication around a bufferevent. If close_flag
* is true, the bufferevent will be freed when the BIO is closed. */
static BIO *
BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
BIO_new_bufferevent(struct bufferevent *bufferevent)
{
BIO *result;
if (!bufferevent)
@ -260,7 +259,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
return NULL;
BIO_set_init(result, 1);
BIO_set_data(result, bufferevent);
BIO_set_shutdown(result, close_flag ? 1 : 0);
/* We don't tell the BIO to close the bufferevent; we do it ourselves on
* be_openssl_destruct() */
BIO_set_shutdown(result, 0);
return result;
}
@ -354,11 +355,11 @@ static inline struct bufferevent_openssl *
upcast(struct bufferevent *bev)
{
struct bufferevent_openssl *bev_o;
if (bev->be_ops != &bufferevent_ops_openssl)
if (!BEV_IS_OPENSSL(bev))
return NULL;
bev_o = (void*)( ((char*)bev) -
evutil_offsetof(struct bufferevent_openssl, bev.bev));
EVUTIL_ASSERT(bev_o->bev.bev.be_ops == &bufferevent_ops_openssl);
EVUTIL_ASSERT(BEV_IS_OPENSSL(&bev_o->bev.bev));
return bev_o;
}
@ -510,12 +511,15 @@ conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
/* IO error; possibly a dirty shutdown. */
if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
dirty_shutdown = 1;
put_error(bev_ssl, errcode);
break;
case SSL_ERROR_SSL:
/* Protocol error. */
put_error(bev_ssl, errcode);
break;
case SSL_ERROR_WANT_X509_LOOKUP:
/* XXXX handle this. */
put_error(bev_ssl, errcode);
break;
case SSL_ERROR_NONE:
case SSL_ERROR_WANT_READ:
@ -803,7 +807,7 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
if (bev_ssl->bev.read_suspended)
break;
/* Read all pending data. This won't hit the network
* again, and will (most importantly) put us in a state
* where we don't need to read anything else until the
@ -963,8 +967,8 @@ be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
}
static int
be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, int fd)
static evutil_socket_t
be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
{
if (!bev_ssl->underlying) {
struct bufferevent *bev = &bev_ssl->bev.bev;
@ -1030,7 +1034,7 @@ do_handshake(struct bufferevent_openssl *bev_ssl)
decrement_buckets(bev_ssl);
if (r==1) {
int fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
evutil_socket_t fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
/* We're done! */
bev_ssl->state = BUFFEREVENT_SSL_OPEN;
set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */
@ -1228,7 +1232,7 @@ be_openssl_destruct(struct bufferevent *bev)
if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
if (! bev_ssl->underlying) {
evutil_socket_t fd = -1;
evutil_socket_t fd = EVUTIL_INVALID_SOCKET;
BIO *bio = SSL_get_wbio(bev_ssl->ssl);
if (bio)
fd = BIO_get_fd(bio, NULL);
@ -1261,17 +1265,21 @@ be_openssl_flush(struct bufferevent *bufev,
static int
be_openssl_set_fd(struct bufferevent_openssl *bev_ssl,
enum bufferevent_ssl_state state, int fd)
enum bufferevent_ssl_state state, evutil_socket_t fd)
{
bev_ssl->state = state;
switch (state) {
case BUFFEREVENT_SSL_ACCEPTING:
if (!SSL_clear(bev_ssl->ssl))
return -1;
SSL_set_accept_state(bev_ssl->ssl);
if (set_handshake_callbacks(bev_ssl, fd) < 0)
return -1;
break;
case BUFFEREVENT_SSL_CONNECTING:
if (!SSL_clear(bev_ssl->ssl))
return -1;
SSL_set_connect_state(bev_ssl->ssl);
if (set_handshake_callbacks(bev_ssl, fd) < 0)
return -1;
@ -1296,11 +1304,11 @@ be_openssl_ctrl(struct bufferevent *bev,
case BEV_CTRL_SET_FD:
if (!bev_ssl->underlying) {
BIO *bio;
bio = BIO_new_socket(data->fd, 0);
bio = BIO_new_socket((int)data->fd, 0);
SSL_set_bio(bev_ssl->ssl, bio, bio);
} else {
BIO *bio;
if (!(bio = BIO_new_bufferevent(bev_ssl->underlying, 0)))
if (!(bio = BIO_new_bufferevent(bev_ssl->underlying)))
return -1;
SSL_set_bio(bev_ssl->ssl, bio, bio);
}
@ -1343,8 +1351,9 @@ bufferevent_openssl_new_impl(struct event_base *base,
struct bufferevent_private *bev_p = NULL;
int tmp_options = options & ~BEV_OPT_THREADSAFE;
/* Only one can be set. */
if (underlying != NULL && fd >= 0)
return NULL; /* Only one can be set. */
goto err;
if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl))))
goto err;
@ -1392,8 +1401,12 @@ bufferevent_openssl_new_impl(struct event_base *base,
return &bev_ssl->bev.bev;
err:
if (bev_ssl)
if (options & BEV_OPT_CLOSE_ON_FREE)
SSL_free(ssl);
if (bev_ssl) {
bev_ssl->ssl = NULL;
bufferevent_free(&bev_ssl->bev.bev);
}
return NULL;
}
@ -1404,19 +1417,24 @@ bufferevent_openssl_filter_new(struct event_base *base,
enum bufferevent_ssl_state state,
int options)
{
/* We don't tell the BIO to close the bufferevent; we do it ourselves
* on be_openssl_destruct */
int close_flag = 0; /* options & BEV_OPT_CLOSE_ON_FREE; */
BIO *bio;
struct bufferevent *bev;
if (!underlying)
return NULL;
if (!(bio = BIO_new_bufferevent(underlying, close_flag)))
return NULL;
goto err;
if (!(bio = BIO_new_bufferevent(underlying)))
goto err;
SSL_set_bio(ssl, bio, bio);
return bufferevent_openssl_new_impl(
bev = bufferevent_openssl_new_impl(
base, underlying, -1, ssl, state, options);
return bev;
err:
if (options & BEV_OPT_CLOSE_ON_FREE)
SSL_free(ssl);
return NULL;
}
struct bufferevent *
@ -1443,14 +1461,14 @@ bufferevent_openssl_socket_new(struct event_base *base,
} else {
/* We specified an fd different from that of the SSL.
This is probably an error on our part. Fail. */
return NULL;
goto err;
}
(void) BIO_set_close(bio, 0);
BIO_set_close(bio, 0);
} else {
/* The SSL isn't configured with a BIO with an fd. */
if (fd >= 0) {
/* ... and we have an fd we want to use. */
bio = BIO_new_socket(fd, 0);
bio = BIO_new_socket((int)fd, 0);
SSL_set_bio(ssl, bio, bio);
} else {
/* Leave the fd unset. */
@ -1459,6 +1477,11 @@ bufferevent_openssl_socket_new(struct event_base *base,
return bufferevent_openssl_new_impl(
base, NULL, fd, ssl, state, options);
err:
if (options & BEV_OPT_CLOSE_ON_FREE)
SSL_free(ssl);
return NULL;
}
int

View File

@ -56,10 +56,10 @@ static inline struct bufferevent_pair *
upcast(struct bufferevent *bev)
{
struct bufferevent_pair *bev_p;
if (bev->be_ops != &bufferevent_ops_pair)
if (!BEV_IS_PAIR(bev))
return NULL;
bev_p = EVUTIL_UPCAST(bev, struct bufferevent_pair, bev.bev);
EVUTIL_ASSERT(bev_p->bev.bev.be_ops == &bufferevent_ops_pair);
EVUTIL_ASSERT(BEV_IS_PAIR(&bev_p->bev.bev));
return bev_p;
}

View File

@ -560,8 +560,7 @@ int
bufferevent_set_rate_limit(struct bufferevent *bev,
struct ev_token_bucket_cfg *cfg)
{
struct bufferevent_private *bevp =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bevp = BEV_UPCAST(bev);
int r = -1;
struct bufferevent_rate_limit *rlim;
struct timeval now;
@ -737,8 +736,7 @@ bufferevent_add_to_rate_limit_group(struct bufferevent *bev,
struct bufferevent_rate_limit_group *g)
{
int wsuspend, rsuspend;
struct bufferevent_private *bevp =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bevp = BEV_UPCAST(bev);
BEV_LOCK(bev);
if (!bevp->rate_limiting) {
@ -789,8 +787,7 @@ int
bufferevent_remove_from_rate_limit_group_internal_(struct bufferevent *bev,
int unsuspend)
{
struct bufferevent_private *bevp =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bevp = BEV_UPCAST(bev);
BEV_LOCK(bev);
if (bevp->rate_limiting && bevp->rate_limiting->group) {
struct bufferevent_rate_limit_group *g =

View File

@ -99,24 +99,28 @@ const struct bufferevent_ops bufferevent_ops_socket = {
const struct sockaddr*
bufferevent_socket_get_conn_address_(struct bufferevent *bev)
{
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
return (struct sockaddr *)&bev_p->conn_address;
}
static void
bufferevent_socket_set_conn_address_fd(struct bufferevent_private *bev_p, int fd)
void
bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev,
evutil_socket_t fd)
{
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
socklen_t len = sizeof(bev_p->conn_address);
struct sockaddr *addr = (struct sockaddr *)&bev_p->conn_address;
if (addr->sa_family != AF_UNSPEC)
getpeername(fd, addr, &len);
}
static void
bufferevent_socket_set_conn_address(struct bufferevent_private *bev_p,
void
bufferevent_socket_set_conn_address_(struct bufferevent *bev,
struct sockaddr *addr, size_t addrlen)
{
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
EVUTIL_ASSERT(addrlen <= sizeof(bev_p->conn_address));
memcpy(&bev_p->conn_address, addr, addrlen);
}
@ -127,8 +131,7 @@ bufferevent_socket_outbuf_cb(struct evbuffer *buf,
void *arg)
{
struct bufferevent *bufev = arg;
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bufev);
if (cbinfo->n_added &&
(bufev->enabled & EV_WRITE) &&
@ -146,8 +149,7 @@ static void
bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
{
struct bufferevent *bufev = arg;
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bufev);
struct evbuffer *input;
int res = 0;
short what = BEV_EVENT_READING;
@ -228,8 +230,7 @@ static void
bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
{
struct bufferevent *bufev = arg;
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bufev);
int res = 0;
short what = BEV_EVENT_WRITING;
int connected = 0;
@ -264,7 +265,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
goto done;
} else {
connected = 1;
bufferevent_socket_set_conn_address_fd(bufev_p, fd);
bufferevent_socket_set_conn_address_fd_(bufev, fd);
#ifdef _WIN32
if (BEV_IS_ASYNC(bufev)) {
event_del(&bufev->ev_write);
@ -379,8 +380,7 @@ int
bufferevent_socket_connect(struct bufferevent *bev,
const struct sockaddr *sa, int socklen)
{
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bev);
evutil_socket_t fd;
int r = 0;
@ -389,9 +389,6 @@ bufferevent_socket_connect(struct bufferevent *bev,
bufferevent_incref_and_lock_(bev);
if (!bufev_p)
goto done;
fd = bufferevent_getfd(bev);
if (fd < 0) {
if (!sa)
@ -399,7 +396,7 @@ bufferevent_socket_connect(struct bufferevent *bev,
fd = evutil_socket_(sa->sa_family,
SOCK_STREAM|EVUTIL_SOCK_NONBLOCK, 0);
if (fd < 0)
goto done;
goto freesock;
ownfd = 1;
}
if (sa) {
@ -449,10 +446,8 @@ bufferevent_socket_connect(struct bufferevent *bev,
goto done;
freesock:
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
if (ownfd)
evutil_closesocket(fd);
/* do something about the error? */
done:
bufferevent_decref_and_unlock_(bev);
return result;
@ -463,8 +458,7 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai,
void *arg)
{
struct bufferevent *bev = arg;
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
int r;
BEV_LOCK(bev);
@ -488,10 +482,10 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai,
}
/* XXX use the other addrinfos? */
/* XXX use this return value */
bufferevent_socket_set_conn_address(bev_p, ai->ai_addr, (int)ai->ai_addrlen);
bufferevent_socket_set_conn_address_(bev, ai->ai_addr, (int)ai->ai_addrlen);
r = bufferevent_socket_connect(bev, ai->ai_addr, (int)ai->ai_addrlen);
(void)r;
if (r < 0)
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
bufferevent_decref_and_unlock_(bev);
evutil_freeaddrinfo(ai);
}
@ -502,8 +496,7 @@ bufferevent_socket_connect_hostname(struct bufferevent *bev,
{
char portbuf[10];
struct evutil_addrinfo hint;
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC)
return -1;
@ -535,8 +528,7 @@ int
bufferevent_socket_get_dns_error(struct bufferevent *bev)
{
int rv;
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
struct bufferevent_private *bev_p = BEV_UPCAST(bev);
BEV_LOCK(bev);
rv = bev_p->dns_error;
@ -587,8 +579,7 @@ be_socket_enable(struct bufferevent *bufev, short event)
static int
be_socket_disable(struct bufferevent *bufev, short event)
{
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bufev);
if (event & EV_READ) {
if (event_del(&bufev->ev_read) == -1)
return -1;
@ -604,10 +595,9 @@ be_socket_disable(struct bufferevent *bufev, short event)
static void
be_socket_destruct(struct bufferevent *bufev)
{
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bufev);
evutil_socket_t fd;
EVUTIL_ASSERT(bufev->be_ops == &bufferevent_ops_socket);
EVUTIL_ASSERT(BEV_IS_SOCKET(bufev));
fd = event_get_fd(&bufev->ev_read);
@ -628,11 +618,10 @@ be_socket_flush(struct bufferevent *bev, short iotype,
static void
be_socket_setfd(struct bufferevent *bufev, evutil_socket_t fd)
{
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
EVUTIL_ASSERT(bufev->be_ops == &bufferevent_ops_socket);
EVUTIL_ASSERT(BEV_IS_SOCKET(bufev));
event_del(&bufev->ev_read);
event_del(&bufev->ev_write);
@ -658,11 +647,10 @@ int
bufferevent_priority_set(struct bufferevent *bufev, int priority)
{
int r = -1;
struct bufferevent_private *bufev_p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
struct bufferevent_private *bufev_p = BEV_UPCAST(bufev);
BEV_LOCK(bufev);
if (bufev->be_ops != &bufferevent_ops_socket)
if (BEV_IS_ASYNC(bufev) || BEV_IS_FILTER(bufev) || BEV_IS_PAIR(bufev))
goto done;
if (event_priority_set(&bufev->ev_read, priority) == -1)
@ -685,7 +673,7 @@ bufferevent_base_set(struct event_base *base, struct bufferevent *bufev)
int res = -1;
BEV_LOCK(bufev);
if (bufev->be_ops != &bufferevent_ops_socket)
if (!BEV_IS_SOCKET(bufev))
goto done;
bufev->ev_base = base;

View File

@ -1,9 +1,9 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -53,7 +53,7 @@ func_file_conv ()
MINGW*)
file_conv=mingw
;;
CYGWIN*)
CYGWIN* | MSYS*)
file_conv=cygwin
;;
*)
@ -67,7 +67,7 @@ func_file_conv ()
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
cygwin/* | msys/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
@ -255,7 +255,8 @@ EOF
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
@ -339,9 +340,9 @@ exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

1793
contrib/libevent/build-aux/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2013-05-30.07; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@ scriptversion=2013-05-30.07; # UTC
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -783,9 +783,9 @@ exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2013-12-25.23; # UTC
scriptversion=2018-03-11.20; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@ -271,15 +271,18 @@ do
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
@ -288,6 +291,11 @@ do
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
@ -324,34 +332,43 @@ do
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# Note that $RANDOM variable is not portable (e.g. dash); Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p' feature.
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
@ -427,14 +444,25 @@ do
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
(umask $cp_umask &&
{ test -z "$stripcmd" || {
# Create $dsttmp read-write so that cp doesn't create it read-only,
# which would cause strip to fail.
if test -z "$doit"; then
: >"$dsttmp" # No need to fork-exec 'touch'.
else
$doit touch "$dsttmp"
fi
}
} &&
$doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
@ -493,9 +521,9 @@ do
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2013-10-28.13; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -101,9 +101,9 @@ else
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
perl_URL=https://www.perl.org/
flex_URL=https://github.com/westes/flex
gnu_software_URL=https://www.gnu.org/software
program_details ()
{
@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,9 +1,9 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
scriptversion=2013-07-13.22; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 2011-2014 Free Software Foundation, Inc.
# Copyright (C) 2011-2020 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@ scriptversion=2013-07-13.22; # UTC
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -140,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -0,0 +1,13 @@
include(CheckCCompilerFlag)
macro(add_compiler_flags)
foreach(flag ${ARGN})
string(REGEX REPLACE "[-.+/:= ]" "_" _flag_esc "${flag}")
check_c_compiler_flag("${flag}" check_c_compiler_flag_${_flag_esc})
if (check_c_compiler_flag_${_flag_esc})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
endif()
endforeach()
endmacro()

View File

@ -0,0 +1,193 @@
include(CMakeParseArguments)
set(LIBEVENT_SHARED_LIBRARIES "")
set(LIBEVENT_STATIC_LIBRARIES "")
macro(set_event_shared_lib_flags LIB_NAME)
set_target_properties("${LIB_NAME}_shared" PROPERTIES
COMPILE_FLAGS ${ARGN})
set_target_properties("${LIB_NAME}_shared" PROPERTIES
LINK_FLAGS ${ARGN})
endmacro()
macro(generate_pkgconfig LIB_NAME)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix ${CMAKE_INSTALL_PREFIX})
set(libdir ${CMAKE_INSTALL_PREFIX}/lib)
set(includedir ${CMAKE_INSTALL_PREFIX}/include)
set(VERSION ${EVENT_ABI_LIBVERSION})
set(LIBS "")
foreach (LIB ${LIB_PLATFORM})
set(LIBS "${LIBS} -L${LIB}")
endforeach()
set(OPENSSL_LIBS "")
foreach(LIB ${OPENSSL_LIBRARIES})
set(OPENSSL_LIBS "${OPENSSL_LIBS} -L${LIB}")
endforeach()
configure_file("lib${LIB_NAME}.pc.in" "lib${LIB_NAME}.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/lib${LIB_NAME}.pc"
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig"
)
endmacro()
# LIB_NAME maybe event_core, event_extra, event_openssl, event_pthreads or event.
# Targets whose LIB_NAME is not 'event' should be exported and installed.
macro(export_install_target TYPE LIB_NAME OUTER_INCLUDES)
if("${LIB_NAME}" STREQUAL "event")
install(TARGETS "${LIB_NAME}_${TYPE}"
LIBRARY DESTINATION "lib" COMPONENT lib
ARCHIVE DESTINATION "lib" COMPONENT lib
RUNTIME DESTINATION "lib" COMPONENT lib
COMPONENT dev
)
else()
string(REPLACE "event_" "" PURE_NAME ${LIB_NAME})
string(TOUPPER ${TYPE} UPPER_TYPE)
list(APPEND LIBEVENT_${UPPER_TYPE}_LIBRARIES "${PURE_NAME}")
set(OUTER_INCS)
if (NOT "${OUTER_INCLUDES}" STREQUAL "NONE")
set(OUTER_INCS ${OUTER_INCLUDES})
endif()
target_include_directories("${LIB_NAME}_${TYPE}"
PUBLIC "$<INSTALL_INTERFACE:include>"
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>"
${OUTER_INCS}
)
set_target_properties("${LIB_NAME}_${TYPE}" PROPERTIES EXPORT_NAME ${PURE_NAME})
export(TARGETS "${LIB_NAME}_${TYPE}"
NAMESPACE ${PROJECT_NAME}::
FILE "${PROJECT_BINARY_DIR}/LibeventTargets-${TYPE}.cmake"
APPEND
)
install(TARGETS "${LIB_NAME}_${TYPE}"
EXPORT LibeventTargets-${TYPE}
LIBRARY DESTINATION "lib" COMPONENT lib
ARCHIVE DESTINATION "lib" COMPONENT lib
RUNTIME DESTINATION "lib" COMPONENT lib
COMPONENT dev
)
endif()
endmacro()
# Global variables that it uses:
# - EVENT_ABI_LIBVERSION
# - EVENT_ABI_LIBVERSION_CURRENT
# - EVENT_ABI_LIBVERSION_REVISION
# - EVENT_ABI_LIBVERSION_AGE
# - EVENT_PACKAGE_RELEASE
# - CMAKE_THREAD_LIBS_INIT LIB_PLATFORM
# - OPENSSL_LIBRARIES
# - EVENT_SHARED_FLAGS
# - EVENT_LIBRARY_STATIC
# - EVENT_LIBRARY_SHARED
#
# Exported variables:
# - LIBEVENT_SHARED_LIBRARIES
# - LIBEVENT_STATIC_LIBRARIES
macro(add_event_library LIB_NAME)
cmake_parse_arguments(LIB
"" # Options
"VERSION" # One val
"SOURCES;LIBRARIES;INNER_LIBRARIES;OUTER_INCLUDES" # Multi val
${ARGN}
)
if ("${LIB_OUTER_INCLUDES}" STREQUAL "")
set(LIB_OUTER_INCLUDES NONE)
endif()
set(ADD_EVENT_LIBRARY_INTERFACE)
if (${EVENT_LIBRARY_STATIC})
add_library("${LIB_NAME}_static" STATIC ${LIB_SOURCES})
set_target_properties("${LIB_NAME}_static" PROPERTIES
OUTPUT_NAME "${LIB_NAME}"
CLEAN_DIRECT_OUTPUT 1)
if(LIB_INNER_LIBRARIES)
set(INNER_LIBRARIES "${LIB_INNER_LIBRARIES}_static")
endif()
target_link_libraries("${LIB_NAME}_static"
${CMAKE_THREAD_LIBS_INIT}
${LIB_PLATFORM}
${INNER_LIBRARIES}
${LIB_LIBRARIES})
export_install_target(static "${LIB_NAME}" "${LIB_OUTER_INCLUDES}")
set(ADD_EVENT_LIBRARY_INTERFACE "${LIB_NAME}_static")
endif()
if (${EVENT_LIBRARY_SHARED})
add_library("${LIB_NAME}_shared" SHARED ${LIB_SOURCES})
if(LIB_INNER_LIBRARIES)
set(INNER_LIBRARIES "${LIB_INNER_LIBRARIES}_shared")
endif()
target_link_libraries("${LIB_NAME}_shared"
${CMAKE_THREAD_LIBS_INIT}
${LIB_PLATFORM}
${INNER_LIBRARIES}
${LIB_LIBRARIES})
if (EVENT_SHARED_FLAGS)
set_event_shared_lib_flags("${LIB_NAME}" "${EVENT_SHARED_FLAGS}")
endif()
if (WIN32)
set_target_properties(
"${LIB_NAME}_shared" PROPERTIES
OUTPUT_NAME "${LIB_NAME}"
SOVERSION ${EVENT_ABI_LIBVERSION})
elseif (APPLE)
math(EXPR COMPATIBILITY_VERSION "${EVENT_ABI_LIBVERSION_CURRENT}+1")
math(EXPR CURRENT_MINUS_AGE "${EVENT_ABI_LIBVERSION_CURRENT}-${EVENT_ABI_LIBVERSION_AGE}")
set_target_properties(
"${LIB_NAME}_shared" PROPERTIES
OUTPUT_NAME "${LIB_NAME}-${EVENT_PACKAGE_RELEASE}.${CURRENT_MINUS_AGE}"
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
LINK_FLAGS "-compatibility_version ${COMPATIBILITY_VERSION} -current_version ${COMPATIBILITY_VERSION}.${EVENT_ABI_LIBVERSION_REVISION}")
else()
math(EXPR CURRENT_MINUS_AGE "${EVENT_ABI_LIBVERSION_CURRENT}-${EVENT_ABI_LIBVERSION_AGE}")
set_target_properties(
"${LIB_NAME}_shared" PROPERTIES
OUTPUT_NAME "${LIB_NAME}-${EVENT_PACKAGE_RELEASE}"
VERSION "${CURRENT_MINUS_AGE}.${EVENT_ABI_LIBVERSION_AGE}.${EVENT_ABI_LIBVERSION_REVISION}"
SOVERSION "${CURRENT_MINUS_AGE}"
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
endif()
if (NOT WIN32)
set(LIB_LINK_NAME
"${CMAKE_SHARED_LIBRARY_PREFIX}${LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}")
add_custom_command(TARGET ${LIB_NAME}_shared
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink
"$<TARGET_FILE_NAME:${LIB_NAME}_shared>"
"${LIB_LINK_NAME}"
WORKING_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
endif()
export_install_target(shared "${LIB_NAME}" "${LIB_OUTER_INCLUDES}")
set(ADD_EVENT_LIBRARY_INTERFACE "${LIB_NAME}_shared")
if (NOT WIN32)
install(FILES
"$<TARGET_FILE_DIR:${LIB_NAME}_shared>/${LIB_LINK_NAME}"
DESTINATION "lib"
COMPONENT lib)
endif()
endif()
add_library(${LIB_NAME} INTERFACE)
target_link_libraries(${LIB_NAME} INTERFACE ${ADD_EVENT_LIBRARY_INTERFACE})
generate_pkgconfig("${LIB_NAME}")
endmacro()

View File

@ -0,0 +1,22 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,25 @@
include(CheckCSourceCompiles)
macro(check_const_exists CONST FILES VARIABLE)
if (NOT DEFINED ${VARIABLE})
set(check_const_exists_source "")
foreach(file ${FILES})
set(check_const_exists_source
"${check_const_exists_source}
#include <${file}>")
endforeach()
set(check_const_exists_source
"${check_const_exists_source}
int main() { (void)${CONST}; return 0; }")
check_c_source_compiles("${check_const_exists_source}" ${VARIABLE})
if (${${VARIABLE}})
set(${VARIABLE} 1 CACHE INTERNAL "Have const ${CONST}")
message(STATUS "Looking for ${CONST} - found")
else()
set(${VARIABLE} 0 CACHE INTERNAL "Have const ${CONST}")
message(STATUS "Looking for ${CONST} - not found")
endif()
endif()
endmacro(check_const_exists)

View File

@ -0,0 +1,14 @@
#include <sys/types.h>
#define KB ((off_t)1024)
#define MB ((off_t)1024 * KB)
#define GB ((off_t)1024 * MB)
#define TB ((off_t)1024 * GB)
int t2[(((64 * GB -1) % 671088649) == 268434537)
&& (((TB - (64 * GB -1) + 255) % 1792151290) == 305159546)? 1: -1];
int main()
{
;
return 0;
}

View File

@ -0,0 +1,43 @@
# - Check if _FILE_OFFSET_BITS macro needed for large files
# CHECK_FILE_OFFSET_BITS ()
#
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# Copyright (c) 2009, Michihiro NAKAJIMA
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#INCLUDE(CheckCSourceCompiles)
GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits
"${CMAKE_CURRENT_LIST_FILE}" PATH)
MACRO (CHECK_FILE_OFFSET_BITS)
IF(NOT DEFINED _FILE_OFFSET_BITS)
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files")
TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64
${CMAKE_CURRENT_BINARY_DIR}
${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
IF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
TRY_COMPILE(__WITH_FILE_OFFSET_BITS_64
${CMAKE_CURRENT_BINARY_DIR}
${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_FILE_OFFSET_BITS=64)
ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files - needed")
ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files - not needed")
ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
ENDIF(NOT DEFINED _FILE_OFFSET_BITS)
ENDMACRO (CHECK_FILE_OFFSET_BITS)

View File

@ -0,0 +1,14 @@
include(CheckCSourceCompiles)
macro(check_function_keywords _wordlist)
set(${_result} "")
foreach(flag ${_wordlist})
string(REGEX REPLACE "[-+/ ()]" "_" flagname "${flag}")
string(TOUPPER "${flagname}" flagname)
set(have_flag "HAVE_${flagname}")
check_c_source_compiles("${flag} void func(); void func() { } int main() { func(); return 0; }" ${have_flag})
if(${have_flag} AND NOT ${_result})
set(${_result} "${flag}")
endif(${have_flag} AND NOT ${_result})
endforeach(flag)
endmacro(check_function_keywords)

View File

@ -0,0 +1,29 @@
@CHECK_PROTOTYPE_DEFINITION_HEADER@
static void cmakeRequireSymbol(int dummy, ...) {
(void) dummy;
}
static void checkSymbol(void) {
#ifndef @CHECK_PROTOTYPE_DEFINITION_SYMBOL@
cmakeRequireSymbol(0, &@CHECK_PROTOTYPE_DEFINITION_SYMBOL@);
#endif
}
@CHECK_PROTOTYPE_DEFINITION_PROTO@ {
return @CHECK_PROTOTYPE_DEFINITION_RETURN@;
}
#ifdef __CLASSIC_C__
int main() {
int ac;
char*av[];
#else
int main(int ac, char *av[]) {
#endif
checkSymbol();
if (ac > 1000) {
return *av[0];
}
return 0;
}

View File

@ -0,0 +1,82 @@
# - Check if the protoype we expect is correct.
# check_prototype_definition(FUNCTION PROTOTYPE RETURN HEADER VARIABLE)
#
# FUNCTION - The name of the function (used to check if prototype exists)
# PROTOTYPE- The prototype to check.
# RETURN - The return value of the function.
# HEADER - The header files required.
# VARIABLE - The variable to store the result.
#
# Example:
#
# check_prototype_definition(getpwent_r
# "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
# "NULL"
# "unistd.h;pwd.h"
# SOLARIS_GETPWENT_R)
#
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
if (${_VARIABLE} MATCHES "^${_VARIABLE}$")
set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
if (CMAKE_REQUIRED_LIBRARIES)
set(CHECK_PROTOTYPE_DEFINITION_LIBS
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
else(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_PROTOTYPE_DEFINITION_LIBS)
endif(CMAKE_REQUIRED_LIBRARIES)
if (CMAKE_REQUIRED_INCLUDES)
set(CMAKE_SYMBOL_EXISTS_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_SYMBOL_EXISTS_INCLUDES)
endif(CMAKE_REQUIRED_INCLUDES)
foreach(_FILE ${_HEADER})
set(CHECK_PROTOTYPE_DEFINITION_HEADER
"${CHECK_PROTOTYPE_DEFINITION_HEADER}#include <${_FILE}>\n")
endforeach(_FILE)
set(CHECK_PROTOTYPE_DEFINITION_SYMBOL ${_FUNCTION})
set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE})
set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN})
configure_file("${PROJECT_SOURCE_DIR}/cmake/CheckPrototypeDefinition.c.in"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c" @ONLY)
file(READ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c _SOURCE)
try_compile(${_VARIABLE}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS}
"${CHECK_PROTOTYPE_DEFINITION_LIBS}"
"${CMAKE_SYMBOL_EXISTS_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
if (${_VARIABLE})
set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n"
"${OUTPUT}\n\n")
else (${_VARIABLE})
message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} failed with the following output:\n"
"${OUTPUT}\n\n${_SOURCE}\n\n")
endif (${_VARIABLE})
endif()
endfunction(CHECK_PROTOTYPE_DEFINITION)

View File

@ -0,0 +1,52 @@
include(CheckCSourceRuns)
check_c_source_runs(
"
#include <sys/types.h>
#include <sys/time.h>
#include <sys/event.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int
main(int argc, char **argv)
{
int kq;
int n;
int fd[2];
struct kevent ev;
struct timespec ts;
char buf[80000];
if (pipe(fd) == -1)
exit(1);
if (fcntl(fd[1], F_SETFL, O_NONBLOCK) == -1)
exit(1);
while ((n = write(fd[1], buf, sizeof(buf))) == sizeof(buf))
;
if ((kq = kqueue()) == -1)
exit(1);
memset(&ev, 0, sizeof(ev));
ev.ident = fd[1];
ev.filter = EVFILT_WRITE;
ev.flags = EV_ADD | EV_ENABLE;
n = kevent(kq, &ev, 1, NULL, 0, NULL);
if (n == -1)
exit(1);
read(fd[0], buf, sizeof(buf));
ts.tv_sec = 0;
ts.tv_nsec = 0;
n = kevent(kq, NULL, 0, &ev, 1, &ts);
if (n == -1 || n == 0)
exit(1);
exit(0);
}
" EVENT__HAVE_WORKING_KQUEUE)

View File

@ -0,0 +1,165 @@
#
# Boost Software License - Version 1.0 - August 17th, 2003
#
# Permission is hereby granted, free of charge, to any person or organization
# obtaining a copy of the software and accompanying documentation covered by
# this license (the "Software") to use, reproduce, display, distribute,
# execute, and transmit the Software, and to prepare derivative works of the
# Software, and to permit third-parties to whom the Software is furnished to
# do so, all subject to the following:
#
# The copyright notices in the Software and this entire statement, including
# the above license grant, this restriction and the following disclaimer,
# must be included in all copies of the Software, in whole or in part, and
# all derivative works of the Software, unless such copies or derivative
# works are solely in the form of machine-executable object code generated by
# a source language processor.
#
# 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
# SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
# FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# 2012-01-31, Lars Bilke
# - Enable Code Coverage
#
# 2013-09-17, Joakim Söderberg
# - Added support for Clang.
# - Some additional usage instructions.
#
# 2016-11-02, Azat Khuzhin
# - Adopt for C compiler only (libevent)
#
# USAGE:
# 1. Copy this file into your cmake modules path.
#
# 2. Add the following line to your CMakeLists.txt:
# INCLUDE(CodeCoverage)
#
# 3. Set compiler flags to turn off optimization and enable coverage:
# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
#
# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target
# which runs your test executable and produces a lcov code coverage report:
# Example:
# SETUP_TARGET_FOR_COVERAGE(
# my_coverage_target # Name for custom target.
# test_driver # Name of the test driver executable that runs the tests.
# # NOTE! This should always have a ZERO as exit code
# # otherwise the coverage generation will not complete.
# coverage # Name of output directory.
# )
#
# 4. Build a Debug build:
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# make
# make my_coverage_target
#
#
# Check prereqs
FIND_PROGRAM( GCOV_PATH gcov )
FIND_PROGRAM( LCOV_PATH lcov )
FIND_PROGRAM( GENHTML_PATH genhtml )
FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
IF(NOT GCOV_PATH)
MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
ENDIF() # NOT GCOV_PATH
IF(NOT CMAKE_COMPILER_IS_GNUCC)
# Clang version 3.0.0 and greater now supports gcov as well.
MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.")
IF(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
ENDIF()
ENDIF() # NOT CMAKE_COMPILER_IS_GNUCC
IF ( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" )
MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" )
ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
# Param _targetname The name of new the custom make target
# Param _testrunner The name of the target which runs the tests.
# MUST return ZERO always, even on errors.
# If not, no coverage report will be created!
# Param _outputname lcov output is generated as _outputname.info
# HTML report is generated in _outputname/index.html
# Optional fourth parameter is passed as arguments to _testrunner
# Pass them in list form, e.g.: "-j;2" for -j 2
FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname)
IF(NOT LCOV_PATH)
MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
ENDIF() # NOT LCOV_PATH
IF(NOT GENHTML_PATH)
MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
ENDIF() # NOT GENHTML_PATH
# Setup target
ADD_CUSTOM_TARGET(${_targetname}
# Cleanup lcov
${LCOV_PATH} --directory . --zerocounters
# Run tests
COMMAND ${_testrunner} ${ARGV3}
# Capturing lcov counters and generating report
COMMAND ${LCOV_PATH} --directory . --capture --output-file ${_outputname}.info
COMMAND ${LCOV_PATH} --remove ${_outputname}.info 'tests/*' '/usr/*' --output-file ${_outputname}.info.cleaned
COMMAND ${GENHTML_PATH} -o ${_outputname} ${_outputname}.info.cleaned
COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info ${_outputname}.info.cleaned
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
)
# Show info where to find the report
ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
COMMAND ;
COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report."
)
ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE
# Param _targetname The name of new the custom make target
# Param _testrunner The name of the target which runs the tests
# Param _outputname cobertura output is generated as _outputname.xml
# Optional fourth parameter is passed as arguments to _testrunner
# Pass them in list form, e.g.: "-j;2" for -j 2
FUNCTION(SETUP_TARGET_FOR_COVERAGE_COBERTURA _targetname _testrunner _outputname)
IF(NOT PYTHON_EXECUTABLE)
MESSAGE(FATAL_ERROR "Python not found! Aborting...")
ENDIF() # NOT PYTHON_EXECUTABLE
IF(NOT GCOVR_PATH)
MESSAGE(FATAL_ERROR "gcovr not found! Aborting...")
ENDIF() # NOT GCOVR_PATH
ADD_CUSTOM_TARGET(${_targetname}
# Run tests
${_testrunner} ${ARGV3}
# Running gcovr
COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} -e '${CMAKE_SOURCE_DIR}/tests/' -o ${_outputname}.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Running gcovr to produce Cobertura code coverage report."
)
# Show info where to find the report
ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
COMMAND ;
COMMENT "Cobertura code coverage report saved in ${_outputname}.xml."
)
ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE_COBERTURA

View File

@ -0,0 +1,57 @@
CMake - Cross Platform Makefile Generator
Copyright 2000-2013 Kitware, Inc.
Copyright 2000-2011 Insight Software Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the names of Kitware, Inc., the Insight Software Consortium,
nor the names of their contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
The above copyright and license notice applies to distributions of
CMake in source and binary form. Some source files contain additional
notices of original copyright by their contributors; see each source
for details. Third-party software packages supplied with CMake under
compatible licenses provide their own copyright notices documented in
corresponding subdirectories.
------------------------------------------------------------------------------
CMake was initially developed by Kitware with the following sponsorship:
* National Library of Medicine at the National Institutes of Health
as part of the Insight Segmentation and Registration Toolkit (ITK).
* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
Visualization Initiative.
* National Alliance for Medical Image Computing (NAMIC) is funded by the
National Institutes of Health through the NIH Roadmap for Medical Research,
Grant U54 EB005149.
* Kitware, Inc.

View File

@ -0,0 +1,183 @@
# - Config file for the Libevent package
# It defines the following variables
# LIBEVENT_FOUND - true if libevent and all required components found on the system
# LIBEVENT_xxx_FOUND - true if component xxx(see available components) found on the system
# LIBEVENT_VERSION - libevent version in format Major.Minor.Patch
# LIBEVENT_INCLUDE_DIRS - directories where libevent header is located.
# LIBEVENT_INCLUDE_DIR - same as DIRS
# LIBEVENT_LIBRARIES - libevent library to link against.
# LIBEVENT_LIBRARY - same as LIBRARIES
#
# These variables are deprecated, don't use them.
# LIBEVENT_STATIC_LIBRARIES - libraries to link against (archive/static)
# LIBEVENT_SHARED_LIBRARIES - libraries to link against (shared)
#
# When you try to locate the libevent libraries, you should specify which components you want to use.
# The following table lists all available components. If none is given, all imported targets will used.
# core - the core functons of libevent
# extra - extra functions, contains http, dns and rpc
# pthreads - multiple threads for libevent, not exists on Windows
# openssl - openssl support for libevent
#
# By default, the shared libraries of libevent will be found. To find the static ones instead,
# you must set the LIBEVENT_STATIC_LINK variable to TRUE before calling find_package(Libevent ...).
# If no component provided, all components will be used.
# example:
# set(LIBEVENT_STATIC_LINK TRUE)
# find_package(Libevent 2.2 REQUIRED COMPONENTS core)
# include_directories(${LIBEVENT_INCLUDE_DIRS}) # Can be omitted
# target_link_libraries(myapp ${LIBEVENT_LIBRARIES})
# or target_link_libraries(myapp libevent::core)
#
# find_package() can handle dependencies automatically. For example, given the 'openssl' component,
# all dependencies (libevent_core, libssl, libcrypto and openssl include directories) will be found.
set(CONFIG_FOR_INSTALL_TREE @CONFIG_FOR_INSTALL_TREE@)
set(LIBEVENT_VERSION @EVENT_PACKAGE_VERSION@)
# IMPORTED targets from LibeventTargets.cmake
set(LIBEVENT_STATIC_LIBRARIES "@LIBEVENT_STATIC_LIBRARIES@")
set(LIBEVENT_SHARED_LIBRARIES "@LIBEVENT_SHARED_LIBRARIES@")
# Default to the same type as libevent was built:
if(NOT DEFINED LIBEVENT_STATIC_LINK)
set(LIBEVENT_STATIC_LINK NOT @EVENT_LIBRARY_SHARED@)
endif()
set(CMAKE_FIND_LIBRARY_SUFFIXES_SAVE "${CMAKE_FIND_LIBRARY_SUFFIXES}")
if(${LIBEVENT_STATIC_LINK})
set(_LIB_TYPE static)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
set(_AVAILABLE_LIBS "${LIBEVENT_STATIC_LIBRARIES}")
else()
set(_LIB_TYPE shared)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
set(_AVAILABLE_LIBS "${LIBEVENT_SHARED_LIBRARIES}")
endif()
# Get the path of the current file.
get_filename_component(LIBEVENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_INSTALL_PREFIX "${LIBEVENT_CMAKE_DIR}/../../.." ABSOLUTE)
macro(message_if_needed _flag _msg)
if (NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
message(${_flag} "${_msg}")
endif()
endmacro()
macro(no_component_msg _comp)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED_${_comp})
set(pthreadlib)
if(NOT WIN32)
set(pthreadlib ", pthreads")
endif()
message(FATAL_ERROR "Your libevent library does not contain a ${_comp} component!\n"
"The valid components are core, extra${pthreadlib} and openssl.")
else()
message_if_needed(WARNING "Your libevent library does not contain a ${_comp} component!")
endif()
endmacro()
set(_EVENT_COMPONENTS)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS)
list(REMOVE_DUPLICATES ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS)
foreach(_comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS})
list(FIND _AVAILABLE_LIBS ${_comp} _INDEX)
if(_INDEX GREATER -1)
list(APPEND _EVENT_COMPONENTS ${_comp})
else()
no_component_msg(${_comp})
endif()
endforeach()
else()
set(_EVENT_COMPONENTS ${_AVAILABLE_LIBS})
endif()
set(_POSSIBLE_PKG_NAMES)
list(APPEND _POSSIBLE_PKG_NAMES ${CMAKE_FIND_PACKAGE_NAME} LIBEVENT Libevent libevent)
list(REMOVE_DUPLICATES _POSSIBLE_PKG_NAMES)
macro(set_case_insensitive_found _comp)
foreach(name ${_POSSIBLE_PKG_NAMES})
if("${_comp}" STREQUAL "")
set(${name}_FOUND TRUE)
set(${name}_NOTFOUND FALSE)
else()
set(${name}_${_comp}_FOUND TRUE)
set(${name}_${_comp}_NOTFOUND FALSE)
endif()
endforeach()
endmacro()
if(CONFIG_FOR_INSTALL_TREE)
## Config for install tree ----------------------------------------
# Find includes
unset(_event_h CACHE)
find_path(_event_h
NAMES event2/event.h
PATHS "${_INSTALL_PREFIX}/include"
NO_DEFAULT_PATH)
if(_event_h)
set(LIBEVENT_INCLUDE_DIRS "${_event_h}")
message_if_needed(STATUS "Found libevent include directory: ${_event_h}")
else()
message_if_needed(WARNING "Your libevent library does not contain header files!")
endif()
# Find libraries
macro(find_event_lib _comp)
unset(_event_lib CACHE)
find_library(_event_lib
NAMES "event_${_comp}"
PATHS "${_INSTALL_PREFIX}/lib"
NO_DEFAULT_PATH)
if(_event_lib)
list(APPEND LIBEVENT_LIBRARIES "libevent::${_comp}")
set_case_insensitive_found(${_comp})
message_if_needed(STATUS "Found libevent component: ${_event_lib}")
else()
no_component_msg(${_comp})
endif()
endmacro()
foreach(comp ${_EVENT_COMPONENTS})
find_event_lib(${comp})
endforeach()
else()
## Config for build tree ----------------------------------------
set(LIBEVENT_INCLUDE_DIRS "@EVENT__INCLUDE_DIRS@")
foreach(_comp ${_EVENT_COMPONENTS})
list(APPEND LIBEVENT_LIBRARIES "libevent::${_comp}")
set_case_insensitive_found(${_comp})
endforeach()
endif()
set(LIBEVENT_INCLUDE_DIR ${LIBEVENT_INCLUDE_DIRS})
if(LIBEVENT_LIBRARIES)
set(LIBEVENT_LIBRARY ${LIBEVENT_LIBRARIES})
if(CONFIG_FOR_INSTALL_TREE)
message_if_needed(STATUS "Found libevent ${LIBEVENT_VERSION} in ${_INSTALL_PREFIX}")
else()
message_if_needed(STATUS "Found libevent ${LIBEVENT_VERSION} in ${LIBEVENT_CMAKE_DIR}")
endif()
# Avoid including targets more than one times
if(NOT TARGET event_core_${_LIB_TYPE})
# Include the project Targets file, this contains definitions for IMPORTED targets.
include(${LIBEVENT_CMAKE_DIR}/LibeventTargets-${_LIB_TYPE}.cmake)
endif()
else()
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
message(FATAL_ERROR "Can not find any libraries for libevent.")
else()
message_if_needed(WARNING "Can not find any libraries for libevent.")
endif()
endif()
set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES_SAVE}")
unset(_LIB_TYPE)
unset(_AVAILABLE_LIBS)
unset(_EVENT_COMPONENTS)
unset(_POSSIBLE_PKG_NAMES)
unset(_INSTALL_PREFIX)

View File

@ -0,0 +1,11 @@
set(PACKAGE_VERSION "@EVENT_PACKAGE_VERSION@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()

View File

@ -0,0 +1,36 @@
include(CheckSymbolExists)
include(CheckIncludeFiles)
# Check if each symbol in the symbol list exists,
# and define PREFIX__HAVE_SYMNAME to 1 if yes.
#
# SYMLIST: list of symbols to check
# HEADERS: header files to be included in check code
# PREFIX: the prefix of definition
macro(CHECK_SYMBOLS_EXIST SYMLIST HEADERS PREFIX)
foreach(SYMNAME ${SYMLIST})
string(TOUPPER "${SYMNAME}" SYMNAME_UPPER)
if ("${PREFIX}" STREQUAL "")
set(HAVE_SYM_DEF "HAVE_${SYMNAME_UPPER}")
else()
set(HAVE_SYM_DEF "${PREFIX}__HAVE_${SYMNAME_UPPER}")
endif()
CHECK_SYMBOL_EXISTS(${SYMNAME} "${HEADERS}" ${HAVE_SYM_DEF})
endforeach()
endmacro()
# Check if file exists, define PREFIX__HAVE_FILE to 1 if yes,
# and collect file to EVENT_INCLUDES
macro(CHECK_INCLUDE_FILE_CONCAT FILE PREFIX)
string(REGEX REPLACE "[./]" "_" FILE_UL ${FILE})
string(TOUPPER "${FILE_UL}" FILE_UL_UPPER)
if ("${PREFIX}" STREQUAL "")
set(HAVE_FILE_DEF "HAVE_${FILE_UL_UPPER}")
else()
set(HAVE_FILE_DEF "${PREFIX}__HAVE_${FILE_UL_UPPER}")
endif()
CHECK_INCLUDE_FILES("${EVENT_INCLUDES};${FILE}" ${HAVE_FILE_DEF})
if(${HAVE_FILE_DEF})
set(EVENT_INCLUDES ${EVENT_INCLUDES} ${FILE})
endif()
endmacro()

View File

@ -0,0 +1,23 @@
# https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)

View File

@ -0,0 +1,111 @@
# Use FindDoxygen.cmake to generate documentation.
option(DOXYGEN_GENERATE_HTML "Generate HTML" ON)
option(DOXYGEN_GENERATE_MAN "Generate man pages" OFF)
option(DOXYGEN_MAN_LINKS "Generate man links" ON)
option(DOXYGEN_GENERATE_LATEX "Generate LaTeX" OFF)
# If the case-insensitive value of the cmake option is one of
# "off, no, false" or 0, it is equal to false, otherwise true.
# And the values of the doxygen config does not exactly match it.
# So we need to convert the cmake option to a doxygen config.
macro(_convert_to_dx_cfg CMK_OPTION)
if (${CMK_OPTION})
set(${CMK_OPTION} YES)
else()
set(${CMK_OPTION} NO)
endif()
endmacro()
macro(UseDoxygen)
if (${CMAKE_VERSION} VERSION_LESS "3.9")
# Old versions of cmake have poor support for Doxygen generation.
message(FATAL_ERROR "Doxygen generation only enabled for cmake 3.9 and higher")
else()
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME})
set(DOXYGEN_PROJECT_NUMBER ${EVENT_PACKAGE_VERSION})
set(DOXYGEN_PROJECT_BRIEF "Event notification library")
set(DOXYGEN_OUTPUT_DIRECTORY doxygen)
set(DOXYGEN_STRIP_FROM_PATH include)
set(DOXYGEN_JAVADOC_AUTOBRIEF YES)
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_SORT_BRIEF_DOCS YES)
set(DOXYGEN_RECURSIVE NO)
_convert_to_dx_cfg(DOXYGEN_GENERATE_HTML)
_convert_to_dx_cfg(DOXYGEN_GENERATE_MAN)
_convert_to_dx_cfg(DOXYGEN_MAN_LINKS)
_convert_to_dx_cfg(DOXYGEN_GENERATE_LATEX)
set(DOXYGEN_LATEX_CMD_NAME latex)
set(DOXYGEN_PAPER_TYPE a4wide)
set(DOXYGEN_PDF_HYPERLINKS NO)
set(DOXYGEN_GENERATE_RTF NO)
set(DOXYGEN_GENERATE_XML NO)
set(DOXYGEN_GENERATE_CHI NO)
set(DOXYGEN_PREDEFINED TAILQ_ENTRY
RB_ENTRY
EVENT_DEFINED_TQENTRY_
EVENT_IN_DOXYGEN_
)
set(DOX_INPUT include/event2/buffer.h
include/event2/buffer_compat.h
include/event2/bufferevent.h
include/event2/bufferevent_compat.h
include/event2/bufferevent_ssl.h
include/event2/dns.h
include/event2/dns_compat.h
include/event2/event.h
include/event2/event_compat.h
include/event2/http.h
include/event2/http_compat.h
include/event2/listener.h
include/event2/rpc.h
include/event2/rpc_compat.h
include/event2/tag.h
include/event2/tag_compat.h
include/event2/thread.h
include/event2/util.h
)
# Add 'doxygen' target
doxygen_add_docs(doxygen
${DOX_INPUT}
ALL
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Generating doxygen documentation for ${PROJECT_NAME}..."
)
# Use 'make clean' to remove the generated directory
set_property(DIRECTORY
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
"${PROJECT_BINARY_DIR}/${DOXYGEN_OUTPUT_DIRECTORY}"
)
# Install html into <prefix>/share/doc/<project>
if ("${DOXYGEN_GENERATE_HTML}" STREQUAL "YES")
install(DIRECTORY
${PROJECT_BINARY_DIR}/${DOXYGEN_OUTPUT_DIRECTORY}/html
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}
COMPONENT doc
)
endif()
# Install manual into <prefix>/share/man/man3
if ("${DOXYGEN_GENERATE_MAN}" STREQUAL "YES")
install(DIRECTORY
${PROJECT_BINARY_DIR}/${DOXYGEN_OUTPUT_DIRECTORY}/man/man3
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man
COMPONENT doc
)
endif()
else(DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen command not found, set EVENT__DOXYGEN to disable")
endif (DOXYGEN_FOUND)
endif()
endmacro()

View File

@ -0,0 +1,66 @@
# This module defines the following variables utilizing
# git to determine the parent tag. And if found the macro
# will attempt to parse them in the github tag fomat
#
# Useful for auto-versioning in our CMakeLists
#
# EVENT_GIT___VERSION_MAJOR - Major version.
# EVENT_GIT___VERSION_MINOR - Minor version
# EVENT_GIT___VERSION_STAGE - Stage version
#
# Example usage:
#
# event_fuzzy_version_from_git()
# message("Libvent major=${EVENT_GIT___VERSION_MAJOR}")
# message(" minor=${EVENT_GIT___VERSION_MINOR}")
# message(" patch=${EVENT_GIT___VERSION_PATCH}")
# message(" stage=${EVENT_GIT___VERSION_STAGE}")
# endif()
include(FindGit)
macro(event_fuzzy_version_from_git)
# set our defaults.
set(EVENT_GIT___VERSION_MAJOR 2)
set(EVENT_GIT___VERSION_MINOR 1)
set(EVENT_GIT___VERSION_PATCH 12)
set(EVENT_GIT___VERSION_STAGE "stable")
find_package(Git)
if (GIT_FOUND)
execute_process(
COMMAND
${GIT_EXECUTABLE} describe --abbrev=0 --always
WORKING_DIRECTORY
${PROJECT_SOURCE_DIR}
RESULT_VARIABLE
GITRET
OUTPUT_VARIABLE
GITVERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REGEX REPLACE "[\\._-]" ";" VERSION_LIST "${GITVERSION}")
if(VERSION_LIST)
list(LENGTH VERSION_LIST VERSION_LIST_LENGTH)
endif()
if ((GITRET EQUAL 0) AND (VERSION_LIST_LENGTH EQUAL 5))
list(GET VERSION_LIST 1 _MAJOR)
list(GET VERSION_LIST 2 _MINOR)
list(GET VERSION_LIST 3 _PATCH)
list(GET VERSION_LIST 4 _STAGE)
set(_DEFAULT_VERSION "${EVENT_GIT___VERSION_MAJOR}.${EVENT_GIT___VERSION_MINOR}.${EVENT_GIT___VERSION_PATCH}-${EVENT_GIT___VERSION_STAGE}")
set(_GIT_VERSION "${_MAJOR}.${_MINOR}.${_PATCH}-${_STAGE}")
if (${_DEFAULT_VERSION} VERSION_LESS ${_GIT_VERSION})
set(EVENT_GIT___VERSION_MAJOR ${_MAJOR})
set(EVENT_GIT___VERSION_MINOR ${_MINOR})
set(EVENT_GIT___VERSION_PATCH ${_PATCH})
set(EVENT_GIT___VERSION_STAGE ${_STAGE})
endif()
endif()
endif()
endmacro()

View File

@ -12,9 +12,15 @@
/* Define to 1 if you have the `accept4' function. */
#undef HAVE_ACCEPT4
/* Define to 1 if you have the <afunix.h> header file. */
#undef HAVE_AFUNIX_H
/* Define to 1 if you have the `arc4random' function. */
#undef HAVE_ARC4RANDOM
/* Define to 1 if you have the `arc4random_addrandom' function. */
#undef HAVE_ARC4RANDOM_ADDRANDOM
/* Define to 1 if you have the `arc4random_buf' function. */
#undef HAVE_ARC4RANDOM_BUF
@ -32,14 +38,6 @@
don't. */
#undef HAVE_DECL_KERN_ARND
/* Define to 1 if you have the declaration of `KERN_RANDOM', and to 0 if you
don't. */
#undef HAVE_DECL_KERN_RANDOM
/* Define to 1 if you have the declaration of `RANDOM_UUID', and to 0 if you
don't. */
#undef HAVE_DECL_RANDOM_UUID
/* Define if /dev/poll is available */
#undef HAVE_DEVPOLL
@ -58,9 +56,6 @@
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have ERR_remove_thread_stat(). */
#undef HAVE_ERR_REMOVE_THREAD_STATE
/* Define to 1 if you have the `eventfd' function. */
#undef HAVE_EVENTFD
@ -106,6 +101,9 @@
/* Define to 1 if you have the `getprotobynumber' function. */
#undef HAVE_GETPROTOBYNUMBER
/* Define to 1 if you have the `getrandom' function. */
#undef HAVE_GETRANDOM
/* Define to 1 if you have the `getservbyname' function. */
#undef HAVE_GETSERVBYNAME
@ -130,12 +128,18 @@
/* Define to 1 if you have the `kqueue' function. */
#undef HAVE_KQUEUE
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
#undef HAVE_LIBWS2_32
/* Define if the system has zlib */
#undef HAVE_LIBZ
/* Define to 1 if you have the `mach_absolute_time' function. */
#undef HAVE_MACH_ABSOLUTE_TIME
/* Define to 1 if you have the <mach/mach.h> header file. */
#undef HAVE_MACH_MACH_H
/* Define to 1 if you have the <mach/mach_time.h> header file. */
#undef HAVE_MACH_MACH_TIME_H
@ -163,6 +167,9 @@
/* Define if the system has openssl */
#undef HAVE_OPENSSL
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define to 1 if you have the `pipe' function. */
#undef HAVE_PIPE
@ -259,6 +266,9 @@
/* Define to 1 if `s6_addr32' is a member of `struct in6_addr'. */
#undef HAVE_STRUCT_IN6_ADDR_S6_ADDR32
/* Define to 1 if the system has the type `struct linger'. */
#undef HAVE_STRUCT_LINGER
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
#undef HAVE_STRUCT_SOCKADDR_IN6
@ -277,8 +287,8 @@
/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
/* Define to 1 if the system has the type `struct so_linger'. */
#undef HAVE_STRUCT_SO_LINGER
/* Define to 1 if the system has the type `struct sockaddr_un'. */
#undef HAVE_STRUCT_SOCKADDR_UN
/* Define to 1 if you have the `sysctl' function. */
#undef HAVE_SYSCTL
@ -307,6 +317,9 @@
/* Define to 1 if you have the <sys/queue.h> header file. */
#undef HAVE_SYS_QUEUE_H
/* Define to 1 if you have the <sys/random.h> header file. */
#undef HAVE_SYS_RANDOM_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
@ -337,6 +350,9 @@
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
@ -388,15 +404,24 @@
/* Define to 1 if you have the `vasprintf' function. */
#undef HAVE_VASPRINTF
/* Define if waitpid() supports WNOWAIT */
#undef HAVE_WAITPID_WITH_WNOWAIT
/* Define if kqueue works correctly with pipes */
#undef HAVE_WORKING_KQUEUE
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
/* Define to 1 if you have the `_gmtime64' function. */
#undef HAVE__GMTIME64
/* Define to 1 if you have the `_gmtime64_s' function. */
#undef HAVE__GMTIME64_S
/* Define to 1 if compiler have __FUNCTION__ */
#undef HAVE___FUNCTION__
/* Define to 1 if compiler have __func__ */
#undef HAVE___func__
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
@ -449,6 +474,9 @@
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* The size of `time_t', as computed by sizeof. */
#undef SIZEOF_TIME_T
/* The size of `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P
@ -504,9 +532,6 @@
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define to appropriate substitue if compiler doesnt have __func__ */
#undef __func__
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,30 +5,23 @@ dnl See LICENSE for copying information.
dnl
dnl Original version Dug Song <dugsong@monkey.org>
AC_INIT(libevent,2.1.8-stable)
AC_PREREQ(2.59)
AC_INIT(libevent,2.1.12-stable)
AC_PREREQ(2.67)
AC_CONFIG_SRCDIR(event.c)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE
dnl AM_SILENT_RULES req. automake 1.11. [no] defaults V=1
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS(config.h evconfig-private.h:evconfig-private.h.in)
AC_DEFINE(NUMERIC_VERSION, 0x02010800, [Numeric representation of the version])
AC_DEFINE(NUMERIC_VERSION, 0x02010c00, [Numeric representation of the version])
dnl Initialize prefix.
if test "$prefix" = "NONE"; then
prefix="/usr/local"
fi
AC_PREFIX_DEFAULT([/usr/local])
dnl Try and get a full POSIX environment on obscure systems
ifdef([AC_USE_SYSTEM_EXTENSIONS], [
AC_USE_SYSTEM_EXTENSIONS
], [
AC_AIX
AC_GNU_SOURCE
AC_MINIX
])
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
@ -48,11 +41,7 @@ AC_PROG_INSTALL
AC_PROG_LN_S
# AC_PROG_MKDIR_P - $(MKDIR_P) should be defined by AM_INIT_AUTOMAKE
# AC_PROG_SED is only available in Autoconf >= 2.59b; workaround for older
# versions
ifdef([AC_PROG_SED], [AC_PROG_SED], [
AC_CHECK_PROGS(SED, [gsed sed])
])
AC_PROG_SED
AC_PROG_GCC_TRADITIONAL
@ -126,7 +115,8 @@ AC_ARG_ENABLE([clock-gettime],
[], [enable_clock_gettime=yes])
AC_PROG_LIBTOOL
LT_PREREQ([2.4.2])
LT_INIT
dnl Uncomment "AC_DISABLE_SHARED" to make shared libraries not get
dnl built by default. You can also turn shared libs on and off from
@ -150,27 +140,46 @@ AC_SEARCH_LIBS([sendfile], [sendfile])
dnl - check if the macro _WIN32 is defined on this compiler.
dnl - (this is how we check for a windows compiler)
AC_MSG_CHECKING(for WIN32)
AC_TRY_COMPILE(,
[
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],
[
#ifndef _WIN32
die horribly
#endif
],
bwin32=true; AC_MSG_RESULT(yes),
bwin32=false; AC_MSG_RESULT(no),
]
)],
[bwin32=true; AC_MSG_RESULT(yes)],
[bwin32=false; AC_MSG_RESULT(no)]
)
dnl - check if the macro __midipix__ is defined on this compiler.
dnl - (this is how we check for a midipix version of GCC)
AC_MSG_CHECKING(for MIDIPIX)
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],
[
#ifndef __midipix__
die horribly
#endif
]
)],
[midipix=true; AC_MSG_RESULT(yes)],
[midipix=false; AC_MSG_RESULT(no)]
)
dnl - check if the macro __CYGWIN__ is defined on this compiler.
dnl - (this is how we check for a cygwin version of GCC)
AC_MSG_CHECKING(for CYGWIN)
AC_TRY_COMPILE(,
[
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],
[
#ifndef __CYGWIN__
die horribly
#endif
],
cygwin=true; AC_MSG_RESULT(yes),
cygwin=false; AC_MSG_RESULT(no),
]
)],
[cygwin=true; AC_MSG_RESULT(yes)],
[cygwin=false; AC_MSG_RESULT(no)]
)
AC_CHECK_HEADERS([zlib.h])
@ -213,10 +222,12 @@ AC_CHECK_HEADERS([ \
fcntl.h \
ifaddrs.h \
mach/mach_time.h \
mach/mach.h \
netdb.h \
netinet/in.h \
netinet/in6.h \
netinet/tcp.h \
sys/un.h \
poll.h \
port.h \
stdarg.h \
@ -238,14 +249,21 @@ AC_CHECK_HEADERS([ \
sys/timerfd.h \
sys/uio.h \
sys/wait.h \
sys/random.h \
errno.h \
afunix.h \
])
AC_CHECK_HEADERS(sys/sysctl.h, [], [], [
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
])
case "${host_os}" in
linux*) ;;
*)
AC_CHECK_HEADERS(sys/sysctl.h, [], [], [
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
])
esac
if test "x$ac_cv_header_sys_queue_h" = "xyes"; then
AC_MSG_CHECKING(for TAILQ_FOREACH in sys/queue.h)
AC_EGREP_CPP(yes,
@ -318,7 +336,7 @@ if test "x$ac_cv_header_sys_time_h" = "xyes"; then
fi
if test "x$ac_cv_header_sys_sysctl_h" = "xyes"; then
AC_CHECK_DECLS([CTL_KERN, KERN_RANDOM, RANDOM_UUID, KERN_ARND], [], [],
AC_CHECK_DECLS([CTL_KERN, KERN_ARND], [], [],
[[#include <sys/types.h>
#include <sys/sysctl.h>]]
)
@ -326,10 +344,11 @@ fi
AM_CONDITIONAL(BUILD_WIN32, test x$bwin32 = xtrue)
AM_CONDITIONAL(BUILD_CYGWIN, test x$cygwin = xtrue)
AM_CONDITIONAL(BUILD_WITH_NO_UNDEFINED, test x$bwin32 = xtrue || test x$cygwin = xtrue)
AM_CONDITIONAL(BUILD_MIDIPIX, test x$midipix = xtrue)
AM_CONDITIONAL(BUILD_WITH_NO_UNDEFINED, test x$bwin32 = xtrue || test x$cygwin = xtrue || test x$midipix = xtrue)
if test x$bwin32 = xtrue; then
AC_SEARCH_LIBS([getservbyname],[ws2_32])
AC_HAVE_LIBRARY([ws2_32])
fi
dnl Checks for typedefs, structures, and compiler characteristics.
@ -342,17 +361,14 @@ AC_CHECK_FUNCS([ \
accept4 \
arc4random \
arc4random_buf \
arc4random_addrandom \
eventfd \
epoll_create1 \
fcntl \
getegid \
geteuid \
getifaddrs \
getnameinfo \
getprotobynumber \
gettimeofday \
inet_ntop \
inet_pton \
issetugid \
mach_absolute_time \
mmap \
@ -376,10 +392,36 @@ AC_CHECK_FUNCS([ \
unsetenv \
usleep \
vasprintf \
getservbyname \
getrandom \
])
AS_IF([test x$bwin32 = xtrue],
AC_CHECK_FUNCS(_gmtime64_s, , [AC_CHECK_FUNCS(_gmtime64)])
)
AM_CONDITIONAL(STRLCPY_IMPL, [test x"$ac_cv_func_strlcpy" = xno])
m4_define([funcstochk],
[getnameinfo
getprotobynumber
getservbyname
inet_ntop
inet_pton]
)
AS_IF([test x$bwin32 = xtrue],
[AX_CHECK_DECLS_EX([funcstochk getaddrinfo],
[#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif])],
[AC_CHECK_FUNCS(m4_normalize(funcstochk))]
)
m4_undefine([funcstochk])
dnl check getaddrinfo and gethostbyname_r for non-windows
AS_IF([test x$bwin32 = xfalse], [
AC_CACHE_CHECK(
[for getaddrinfo],
[libevent_cv_getaddrinfo],
@ -425,27 +467,27 @@ AC_CHECK_FUNC(gethostbyname_r, [
[Define this if gethostbyname_r takes 6 arguments])
AC_MSG_RESULT(6)
], [
AC_TRY_COMPILE([
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
#include <netdb.h>
], [
char *cp1, *cp2;
struct hostent *h1;
int i1, i2;
(void)gethostbyname_r(cp1,h1,cp2,i1,&i2);
], [
])], [
AC_DEFINE(HAVE_GETHOSTBYNAME_R)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_5_ARG, 1,
[Define this if gethostbyname_r takes 5 arguments])
AC_MSG_RESULT(5)
], [
AC_TRY_COMPILE([
], [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
#include <netdb.h>
], [
char *cp1;
struct hostent *h1;
struct hostent_data hd;
(void) gethostbyname_r(cp1,h1,&hd);
], [
])], [
AC_DEFINE(HAVE_GETHOSTBYNAME_R)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_3_ARG, 1,
[Define this if gethostbyname_r takes 3 arguments])
@ -459,11 +501,12 @@ AC_CHECK_FUNC(gethostbyname_r, [
])
fi
]) dnl end of checking getaddrinfo and gethostbyname_r
AC_MSG_CHECKING(for F_SETFD in fcntl.h)
AC_EGREP_CPP(yes,
[
#define _GNU_SOURCE
#define _GNU_SOURCE 1
#include <fcntl.h>
#ifdef F_SETFD
yes
@ -501,57 +544,64 @@ if test "x$ac_cv_header_sys_event_h" = "xyes"; then
AC_CHECK_FUNCS(kqueue, [havekqueue=yes], )
if test "x$havekqueue" = "xyes" ; then
AC_MSG_CHECKING(for working kqueue)
AC_TRY_RUN(
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/event.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int
main(int argc, char **argv)
{
], [[
int kq;
int n;
int fd[[2]];
int fd[2];
struct kevent ev;
struct timespec ts;
char buf[[8000]];
char buf[80000];
if (pipe(fd) == -1)
exit(1);
if (fcntl(fd[[1]], F_SETFL, O_NONBLOCK) == -1)
exit(1);
return 1;
if (fcntl(fd[1], F_SETFL, O_NONBLOCK) == -1)
return 1;
while ((n = write(fd[[1]], buf, sizeof(buf))) == sizeof(buf))
while ((n = write(fd[1], buf, sizeof(buf))) == sizeof(buf))
;
if ((kq = kqueue()) == -1)
exit(1);
if ((kq = kqueue()) == -1)
return 1;
memset(&ev, 0, sizeof(ev));
ev.ident = fd[[1]];
ev.ident = fd[1];
ev.filter = EVFILT_WRITE;
ev.flags = EV_ADD | EV_ENABLE;
n = kevent(kq, &ev, 1, NULL, 0, NULL);
if (n == -1)
exit(1);
return 1;
read(fd[[0]], buf, sizeof(buf));
read(fd[0], buf, sizeof(buf));
ts.tv_sec = 0;
ts.tv_nsec = 0;
n = kevent(kq, NULL, 0, &ev, 1, &ts);
if (n == -1 || n == 0)
exit(1);
return 1;
exit(0);
}, [AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_WORKING_KQUEUE, 1,
[Define if kqueue works correctly with pipes])
havekqueue=yes
], AC_MSG_RESULT(no), AC_MSG_RESULT(no))
return 0;
]]
)],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_WORKING_KQUEUE, 1,
[Define if kqueue works correctly with pipes])
havekqueue=yes
], [AC_MSG_RESULT(no)], [AC_MSG_RESULT(no)]
)
fi
fi
AM_CONDITIONAL(KQUEUE_BACKEND, [test "x$havekqueue" = "xyes"])
@ -567,7 +617,8 @@ fi
if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
if test "x$haveepoll" = "xno" ; then
AC_MSG_CHECKING(for epoll system call)
AC_TRY_RUN(
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdint.h>
#include <sys/param.h>
#include <sys/types.h>
@ -580,45 +631,25 @@ epoll_create(int size)
{
return (syscall(__NR_epoll_create, size));
}
int
main(int argc, char **argv)
{
]],[[
int epfd;
epfd = epoll_create(256);
exit (epfd == -1 ? 1 : 0);
}, [AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_EPOLL, 1,
[Define if your system supports the epoll system calls])
needsignal=yes
have_epoll=yes
AC_LIBOBJ(epoll_sub)
], AC_MSG_RESULT(no), AC_MSG_RESULT(no))
return (epfd == -1 ? 1 : 0);
]]
)],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_EPOLL, 1,
[Define if your system supports the epoll system calls])
needsignal=yes
have_epoll=yes
AC_LIBOBJ(epoll_sub)
], [AC_MSG_RESULT(no)], [AC_MSG_RESULT(no)]
)
fi
fi
AM_CONDITIONAL(EPOLL_BACKEND, [test "x$haveepoll" = "xyes"])
AC_MSG_CHECKING(waitpid support WNOWAIT)
AC_TRY_RUN(
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
int
main(int argc, char** argv)
{
pid_t pid;
int status;
if ((pid = fork()) == 0) _exit(0);
_exit(waitpid(pid, &status, WNOWAIT) == -1);
}, [AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_WAITPID_WITH_WNOWAIT, 1,
[Define if waitpid() supports WNOWAIT])
], AC_MSG_RESULT(no), AC_MSG_RESULT(no))
haveeventports=no
AC_CHECK_FUNCS(port_create, [haveeventports=yes], )
if test "x$haveeventports" = "xyes" ; then
@ -663,9 +694,10 @@ AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(size_t)
AC_CHECK_SIZEOF(void *)
AC_CHECK_SIZEOF(off_t)
AC_CHECK_SIZEOF(time_t)
AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrinfo, struct sockaddr_storage], , ,
[#define _GNU_SOURCE
AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, struct sockaddr_un, sa_family_t, struct addrinfo, struct sockaddr_storage], , ,
[#define _GNU_SOURCE 1
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
@ -673,6 +705,9 @@ AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrin
#ifdef HAVE_NETINET_IN6_H
#include <netinet/in6.h>
#endif
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@ -715,40 +750,54 @@ AC_CHECK_MEMBERS([struct in6_addr.s6_addr32, struct in6_addr.s6_addr16, struct s
#endif
])
AC_CHECK_TYPES([struct so_linger],
[#define HAVE_SO_LINGER], ,
AC_CHECK_TYPES([struct linger],,,
[
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef _WIN32
#include <winsock2.h>
#endif
])
AC_MSG_CHECKING([for socklen_t])
AC_TRY_COMPILE([
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([
#include <sys/types.h>
#include <sys/socket.h>],
[socklen_t x;],
AC_MSG_RESULT([yes]),
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#endif
],[socklen_t x;]
)],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_DEFINE(socklen_t, unsigned int,
[Define to unsigned int if you dont have it])]
[Define to unsigned int if you dont have it])]
)
# __func__/__FUNCTION__ is not a macros in general
AC_MSG_CHECKING([whether our compiler supports __func__])
AC_TRY_COMPILE([],
[ const char *cp = __func__; ],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
AC_MSG_CHECKING([whether our compiler supports __FUNCTION__])
AC_TRY_COMPILE([],
[ const char *cp = __FUNCTION__; ],
AC_MSG_RESULT([yes])
AC_DEFINE(__func__, __FUNCTION__,
[Define to appropriate substitue if compiler doesnt have __func__]),
AC_MSG_RESULT([no])
AC_DEFINE(__func__, __FILE__,
[Define to appropriate substitue if compiler doesnt have __func__])))
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],
[ const char *cp = __func__; ]
)],
[ AC_DEFINE(HAVE___func__, 1, [Define to 1 if compiler have __func__])
AC_MSG_RESULT([yes])
],
[AC_MSG_RESULT([no])]
)
AC_MSG_CHECKING([whether our compiler supports __FUNCTION__])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],
[ const char *cp = __FUNCTION__; ]
)],
[ AC_DEFINE(HAVE___FUNCTION__, 1, [Define to 1 if compiler have __FUNCTION__])
AC_MSG_RESULT([yes])
],
[AC_MSG_RESULT([no])]
)
# check if we can compile with pthreads
have_pthreads=no
@ -791,10 +840,6 @@ fi
# check if we have and should use openssl
AM_CONDITIONAL(OPENSSL, [test "$enable_openssl" != "no" && test "$have_openssl" = "yes"])
if test "x$enable_openssl" = "xyes"; then
AC_SEARCH_LIBS([ERR_remove_thread_state], [crypto eay32],
[AC_DEFINE(HAVE_ERR_REMOVE_THREAD_STATE, 1, [Define to 1 if you have ERR_remove_thread_stat().])])
fi
# Add some more warnings which we use in development but not in the
# released versions. (Some relevant gcc versions can't handle these.)
@ -820,7 +865,8 @@ if test x$enable_gcc_warnings != xno && test "$GCC" = "yes"; then
#error
#endif])], have_clang=yes, have_clang=no)
CFLAGS="$CFLAGS -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch"
# -W is the same as -Wextra
CFLAGS="$CFLAGS -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wmissing-declarations -Wnested-externs -Wbad-function-cast"
if test x$enable_gcc_warnings = xyes; then
CFLAGS="$CFLAGS -Werror"
fi
@ -853,7 +899,7 @@ if test x$enable_gcc_warnings != xno && test "$GCC" = "yes"; then
# for minheap-internal.h related code.
CFLAGS="$CFLAGS -Wno-unused-function"
# clang on macosx emits warnigns for each directory specified which
# clang on macosx emits warnings for each directory specified which
# isn't "used" generating a lot of build noise (typically 3 warnings
# per file
case "$host_os" in
@ -943,5 +989,19 @@ AC_SUBST([LIBEVENT_GC_SECTIONS])
AM_CONDITIONAL([INSTALL_LIBEVENT], [test "$enable_libevent_install" = "yes"])
# Doxygen support
DX_HTML_FEATURE(ON)
DX_MAN_FEATURE(OFF)
DX_RTF_FEATURE(OFF)
DX_XML_FEATURE(OFF)
DX_PDF_FEATURE(OFF)
DX_PS_FEATURE(OFF)
DX_CHM_FEATURE(OFF)
DX_CHI_FEATURE(OFF)
DX_INIT_DOXYGEN([libevent], [${top_srcdir}/Doxyfile], [doxygen])
AM_CONDITIONAL([ENABLE_DOXYGEN], [test "$DX_FLAG_doc" = "1"])
AM_CONDITIONAL([ENABLE_DOXYGEN_MAN], [test "$DX_FLAG_man" = "1"])
AC_CONFIG_FILES( [libevent.pc libevent_openssl.pc libevent_pthreads.pc libevent_core.pc libevent_extra.pc] )
AC_OUTPUT(Makefile)

View File

@ -46,6 +46,7 @@ typedef void (*deferred_cb_fn)(struct event_callback *, void *);
@param cb The function to run when the struct event_callback executes.
@param arg The function's second argument.
*/
EVENT2_EXPORT_SYMBOL
void event_deferred_cb_init_(struct event_callback *, ev_uint8_t, deferred_cb_fn, void *);
/**
Change the priority of a non-pending event_callback.
@ -54,12 +55,14 @@ void event_deferred_cb_set_priority_(struct event_callback *, ev_uint8_t);
/**
Cancel a struct event_callback if it is currently scheduled in an event_base.
*/
EVENT2_EXPORT_SYMBOL
void event_deferred_cb_cancel_(struct event_base *, struct event_callback *);
/**
Activate a struct event_callback if it is not currently scheduled in an event_base.
Return true if it was not previously scheduled.
*/
EVENT2_EXPORT_SYMBOL
int event_deferred_cb_schedule_(struct event_base *, struct event_callback *);
#ifdef __cplusplus

View File

@ -0,0 +1,55 @@
# Doxygen documentation will not be generated with default configuration,
# unless '--enable-doxygen-doc' is configured.
# The following targets are all about doxygen:
# make # 'make doxygen' would be auto executed
# make doxygen # generating doxygen documentation
# make doxygen-doc # same as 'make doxygen'
# make clean # clean docs generated by doxygen
# make install # install doxygen documentation
# make uninstall # uninstall doxygen documentation
if ENABLE_DOXYGEN
# Add all needed rules defined in ax_prog_doxygen.m4
@DX_RULES@
# Use 'make clean' to clean docs generated by doxygen.
clean-local:
-rm -rf $(DX_CLEANFILES)
# integrate doxygen with automake targets
man3_MANS = @DX_DOCDIR@/man/man3/*
$(man3_MANS): doxygen-doc
# Docs will be installed. It may be one or more docs supported
# by doxygen, but does not include 'man'.
docdirs = $(DX_INSTALL_DOCS)
# Rules for installing docs generated by doxygen into $(htmldir),
# The typical value of $(htmldir) is '/usr/local/share/doc/$(PACKAGE)'
install-data-local:
@if ! test -d "$(DESTDIR)$(htmldir)"; then \
echo "$(mkinstalldirs) '$(DESTDIR)$(htmldir)'"; \
$(mkinstalldirs) '$(DESTDIR)$(htmldir)'; \
fi
@for d in $(docdirs); do \
echo "cp -pR $$d '$(DESTDIR)$(htmldir)/'"; \
cp -pR $$d '$(DESTDIR)$(htmldir)/'; \
done
# Rules for uninstalling docs generated by doxygen from $(htmldir)
uninstall-local:
@for d in $(docdirs); do \
d=`basename $$d`; \
echo "test ! -d '$(DESTDIR)$(htmldir)/'$$d || \
{ find '$(DESTDIR)$(htmldir)/'$$d -type d ! -perm -200 -exec chmod u+w '{}' ';' && \
rm -rf '$(DESTDIR)$(htmldir)/'$$d; }"; \
test ! -d '$(DESTDIR)$(htmldir)/'$$d || \
{ find '$(DESTDIR)$(htmldir)/'$$d -type d ! -perm -200 -exec chmod u+w '{}' ';' && \
rm -rf '$(DESTDIR)$(htmldir)/'$$d; }; \
done
rmdir "$(DESTDIR)$(htmldir)/" || true
doxygen: doxygen-doc
endif ENABLE_DOXYGEN

View File

@ -281,7 +281,7 @@ epoll_apply_one_change(struct event_base *base,
return 0;
}
if ((ch->read_change|ch->write_change) & EV_CHANGE_ET)
if ((ch->read_change|ch->write_change|ch->close_change) & EV_CHANGE_ET)
events |= EPOLLET;
memset(&epev, 0, sizeof(epev));
@ -401,11 +401,14 @@ epoll_nochangelist_del(struct event_base *base, evutil_socket_t fd,
ch.old_events = old;
ch.read_change = ch.write_change = ch.close_change = 0;
if (events & EV_WRITE)
ch.write_change = EV_CHANGE_DEL;
ch.write_change = EV_CHANGE_DEL |
(events & EV_ET);
if (events & EV_READ)
ch.read_change = EV_CHANGE_DEL;
ch.read_change = EV_CHANGE_DEL |
(events & EV_ET);
if (events & EV_CLOSED)
ch.close_change = EV_CHANGE_DEL;
ch.close_change = EV_CHANGE_DEL |
(events & EV_ET);
return epoll_apply_one_change(base, base->evbase, &ch);
}
@ -483,7 +486,9 @@ epoll_dispatch(struct event_base *base, struct timeval *tv)
continue;
#endif
if (what & (EPOLLHUP|EPOLLERR)) {
if (what & EPOLLERR) {
ev = EV_READ | EV_WRITE;
} else if ((what & EPOLLHUP) && !(what & EPOLLRDHUP)) {
ev = EV_READ | EV_WRITE;
} else {
if (what & EPOLLIN)

View File

@ -34,7 +34,7 @@
Note also that this table is a little sparse, since ADD+DEL is
nonsensical ("xxx" in the list below.)
Note also also that we are shifting old_events by only 5 bits, since
Note also that we are shifting old_events by only 5 bits, since
EV_READ is 2 and EV_WRITE is 4.
The table was auto-generated with a python script, according to this

View File

@ -92,7 +92,7 @@ struct evbuffer {
* If the buffer has no chains, it is NULL.
*
* The last_with_datap pointer points at _whatever 'next' pointer_
* points at the last_with_datap chain. If the last_with_data chain
* pointing at the last_with_data chain. If the last_with_data chain
* is the first chain, or it is NULL, then the last_with_datap pointer
* is &buf->first.
*/

View File

@ -0,0 +1,40 @@
#ifndef EVCONFIG_PRIVATE_H_INCLUDED_
#define EVCONFIG_PRIVATE_H_INCLUDED_
/* Enable extensions on AIX 3, Interix. */
#cmakedefine _ALL_SOURCE
/* Enable GNU extensions on systems that have them. */
#cmakedefine _GNU_SOURCE 1
/* Enable threading extensions on Solaris. */
#cmakedefine _POSIX_PTHREAD_SEMANTICS 1
/* Enable extensions on HP NonStop. */
#cmakedefine _TANDEM_SOURCE 1
/* Enable general extensions on Solaris. */
#cmakedefine __EXTENSIONS__
/* Number of bits in a file offset, on hosts where this is settable. */
#cmakedefine _FILE_OFFSET_BITS 1
/* Define for large files, on AIX-style hosts. */
#cmakedefine _LARGE_FILES 1
/* Define to 1 if on MINIX. */
#cmakedefine _MINIX 1
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#cmakedefine _POSIX_1_SOURCE 1
/* Define to 1 if you need to in order for `stat' and other things to work. */
#cmakedefine _POSIX_SOURCE 1
/* Enable POSIX.2 extensions on QNX for getopt */
#ifdef __QNX__
#cmakedefine __EXT_POSIX2 1
#endif
#endif

View File

@ -45,4 +45,11 @@
#undef _POSIX_SOURCE
#endif
/* Enable POSIX.2 extensions on QNX for getopt */
#ifdef __QNX__
# ifndef __EXT_POSIX2
# define __EXT_POSIX2
# endif
#endif
#endif

View File

@ -77,6 +77,7 @@
#include <stdarg.h>
#ifdef _WIN32
#include <winsock2.h>
#include <winerror.h>
#include <ws2tcpip.h>
#ifndef _WIN32_IE
#define _WIN32_IE 0x400
@ -346,6 +347,9 @@ struct evdns_base {
struct timeval global_getaddrinfo_allow_skew;
int so_rcvbuf;
int so_sndbuf;
int getaddrinfo_ipv4_timeouts;
int getaddrinfo_ipv6_timeouts;
int getaddrinfo_ipv4_answered;
@ -863,6 +867,19 @@ reply_schedule_callback(struct request *const req, u32 ttl, u32 err, struct repl
&d->deferred);
}
#define _QR_MASK 0x8000U
#define _OP_MASK 0x7800U
#define _AA_MASK 0x0400U
#define _TC_MASK 0x0200U
#define _RD_MASK 0x0100U
#define _RA_MASK 0x0080U
#define _Z_MASK 0x0040U
#define _AD_MASK 0x0020U
#define _CD_MASK 0x0010U
#define _RCODE_MASK 0x000fU
#define _Z_MASK_DEPRECATED 0x0070U
/* this processes a parsed reply packet */
static void
reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
@ -876,12 +893,12 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
ASSERT_LOCKED(req->base);
ASSERT_VALID_REQUEST(req);
if (flags & 0x020f || !reply || !reply->have_answer) {
if (flags & (_RCODE_MASK | _TC_MASK) || !reply || !reply->have_answer) {
/* there was an error */
if (flags & 0x0200) {
if (flags & _TC_MASK) {
error = DNS_ERR_TRUNCATED;
} else if (flags & 0x000f) {
u16 error_code = (flags & 0x000f) - 1;
} else if (flags & _RCODE_MASK) {
u16 error_code = (flags & _RCODE_MASK) - 1;
if (error_code > 4) {
error = DNS_ERR_UNKNOWN;
} else {
@ -1046,8 +1063,8 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) {
memset(&reply, 0, sizeof(reply));
/* If it's not an answer, it doesn't correspond to any request. */
if (!(flags & 0x8000)) return -1; /* must be an answer */
if ((flags & 0x020f) && (flags & 0x020f) != DNS_ERR_NOTEXIST) {
if (!(flags & _QR_MASK)) return -1; /* must be an answer */
if ((flags & (_RCODE_MASK|_TC_MASK)) && (flags & (_RCODE_MASK|_TC_MASK)) != DNS_ERR_NOTEXIST) {
/* there was an error and it's not NXDOMAIN */
goto err;
}
@ -1236,8 +1253,8 @@ request_parse(u8 *packet, int length, struct evdns_server_port *port, struct soc
(void)additional;
(void)authority;
if (flags & 0x8000) return -1; /* Must not be an answer. */
flags &= 0x0110; /* Only RD and CD get preserved. */
if (flags & _QR_MASK) return -1; /* Must not be an answer. */
flags &= (_RD_MASK|_CD_MASK); /* Only RD and CD get preserved. */
server_req = mm_malloc(sizeof(struct server_request));
if (server_req == NULL) return -1;
@ -1277,7 +1294,7 @@ request_parse(u8 *packet, int length, struct evdns_server_port *port, struct soc
port->refcnt++;
/* Only standard queries are supported. */
if (flags & 0x7800) {
if (flags & _OP_MASK) {
evdns_server_request_respond(&(server_req->base), DNS_ERR_NOTIMPL);
return -1;
}
@ -1286,14 +1303,12 @@ request_parse(u8 *packet, int length, struct evdns_server_port *port, struct soc
return 0;
err:
if (server_req) {
if (server_req->base.questions) {
for (i = 0; i < server_req->base.nquestions; ++i)
mm_free(server_req->base.questions[i]);
mm_free(server_req->base.questions);
}
mm_free(server_req);
if (server_req->base.questions) {
for (i = 0; i < server_req->base.nquestions; ++i)
mm_free(server_req->base.questions[i]);
mm_free(server_req->base.questions);
}
mm_free(server_req);
return -1;
#undef SKIP_NAME
@ -1751,6 +1766,7 @@ evdns_close_server_port(struct evdns_server_port *port)
server_port_free(port);
} else {
port->closing = 1;
EVDNS_UNLOCK(port);
}
}
@ -1904,7 +1920,7 @@ evdns_server_request_format_response(struct server_request *req, int err)
/* Set response bit and error code; copy OPCODE and RD fields from
* question; copy RA and AA if set by caller. */
flags = req->base.flags;
flags |= (0x8000 | err);
flags |= (_QR_MASK | err);
dnslabel_table_init(&table);
APPEND16(req->trans_id);
@ -2265,10 +2281,11 @@ evdns_request_transmit(struct request *req) {
nameserver_write_waiting(req->ns, 1);
return 1;
case 2:
/* failed to transmit the request entirely. */
/* failed to transmit the request entirely. we can fallthrough since
* we'll set a timeout, which will time out, and make us retransmit the
* request anyway. */
retcode = 1;
/* fall through: we'll set a timeout, which will time out,
* and make us retransmit the request anyway. */
EVUTIL_FALLTHROUGH;
default:
/* all ok */
log(EVDNS_LOG_DEBUG,
@ -2525,6 +2542,23 @@ evdns_nameserver_add_impl_(struct evdns_base *base, const struct sockaddr *addre
}
}
if (base->so_rcvbuf) {
if (setsockopt(ns->socket, SOL_SOCKET, SO_RCVBUF,
(void *)&base->so_rcvbuf, sizeof(base->so_rcvbuf))) {
log(EVDNS_LOG_WARN, "Couldn't set SO_RCVBUF to %i", base->so_rcvbuf);
err = -SO_RCVBUF;
goto out2;
}
}
if (base->so_sndbuf) {
if (setsockopt(ns->socket, SOL_SOCKET, SO_SNDBUF,
(void *)&base->so_sndbuf, sizeof(base->so_sndbuf))) {
log(EVDNS_LOG_WARN, "Couldn't set SO_SNDBUF to %i", base->so_sndbuf);
err = -SO_SNDBUF;
goto out2;
}
}
memcpy(&ns->address, address, addrlen);
ns->addrlen = addrlen;
ns->state = 1;
@ -3313,10 +3347,16 @@ search_request_finished(struct evdns_request *const handle) {
static void
evdns_resolv_set_defaults(struct evdns_base *base, int flags) {
int add_default = flags & DNS_OPTION_NAMESERVERS;
if (flags & DNS_OPTION_NAMESERVERS_NO_DEFAULT)
add_default = 0;
/* if the file isn't found then we assume a local resolver */
ASSERT_LOCKED(base);
if (flags & DNS_OPTION_SEARCH) search_set_from_hostname(base);
if (flags & DNS_OPTION_NAMESERVERS) evdns_base_nameserver_ip_add(base,"127.0.0.1");
if (flags & DNS_OPTION_SEARCH)
search_set_from_hostname(base);
if (add_default)
evdns_base_nameserver_ip_add(base, "127.0.0.1");
}
#ifndef EVENT__HAVE_STRTOK_R
@ -3491,6 +3531,7 @@ evdns_base_set_option_impl(struct evdns_base *base,
base->global_max_retransmits = retries;
} else if (str_matches_option(option, "randomize-case:")) {
int randcase = strtoint(val);
if (randcase == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0;
base->global_randomize_case = randcase;
} else if (str_matches_option(option, "bind-to:")) {
@ -3512,6 +3553,18 @@ evdns_base_set_option_impl(struct evdns_base *base,
val);
memcpy(&base->global_nameserver_probe_initial_timeout, &tv,
sizeof(tv));
} else if (str_matches_option(option, "so-rcvbuf:")) {
int buf = strtoint(val);
if (buf == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0;
log(EVDNS_LOG_DEBUG, "Setting SO_RCVBUF to %s", val);
base->so_rcvbuf = buf;
} else if (str_matches_option(option, "so-sndbuf:")) {
int buf = strtoint(val);
if (buf == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0;
log(EVDNS_LOG_DEBUG, "Setting SO_SNDBUF to %s", val);
base->so_sndbuf = buf;
}
return 0;
}
@ -3612,9 +3665,14 @@ evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char
char *resolv;
char *start;
int err = 0;
int add_default;
log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
add_default = flags & DNS_OPTION_NAMESERVERS;
if (flags & DNS_OPTION_NAMESERVERS_NO_DEFAULT)
add_default = 0;
if (flags & DNS_OPTION_HOSTSFILE) {
char *fname = evdns_get_default_hosts_filename();
evdns_base_load_hosts(base, fname);
@ -3622,6 +3680,11 @@ evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char
mm_free(fname);
}
if (!filename) {
evdns_resolv_set_defaults(base, flags);
return 1;
}
if ((err = evutil_read_file_(filename, &resolv, &n, 0)) < 0) {
if (err == -1) {
/* No file. */
@ -3645,7 +3708,7 @@ evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char
}
}
if (!base->server_head && (flags & DNS_OPTION_NAMESERVERS)) {
if (!base->server_head && add_default) {
/* no nameservers were configured. */
evdns_base_nameserver_ip_add(base, "127.0.0.1");
err = 6;
@ -3946,7 +4009,12 @@ evdns_base_new(struct event_base *event_base, int flags)
TAILQ_INIT(&base->hostsdb);
#define EVDNS_BASE_ALL_FLAGS (0x8001)
#define EVDNS_BASE_ALL_FLAGS ( \
EVDNS_BASE_INITIALIZE_NAMESERVERS | \
EVDNS_BASE_DISABLE_WHEN_INACTIVE | \
EVDNS_BASE_NAMESERVERS_NO_DEFAULT | \
0)
if (flags & ~EVDNS_BASE_ALL_FLAGS) {
flags = EVDNS_BASE_INITIALIZE_NAMESERVERS;
log(EVDNS_LOG_WARN,
@ -3957,12 +4025,17 @@ evdns_base_new(struct event_base *event_base, int flags)
if (flags & EVDNS_BASE_INITIALIZE_NAMESERVERS) {
int r;
int opts = DNS_OPTIONS_ALL;
if (flags & EVDNS_BASE_NAMESERVERS_NO_DEFAULT) {
opts |= DNS_OPTION_NAMESERVERS_NO_DEFAULT;
}
#ifdef _WIN32
r = evdns_base_config_windows_nameservers(base);
#else
r = evdns_base_resolv_conf_parse(base, DNS_OPTIONS_ALL, "/etc/resolv.conf");
r = evdns_base_resolv_conf_parse(base, opts, "/etc/resolv.conf");
#endif
if (r == -1) {
if (r) {
evdns_base_free_and_unlock(base, 0);
return NULL;
}
@ -4036,6 +4109,11 @@ evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests)
/* TODO(nickm) we might need to refcount here. */
while (base->req_waiting_head) {
if (fail_requests)
reply_schedule_callback(base->req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);
request_finished(base->req_waiting_head, &base->req_waiting_head, 1);
}
for (i = 0; i < base->n_req_heads; ++i) {
while (base->req_heads[i]) {
if (fail_requests)
@ -4043,11 +4121,6 @@ evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests)
request_finished(base->req_heads[i], &REQ_HEAD(base, base->req_heads[i]->trans_id), 1);
}
}
while (base->req_waiting_head) {
if (fail_requests)
reply_schedule_callback(base->req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);
request_finished(base->req_waiting_head, &base->req_waiting_head, 1);
}
base->global_requests_inflight = base->global_requests_waiting = 0;
for (server = base->server_head; server; server = server_next) {
@ -4636,6 +4709,7 @@ evdns_getaddrinfo(struct evdns_base *dns_base,
int err;
int port = 0;
int want_cname = 0;
int started = 0;
if (!dns_base) {
dns_base = current_base;
@ -4714,6 +4788,8 @@ evdns_getaddrinfo(struct evdns_base *dns_base,
* launching those requests. (XXX we don't do that yet.)
*/
EVDNS_LOCK(dns_base);
if (hints.ai_family != PF_INET6) {
log(EVDNS_LOG_DEBUG, "Sending request for %s on ipv4 as %p",
nodename, &data->ipv4_request);
@ -4740,7 +4816,11 @@ evdns_getaddrinfo(struct evdns_base *dns_base,
evtimer_assign(&data->timeout, dns_base->event_base,
evdns_getaddrinfo_timeout_cb, data);
if (data->ipv4_request.r || data->ipv6_request.r) {
started = (data->ipv4_request.r || data->ipv6_request.r);
EVDNS_UNLOCK(dns_base);
if (started) {
return data;
} else {
mm_free(data);

View File

@ -0,0 +1,513 @@
/* event-config.h
*
* This file was generated by cmake when the makefiles were generated.
*
* DO NOT EDIT THIS FILE.
*
* Do not rely on macros in this file existing in later versions.
*/
#ifndef EVENT2_EVENT_CONFIG_H_INCLUDED_
#define EVENT2_EVENT_CONFIG_H_INCLUDED_
/* Numeric representation of the version */
#define EVENT__NUMERIC_VERSION @EVENT_NUMERIC_VERSION@
#define EVENT__PACKAGE_VERSION "@EVENT_PACKAGE_VERSION@"
#define EVENT__VERSION_MAJOR @EVENT_VERSION_MAJOR@
#define EVENT__VERSION_MINOR @EVENT_VERSION_MINOR@
#define EVENT__VERSION_PATCH @EVENT_VERSION_PATCH@
/* Version number of package */
#define EVENT__VERSION "@EVENT_VERSION@"
/* Name of package */
#define EVENT__PACKAGE "libevent"
/* Define to the address where bug reports for this package should be sent. */
#define EVENT__PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define EVENT__PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define EVENT__PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define EVENT__PACKAGE_TARNAME ""
/* Define if libevent should build without support for a debug mode */
#cmakedefine EVENT__DISABLE_DEBUG_MODE 1
/* Define if libevent should not allow replacing the mm functions */
#cmakedefine EVENT__DISABLE_MM_REPLACEMENT 1
/* Define if libevent should not be compiled with thread support */
#cmakedefine EVENT__DISABLE_THREAD_SUPPORT 1
/* Define to 1 if you have the `accept4' function. */
#cmakedefine EVENT__HAVE_ACCEPT4 1
/* Define to 1 if you have the `arc4random' function. */
#cmakedefine EVENT__HAVE_ARC4RANDOM 1
/* Define to 1 if you have the `arc4random_buf' function. */
#cmakedefine EVENT__HAVE_ARC4RANDOM_BUF 1
/* Define to 1 if you have the `arc4random_addrandom' function. */
#cmakedefine EVENT__HAVE_ARC4RANDOM_ADDRANDOM 1
/* Define if clock_gettime is available in libc */
#cmakedefine EVENT__DNS_USE_CPU_CLOCK_FOR_ID 1
/* Define is no secure id variant is available */
#cmakedefine EVENT__DNS_USE_GETTIMEOFDAY_FOR_ID 1
#cmakedefine EVENT__DNS_USE_FTIME_FOR_ID 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#cmakedefine EVENT__HAVE_ARPA_INET_H 1
/* Define to 1 if you have the `clock_gettime' function. */
#cmakedefine EVENT__HAVE_CLOCK_GETTIME 1
/* Define to 1 if you have the declaration of `CTL_KERN'. */
#define EVENT__HAVE_DECL_CTL_KERN @EVENT__HAVE_DECL_CTL_KERN@
/* Define to 1 if you have the declaration of `KERN_ARND'. */
#define EVENT__HAVE_DECL_KERN_ARND @EVENT__HAVE_DECL_KERN_ARND@
/* Define to 1 if you have `getrandom' function. */
#cmakedefine EVENT__HAVE_GETRANDOM 1
/* Define if /dev/poll is available */
#cmakedefine EVENT__HAVE_DEVPOLL 1
/* Define to 1 if you have the <netdb.h> header file. */
#cmakedefine EVENT__HAVE_NETDB_H 1
/* Define to 1 if fd_mask type is defined */
#cmakedefine EVENT__HAVE_FD_MASK 1
/* Define to 1 if the <sys/queue.h> header file defines TAILQ_FOREACH. */
#cmakedefine EVENT__HAVE_TAILQFOREACH 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine EVENT__HAVE_DLFCN_H 1
/* Define if your system supports the epoll system calls */
#cmakedefine EVENT__HAVE_EPOLL 1
/* Define to 1 if you have the `epoll_create1' function. */
#cmakedefine EVENT__HAVE_EPOLL_CREATE1 1
/* Define to 1 if you have the `epoll_ctl' function. */
#cmakedefine EVENT__HAVE_EPOLL_CTL 1
/* Define to 1 if you have the `eventfd' function. */
#cmakedefine EVENT__HAVE_EVENTFD 1
/* Define if your system supports event ports */
#cmakedefine EVENT__HAVE_EVENT_PORTS 1
/* Define to 1 if you have the `fcntl' function. */
#cmakedefine EVENT__HAVE_FCNTL 1
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine EVENT__HAVE_FCNTL_H 1
/* Define to 1 if you have the `getaddrinfo' function. */
#cmakedefine EVENT__HAVE_GETADDRINFO 1
/* Define to 1 if you have the `getegid' function. */
#cmakedefine EVENT__HAVE_GETEGID 1
/* Define to 1 if you have the `geteuid' function. */
#cmakedefine EVENT__HAVE_GETEUID 1
/* TODO: Check for different gethostname argument counts. CheckPrototypeDefinition.cmake can be used. */
/* Define this if you have any gethostbyname_r() */
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R 1
/* Define this if gethostbyname_r takes 3 arguments */
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_3_ARG 1
/* Define this if gethostbyname_r takes 5 arguments */
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_5_ARG 1
/* Define this if gethostbyname_r takes 6 arguments */
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_6_ARG 1
/* Define to 1 if you have the `getifaddrs' function. */
#cmakedefine EVENT__HAVE_GETIFADDRS 1
/* Define to 1 if you have the `getnameinfo' function. */
#cmakedefine EVENT__HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `getprotobynumber' function. */
#cmakedefine EVENT__HAVE_GETPROTOBYNUMBER 1
/* Define to 1 if you have the `getservbyname' function. */
#cmakedefine EVENT__HAVE_GETSERVBYNAME 1
/* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine EVENT__HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the <ifaddrs.h> header file. */
#cmakedefine EVENT__HAVE_IFADDRS_H 1
/* Define to 1 if you have the `inet_ntop' function. */
#cmakedefine EVENT__HAVE_INET_NTOP 1
/* Define to 1 if you have the `inet_pton' function. */
#cmakedefine EVENT__HAVE_INET_PTON 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine EVENT__HAVE_INTTYPES_H 1
/* Define to 1 if you have the `issetugid' function. */
#cmakedefine EVENT__HAVE_ISSETUGID 1
/* Define to 1 if you have the `kqueue' function. */
#cmakedefine EVENT__HAVE_KQUEUE 1
/* Define if the system has zlib */
#cmakedefine EVENT__HAVE_LIBZ 1
/* Define to 1 if you have the `mach_absolute_time' function. */
#cmakedefine EVENT__HAVE_MACH_ABSOLUTE_TIME 1
/* Define to 1 if you have the <mach/mach_time.h> header file. */
#cmakedefine EVENT__HAVE_MACH_MACH_TIME_H 1
/* Define to 1 if you have the <mach/mach.h> header file. */
#cmakedefine EVENT__HAVE_MACH_MACH_H 1
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine EVENT__HAVE_MEMORY_H 1
/* Define to 1 if you have the `mmap' function. */
#cmakedefine EVENT__HAVE_MMAP 1
/* Define to 1 if you have the `nanosleep' function. */
#cmakedefine EVENT__HAVE_NANOSLEEP 1
/* Define to 1 if you have the `usleep' function. */
#cmakedefine EVENT__HAVE_USLEEP 1
/* Define to 1 if you have the <netinet/in6.h> header file. */
#cmakedefine EVENT__HAVE_NETINET_IN6_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine EVENT__HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#cmakedefine EVENT__HAVE_NETINET_TCP_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
#cmakedefine EVENT__HAVE_SYS_UN_H 1
/* Define to 1 if you have the <afunix.h> header file. */
#cmakedefine EVENT__HAVE_AFUNIX_H 1
/* Define if the system has openssl */
#cmakedefine EVENT__HAVE_OPENSSL 1
/* Define to 1 if you have the `pipe' function. */
#cmakedefine EVENT__HAVE_PIPE 1
/* Define to 1 if you have the `pipe2' function. */
#cmakedefine EVENT__HAVE_PIPE2 1
/* Define to 1 if you have the `poll' function. */
#cmakedefine EVENT__HAVE_POLL 1
/* Define to 1 if you have the <poll.h> header file. */
#cmakedefine EVENT__HAVE_POLL_H 1
/* Define to 1 if you have the `port_create' function. */
#cmakedefine EVENT__HAVE_PORT_CREATE 1
/* Define to 1 if you have the <port.h> header file. */
#cmakedefine EVENT__HAVE_PORT_H 1
/* Define if we have pthreads on this system */
#cmakedefine EVENT__HAVE_PTHREADS 1
/* Define to 1 if you have the `putenv' function. */
#cmakedefine EVENT__HAVE_PUTENV 1
/* Define to 1 if the system has the type `sa_family_t'. */
#cmakedefine EVENT__HAVE_SA_FAMILY_T 1
/* Define to 1 if you have the `select' function. */
#cmakedefine EVENT__HAVE_SELECT 1
/* Define to 1 if you have the `setenv' function. */
#cmakedefine EVENT__HAVE_SETENV 1
/* Define if F_SETFD is defined in <fcntl.h> */
#cmakedefine EVENT__HAVE_SETFD 1
/* Define to 1 if you have the `setrlimit' function. */
#cmakedefine EVENT__HAVE_SETRLIMIT 1
/* Define to 1 if you have the `sendfile' function. */
#cmakedefine EVENT__HAVE_SENDFILE 1
/* Define to 1 if you have the `sigaction' function. */
#cmakedefine EVENT__HAVE_SIGACTION 1
/* Define to 1 if you have the `signal' function. */
#cmakedefine EVENT__HAVE_SIGNAL 1
/* Define to 1 if you have the `splice' function. */
#cmakedefine EVENT__HAVE_SPLICE 1
/* Define to 1 if you have the <stdarg.h> header file. */
#cmakedefine EVENT__HAVE_STDARG_H 1
/* Define to 1 if you have the <stddef.h> header file. */
#cmakedefine EVENT__HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine EVENT__HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine EVENT__HAVE_STDLIB_H 1
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine EVENT__HAVE_STRING_H 1
/* Define to 1 if you have the `strlcpy' function. */
#cmakedefine EVENT__HAVE_STRLCPY 1
/* Define to 1 if you have the `strsep' function. */
#cmakedefine EVENT__HAVE_STRSEP 1
/* Define to 1 if you have the `strtok_r' function. */
#cmakedefine EVENT__HAVE_STRTOK_R 1
/* Define to 1 if you have the `strtoll' function. */
#cmakedefine EVENT__HAVE_STRTOLL 1
/* Define to 1 if you have the `_gmtime64_s' function. */
#cmakedefine EVENT__HAVE__GMTIME64_S 1
/* Define to 1 if you have the `_gmtime64' function. */
#cmakedefine EVENT__HAVE__GMTIME64 1
/* Define to 1 if the system has the type `struct addrinfo'. */
#cmakedefine EVENT__HAVE_STRUCT_ADDRINFO 1
/* Define to 1 if the system has the type `struct in6_addr'. */
#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR 1
/* Define to 1 if `s6_addr16' is member of `struct in6_addr'. */
#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1
/* Define to 1 if `s6_addr32' is member of `struct in6_addr'. */
#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6 1
/* Define to 1 if `sin6_len' is member of `struct sockaddr_in6'. */
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 1
/* Define to 1 if `sin_len' is member of `struct sockaddr_in'. */
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1
/* Define to 1 if the system has the type `struct sockaddr_un'. */
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_UN 1
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1
/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1
/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY 1
/* Define to 1 if the system has the type `struct linger'. */
#cmakedefine EVENT__HAVE_STRUCT_LINGER 1
/* Define to 1 if you have the `sysctl' function. */
#cmakedefine EVENT__HAVE_SYSCTL 1
/* Define to 1 if you have the <sys/epoll.h> header file. */
#cmakedefine EVENT__HAVE_SYS_EPOLL_H 1
/* Define to 1 if you have the <sys/eventfd.h> header file. */
#cmakedefine EVENT__HAVE_SYS_EVENTFD_H 1
/* Define to 1 if you have the <sys/event.h> header file. */
#cmakedefine EVENT__HAVE_SYS_EVENT_H 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#cmakedefine EVENT__HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#cmakedefine EVENT__HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#cmakedefine EVENT__HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/queue.h> header file. */
#cmakedefine EVENT__HAVE_SYS_QUEUE_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#cmakedefine EVENT__HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#cmakedefine EVENT__HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/sendfile.h> header file. */
#cmakedefine EVENT__HAVE_SYS_SENDFILE_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#cmakedefine EVENT__HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine EVENT__HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/random.h> header file. */
#cmakedefine EVENT__HAVE_SYS_RANDOM_H 1
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#cmakedefine EVENT__HAVE_SYS_SYSCTL_H 1
/* Define to 1 if you have the <sys/timerfd.h> header file. */
#cmakedefine EVENT__HAVE_SYS_TIMERFD_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine EVENT__HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine EVENT__HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#cmakedefine EVENT__HAVE_SYS_UIO_H 1
/* Define to 1 if you have the <sys/wait.h> header file. */
#cmakedefine EVENT__HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <errno.h> header file. */
#cmakedefine EVENT__HAVE_ERRNO_H 1
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
#cmakedefine EVENT__HAVE_TAILQFOREACH 1
/* Define if timeradd is defined in <sys/time.h> */
#cmakedefine EVENT__HAVE_TIMERADD 1
/* Define if timerclear is defined in <sys/time.h> */
#cmakedefine EVENT__HAVE_TIMERCLEAR 1
/* Define if timercmp is defined in <sys/time.h> */
#cmakedefine EVENT__HAVE_TIMERCMP 1
/* Define to 1 if you have the `timerfd_create' function. */
#cmakedefine EVENT__HAVE_TIMERFD_CREATE 1
/* Define if timerisset is defined in <sys/time.h> */
#cmakedefine EVENT__HAVE_TIMERISSET 1
/* Define to 1 if the system has the type `uint8_t'. */
#cmakedefine EVENT__HAVE_UINT8_T 1
/* Define to 1 if the system has the type `uint16_t'. */
#cmakedefine EVENT__HAVE_UINT16_T 1
/* Define to 1 if the system has the type `uint32_t'. */
#cmakedefine EVENT__HAVE_UINT32_T 1
/* Define to 1 if the system has the type `uint64_t'. */
#cmakedefine EVENT__HAVE_UINT64_T 1
/* Define to 1 if the system has the type `uintptr_t'. */
#cmakedefine EVENT__HAVE_UINTPTR_T 1
/* Define to 1 if you have the `umask' function. */
#cmakedefine EVENT__HAVE_UMASK 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine EVENT__HAVE_UNISTD_H 1
/* Define to 1 if you have the `unsetenv' function. */
#cmakedefine EVENT__HAVE_UNSETENV 1
/* Define to 1 if you have the `vasprintf' function. */
#cmakedefine EVENT__HAVE_VASPRINTF 1
/* Define if kqueue works correctly with pipes */
#cmakedefine EVENT__HAVE_WORKING_KQUEUE 1
#ifdef __USE_UNUSED_DEFINITIONS__
/* Define to necessary symbol if this constant uses a non-standard name on your system. */
/* XXX: Hello, this isn't even used, nor is it defined anywhere... - Ellzey */
#define EVENT__PTHREAD_CREATE_JOINABLE ${EVENT__PTHREAD_CREATE_JOINABLE}
#endif
/* The size of `pthread_t', as computed by sizeof. */
#define EVENT__SIZEOF_PTHREAD_T @EVENT__SIZEOF_PTHREAD_T@
/* The size of a `int', as computed by sizeof. */
#define EVENT__SIZEOF_INT @EVENT__SIZEOF_INT@
/* The size of a `long', as computed by sizeof. */
#define EVENT__SIZEOF_LONG @EVENT__SIZEOF_LONG@
/* The size of a `long long', as computed by sizeof. */
#define EVENT__SIZEOF_LONG_LONG @EVENT__SIZEOF_LONG_LONG@
/* The size of `off_t', as computed by sizeof. */
#define EVENT__SIZEOF_OFF_T @EVENT__SIZEOF_OFF_T@
#define EVENT__SIZEOF_SSIZE_T @EVENT__SIZEOF_SSIZE_T@
/* The size of a `short', as computed by sizeof. */
#define EVENT__SIZEOF_SHORT @EVENT__SIZEOF_SHORT@
/* The size of `size_t', as computed by sizeof. */
#define EVENT__SIZEOF_SIZE_T @EVENT__SIZEOF_SIZE_T@
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine EVENT__TIME_WITH_SYS_TIME 1
/* The size of `socklen_t', as computed by sizeof. */
#define EVENT__SIZEOF_SOCKLEN_T @EVENT__SIZEOF_SOCKLEN_T@
/* The size of 'void *', as computer by sizeof */
#define EVENT__SIZEOF_VOID_P @EVENT__SIZEOF_VOID_P@
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* why not c++?
*
* and are we really expected to use EVENT__inline everywhere,
* shouldn't we just do:
* ifdef EVENT__inline
* define inline EVENT__inline
*
* - Ellzey
*/
#define EVENT__inline @EVENT__inline@
#endif
#cmakedefine EVENT__HAVE___func__ 1
#cmakedefine EVENT__HAVE___FUNCTION__ 1
/* Define to `unsigned' if <sys/types.h> does not define. */
#define EVENT__size_t @EVENT__size_t@
/* Define to unsigned int if you dont have it */
#define EVENT__socklen_t @EVENT__socklen_t@
/* Define to `int' if <sys/types.h> does not define. */
#define EVENT__ssize_t @EVENT__ssize_t@
#endif /* \EVENT2_EVENT_CONFIG_H_INCLUDED_ */

View File

@ -219,7 +219,7 @@ struct event_base {
/** Function pointers used to describe the backend that this event_base
* uses for signals */
const struct eventop *evsigsel;
/** Data to implement the common signal handelr code. */
/** Data to implement the common signal handler code. */
struct evsig_info sig;
/** Number of virtual events */
@ -368,6 +368,10 @@ struct event_config {
};
/* Internal use only: Functions that might be missing from <sys/queue.h> */
#ifndef LIST_END
#define LIST_END(head) NULL
#endif
#ifndef TAILQ_FIRST
#define TAILQ_FIRST(head) ((head)->tqh_first)
#endif
@ -414,23 +418,26 @@ int event_add_nolock_(struct event *ev,
* if it is running in another thread and it doesn't have EV_FINALIZE set.
*/
#define EVENT_DEL_AUTOBLOCK 2
/** Argument for event_del_nolock_. Tells event_del to procede even if the
/** Argument for event_del_nolock_. Tells event_del to proceed even if the
* event is set up for finalization rather for regular use.*/
#define EVENT_DEL_EVEN_IF_FINALIZING 3
int event_del_nolock_(struct event *ev, int blocking);
int event_remove_timer_nolock_(struct event *ev);
void event_active_nolock_(struct event *ev, int res, short count);
EVENT2_EXPORT_SYMBOL
int event_callback_activate_(struct event_base *, struct event_callback *);
int event_callback_activate_nolock_(struct event_base *, struct event_callback *);
int event_callback_cancel_(struct event_base *base,
struct event_callback *evcb);
void event_callback_finalize_nolock_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *));
EVENT2_EXPORT_SYMBOL
void event_callback_finalize_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *));
int event_callback_finalize_many_(struct event_base *base, int n_cbs, struct event_callback **evcb, void (*cb)(struct event_callback *, void *));
EVENT2_EXPORT_SYMBOL
void event_active_later_(struct event *ev, int res);
void event_active_later_nolock_(struct event *ev, int res);
int event_callback_activate_later_nolock_(struct event_base *base,
@ -441,6 +448,7 @@ void event_callback_init_(struct event_base *base,
struct event_callback *cb);
/* FIXME document. */
EVENT2_EXPORT_SYMBOL
void event_base_add_virtual_(struct event_base *base);
void event_base_del_virtual_(struct event_base *base);
@ -450,6 +458,7 @@ void event_base_del_virtual_(struct event_base *base);
Returns on success; aborts on failure.
*/
EVENT2_EXPORT_SYMBOL
void event_base_assert_ok_(struct event_base *base);
void event_base_assert_ok_nolock_(struct event_base *base);

View File

@ -52,6 +52,9 @@
#include <string.h>
#include <time.h>
#include <limits.h>
#ifdef EVENT__HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "event2/event.h"
#include "event2/event_struct.h"
@ -123,6 +126,7 @@ static const struct eventop *eventops[] = {
};
/* Global state; deprecated */
EVENT2_EXPORT_SYMBOL
struct event_base *event_global_current_base_ = NULL;
#define current_base event_global_current_base_
@ -228,133 +232,169 @@ HT_PROTOTYPE(event_debug_map, event_debug_entry, node, hash_debug_entry,
HT_GENERATE(event_debug_map, event_debug_entry, node, hash_debug_entry,
eq_debug_entry, 0.5, mm_malloc, mm_realloc, mm_free)
/* Macro: record that ev is now setup (that is, ready for an add) */
#define event_debug_note_setup_(ev) do { \
if (event_debug_mode_on_) { \
struct event_debug_entry *dent,find; \
find.ptr = (ev); \
EVLOCK_LOCK(event_debug_map_lock_, 0); \
dent = HT_FIND(event_debug_map, &global_debug_map, &find); \
if (dent) { \
dent->added = 0; \
} else { \
dent = mm_malloc(sizeof(*dent)); \
if (!dent) \
event_err(1, \
"Out of memory in debugging code"); \
dent->ptr = (ev); \
dent->added = 0; \
HT_INSERT(event_debug_map, &global_debug_map, dent); \
} \
EVLOCK_UNLOCK(event_debug_map_lock_, 0); \
} \
event_debug_mode_too_late = 1; \
} while (0)
/* Macro: record that ev is no longer setup */
#define event_debug_note_teardown_(ev) do { \
if (event_debug_mode_on_) { \
struct event_debug_entry *dent,find; \
find.ptr = (ev); \
EVLOCK_LOCK(event_debug_map_lock_, 0); \
dent = HT_REMOVE(event_debug_map, &global_debug_map, &find); \
if (dent) \
mm_free(dent); \
EVLOCK_UNLOCK(event_debug_map_lock_, 0); \
} \
event_debug_mode_too_late = 1; \
} while (0)
/* record that ev is now setup (that is, ready for an add) */
static void event_debug_note_setup_(const struct event *ev)
{
struct event_debug_entry *dent, find;
if (!event_debug_mode_on_)
goto out;
find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0);
dent = HT_FIND(event_debug_map, &global_debug_map, &find);
if (dent) {
dent->added = 0;
} else {
dent = mm_malloc(sizeof(*dent));
if (!dent)
event_err(1,
"Out of memory in debugging code");
dent->ptr = ev;
dent->added = 0;
HT_INSERT(event_debug_map, &global_debug_map, dent);
}
EVLOCK_UNLOCK(event_debug_map_lock_, 0);
out:
event_debug_mode_too_late = 1;
}
/* record that ev is no longer setup */
static void event_debug_note_teardown_(const struct event *ev)
{
struct event_debug_entry *dent, find;
if (!event_debug_mode_on_)
goto out;
find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0);
dent = HT_REMOVE(event_debug_map, &global_debug_map, &find);
if (dent)
mm_free(dent);
EVLOCK_UNLOCK(event_debug_map_lock_, 0);
out:
event_debug_mode_too_late = 1;
}
/* Macro: record that ev is now added */
#define event_debug_note_add_(ev) do { \
if (event_debug_mode_on_) { \
struct event_debug_entry *dent,find; \
find.ptr = (ev); \
EVLOCK_LOCK(event_debug_map_lock_, 0); \
dent = HT_FIND(event_debug_map, &global_debug_map, &find); \
if (dent) { \
dent->added = 1; \
} else { \
event_errx(EVENT_ERR_ABORT_, \
"%s: noting an add on a non-setup event %p" \
" (events: 0x%x, fd: "EV_SOCK_FMT \
", flags: 0x%x)", \
__func__, (ev), (ev)->ev_events, \
EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \
} \
EVLOCK_UNLOCK(event_debug_map_lock_, 0); \
} \
event_debug_mode_too_late = 1; \
} while (0)
/* Macro: record that ev is no longer added */
#define event_debug_note_del_(ev) do { \
if (event_debug_mode_on_) { \
struct event_debug_entry *dent,find; \
find.ptr = (ev); \
EVLOCK_LOCK(event_debug_map_lock_, 0); \
dent = HT_FIND(event_debug_map, &global_debug_map, &find); \
if (dent) { \
dent->added = 0; \
} else { \
event_errx(EVENT_ERR_ABORT_, \
"%s: noting a del on a non-setup event %p" \
" (events: 0x%x, fd: "EV_SOCK_FMT \
", flags: 0x%x)", \
__func__, (ev), (ev)->ev_events, \
EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \
} \
EVLOCK_UNLOCK(event_debug_map_lock_, 0); \
} \
event_debug_mode_too_late = 1; \
} while (0)
/* Macro: assert that ev is setup (i.e., okay to add or inspect) */
#define event_debug_assert_is_setup_(ev) do { \
if (event_debug_mode_on_) { \
struct event_debug_entry *dent,find; \
find.ptr = (ev); \
EVLOCK_LOCK(event_debug_map_lock_, 0); \
dent = HT_FIND(event_debug_map, &global_debug_map, &find); \
if (!dent) { \
event_errx(EVENT_ERR_ABORT_, \
"%s called on a non-initialized event %p" \
" (events: 0x%x, fd: "EV_SOCK_FMT\
", flags: 0x%x)", \
__func__, (ev), (ev)->ev_events, \
EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \
} \
EVLOCK_UNLOCK(event_debug_map_lock_, 0); \
} \
} while (0)
/* Macro: assert that ev is not added (i.e., okay to tear down or set
* up again) */
#define event_debug_assert_not_added_(ev) do { \
if (event_debug_mode_on_) { \
struct event_debug_entry *dent,find; \
find.ptr = (ev); \
EVLOCK_LOCK(event_debug_map_lock_, 0); \
dent = HT_FIND(event_debug_map, &global_debug_map, &find); \
if (dent && dent->added) { \
event_errx(EVENT_ERR_ABORT_, \
"%s called on an already added event %p" \
" (events: 0x%x, fd: "EV_SOCK_FMT", " \
"flags: 0x%x)", \
__func__, (ev), (ev)->ev_events, \
EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \
} \
EVLOCK_UNLOCK(event_debug_map_lock_, 0); \
} \
} while (0)
static void event_debug_note_add_(const struct event *ev)
{
struct event_debug_entry *dent,find;
if (!event_debug_mode_on_)
goto out;
find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0);
dent = HT_FIND(event_debug_map, &global_debug_map, &find);
if (dent) {
dent->added = 1;
} else {
event_errx(EVENT_ERR_ABORT_,
"%s: noting an add on a non-setup event %p"
" (events: 0x%x, fd: "EV_SOCK_FMT
", flags: 0x%x)",
__func__, ev, ev->ev_events,
EV_SOCK_ARG(ev->ev_fd), ev->ev_flags);
}
EVLOCK_UNLOCK(event_debug_map_lock_, 0);
out:
event_debug_mode_too_late = 1;
}
/* record that ev is no longer added */
static void event_debug_note_del_(const struct event *ev)
{
struct event_debug_entry *dent, find;
if (!event_debug_mode_on_)
goto out;
find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0);
dent = HT_FIND(event_debug_map, &global_debug_map, &find);
if (dent) {
dent->added = 0;
} else {
event_errx(EVENT_ERR_ABORT_,
"%s: noting a del on a non-setup event %p"
" (events: 0x%x, fd: "EV_SOCK_FMT
", flags: 0x%x)",
__func__, ev, ev->ev_events,
EV_SOCK_ARG(ev->ev_fd), ev->ev_flags);
}
EVLOCK_UNLOCK(event_debug_map_lock_, 0);
out:
event_debug_mode_too_late = 1;
}
/* assert that ev is setup (i.e., okay to add or inspect) */
static void event_debug_assert_is_setup_(const struct event *ev)
{
struct event_debug_entry *dent, find;
if (!event_debug_mode_on_)
return;
find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0);
dent = HT_FIND(event_debug_map, &global_debug_map, &find);
if (!dent) {
event_errx(EVENT_ERR_ABORT_,
"%s called on a non-initialized event %p"
" (events: 0x%x, fd: "EV_SOCK_FMT
", flags: 0x%x)",
__func__, ev, ev->ev_events,
EV_SOCK_ARG(ev->ev_fd), ev->ev_flags);
}
EVLOCK_UNLOCK(event_debug_map_lock_, 0);
}
/* assert that ev is not added (i.e., okay to tear down or set up again) */
static void event_debug_assert_not_added_(const struct event *ev)
{
struct event_debug_entry *dent, find;
if (!event_debug_mode_on_)
return;
find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0);
dent = HT_FIND(event_debug_map, &global_debug_map, &find);
if (dent && dent->added) {
event_errx(EVENT_ERR_ABORT_,
"%s called on an already added event %p"
" (events: 0x%x, fd: "EV_SOCK_FMT", "
"flags: 0x%x)",
__func__, ev, ev->ev_events,
EV_SOCK_ARG(ev->ev_fd), ev->ev_flags);
}
EVLOCK_UNLOCK(event_debug_map_lock_, 0);
}
static void event_debug_assert_socket_nonblocking_(evutil_socket_t fd)
{
if (!event_debug_mode_on_)
return;
if (fd < 0)
return;
#ifndef _WIN32
{
int flags;
if ((flags = fcntl(fd, F_GETFL, NULL)) >= 0) {
EVUTIL_ASSERT(flags & O_NONBLOCK);
}
}
#endif
}
#else
#define event_debug_note_setup_(ev) \
((void)0)
#define event_debug_note_teardown_(ev) \
((void)0)
#define event_debug_note_add_(ev) \
((void)0)
#define event_debug_note_del_(ev) \
((void)0)
#define event_debug_assert_is_setup_(ev) \
((void)0)
#define event_debug_assert_not_added_(ev) \
((void)0)
static void event_debug_note_setup_(const struct event *ev) { (void)ev; }
static void event_debug_note_teardown_(const struct event *ev) { (void)ev; }
static void event_debug_note_add_(const struct event *ev) { (void)ev; }
static void event_debug_note_del_(const struct event *ev) { (void)ev; }
static void event_debug_assert_is_setup_(const struct event *ev) { (void)ev; }
static void event_debug_assert_not_added_(const struct event *ev) { (void)ev; }
static void event_debug_assert_socket_nonblocking_(evutil_socket_t fd) { (void)fd; }
#endif
#define EVENT_BASE_ASSERT_LOCKED(base) \
@ -590,7 +630,9 @@ event_base_new_with_config(const struct event_config *cfg)
int flags;
if (should_check_environment && !precise_time) {
precise_time = evutil_getenv_("EVENT_PRECISE_TIMER") != NULL;
base->flags |= EVENT_BASE_FLAG_PRECISE_TIMER;
if (precise_time) {
base->flags |= EVENT_BASE_FLAG_PRECISE_TIMER;
}
}
flags = precise_time ? EV_MONOT_PRECISE : 0;
evutil_configure_monotonic_time_(&base->monotonic_timer, flags);
@ -862,6 +904,7 @@ event_base_free_(struct event_base *base, int run_finalizers)
* A simple case is bufferevent with underlying (i.e. filters).
*/
int i = event_base_free_queues_(base, run_finalizers);
event_debug(("%s: %d events freed", __func__, i));
if (!i) {
break;
}
@ -1640,10 +1683,12 @@ event_process_active_single_queue(struct event_base *base,
break;
case EV_CLOSURE_EVENT: {
void (*evcb_callback)(evutil_socket_t, short, void *);
short res;
EVUTIL_ASSERT(ev != NULL);
evcb_callback = *ev->ev_callback;
res = ev->ev_res;
EVBASE_RELEASE_LOCK(base, th_base_lock);
evcb_callback(ev->ev_fd, ev->ev_res, ev->ev_arg);
evcb_callback(ev->ev_fd, res, ev->ev_arg);
}
break;
case EV_CLOSURE_CB_SELF: {
@ -1661,8 +1706,8 @@ event_process_active_single_queue(struct event_base *base,
evcb_evfinalize = ev->ev_evcallback.evcb_cb_union.evcb_evfinalize;
EVUTIL_ASSERT((evcb->evcb_flags & EVLIST_FINALIZING));
EVBASE_RELEASE_LOCK(base, th_base_lock);
evcb_evfinalize(ev, ev->ev_arg);
event_debug_note_teardown_(ev);
evcb_evfinalize(ev, ev->ev_arg);
if (evcb_closure == EV_CLOSURE_EVENT_FINALIZE_FREE)
mm_free(ev);
}
@ -2011,6 +2056,9 @@ event_base_once(struct event_base *base, evutil_socket_t fd, short events,
int res = 0;
int activate = 0;
if (!base)
return (-1);
/* We cannot support signals that just fire once, or persistent
* events. */
if (events & (EV_SIGNAL|EV_PERSIST))
@ -2069,6 +2117,8 @@ event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, shor
if (arg == &event_self_cbarg_ptr_)
arg = ev;
if (!(events & EV_SIGNAL))
event_debug_assert_socket_nonblocking_(fd);
event_debug_assert_not_added_(ev);
ev->ev_base = base;
@ -2719,17 +2769,16 @@ static int
event_del_(struct event *ev, int blocking)
{
int res;
struct event_base *base = ev->ev_base;
if (EVUTIL_FAILURE_CHECK(!ev->ev_base)) {
if (EVUTIL_FAILURE_CHECK(!base)) {
event_warnx("%s: event has no event_base set.", __func__);
return -1;
}
EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);
EVBASE_ACQUIRE_LOCK(base, th_base_lock);
res = event_del_nolock_(ev, blocking);
EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock);
EVBASE_RELEASE_LOCK(base, th_base_lock);
return (res);
}
@ -2779,21 +2828,7 @@ event_del_nolock_(struct event *ev, int blocking)
}
}
/* If the main thread is currently executing this event's callback,
* and we are not the main thread, then we want to wait until the
* callback is done before we start removing the event. That way,
* when this function returns, it will be safe to free the
* user-supplied argument. */
base = ev->ev_base;
#ifndef EVENT__DISABLE_THREAD_SUPPORT
if (blocking != EVENT_DEL_NOBLOCK &&
base->current_event == event_to_event_callback(ev) &&
!EVBASE_IN_THREAD(base) &&
(blocking == EVENT_DEL_BLOCK || !(ev->ev_events & EV_FINALIZE))) {
++base->current_event_waiters;
EVTHREAD_COND_WAIT(base->current_event_cond, base->th_base_lock);
}
#endif
EVUTIL_ASSERT(!(ev->ev_flags & ~EVLIST_ALL));
@ -2832,6 +2867,10 @@ event_del_nolock_(struct event *ev, int blocking)
notify = 1;
res = 0;
}
/* If we do not have events, let's notify event base so it can
* exit without waiting */
if (!event_haveevents(base) && !N_ACTIVE_CALLBACKS(base))
notify = 1;
}
/* if we are not in the right thread, we need to wake up the loop */
@ -2840,6 +2879,21 @@ event_del_nolock_(struct event *ev, int blocking)
event_debug_note_del_(ev);
/* If the main thread is currently executing this event's callback,
* and we are not the main thread, then we want to wait until the
* callback is done before returning. That way, when this function
* returns, it will be safe to free the user-supplied argument.
*/
#ifndef EVENT__DISABLE_THREAD_SUPPORT
if (blocking != EVENT_DEL_NOBLOCK &&
base->current_event == event_to_event_callback(ev) &&
!EVBASE_IN_THREAD(base) &&
(blocking == EVENT_DEL_BLOCK || !(ev->ev_events & EV_FINALIZE))) {
++base->current_event_waiters;
EVTHREAD_COND_WAIT(base->current_event_cond, base->th_base_lock);
}
#endif
return (res);
}
@ -2960,6 +3014,7 @@ event_callback_activate_nolock_(struct event_base *base,
switch (evcb->evcb_flags & (EVLIST_ACTIVE|EVLIST_ACTIVE_LATER)) {
default:
EVUTIL_ASSERT(0);
EVUTIL_FALLTHROUGH;
case EVLIST_ACTIVE_LATER:
event_queue_remove_active_later(base, evcb);
r = 0;
@ -3148,10 +3203,6 @@ timeout_process(struct event_base *base)
}
}
#if (EVLIST_INTERNAL >> 4) != 1
#error "Mismatch for value of EVLIST_INTERNAL"
#endif
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
@ -3159,13 +3210,13 @@ timeout_process(struct event_base *base)
#define MAX_EVENT_COUNT(var, v) var = MAX(var, v)
/* These are a fancy way to spell
if (flags & EVLIST_INTERNAL)
if (~flags & EVLIST_INTERNAL)
base->event_count--/++;
*/
#define DECR_EVENT_COUNT(base,flags) \
((base)->event_count -= (~((flags) >> 4) & 1))
((base)->event_count -= !((flags) & EVLIST_INTERNAL))
#define INCR_EVENT_COUNT(base,flags) do { \
((base)->event_count += (~((flags) >> 4) & 1)); \
((base)->event_count += !((flags) & EVLIST_INTERNAL)); \
MAX_EVENT_COUNT((base)->event_count_max, (base)->event_count); \
} while (0)
@ -3697,13 +3748,14 @@ dump_inserted_event_fn(const struct event_base *base, const struct event *e, voi
if (! (e->ev_flags & (EVLIST_INSERTED|EVLIST_TIMEOUT)))
return 0;
fprintf(output, " %p [%s "EV_SOCK_FMT"]%s%s%s%s%s%s",
fprintf(output, " %p [%s "EV_SOCK_FMT"]%s%s%s%s%s%s%s",
(void*)e, gloss, EV_SOCK_ARG(e->ev_fd),
(e->ev_events&EV_READ)?" Read":"",
(e->ev_events&EV_WRITE)?" Write":"",
(e->ev_events&EV_CLOSED)?" EOF":"",
(e->ev_events&EV_SIGNAL)?" Signal":"",
(e->ev_events&EV_PERSIST)?" Persist":"",
(e->ev_events&EV_ET)?" ET":"",
(e->ev_flags&EVLIST_INTERNAL)?" Internal":"");
if (e->ev_flags & EVLIST_TIMEOUT) {
struct timeval tv;
@ -3774,7 +3826,35 @@ void
event_base_active_by_fd(struct event_base *base, evutil_socket_t fd, short events)
{
EVBASE_ACQUIRE_LOCK(base, th_base_lock);
evmap_io_active_(base, fd, events & (EV_READ|EV_WRITE|EV_CLOSED));
/* Activate any non timer events */
if (!(events & EV_TIMEOUT)) {
evmap_io_active_(base, fd, events & (EV_READ|EV_WRITE|EV_CLOSED));
} else {
/* If we want to activate timer events, loop and activate each event with
* the same fd in both the timeheap and common timeouts list */
int i;
unsigned u;
struct event *ev;
for (u = 0; u < base->timeheap.n; ++u) {
ev = base->timeheap.p[u];
if (ev->ev_fd == fd) {
event_active_nolock_(ev, EV_TIMEOUT, 1);
}
}
for (i = 0; i < base->n_common_timeouts; ++i) {
struct common_timeout_list *ctl = base->common_timeout_queues[i];
TAILQ_FOREACH(ev, &ctl->events,
ev_timeout_pos.ev_next_with_common_timeout) {
if (ev->ev_fd == fd) {
event_active_nolock_(ev, EV_TIMEOUT, 1);
}
}
}
}
EVBASE_RELEASE_LOCK(base, th_base_lock);
}

View File

@ -151,7 +151,7 @@ init_extension_functions(struct win32_extension_fns *ext)
const GUID connectex = WSAID_CONNECTEX;
const GUID getacceptexsockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET)
if (s == EVUTIL_INVALID_SOCKET)
return;
ext->AcceptEx = get_extension_function(s, &acceptex);
ext->ConnectEx = get_extension_function(s, &connectex);

File diff suppressed because it is too large Load Diff

View File

@ -93,9 +93,13 @@
a final padding nibble with value 0 is appended.
*/
EVENT2_EXPORT_SYMBOL
int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
EVENT2_EXPORT_SYMBOL
int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf);
EVENT2_EXPORT_SYMBOL
int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag);
EVENT2_EXPORT_SYMBOL
int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf);
void

View File

@ -43,6 +43,7 @@
#include <unistd.h>
#endif
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <string.h>
#include <time.h>
@ -207,9 +208,15 @@ evmap_make_space(struct event_signal_map *map, int slot, int msize)
int nentries = map->nentries ? map->nentries : 32;
void **tmp;
if (slot > INT_MAX / 2)
return (-1);
while (nentries <= slot)
nentries <<= 1;
if (nentries > INT_MAX / msize)
return (-1);
tmp = (void **)mm_realloc(map->entries, nentries * msize);
if (tmp == NULL)
return (-1);
@ -393,7 +400,8 @@ evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev)
if (res) {
void *extra = ((char*)ctx) + sizeof(struct evmap_io);
if (evsel->del(base, ev->ev_fd, old, res, extra) == -1) {
if (evsel->del(base, ev->ev_fd,
old, (ev->ev_events & EV_ET) | res, extra) == -1) {
retval = -1;
} else {
retval = 1;
@ -424,7 +432,7 @@ evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events)
if (NULL == ctx)
return;
LIST_FOREACH(ev, &ctx->events, ev_io_next) {
if (ev->ev_events & events)
if (ev->ev_events & (events & ~EV_ET))
event_active_nolock_(ev, ev->ev_events & events, 1);
}
}
@ -445,6 +453,9 @@ evmap_signal_add_(struct event_base *base, int sig, struct event *ev)
struct event_signal_map *map = &base->sigmap;
struct evmap_signal *ctx = NULL;
if (sig < 0 || sig >= NSIG)
return (-1);
if (sig >= map->nentries) {
if (evmap_make_space(
map, sig, sizeof(struct evmap_signal *)) == -1)
@ -471,7 +482,7 @@ evmap_signal_del_(struct event_base *base, int sig, struct event *ev)
struct event_signal_map *map = &base->sigmap;
struct evmap_signal *ctx;
if (sig >= map->nentries)
if (sig < 0 || sig >= map->nentries)
return (-1);
GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
@ -858,6 +869,7 @@ event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, sh
struct event_changelist *changelist = &base->changelist;
struct event_changelist_fdinfo *fdinfo = p;
struct event_change *change;
ev_uint8_t evchange = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL));
event_changelist_check(base);
@ -869,18 +881,12 @@ event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, sh
* since the delete might fail (because the fd had been closed since
* the last add, for instance. */
if (events & (EV_READ|EV_SIGNAL)) {
change->read_change = EV_CHANGE_ADD |
(events & (EV_ET|EV_PERSIST|EV_SIGNAL));
}
if (events & EV_WRITE) {
change->write_change = EV_CHANGE_ADD |
(events & (EV_ET|EV_PERSIST|EV_SIGNAL));
}
if (events & EV_CLOSED) {
change->close_change = EV_CHANGE_ADD |
(events & (EV_ET|EV_PERSIST|EV_SIGNAL));
}
if (events & (EV_READ|EV_SIGNAL))
change->read_change = evchange;
if (events & EV_WRITE)
change->write_change = evchange;
if (events & EV_CLOSED)
change->close_change = evchange;
event_changelist_check(base);
return (0);
@ -893,6 +899,7 @@ event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, sh
struct event_changelist *changelist = &base->changelist;
struct event_changelist_fdinfo *fdinfo = p;
struct event_change *change;
ev_uint8_t del = EV_CHANGE_DEL | (events & EV_ET);
event_changelist_check(base);
change = event_changelist_get_or_construct(changelist, fd, old, fdinfo);
@ -919,19 +926,19 @@ event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, sh
if (!(change->old_events & (EV_READ | EV_SIGNAL)))
change->read_change = 0;
else
change->read_change = EV_CHANGE_DEL;
change->read_change = del;
}
if (events & EV_WRITE) {
if (!(change->old_events & EV_WRITE))
change->write_change = 0;
else
change->write_change = EV_CHANGE_DEL;
change->write_change = del;
}
if (events & EV_CLOSED) {
if (!(change->old_events & EV_CLOSED))
change->close_change = 0;
else
change->close_change = EV_CHANGE_DEL;
change->close_change = del;
}
event_changelist_check(base);

View File

@ -329,7 +329,8 @@ evrpc_request_cb(struct evhttp_request *req, void *arg)
return;
error:
evrpc_reqstate_free_(rpc_state);
if (rpc_state)
evrpc_reqstate_free_(rpc_state);
evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
return;
}
@ -891,8 +892,7 @@ evrpc_reply_done(struct evhttp_request *req, void *arg)
* layer is going to free it. we need to
* request ownership explicitly
*/
if (req != NULL)
evhttp_request_own(req);
evhttp_request_own(req);
evrpc_pause_request(pool, ctx,
evrpc_reply_done_closure);

View File

@ -38,7 +38,7 @@ extern "C" {
struct event_base;
#ifndef _WIN32
#if !defined(_WIN32) && !defined(__CYGWIN__)
/* On Windows, the way we currently make DLLs, it's not allowed for us to
* have shared global structures. Thus, we only do the direct-call-to-function
* code path if we know that the local shared library system supports it.
@ -49,9 +49,12 @@ struct event_base;
#if ! defined(EVENT__DISABLE_THREAD_SUPPORT) && defined(EVTHREAD_EXPOSE_STRUCTS)
/* Global function pointers to lock-related functions. NULL if locking isn't
enabled. */
EVENT2_EXPORT_SYMBOL
extern struct evthread_lock_callbacks evthread_lock_fns_;
EVENT2_EXPORT_SYMBOL
extern struct evthread_condition_callbacks evthread_cond_fns_;
extern unsigned long (*evthread_id_fn_)(void);
EVENT2_EXPORT_SYMBOL
extern int evthread_lock_debugging_enabled_;
/** Return the ID of the current thread, or 1 if threading isn't enabled. */
@ -182,14 +185,23 @@ EVLOCK_TRY_LOCK_(void *lock)
#elif ! defined(EVENT__DISABLE_THREAD_SUPPORT)
unsigned long evthreadimpl_get_id_(void);
EVENT2_EXPORT_SYMBOL
int evthreadimpl_is_lock_debugging_enabled_(void);
EVENT2_EXPORT_SYMBOL
void *evthreadimpl_lock_alloc_(unsigned locktype);
EVENT2_EXPORT_SYMBOL
void evthreadimpl_lock_free_(void *lock, unsigned locktype);
EVENT2_EXPORT_SYMBOL
int evthreadimpl_lock_lock_(unsigned mode, void *lock);
EVENT2_EXPORT_SYMBOL
int evthreadimpl_lock_unlock_(unsigned mode, void *lock);
EVENT2_EXPORT_SYMBOL
void *evthreadimpl_cond_alloc_(unsigned condtype);
EVENT2_EXPORT_SYMBOL
void evthreadimpl_cond_free_(void *cond);
EVENT2_EXPORT_SYMBOL
int evthreadimpl_cond_signal_(void *cond, int broadcast);
EVENT2_EXPORT_SYMBOL
int evthreadimpl_cond_wait_(void *cond, void *lock, const struct timeval *tv);
int evthreadimpl_locking_enabled_(void);
@ -355,6 +367,7 @@ EVLOCK_TRY_LOCK_(void *lock)
EVLOCK_UNLOCK(lock1_tmplock_,mode1); \
} while (0)
EVENT2_EXPORT_SYMBOL
int evthread_is_debug_lock_held_(void *lock);
void *evthread_debug_get_real_lock_(void *lock);
@ -377,6 +390,7 @@ int evutil_global_setup_locks_(const int enable_locks);
int evutil_secure_rng_global_setup_locks_(const int enable_locks);
/** Return current evthread_lock_callbacks */
EVENT2_EXPORT_SYMBOL
struct evthread_lock_callbacks *evthread_get_lock_callbacks(void);
/** Return current evthread_condition_callbacks */
struct evthread_condition_callbacks *evthread_get_condition_callbacks(void);

View File

@ -46,7 +46,7 @@
#endif
#ifndef EVENT__DISABLE_DEBUG_MODE
extern int event_debug_created_threadable_ctx_;
extern int event_debug_created_threadable_ctx_;
extern int event_debug_mode_on_;
#endif

View File

@ -29,6 +29,7 @@
#ifdef _WIN32
#include <winsock2.h>
#include <winerror.h>
#include <ws2tcpip.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@ -40,6 +41,7 @@
/* For structs needed by GetAdaptersAddresses */
#define _WIN32_WINNT 0x0501
#include <iphlpapi.h>
#include <netioapi.h>
#endif
#include <sys/types.h>
@ -73,6 +75,9 @@
#endif
#include <time.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <net/if.h>
#endif
#ifdef EVENT__HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
@ -385,6 +390,17 @@ evutil_make_listen_socket_reuseable_port(evutil_socket_t sock)
#endif
}
int
evutil_make_listen_socket_ipv6only(evutil_socket_t sock)
{
#if defined(IPV6_V6ONLY)
int one = 1;
return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one,
(ev_socklen_t)sizeof(one));
#endif
return 0;
}
int
evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)
{
@ -595,44 +611,56 @@ evutil_socket_finished_connecting_(evutil_socket_t fd)
set by evutil_check_interfaces. */
static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
/* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8
*/
#define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127)
/* True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8 */
static inline int evutil_v4addr_is_localhost(ev_uint32_t addr)
{ return addr>>24 == 127; }
/* Macro: True iff the IPv4 address 'addr', in host order, is a class D
* (multiclass) address.
*/
#define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0)
/* True iff the IPv4 address 'addr', in host order, is link-local
* 169.254.0.0/16 (RFC3927) */
static inline int evutil_v4addr_is_linklocal(ev_uint32_t addr)
{ return ((addr & 0xffff0000U) == 0xa9fe0000U); }
/* True iff the IPv4 address 'addr', in host order, is a class D
* (multiclass) address. */
static inline int evutil_v4addr_is_classd(ev_uint32_t addr)
{ return ((addr>>24) & 0xf0) == 0xe0; }
int
evutil_v4addr_is_local_(const struct in_addr *in)
{
const ev_uint32_t addr = ntohl(in->s_addr);
return addr == INADDR_ANY ||
evutil_v4addr_is_localhost(addr) ||
evutil_v4addr_is_linklocal(addr) ||
evutil_v4addr_is_classd(addr);
}
int
evutil_v6addr_is_local_(const struct in6_addr *in)
{
static const char ZEROES[] =
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00";
const unsigned char *addr = (const unsigned char *)in->s6_addr;
return !memcmp(addr, ZEROES, 8) ||
((addr[0] & 0xfe) == 0xfc) ||
(addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) ||
(addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) ||
(addr[0] == 0xff);
}
static void
evutil_found_ifaddr(const struct sockaddr *sa)
{
const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00";
if (sa->sa_family == AF_INET) {
const struct sockaddr_in *sin = (struct sockaddr_in *)sa;
ev_uint32_t addr = ntohl(sin->sin_addr.s_addr);
if (addr == 0 ||
EVUTIL_V4ADDR_IS_LOCALHOST(addr) ||
EVUTIL_V4ADDR_IS_CLASSD(addr)) {
/* Not actually a usable external address. */
} else {
if (!evutil_v4addr_is_local_(&sin->sin_addr)) {
event_debug(("Detected an IPv4 interface"));
had_ipv4_address = 1;
}
} else if (sa->sa_family == AF_INET6) {
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
const unsigned char *addr =
(unsigned char*)sin6->sin6_addr.s6_addr;
if (!memcmp(addr, ZEROES, 8) ||
((addr[0] & 0xfe) == 0xfc) ||
(addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) ||
(addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) ||
(addr[0] == 0xff)) {
/* This is a reserved, ipv4compat, ipv4map, loopback,
* link-local, multicast, or unspecified address. */
} else {
if (!evutil_v6addr_is_local_(&sin6->sin6_addr)) {
event_debug(("Detected an IPv6 interface"));
had_ipv6_address = 1;
}
@ -670,7 +698,7 @@ evutil_check_ifaddrs(void)
"GetAdaptersInfo", but that's deprecated; let's just try
GetAdaptersAddresses and fall back to connect+getsockname.
*/
HMODULE lib = evutil_load_windows_system_library_(TEXT("ihplapi.dll"));
HMODULE lib = evutil_load_windows_system_library_(TEXT("iphlpapi.dll"));
GetAdaptersAddresses_fn_t fn;
ULONG size, res;
IP_ADAPTER_ADDRESSES *addresses = NULL, *address;
@ -727,7 +755,7 @@ done:
/* Test whether we have an ipv4 interface and an ipv6 interface. Return 0 if
* the test seemed successful. */
static int
evutil_check_interfaces(int force_recheck)
evutil_check_interfaces(void)
{
evutil_socket_t fd = -1;
struct sockaddr_in sin, sin_out;
@ -735,9 +763,12 @@ evutil_check_interfaces(int force_recheck)
ev_socklen_t sin_out_len = sizeof(sin_out);
ev_socklen_t sin6_out_len = sizeof(sin6_out);
int r;
if (have_checked_interfaces && !force_recheck)
if (have_checked_interfaces)
return 0;
/* From this point on we have done the ipv4/ipv6 interface check */
have_checked_interfaces = 1;
if (evutil_check_ifaddrs() == 0) {
/* Use a nice sane interface, if this system has one. */
return 0;
@ -963,6 +994,7 @@ evutil_getaddrinfo_common_(const char *nodename, const char *servname,
struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
{
int port = 0;
unsigned int if_index;
const char *pname;
if (nodename == NULL && servname == NULL)
@ -1036,10 +1068,12 @@ evutil_getaddrinfo_common_(const char *nodename, const char *servname,
if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
struct sockaddr_in6 sin6;
memset(&sin6, 0, sizeof(sin6));
if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
if (1 == evutil_inet_pton_scope(
AF_INET6, nodename, &sin6.sin6_addr, &if_index)) {
/* Got an ipv6 address. */
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(port);
sin6.sin6_scope_id = if_index;
*res = evutil_new_addrinfo_((struct sockaddr*)&sin6,
sizeof(sin6), hints);
if (!*res)
@ -1053,7 +1087,7 @@ evutil_getaddrinfo_common_(const char *nodename, const char *servname,
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
/* Got an ipv6 address. */
/* Got an ipv4 address. */
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
*res = evutil_new_addrinfo_((struct sockaddr*)&sin,
@ -1205,8 +1239,7 @@ evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints)
return;
if (hints->ai_family != PF_UNSPEC)
return;
if (!have_checked_interfaces)
evutil_check_interfaces(0);
evutil_check_interfaces();
if (had_ipv4_address && !had_ipv6_address) {
hints->ai_family = PF_INET;
} else if (!had_ipv4_address && had_ipv6_address) {
@ -1955,6 +1988,41 @@ evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
#endif
}
int
evutil_inet_pton_scope(int af, const char *src, void *dst, unsigned *indexp)
{
int r;
unsigned if_index;
char *check, *cp, *tmp_src;
*indexp = 0; /* Reasonable default */
/* Bail out if not IPv6 */
if (af != AF_INET6)
return evutil_inet_pton(af, src, dst);
cp = strchr(src, '%');
/* Bail out if no zone ID */
if (cp == NULL)
return evutil_inet_pton(af, src, dst);
if_index = if_nametoindex(cp + 1);
if (if_index == 0) {
/* Could be numeric */
if_index = strtoul(cp + 1, &check, 10);
if (check[0] != '\0')
return 0;
}
*indexp = if_index;
tmp_src = mm_strdup(src);
cp = strchr(tmp_src, '%');
*cp = '\0';
r = evutil_inet_pton(af, tmp_src, dst);
free(tmp_src);
return r;
}
int
evutil_inet_pton(int af, const char *src, void *dst)
{
@ -2071,6 +2139,7 @@ int
evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
{
int port;
unsigned int if_index;
char buf[128];
const char *cp, *addr_part, *port_part;
int is_ipv6;
@ -2140,10 +2209,13 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *
#endif
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(port);
if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
if (1 != evutil_inet_pton_scope(
AF_INET6, addr_part, &sin6.sin6_addr, &if_index)) {
return -1;
}
if ((int)sizeof(sin6) > *outlen)
return -1;
sin6.sin6_scope_id = if_index;
memset(out, 0, *outlen);
memcpy(out, &sin6, sizeof(sin6));
*outlen = sizeof(sin6);
@ -2297,7 +2369,7 @@ static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
#define IMPL_CTYPE_FN(name) \
int EVUTIL_##name##_(char c) { \
ev_uint8_t u = c; \
return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1U << (u & 31))); \
}
IMPL_CTYPE_FN(ISALPHA)
IMPL_CTYPE_FN(ISALNUM)
@ -2593,7 +2665,7 @@ evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
}
/* Internal function: Set fd[0] and fd[1] to a pair of fds such that writes on
* fd[0] get read from fd[1]. Make both fds nonblocking and close-on-exec.
* fd[1] get read from fd[0]. Make both fds nonblocking and close-on-exec.
* Return 0 on success, -1 on failure.
*/
int

View File

@ -171,9 +171,7 @@ evutil_secure_rng_init(void)
int val;
ARC4_LOCK_();
if (!arc4_seeded_ok)
arc4_stir();
val = arc4_seeded_ok ? 0 : -1;
val = (!arc4_stir()) ? 0 : -1;
ARC4_UNLOCK_();
return val;
}
@ -192,10 +190,12 @@ evutil_secure_rng_get_bytes(void *buf, size_t n)
ev_arc4random_buf(buf, n);
}
#if !defined(EVENT__HAVE_ARC4RANDOM) || defined(EVENT__HAVE_ARC4RANDOM_ADDRANDOM)
void
evutil_secure_rng_add_bytes(const char *buf, size_t n)
{
}
#endif
void
evutil_free_secure_rng_globals_(void)

View File

@ -43,7 +43,7 @@
#ifndef EVENT__HAVE_GETTIMEOFDAY
#include <sys/timeb.h>
#endif
#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT_HAVE_USLEEP) && \
#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT__HAVE_USLEEP) && \
!defined(_WIN32)
#include <sys/select.h>
#endif
@ -65,6 +65,9 @@
#ifndef EVENT__HAVE_GETTIMEOFDAY
/* No gettimeofday; this must be windows. */
typedef void (WINAPI *GetSystemTimePreciseAsFileTime_fn_t) (LPFILETIME);
int
evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
{
@ -90,7 +93,22 @@ evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
if (tv == NULL)
return -1;
GetSystemTimeAsFileTime(&ft.ft_ft);
static GetSystemTimePreciseAsFileTime_fn_t GetSystemTimePreciseAsFileTime_fn = NULL;
static int check_precise = 1;
if (EVUTIL_UNLIKELY(check_precise)) {
HMODULE h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
if (h != NULL)
GetSystemTimePreciseAsFileTime_fn =
(GetSystemTimePreciseAsFileTime_fn_t)
GetProcAddress(h, "GetSystemTimePreciseAsFileTime");
check_precise = 0;
}
if (GetSystemTimePreciseAsFileTime_fn != NULL)
GetSystemTimePreciseAsFileTime_fn(&ft.ft_ft);
else
GetSystemTimeAsFileTime(&ft.ft_ft);
if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) {
/* Time before the unix epoch. */
@ -126,8 +144,22 @@ evutil_usleep_(const struct timeval *tv)
return;
#if defined(_WIN32)
{
long msec = evutil_tv_to_msec_(tv);
Sleep((DWORD)msec);
__int64 usec;
LARGE_INTEGER li;
HANDLE timer;
usec = tv->tv_sec * 1000000LL + tv->tv_usec;
if (!usec)
return;
li.QuadPart = -10LL * usec;
timer = CreateWaitableTimer(NULL, TRUE, NULL);
if (!timer)
return;
SetWaitableTimer(timer, &li, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
}
#elif defined(EVENT__HAVE_NANOSLEEP)
{
@ -141,7 +173,10 @@ evutil_usleep_(const struct timeval *tv)
sleep(tv->tv_sec);
usleep(tv->tv_usec);
#else
select(0, NULL, NULL, NULL, tv);
{
struct timeval tv2 = *tv;
select(0, NULL, NULL, NULL, &tv2);
}
#endif
}
@ -155,18 +190,28 @@ evutil_date_rfc1123(char *date, const size_t datelen, const struct tm *tm)
time_t t = time(NULL);
#ifndef _WIN32
#if defined(EVENT__HAVE__GMTIME64_S) || !defined(_WIN32)
struct tm sys;
#endif
/* If `tm` is null, set system's current time. */
if (tm == NULL) {
#ifdef _WIN32
/** TODO: detect _gmtime64()/_gmtime64_s() */
tm = gmtime(&t);
#else
#if !defined(_WIN32)
gmtime_r(&t, &sys);
tm = &sys;
/** detect _gmtime64()/_gmtime64_s() */
#elif defined(EVENT__HAVE__GMTIME64_S)
errno_t err;
err = _gmtime64_s(&sys, &t);
if (err) {
event_errx(1, "Invalid argument to _gmtime64_s");
} else {
tm = &sys;
}
#elif defined(EVENT__HAVE__GMTIME64)
tm = _gmtime64(&t);
#else
tm = gmtime(&t);
#endif
}

View File

@ -18,9 +18,6 @@
#define HTTP_WRITE_TIMEOUT 50
#define HTTP_READ_TIMEOUT 50
#define HTTP_PREFIX "http://"
#define HTTP_DEFAULTPORT 80
enum message_read_status {
ALL_DATA_READ = 1,
MORE_DATA_EXPECTED = 0,
@ -184,12 +181,15 @@ int evhttp_connection_connect_(struct evhttp_connection *);
enum evhttp_request_error;
/* notifies the current request that it failed; resets connection */
EVENT2_EXPORT_SYMBOL
void evhttp_connection_fail_(struct evhttp_connection *,
enum evhttp_request_error error);
enum message_read_status;
EVENT2_EXPORT_SYMBOL
enum message_read_status evhttp_parse_firstline_(struct evhttp_request *, struct evbuffer*);
EVENT2_EXPORT_SYMBOL
enum message_read_status evhttp_parse_headers_(struct evhttp_request *, struct evbuffer*);
void evhttp_start_read_(struct evhttp_connection *);
@ -199,7 +199,8 @@ void evhttp_start_write_(struct evhttp_connection *);
void evhttp_response_code_(struct evhttp_request *, int, const char *);
void evhttp_send_page_(struct evhttp_request *, struct evbuffer *);
EVENT2_EXPORT_SYMBOL
int evhttp_decode_uri_internal(const char *uri, size_t length,
char *ret, int decode_plus);
#endif /* _HTTP_H */
#endif /* HTTP_INTERNAL_H_INCLUDED_ */

View File

@ -51,9 +51,16 @@
#ifndef _WIN32
#include <sys/socket.h>
#include <sys/stat.h>
#else
#else /* _WIN32 */
#include <winsock2.h>
#include <ws2tcpip.h>
#endif /* _WIN32 */
#ifdef EVENT__HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#ifdef EVENT__HAVE_AFUNIX_H
#include <afunix.h>
#endif
#include <sys/queue.h>
@ -78,7 +85,7 @@
#include <string.h>
#ifndef _WIN32
#include <syslog.h>
#endif
#endif /* !_WIN32 */
#include <signal.h>
#ifdef EVENT__HAVE_UNISTD_H
#include <unistd.h>
@ -170,9 +177,10 @@ fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
extern int debug;
static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
static evutil_socket_t create_bind_socket_nonblock(struct evutil_addrinfo *, int reuse);
static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri);
static int evhttp_associate_new_request_with_connection(
struct evhttp_connection *evcon);
static void evhttp_connection_start_detectclose(
@ -350,6 +358,7 @@ evhttp_response_needs_body(struct evhttp_request *req)
return (req->response_code != HTTP_NOCONTENT &&
req->response_code != HTTP_NOTMODIFIED &&
(req->response_code < 100 || req->response_code >= 200) &&
req->type != EVHTTP_REQ_CONNECT &&
req->type != EVHTTP_REQ_HEAD);
}
@ -368,15 +377,15 @@ evhttp_write_buffer(struct evhttp_connection *evcon,
evcon->cb_arg = arg;
/* Disable the read callback: we don't actually care about data;
* we only care about close detection. (We don't disable reading,
* since we *do* want to learn about any close events.) */
* we only care about close detection. (We don't disable reading --
* EV_READ, since we *do* want to learn about any close events.) */
bufferevent_setcb(evcon->bufev,
NULL, /*read*/
evhttp_write_cb,
evhttp_error_cb,
evcon);
bufferevent_enable(evcon->bufev, EV_WRITE);
bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
}
static void
@ -470,6 +479,9 @@ evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
static int
evhttp_is_request_connection_close(struct evhttp_request *req)
{
if (req->type == EVHTTP_REQ_CONNECT)
return 0;
return
evhttp_is_connection_close(req->flags, req->input_headers) ||
evhttp_is_connection_close(req->flags, req->output_headers);
@ -770,6 +782,11 @@ evhttp_connection_fail_(struct evhttp_connection *evcon,
/* We are trying the next request that was queued on us */
if (TAILQ_FIRST(&evcon->requests) != NULL)
evhttp_connection_connect_(evcon);
else
if ((evcon->flags & EVHTTP_CON_OUTGOING) &&
(evcon->flags & EVHTTP_CON_AUTOFREE)) {
evhttp_connection_free(evcon);
}
/* The call to evhttp_connection_reset_ overwrote errno.
* Let's restore the original errno, so that the user's
@ -1170,7 +1187,9 @@ static void
evhttp_deferred_read_cb(struct event_callback *cb, void *data)
{
struct evhttp_connection *evcon = data;
evhttp_read_cb(evcon->bufev, evcon);
struct bufferevent *bev = evcon->bufev;
if (bev->readcb)
(bev->readcb)(evcon->bufev, evcon);
}
static void
@ -1202,6 +1221,7 @@ void
evhttp_connection_free(struct evhttp_connection *evcon)
{
struct evhttp_request *req;
int need_close = 0;
/* notify interested parties that this connection is going down */
if (evcon->fd != -1) {
@ -1228,21 +1248,22 @@ evhttp_connection_free(struct evhttp_connection *evcon)
event_debug_unassign(&evcon->retry_ev);
}
if (evcon->bufev != NULL)
bufferevent_free(evcon->bufev);
event_deferred_cb_cancel_(get_deferred_queue(evcon),
&evcon->read_more_deferred_cb);
if (evcon->fd == -1)
evcon->fd = bufferevent_getfd(evcon->bufev);
if (evcon->bufev != NULL) {
need_close =
!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
if (evcon->fd == -1)
evcon->fd = bufferevent_getfd(evcon->bufev);
bufferevent_free(evcon->bufev);
}
if (evcon->fd != -1) {
bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
shutdown(evcon->fd, EVUTIL_SHUT_WR);
if (!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE)) {
if (need_close)
evutil_closesocket(evcon->fd);
}
}
if (evcon->bind_address != NULL)
@ -1287,6 +1308,8 @@ evhttp_request_dispatch(struct evhttp_connection* evcon)
if (req == NULL)
return;
EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
/* delete possible close detection events */
evhttp_connection_stop_detectclose(evcon);
@ -1309,6 +1332,8 @@ evhttp_connection_reset_(struct evhttp_connection *evcon)
struct evbuffer *tmp;
int err;
bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
/* XXXX This is not actually an optimal fix. Instead we ought to have
an API for "stop connecting", or use bufferevent_setfd to turn off
connecting. But for Libevent 2.0, this seems like a minimal change
@ -1334,7 +1359,8 @@ evhttp_connection_reset_(struct evhttp_connection *evcon)
evutil_closesocket(evcon->fd);
evcon->fd = -1;
}
bufferevent_setfd(evcon->bufev, -1);
err = bufferevent_setfd(evcon->bufev, -1);
EVUTIL_ASSERT(!err && "setfd");
/* we need to clean up any buffered data */
tmp = bufferevent_get_output(evcon->bufev);
@ -1353,7 +1379,6 @@ static void
evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
{
evcon->flags |= EVHTTP_CON_CLOSEDETECT;
bufferevent_enable(evcon->bufev, EV_READ);
}
@ -1361,7 +1386,6 @@ static void
evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
{
evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
bufferevent_disable(evcon->bufev, EV_READ);
}
@ -1526,6 +1550,14 @@ evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
return;
}
if (what & BEV_EVENT_READING &&
evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
evbuffer_get_length(bufferevent_get_input(bufev))) {
event_deferred_cb_schedule_(get_deferred_queue(evcon),
&evcon->read_more_deferred_cb);
return;
}
evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
} else if (what == BEV_EVENT_CONNECTED) {
} else {
@ -1683,8 +1715,9 @@ evhttp_parse_response_line(struct evhttp_request *req, char *line)
/* Parse the first line of a HTTP request */
static int
evhttp_parse_request_line(struct evhttp_request *req, char *line)
evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
{
char *eos = line + len;
char *method;
char *uri;
char *version;
@ -1693,16 +1726,24 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line)
size_t method_len;
enum evhttp_cmd_type type;
while (eos > line && *(eos-1) == ' ') {
*(eos-1) = '\0';
--eos;
--len;
}
if (len < strlen("GET / HTTP/1.0"))
return -1;
/* Parse the request line */
method = strsep(&line, " ");
if (line == NULL)
return (-1);
uri = strsep(&line, " ");
if (line == NULL)
return (-1);
version = strsep(&line, " ");
if (line != NULL)
return (-1);
if (!line)
return -1;
uri = line;
version = strrchr(uri, ' ');
if (!version || uri == version)
return -1;
*version = '\0';
version++;
method_len = (uri - method) - 1;
type = EVHTTP_REQ_UNKNOWN_;
@ -1822,16 +1863,22 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line)
req->type = type;
if (evhttp_parse_http_version(version, req) < 0)
return (-1);
return -1;
if ((req->uri = mm_strdup(uri)) == NULL) {
event_debug(("%s: mm_strdup", __func__));
return (-1);
return -1;
}
if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
EVHTTP_URI_NONCONFORMANT)) == NULL) {
return -1;
if (type == EVHTTP_REQ_CONNECT) {
if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
return -1;
}
} else {
if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
EVHTTP_URI_NONCONFORMANT)) == NULL) {
return -1;
}
}
/* If we have an absolute-URI, check to see if it is an http request
@ -1845,7 +1892,7 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line)
!evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
req->flags |= EVHTTP_PROXY_REQUEST;
return (0);
return 0;
}
const char *
@ -1980,9 +2027,9 @@ evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
char *line;
enum message_read_status status = ALL_DATA_READ;
size_t line_length;
size_t len;
/* XXX try */
line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
if (line == NULL) {
if (req->evcon != NULL &&
evbuffer_get_length(buffer) > req->evcon->max_headers_size)
@ -1991,17 +2038,16 @@ evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
return (MORE_DATA_EXPECTED);
}
if (req->evcon != NULL &&
line_length > req->evcon->max_headers_size) {
if (req->evcon != NULL && len > req->evcon->max_headers_size) {
mm_free(line);
return (DATA_TOO_LONG);
}
req->headers_size = line_length;
req->headers_size = len;
switch (req->kind) {
case EVHTTP_REQUEST:
if (evhttp_parse_request_line(req, line) == -1)
if (evhttp_parse_request_line(req, line, len) == -1)
status = DATA_CORRUPTED;
break;
case EVHTTP_RESPONSE:
@ -2054,12 +2100,12 @@ evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
enum message_read_status status = MORE_DATA_EXPECTED;
struct evkeyvalq* headers = req->input_headers;
size_t line_length;
while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
size_t len;
while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
!= NULL) {
char *skey, *svalue;
req->headers_size += line_length;
req->headers_size += len;
if (req->evcon != NULL &&
req->headers_size > req->evcon->max_headers_size) {
@ -2123,11 +2169,7 @@ evhttp_get_body_length(struct evhttp_request *req)
req->ntoread = -1;
else if (content_length == NULL &&
evutil_ascii_strcasecmp(connection, "Close") != 0) {
/* Bad combination, we don't know when it will end */
event_warnx("%s: we got no content length, but the "
"server wants to keep the connection open: %s.",
__func__, connection);
return (-1);
req->ntoread = 0;
} else if (content_length == NULL) {
req->ntoread = -1;
} else {
@ -2155,16 +2197,15 @@ evhttp_method_may_have_body(enum evhttp_cmd_type type)
case EVHTTP_REQ_POST:
case EVHTTP_REQ_PUT:
case EVHTTP_REQ_PATCH:
return 1;
case EVHTTP_REQ_TRACE:
return 0;
/* XXX May any of the below methods have a body? */
case EVHTTP_REQ_GET:
case EVHTTP_REQ_HEAD:
case EVHTTP_REQ_DELETE:
case EVHTTP_REQ_OPTIONS:
case EVHTTP_REQ_CONNECT:
return 0;
return 1;
case EVHTTP_REQ_TRACE:
case EVHTTP_REQ_HEAD:
default:
return 0;
}
@ -2544,9 +2585,11 @@ evhttp_connection_connect_(struct evhttp_connection *evcon)
return (-1);
}
bufferevent_setfd(evcon->bufev, evcon->fd);
if (bufferevent_setfd(evcon->bufev, evcon->fd))
return (-1);
} else {
bufferevent_setfd(evcon->bufev, -1);
if (bufferevent_setfd(evcon->bufev, -1))
return (-1);
}
/* Set up a callback for successful connection setup */
@ -2562,7 +2605,8 @@ evhttp_connection_connect_(struct evhttp_connection *evcon)
bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
}
/* make sure that we get a write callback */
bufferevent_enable(evcon->bufev, EV_WRITE);
if (bufferevent_enable(evcon->bufev, EV_WRITE))
return (-1);
evcon->state = EVCON_CONNECTING;
@ -2628,6 +2672,10 @@ evhttp_make_request(struct evhttp_connection *evcon,
TAILQ_INSERT_TAIL(&evcon->requests, req, next);
/* We do not want to conflict with retry_ev */
if (evcon->retry_cnt)
return (0);
/* If the connection object is not connected; make it so */
if (!evhttp_connected(evcon)) {
int res = evhttp_connection_connect_(evcon);
@ -2638,7 +2686,7 @@ evhttp_make_request(struct evhttp_connection *evcon,
if (res != 0)
TAILQ_REMOVE(&evcon->requests, req, next);
return res;
return (res);
}
/*
@ -2820,6 +2868,10 @@ evhttp_send_reply_start(struct evhttp_request *req, int code,
const char *reason)
{
evhttp_response_code_(req, code, reason);
if (req->evcon == NULL)
return;
if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
REQ_VERSION_ATLEAST(req, 1, 1) &&
evhttp_response_needs_body(req)) {
@ -3059,16 +3111,15 @@ evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
{
struct evbuffer *buf = evbuffer_new();
const char *p, *end;
char *result;
char *result = NULL;
if (buf == NULL) {
return (NULL);
if (!buf) {
goto out;
}
if (len >= 0) {
if (uri + len < uri) {
return (NULL);
goto out;
}
end = uri + len;
@ -3077,11 +3128,11 @@ evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
if (slen >= EV_SSIZE_MAX) {
/* we don't want to mix signed and unsigned */
return (NULL);
goto out;
}
if (uri + slen < uri) {
return (NULL);
goto out;
}
end = uri + slen;
@ -3103,9 +3154,10 @@ evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
if (result)
evbuffer_remove(buf, result, evbuffer_get_length(buf));
evbuffer_free(buf);
return (result);
out:
if (buf)
evbuffer_free(buf);
return result;
}
char *
@ -3234,6 +3286,7 @@ evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
p = argument = line;
while (p != NULL && *p != '\0') {
char *key, *value, *decoded_value;
int err;
argument = strsep(&p, "&");
value = argument;
@ -3249,8 +3302,10 @@ evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
evhttp_decode_uri_internal(value, strlen(value),
decoded_value, 1 /*always_decode_plus*/);
event_debug(("Query Param: %s -> %s\n", key, decoded_value));
evhttp_add_header_internal(headers, key, decoded_value);
err = evhttp_add_header_internal(headers, key, decoded_value);
mm_free(decoded_value);
if (err)
goto error;
}
result = 0;
@ -3416,6 +3471,8 @@ evhttp_handle_request(struct evhttp_request *req, void *arg)
/* we have a new request on which the user needs to take action */
req->userdone = 0;
bufferevent_disable(req->evcon->bufev, EV_READ);
if (req->type == 0 || req->uri == NULL) {
evhttp_send_error(req, req->response_code, NULL);
return;
@ -3503,13 +3560,16 @@ evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint
{
evutil_socket_t fd;
struct evhttp_bound_socket *bound;
int serrno;
if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
return (NULL);
if (listen(fd, 128) == -1) {
serrno = EVUTIL_SOCKET_ERROR();
event_sock_warn(fd, "%s: listen", __func__);
evutil_closesocket(fd);
EVUTIL_SET_SOCKET_ERROR(serrno);
return (NULL);
}
@ -4169,6 +4229,13 @@ evhttp_get_request_connection(
char *hostname = NULL, *portname = NULL;
struct bufferevent* bev = NULL;
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
if (sa->sa_family == AF_UNIX) {
struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
sa_un->sun_path[0] = '\0';
}
#endif
name_from_addr(sa, salen, &hostname, &portname);
if (hostname == NULL || portname == NULL) {
if (hostname) mm_free(hostname);
@ -4200,11 +4267,19 @@ evhttp_get_request_connection(
evcon->fd = fd;
bufferevent_enable(evcon->bufev, EV_READ);
bufferevent_disable(evcon->bufev, EV_WRITE);
bufferevent_setfd(evcon->bufev, fd);
if (bufferevent_setfd(evcon->bufev, fd))
goto err;
if (bufferevent_enable(evcon->bufev, EV_READ))
goto err;
if (bufferevent_disable(evcon->bufev, EV_WRITE))
goto err;
bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
return (evcon);
err:
evhttp_connection_free(evcon);
return (NULL);
}
static int
@ -4313,9 +4388,8 @@ name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
}
/* Create a non-blocking socket and bind it */
/* todo: rename this function */
static evutil_socket_t
bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
create_bind_socket_nonblock(struct evutil_addrinfo *ai, int reuse)
{
evutil_socket_t fd;
@ -4389,14 +4463,14 @@ bind_socket(const char *address, ev_uint16_t port, int reuse)
/* just create an unbound socket */
if (address == NULL && port == 0)
return bind_socket_ai(NULL, 0);
return create_bind_socket_nonblock(NULL, 0);
aitop = make_addrinfo(address, port);
if (aitop == NULL)
return (-1);
fd = bind_socket_ai(aitop, reuse);
fd = create_bind_socket_nonblock(aitop, reuse);
evutil_freeaddrinfo(aitop);
@ -4821,6 +4895,36 @@ err:
return NULL;
}
static struct evhttp_uri *
evhttp_uri_parse_authority(char *source_uri)
{
struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
char *end;
if (uri == NULL) {
event_warn("%s: calloc", __func__);
goto err;
}
uri->port = -1;
uri->flags = 0;
end = end_of_authority(source_uri);
if (parse_authority(uri, source_uri, end) < 0)
goto err;
uri->path = mm_strdup("");
if (uri->path == NULL) {
event_warn("%s: strdup", __func__);
goto err;
}
return uri;
err:
if (uri)
evhttp_uri_free(uri);
return NULL;
}
void
evhttp_uri_free(struct evhttp_uri *uri)
{

View File

@ -726,7 +726,8 @@ int evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
@param buffer the evbuffer to store the result
@param fd the file descriptor to read from
@param howmuch the number of bytes to be read
@param howmuch the number of bytes to be read. If the given number is negative
or out of maximum bytes per one read, as many bytes as we can will be read.
@return the number of bytes read, or -1 if an error occurred
@see evbuffer_write()
*/

View File

@ -90,9 +90,10 @@ typedef void (*evbuffer_cb)(struct evbuffer *buffer, size_t old_len, size_t new_
@param cb the callback function to invoke when the evbuffer is modified,
or NULL to remove all callbacks.
@param cbarg an argument to be provided to the callback function
@return 0 if successful, or -1 on error
*/
EVENT2_EXPORT_SYMBOL
void evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg);
int evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg);
/**

View File

@ -491,7 +491,7 @@ short bufferevent_get_enabled(struct bufferevent *bufev);
(In other words, if reading or writing is disabled, or if the
bufferevent's read or write operation has been suspended because
there's no data to write, or not enough banwidth, or so on, the
there's no data to write, or not enough bandwidth, or so on, the
timeout isn't active. The timeout only becomes active when we we're
willing to actually read or write.)
@ -518,6 +518,9 @@ int bufferevent_set_timeouts(struct bufferevent *bufev,
On input, a bufferevent does not invoke the user read callback unless
there is at least low watermark data in the buffer. If the read buffer
is beyond the high watermark, the bufferevent stops reading from the network.
But be aware that bufferevent input/read buffer can overrun high watermark
limit (typical example is openssl bufferevent), so you should not relay in
this.
On output, the user write callback is invoked whenever the buffered data
falls below the low watermark. Filters that write to this bufev will try
@ -566,7 +569,7 @@ void bufferevent_unlock(struct bufferevent *bufev);
/**
* Public interface to manually increase the reference count of a bufferevent
* this is useful in situations where a user may reference the bufferevent
* somewhere eles (unknown to libevent)
* somewhere else (unknown to libevent)
*
* @param bufev the bufferevent to increase the refcount on
*
@ -799,7 +802,7 @@ void ev_token_bucket_cfg_free(struct ev_token_bucket_cfg *cfg);
They are: socket-based bufferevents (normal and IOCP-based), and SSL-based
bufferevents.
Return 0 on sucess, -1 on failure.
Return 0 on success, -1 on failure.
*/
EVENT2_EXPORT_SYMBOL
int bufferevent_set_rate_limit(struct bufferevent *bev,
@ -850,7 +853,7 @@ int bufferevent_rate_limit_group_set_cfg(
The default min-share is currently 64 bytes.
Returns 0 on success, -1 on faulre.
Returns 0 on success, -1 on failure.
*/
EVENT2_EXPORT_SYMBOL
int bufferevent_rate_limit_group_set_min_share(

View File

@ -28,6 +28,8 @@
#ifndef EVENT2_BUFFEREVENT_COMPAT_H_INCLUDED_
#define EVENT2_BUFFEREVENT_COMPAT_H_INCLUDED_
#include <event2/visibility.h>
#define evbuffercb bufferevent_data_cb
#define everrorcb bufferevent_event_cb
@ -72,6 +74,7 @@
error occurred
@see bufferevent_base_set(), bufferevent_free()
*/
EVENT2_EXPORT_SYMBOL
struct bufferevent *bufferevent_new(evutil_socket_t fd,
evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg);
@ -83,6 +86,7 @@ struct bufferevent *bufferevent_new(evutil_socket_t fd,
@param timeout_read the read timeout
@param timeout_write the write timeout
*/
EVENT2_EXPORT_SYMBOL
void bufferevent_settimeout(struct bufferevent *bufev,
int timeout_read, int timeout_write);

View File

@ -179,11 +179,39 @@ extern "C" {
#define DNS_QUERY_NO_SEARCH 1
/* Allow searching */
#define DNS_OPTION_SEARCH 1
/* Parse "nameserver" and add default if no such section */
#define DNS_OPTION_NAMESERVERS 2
/* Parse additional options like:
* - timeout:
* - getaddrinfo-allow-skew:
* - max-timeouts:
* - max-inflight:
* - attempts:
* - randomize-case:
* - initial-probe-timeout:
*/
#define DNS_OPTION_MISC 4
/* Load hosts file (i.e. "/etc/hosts") */
#define DNS_OPTION_HOSTSFILE 8
#define DNS_OPTIONS_ALL 15
/**
* All above:
* - DNS_OPTION_SEARCH
* - DNS_OPTION_NAMESERVERS
* - DNS_OPTION_MISC
* - DNS_OPTION_HOSTSFILE
*/
#define DNS_OPTIONS_ALL ( \
DNS_OPTION_SEARCH | \
DNS_OPTION_NAMESERVERS | \
DNS_OPTION_MISC | \
DNS_OPTION_HOSTSFILE | \
0 \
)
/* Do not "default" nameserver (i.e. "127.0.0.1:53") if there is no nameservers
* in resolv.conf, (iff DNS_OPTION_NAMESERVERS is set) */
#define DNS_OPTION_NAMESERVERS_NO_DEFAULT 16
/* Obsolete name for DNS_QUERY_NO_SEARCH */
#define DNS_NO_SEARCH DNS_QUERY_NO_SEARCH
@ -208,6 +236,10 @@ struct event_base;
/** Flag for evdns_base_new: Do not prevent the libevent event loop from
* exiting when we have no active dns requests. */
#define EVDNS_BASE_DISABLE_WHEN_INACTIVE 0x8000
/** Flag for evdns_base_new: If EVDNS_BASE_INITIALIZE_NAMESERVERS isset, do not
* add default nameserver if there are no nameservers in resolv.conf
* @see DNS_OPTION_NAMESERVERS_NO_DEFAULT */
#define EVDNS_BASE_NAMESERVERS_NO_DEFAULT 0x10000
/**
Initialize the asynchronous DNS library.
@ -218,7 +250,7 @@ struct event_base;
@param event_base the event base to associate the dns client with
@param flags any of EVDNS_BASE_INITIALIZE_NAMESERVERS|
EVDNS_BASE_DISABLE_WHEN_INACTIVE
EVDNS_BASE_DISABLE_WHEN_INACTIVE|EVDNS_BASE_NAMESERVERS_NO_DEFAULT
@return evdns_base object if successful, or NULL if an error occurred.
@see evdns_base_free()
*/
@ -423,7 +455,8 @@ void evdns_cancel_request(struct evdns_base *base, struct evdns_request *req);
The currently available configuration options are:
ndots, timeout, max-timeouts, max-inflight, attempts, randomize-case,
bind-to, initial-probe-timeout, getaddrinfo-allow-skew.
bind-to, initial-probe-timeout, getaddrinfo-allow-skew,
so-rcvbuf, so-sndbuf.
In versions before Libevent 2.0.3-alpha, the option name needed to end with
a colon.
@ -453,7 +486,7 @@ int evdns_base_set_option(struct evdns_base *base, const char *option, const cha
@param base the evdns_base to which to apply this operation
@param flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC|
DNS_OPTION_HOSTSFILE|DNS_OPTIONS_ALL
DNS_OPTION_HOSTSFILE|DNS_OPTIONS_ALL|DNS_OPTION_NAMESERVERS_NO_DEFAULT
@param filename the path to the resolv.conf file
@return 0 if successful, or various positive error codes if an error
occurred (see above)
@ -478,6 +511,7 @@ int evdns_base_resolv_conf_parse(struct evdns_base *base, int flags, const char
EVENT2_EXPORT_SYMBOL
int evdns_base_load_hosts(struct evdns_base *base, const char *hosts_fname);
#if defined(EVENT_IN_DOXYGEN_) || defined(_WIN32)
/**
Obtain nameserver information using the Windows API.
@ -488,7 +522,6 @@ int evdns_base_load_hosts(struct evdns_base *base, const char *hosts_fname);
@return 0 if successful, or -1 if an error occurred
@see evdns_resolv_conf_parse()
*/
#ifdef _WIN32
EVENT2_EXPORT_SYMBOL
int evdns_base_config_windows_nameservers(struct evdns_base *);
#define EVDNS_BASE_CONFIG_WINDOWS_NAMESERVERS_IMPLEMENTED
@ -615,7 +648,8 @@ typedef void (*evdns_request_callback_fn_type)(struct evdns_server_request *, vo
@param callback A function to invoke whenever we get a DNS request
on the socket.
@param user_data Data to pass to the callback.
@return an evdns_server_port structure for this server port.
@return an evdns_server_port structure for this server port or NULL if
an error occurred.
*/
EVENT2_EXPORT_SYMBOL
struct evdns_server_port *evdns_add_server_port_with_base(struct event_base *base, evutil_socket_t socket, int flags, evdns_request_callback_fn_type callback, void *user_data);

View File

@ -49,6 +49,7 @@ extern "C" {
/* For int types. */
#include <event2/util.h>
#include <event2/visibility.h>
/**
Initialize the asynchronous DNS library.
@ -66,6 +67,7 @@ extern "C" {
@return 0 if successful, or -1 if an error occurred
@see evdns_shutdown()
*/
EVENT2_EXPORT_SYMBOL
int evdns_init(void);
struct evdns_base;
@ -76,6 +78,7 @@ struct evdns_base;
@deprecated This function is deprecated because use of the global
evdns_base is error-prone.
*/
EVENT2_EXPORT_SYMBOL
struct evdns_base *evdns_get_global_base(void);
/**
@ -93,6 +96,7 @@ struct evdns_base *evdns_get_global_base(void);
active requests will return DNS_ERR_SHUTDOWN.
@see evdns_init()
*/
EVENT2_EXPORT_SYMBOL
void evdns_shutdown(int fail_requests);
/**
@ -109,6 +113,7 @@ void evdns_shutdown(int fail_requests);
@return 0 if successful, or -1 if an error occurred
@see evdns_nameserver_ip_add()
*/
EVENT2_EXPORT_SYMBOL
int evdns_nameserver_add(unsigned long int address);
/**
@ -126,6 +131,7 @@ int evdns_nameserver_add(unsigned long int address);
@return the number of configured nameservers
@see evdns_nameserver_add()
*/
EVENT2_EXPORT_SYMBOL
int evdns_count_nameservers(void);
/**
@ -140,6 +146,7 @@ int evdns_count_nameservers(void);
@return 0 if successful, or -1 if an error occurred
@see evdns_resume()
*/
EVENT2_EXPORT_SYMBOL
int evdns_clear_nameservers_and_suspend(void);
/**
@ -155,6 +162,7 @@ int evdns_clear_nameservers_and_suspend(void);
@return 0 if successful, or -1 if an error occurred
@see evdns_clear_nameservers_and_suspend()
*/
EVENT2_EXPORT_SYMBOL
int evdns_resume(void);
/**
@ -170,6 +178,7 @@ int evdns_resume(void);
@return 0 if successful, or -1 if an error occurred
@see evdns_nameserver_add()
*/
EVENT2_EXPORT_SYMBOL
int evdns_nameserver_ip_add(const char *ip_as_string);
/**
@ -186,6 +195,7 @@ int evdns_nameserver_ip_add(const char *ip_as_string);
@return 0 if successful, or -1 if an error occurred
@see evdns_resolve_ipv6(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6()
*/
EVENT2_EXPORT_SYMBOL
int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr);
/**
@ -198,6 +208,7 @@ int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback
@return 0 if successful, or -1 if an error occurred
@see evdns_resolve_ipv4(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6()
*/
EVENT2_EXPORT_SYMBOL
int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr);
struct in_addr;
@ -217,6 +228,7 @@ struct in6_addr;
@return 0 if successful, or -1 if an error occurred
@see evdns_resolve_reverse_ipv6()
*/
EVENT2_EXPORT_SYMBOL
int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr);
/**
@ -233,6 +245,7 @@ int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_ty
@return 0 if successful, or -1 if an error occurred
@see evdns_resolve_reverse_ipv6()
*/
EVENT2_EXPORT_SYMBOL
int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
/**
@ -251,6 +264,7 @@ int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callb
@param flags Ignored.
@return 0 if successful, or -1 if an error occurred
*/
EVENT2_EXPORT_SYMBOL
int evdns_set_option(const char *option, const char *val, int flags);
/**
@ -278,6 +292,7 @@ int evdns_set_option(const char *option, const char *val, int flags);
occurred (see above)
@see resolv.conf(3), evdns_config_windows_nameservers()
*/
EVENT2_EXPORT_SYMBOL
int evdns_resolv_conf_parse(int flags, const char *const filename);
/**
@ -287,6 +302,7 @@ int evdns_resolv_conf_parse(int flags, const char *const filename);
caller to specify which evdns_base it applies to. The recommended
function is evdns_base_search_clear().
*/
EVENT2_EXPORT_SYMBOL
void evdns_search_clear(void);
/**
@ -298,6 +314,7 @@ void evdns_search_clear(void);
@param domain the domain to be added to the search list
*/
EVENT2_EXPORT_SYMBOL
void evdns_search_add(const char *domain);
/**
@ -312,6 +329,7 @@ void evdns_search_add(const char *domain);
@param ndots the new ndots parameter
*/
EVENT2_EXPORT_SYMBOL
void evdns_search_ndots_set(const int ndots);
/**
@ -322,9 +340,13 @@ void evdns_search_ndots_set(const int ndots);
function is evdns_add_server_port_with_base().
*/
struct evdns_server_port *evdns_add_server_port(evutil_socket_t socket, int flags, evdns_request_callback_fn_type callback, void *user_data);
EVENT2_EXPORT_SYMBOL
struct evdns_server_port *
evdns_add_server_port(evutil_socket_t socket, int flags,
evdns_request_callback_fn_type callback, void *user_data);
#ifdef _WIN32
EVENT2_EXPORT_SYMBOL
int evdns_config_windows_nameservers(void);
#define EVDNS_CONFIG_WINDOWS_NAMESERVERS_IMPLEMENTED
#endif

View File

@ -232,7 +232,7 @@ struct event_base
*
* Generally, you can create events with event_new(), then make them
* pending with event_add(). As your event_base runs, it will run the
* callbacks of an events whose conditions are triggered. When you
* callbacks of an events whose conditions are triggered. When you no
* longer want the event, free it with event_free().
*
* In more depth:
@ -285,7 +285,7 @@ struct event
* There are many options that can be used to alter the behavior and
* implementation of an event_base. To avoid having to pass them all in a
* complex many-argument constructor, we provide an abstract data type
* wrhere you set up configation information before passing it to
* where you set up configuration information before passing it to
* event_base_new_with_config().
*
* @see event_config_new(), event_config_free(), event_base_new_with_config(),
@ -632,7 +632,7 @@ int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus);
/**
* Record an interval and/or a number of callbacks after which the event base
* should check for new events. By default, the event base will run as many
* events are as activated at the higest activated priority before checking
* events are as activated at the highest activated priority before checking
* for new events. If you configure it by setting max_interval, it will check
* the time after each callback, and not allow more than max_interval to
* elapse before checking for new events. If you configure it by setting
@ -692,10 +692,7 @@ EVENT2_EXPORT_SYMBOL
void event_base_free(struct event_base *);
/**
As event_free, but do not run finalizers.
THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
BECOMES STABLE.
As event_base_free, but do not run finalizers.
*/
EVENT2_EXPORT_SYMBOL
void event_base_free_nofinalize(struct event_base *);
@ -944,9 +941,6 @@ int event_base_got_break(struct event_base *);
* To use this option safely, you may need to use event_finalize() or
* event_free_finalize() in order to safely tear down an event in a
* multithreaded application. See those functions for more information.
*
* THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
* BECOMES STABLE.
**/
#define EV_FINALIZE 0x40
/**
@ -963,11 +957,13 @@ int event_base_got_break(struct event_base *);
/**
@name evtimer_* macros
Aliases for working with one-shot timer events */
Aliases for working with one-shot timer events
If you need EV_PERSIST timer use event_*() functions.
*/
/**@{*/
#define evtimer_assign(ev, b, cb, arg) \
event_assign((ev), (b), -1, 0, (cb), (arg))
#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
#define evtimer_add(ev, tv) event_add((ev), (tv))
#define evtimer_del(ev) event_del(ev)
#define evtimer_pending(ev, tv) event_pending((ev), EV_TIMEOUT, (tv))
@ -990,6 +986,20 @@ int event_base_got_break(struct event_base *);
#define evsignal_initialized(ev) event_initialized(ev)
/**@}*/
/**
@name evuser_* macros
Aliases for working with user-triggered events
If you need EV_PERSIST event use event_*() functions.
*/
/**@{*/
#define evuser_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
#define evuser_del(ev) event_del(ev)
#define evuser_pending(ev, tv) event_pending((ev), 0, (tv))
#define evuser_initialized(ev) event_initialized(ev)
#define evuser_trigger(ev) event_active((ev), 0, 0)
/**@}*/
/**
A callback function for an event.
@ -1029,7 +1039,7 @@ EVENT2_EXPORT_SYMBOL
void *event_self_cbarg(void);
/**
Allocate and asssign a new event structure, ready to be added.
Allocate and assign a new event structure, ready to be added.
The function event_new() returns a new event that can be used in
future calls to event_add() and event_del(). The fd and events
@ -1055,10 +1065,10 @@ void *event_self_cbarg(void);
The EV_TIMEOUT flag has no effect here.
It is okay to have multiple events all listening on the same fds; but
they must either all be edge-triggered, or all not be edge triggerd.
they must either all be edge-triggered, or all not be edge triggered.
When the event becomes active, the event loop will run the provided
callbuck function, with three arguments. The first will be the provided
callback function, with three arguments. The first will be the provided
fd value. The second will be a bitfield of the events that triggered:
EV_READ, EV_WRITE, or EV_SIGNAL. Here the EV_TIMEOUT flag indicates
that a timeout occurred, and EV_ET indicates that an edge-triggered
@ -1073,7 +1083,7 @@ void *event_self_cbarg(void);
@param callback_arg an argument to be passed to the callback function
@return a newly allocated struct event that must later be freed with
event_free().
event_free() or NULL if an error occurred.
@see event_free(), event_add(), event_del(), event_assign()
*/
EVENT2_EXPORT_SYMBOL
@ -1124,18 +1134,14 @@ int event_assign(struct event *, struct event_base *, evutil_socket_t, short, ev
/**
Deallocate a struct event * returned by event_new().
If the event is pending or active, first make it non-pending and
non-active.
If the event is pending or active, this function makes it non-pending
and non-active first.
*/
EVENT2_EXPORT_SYMBOL
void event_free(struct event *);
/**
* Callback type for event_finalize and event_free_finalize().
*
* THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
* BECOMES STABLE.
*
**/
typedef void (*event_finalize_callback_fn)(struct event *, void *);
/**
@ -1163,13 +1169,10 @@ typedef void (*event_finalize_callback_fn)(struct event *, void *);
event_finalize() does not.
A finalizer callback must not make events pending or active. It must not
add events, activate events, or attempt to "resucitate" the event being
add events, activate events, or attempt to "resuscitate" the event being
finalized in any way.
THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
BECOMES STABLE.
@return 0 on succes, -1 on failure.
@return 0 on success, -1 on failure.
*/
/**@{*/
EVENT2_EXPORT_SYMBOL
@ -1199,7 +1202,7 @@ int event_free_finalize(unsigned, struct event *, event_finalize_callback_fn);
@param arg an argument to be passed to the callback function
@param timeout the maximum amount of time to wait for the event. NULL
makes an EV_READ/EV_WRITE event make forever; NULL makes an
EV_TIMEOUT event succees immediately.
EV_TIMEOUT event success immediately.
@return 0 if successful, or -1 if an error occurred
*/
EVENT2_EXPORT_SYMBOL
@ -1210,7 +1213,7 @@ int event_base_once(struct event_base *, evutil_socket_t, short, event_callback_
The function event_add() schedules the execution of the event 'ev' when the
condition specified by event_assign() or event_new() occurs, or when the time
specified in timeout has elapesed. If atimeout is NULL, no timeout
specified in timeout has elapsed. If a timeout is NULL, no timeout
occurs and the function will only be
called if a matching event occurs. The event in the
ev argument must be already initialized by event_assign() or event_new()
@ -1236,7 +1239,7 @@ int event_add(struct event *ev, const struct timeval *timeout);
leaves the event otherwise pending.
@param ev an event struct initialized via event_assign() or event_new()
@return 0 on success, or -1 if an error occurrect.
@return 0 on success, or -1 if an error occurred.
*/
EVENT2_EXPORT_SYMBOL
int event_remove_timer(struct event *ev);
@ -1259,9 +1262,6 @@ int event_del(struct event *);
As event_del(), but never blocks while the event's callback is running
in another thread, even if the event was constructed without the
EV_FINALIZE flag.
THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
BECOMES STABLE.
*/
EVENT2_EXPORT_SYMBOL
int event_del_noblock(struct event *ev);
@ -1269,9 +1269,6 @@ int event_del_noblock(struct event *ev);
As event_del(), but always blocks while the event's callback is running
in another thread, even if the event was constructed with the
EV_FINALIZE flag.
THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
BECOMES STABLE.
*/
EVENT2_EXPORT_SYMBOL
int event_del_block(struct event *ev);
@ -1324,7 +1321,7 @@ struct event *event_base_get_running_event(struct event_base *base);
The event_initialized() function can be used to check if an event has been
initialized.
Warning: This function is only useful for distinguishing a a zeroed-out
Warning: This function is only useful for distinguishing a zeroed-out
piece of memory from an initialized event, it can easily be confused by
uninitialized memory. Thus, it should ONLY be used to distinguish an
initialized event from zero.
@ -1531,7 +1528,7 @@ const struct timeval *event_base_init_common_timeout(struct event_base *base,
Note also that if you are going to call this function, you should do so
before any call to any Libevent function that does allocation.
Otherwise, those funtions will allocate their memory using malloc(), but
Otherwise, those functions will allocate their memory using malloc(), but
then later free it using your provided free_fn.
@param malloc_fn A replacement for malloc.
@ -1570,7 +1567,7 @@ void event_base_dump_events(struct event_base *, FILE *);
@param base the event_base on which to activate the events.
@param fd An fd to active events on.
@param events One or more of EV_{READ,WRITE}.
@param events One or more of EV_{READ,WRITE,TIMEOUT}.
*/
EVENT2_EXPORT_SYMBOL
void event_base_active_by_fd(struct event_base *base, evutil_socket_t fd, short events);
@ -1627,7 +1624,7 @@ int event_base_foreach_event(struct event_base *base, event_base_foreach_event_c
cached time.
Generally, this value will only be cached while actually
processing event callbacks, and may be very inaccuate if your
processing event callbacks, and may be very inaccurate if your
callbacks take a long time to execute.
Returns 0 on success, negative on failure.

View File

@ -78,7 +78,8 @@ struct evdns_base;
* Create a new HTTP server.
*
* @param base (optional) the event base to receive the HTTP events
* @return a pointer to a newly initialized evhttp server structure
* @return a pointer to a newly initialized evhttp server structure or NULL
* on error
* @see evhttp_free()
*/
EVENT2_EXPORT_SYMBOL
@ -516,7 +517,8 @@ enum evhttp_request_kind { EVHTTP_REQUEST, EVHTTP_RESPONSE };
* when the connection closes. It must have no fd set on it.
* @param address the address to which to connect
* @param port the port to connect to
* @return an evhttp_connection object that can be used for making requests
* @return an evhttp_connection object that can be used for making requests or
* NULL on error
*/
EVENT2_EXPORT_SYMBOL
struct evhttp_connection *evhttp_connection_base_bufferevent_new(
@ -636,7 +638,8 @@ void evhttp_request_free(struct evhttp_request *req);
* specified host name resolution will block.
* @param address the address to which to connect
* @param port the port to connect to
* @return an evhttp_connection object that can be used for making requests
* @return an evhttp_connection object that can be used for making requests or
* NULL on error
*/
EVENT2_EXPORT_SYMBOL
struct evhttp_connection *evhttp_connection_base_new(
@ -927,14 +930,14 @@ char *evhttp_uriencode(const char *str, ev_ssize_t size, int space_to_plus);
/**
Helper function to sort of decode a URI-encoded string. Unlike
evhttp_get_decoded_uri, it decodes all plus characters that appear
evhttp_uridecode, it decodes all plus characters that appear
_after_ the first question mark character, but no plusses that occur
before. This is not a good way to decode URIs in whole or in part.
The returned string must be freed by the caller
@deprecated This function is deprecated; you probably want to use
evhttp_get_decoded_uri instead.
evhttp_uridecode instead.
@param uri an encoded URI
@return a newly allocated unencoded URI or NULL on failure

View File

@ -56,8 +56,10 @@ extern "C" {
*
* @param address the address to which the HTTP server should be bound
* @param port the port number on which the HTTP server should listen
* @return an struct evhttp object
* @return a pointer to a newly initialized evhttp server structure
* or NULL on error
*/
EVENT2_EXPORT_SYMBOL
struct evhttp *evhttp_start(const char *address, ev_uint16_t port);
/**
@ -67,6 +69,7 @@ struct evhttp *evhttp_start(const char *address, ev_uint16_t port);
*
* @deprecated It does not allow an event base to be specified
*/
EVENT2_EXPORT_SYMBOL
struct evhttp_connection *evhttp_connection_new(
const char *address, ev_uint16_t port);
@ -76,6 +79,7 @@ struct evhttp_connection *evhttp_connection_new(
*
* @deprecated XXXX Why?
*/
EVENT2_EXPORT_SYMBOL
void evhttp_connection_set_base(struct evhttp_connection *evcon,
struct event_base *base);

View File

@ -97,6 +97,18 @@ typedef void (*evconnlistener_errorcb)(struct evconnlistener *, void *);
* This is only available on Linux and kernel 3.9+
*/
#define LEV_OPT_REUSEABLE_PORT (1u<<7)
/** Flag: Indicates that the listener wants to work only in IPv6 socket.
*
* According to RFC3493 and most Linux distributions, default value is to
* work in IPv4-mapped mode. If there is a requirement to bind same port
* on same ip addresses but different handlers for both IPv4 and IPv6,
* it is required to set IPV6_V6ONLY socket option to be sure that the
* code works as expected without affected by bindv6only sysctl setting in
* system.
*
* This socket option also supported by Windows.
*/
#define LEV_OPT_BIND_IPV6ONLY (1u<<8)
/**
Allocate a new evconnlistener object to listen for incoming TCP connections

View File

@ -27,6 +27,10 @@
#ifndef EVENT2_RPC_H_INCLUDED_
#define EVENT2_RPC_H_INCLUDED_
/* For int types. */
#include <event2/util.h>
#include <event2/visibility.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -178,6 +182,7 @@ EVRPC_STRUCT(rpcname) { \
struct evhttp_request* http_req; \
struct evbuffer* rpc_data; \
}; \
EVENT2_EXPORT_SYMBOL \
int evrpc_send_request_##rpcname(struct evrpc_pool *, \
struct reqstruct *, struct rplystruct *, \
void (*)(struct evrpc_status *, \
@ -187,6 +192,7 @@ int evrpc_send_request_##rpcname(struct evrpc_pool *, \
struct evrpc_pool;
/** use EVRPC_GENERATE instead */
EVENT2_EXPORT_SYMBOL
struct evrpc_request_wrapper *evrpc_make_request_ctx(
struct evrpc_pool *pool, void *request, void *reply,
const char *rpcname,
@ -257,10 +263,13 @@ struct evrpc_request_wrapper *evrpc_make_request_ctx(
#define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req
/** completes the server response to an rpc request */
EVENT2_EXPORT_SYMBOL
void evrpc_request_done(struct evrpc_req_generic *req);
/** accessors for request and reply */
EVENT2_EXPORT_SYMBOL
void *evrpc_get_request(struct evrpc_req_generic *req);
EVENT2_EXPORT_SYMBOL
void *evrpc_get_reply(struct evrpc_req_generic *req);
/** Creates the reply to an RPC request
@ -285,9 +294,10 @@ struct evhttp;
/** Creates a new rpc base from which RPC requests can be received
*
* @param server a pointer to an existing HTTP server
* @return a newly allocated evrpc_base struct
* @return a newly allocated evrpc_base struct or NULL if an error occurred
* @see evrpc_free()
*/
EVENT2_EXPORT_SYMBOL
struct evrpc_base *evrpc_init(struct evhttp *server);
/**
@ -298,6 +308,7 @@ struct evrpc_base *evrpc_init(struct evhttp *server);
* @param base the evrpc_base object to be freed
* @see evrpc_init
*/
EVENT2_EXPORT_SYMBOL
void evrpc_free(struct evrpc_base *base);
/** register RPCs with the HTTP Server
@ -319,10 +330,10 @@ void evrpc_free(struct evrpc_base *base);
#define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \
evrpc_register_generic(base, #name, \
(void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \
(void *(*)(void *))request##_new, NULL, \
(void *(*)(void *))request##_new_with_arg, NULL, \
(void (*)(void *))request##_free, \
(int (*)(void *, struct evbuffer *))request##_unmarshal, \
(void *(*)(void *))reply##_new, NULL, \
(void *(*)(void *))reply##_new_with_arg, NULL, \
(void (*)(void *))reply##_free, \
(int (*)(void *))reply##_complete, \
(void (*)(struct evbuffer *, void *))reply##_marshal)
@ -334,6 +345,7 @@ void evrpc_free(struct evrpc_base *base);
@see EVRPC_REGISTER()
*/
EVENT2_EXPORT_SYMBOL
int evrpc_register_rpc(struct evrpc_base *, struct evrpc *,
void (*)(struct evrpc_req_generic*, void *), void *);
@ -347,6 +359,7 @@ int evrpc_register_rpc(struct evrpc_base *, struct evrpc *,
*/
#define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name)
EVENT2_EXPORT_SYMBOL
int evrpc_unregister_rpc(struct evrpc_base *base, const char *name);
/*
@ -385,6 +398,7 @@ struct evrpc_status;
@returns 0 on success, -1 otherwise.
@see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX()
*/
EVENT2_EXPORT_SYMBOL
int evrpc_make_request(struct evrpc_request_wrapper *ctx);
/** creates an rpc connection pool
@ -394,15 +408,18 @@ int evrpc_make_request(struct evrpc_request_wrapper *ctx);
*
* @param base a pointer to an struct event_based object; can be left NULL
* in singled-threaded applications
* @return a newly allocated struct evrpc_pool object
* @return a newly allocated struct evrpc_pool object or NULL if an error
* occurred
* @see evrpc_pool_free()
*/
EVENT2_EXPORT_SYMBOL
struct evrpc_pool *evrpc_pool_new(struct event_base *base);
/** frees an rpc connection pool
*
* @param pool a pointer to an evrpc_pool allocated via evrpc_pool_new()
* @see evrpc_pool_new()
*/
EVENT2_EXPORT_SYMBOL
void evrpc_pool_free(struct evrpc_pool *pool);
/**
@ -413,6 +430,7 @@ void evrpc_pool_free(struct evrpc_pool *pool);
* @param pool the pool to which to add the connection
* @param evcon the connection to add to the pool.
*/
EVENT2_EXPORT_SYMBOL
void evrpc_pool_add_connection(struct evrpc_pool *pool,
struct evhttp_connection *evcon);
@ -424,6 +442,7 @@ void evrpc_pool_add_connection(struct evrpc_pool *pool,
* @param pool the pool from which to remove the connection
* @param evcon the connection to remove from the pool.
*/
EVENT2_EXPORT_SYMBOL
void evrpc_pool_remove_connection(struct evrpc_pool *pool,
struct evhttp_connection *evcon);
@ -442,6 +461,7 @@ void evrpc_pool_remove_connection(struct evrpc_pool *pool,
* @param timeout_in_secs the number of seconds after which a request should
* timeout and a failure be returned to the callback.
*/
EVENT2_EXPORT_SYMBOL
void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs);
/**
@ -489,6 +509,7 @@ enum EVRPC_HOOK_RESULT {
* @return a handle to the hook so it can be removed later
* @see evrpc_remove_hook()
*/
EVENT2_EXPORT_SYMBOL
void *evrpc_add_hook(void *vbase,
enum EVRPC_HOOK_TYPE hook_type,
int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *),
@ -502,6 +523,7 @@ void *evrpc_add_hook(void *vbase,
* @return 1 on success or 0 on failure
* @see evrpc_add_hook()
*/
EVENT2_EXPORT_SYMBOL
int evrpc_remove_hook(void *vbase,
enum EVRPC_HOOK_TYPE hook_type,
void *handle);
@ -511,8 +533,8 @@ int evrpc_remove_hook(void *vbase,
* @param vbase a pointer to either struct evrpc_base or struct evrpc_pool
* @param ctx the context pointer provided to the original hook call
*/
int
evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res);
EVENT2_EXPORT_SYMBOL
int evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res);
/** adds meta data to request
*
@ -525,6 +547,7 @@ evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res);
* @param data the data to be associated with the key
* @param data_size the size of the data
*/
EVENT2_EXPORT_SYMBOL
void evrpc_hook_add_meta(void *ctx, const char *key,
const void *data, size_t data_size);
@ -538,6 +561,7 @@ void evrpc_hook_add_meta(void *ctx, const char *key,
* @param data_size pointer to the size of the data
* @return 0 on success or -1 on failure
*/
EVENT2_EXPORT_SYMBOL
int evrpc_hook_find_meta(void *ctx, const char *key,
void **data, size_t *data_size);
@ -545,8 +569,10 @@ int evrpc_hook_find_meta(void *ctx, const char *key,
* returns the connection object associated with the request
*
* @param ctx the context provided to the hook call
* @return a pointer to the evhttp_connection object
* @return a pointer to the evhttp_connection object or NULL if an error
* occurred
*/
EVENT2_EXPORT_SYMBOL
struct evhttp_connection *evrpc_hook_get_connection(void *ctx);
/**
@ -556,6 +582,7 @@ struct evhttp_connection *evrpc_hook_get_connection(void *ctx);
@see EVRPC_MAKE_REQUEST()
*/
EVENT2_EXPORT_SYMBOL
int evrpc_send_request_generic(struct evrpc_pool *pool,
void *request, void *reply,
void (*cb)(struct evrpc_status *, void *, void *, void *),
@ -572,8 +599,8 @@ int evrpc_send_request_generic(struct evrpc_pool *pool,
@see EVRPC_REGISTER()
*/
int
evrpc_register_generic(struct evrpc_base *base, const char *name,
EVENT2_EXPORT_SYMBOL
int evrpc_register_generic(struct evrpc_base *base, const char *name,
void (*callback)(struct evrpc_req_generic *, void *), void *cbarg,
void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *),
int (*req_unmarshal)(void *, struct evbuffer *),
@ -582,9 +609,12 @@ evrpc_register_generic(struct evrpc_base *base, const char *name,
void (*rpl_marshal)(struct evbuffer *, void *));
/** accessors for obscure and undocumented functionality */
EVENT2_EXPORT_SYMBOL
struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx);
EVENT2_EXPORT_SYMBOL
void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx,
struct evrpc_pool *pool);
EVENT2_EXPORT_SYMBOL
void evrpc_request_set_cb(struct evrpc_request_wrapper *ctx,
void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg),
void *cb_arg);

View File

@ -38,6 +38,16 @@ extern "C" {
*/
/* Fix so that people don't have to run with <sys/queue.h> */
#ifndef TAILQ_ENTRY
#define EVENT_DEFINED_TQENTRY_
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
#endif /* !TAILQ_ENTRY */
/**
* provides information about the completed RPC request.
*/
@ -93,6 +103,10 @@ struct evrpc {
struct evrpc_base *base;
};
#ifdef EVENT_DEFINED_TQENTRY_
#undef TAILQ_ENTRY
#endif
#ifdef __cplusplus
}
#endif

View File

@ -58,9 +58,6 @@ extern "C" {
#endif
#include <stdarg.h>
#ifdef EVENT__HAVE_NETDB_H
#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#include <netdb.h>
#endif
@ -259,6 +256,7 @@ extern "C" {
#define EV_INT32_MAX INT32_MAX
#define EV_INT32_MIN INT32_MIN
#define EV_UINT16_MAX UINT16_MAX
#define EV_INT16_MIN INT16_MIN
#define EV_INT16_MAX INT16_MAX
#define EV_UINT8_MAX UINT8_MAX
#define EV_INT8_MAX INT8_MAX
@ -425,6 +423,18 @@ int evutil_make_listen_socket_reuseable(evutil_socket_t sock);
EVENT2_EXPORT_SYMBOL
int evutil_make_listen_socket_reuseable_port(evutil_socket_t sock);
/** Set ipv6 only bind socket option to make listener work only in ipv6 sockets.
According to RFC3493 and most Linux distributions, default value for the
sockets is to work in IPv4-mapped mode. In IPv4-mapped mode, it is not possible
to bind same port from different IPv4 and IPv6 handlers.
@param sock The socket to make in ipv6only working mode
@return 0 on success, -1 on failure
*/
EVENT2_EXPORT_SYMBOL
int evutil_make_listen_socket_ipv6only(evutil_socket_t sock);
/** Do platform-specific operations as needed to close a socket upon a
successful execution of one of the exec*() functions.
@ -438,7 +448,8 @@ int evutil_make_socket_closeonexec(evutil_socket_t sock);
socket() or accept().
@param sock The socket to be closed
@return 0 on success, -1 on failure
@return 0 on success (whether the operation is supported or not),
-1 on failure
*/
EVENT2_EXPORT_SYMBOL
int evutil_closesocket(evutil_socket_t sock);
@ -470,6 +481,7 @@ int evutil_socket_geterror(evutil_socket_t sock);
/** Convert a socket error to a string. */
EVENT2_EXPORT_SYMBOL
const char *evutil_socket_error_to_string(int errcode);
#define EVUTIL_INVALID_SOCKET INVALID_SOCKET
#elif defined(EVENT_IN_DOXYGEN_)
/**
@name Socket error functions
@ -493,14 +505,16 @@ const char *evutil_socket_error_to_string(int errcode);
#define evutil_socket_geterror(sock) ...
/** Convert a socket error to a string. */
#define evutil_socket_error_to_string(errcode) ...
#define EVUTIL_INVALID_SOCKET -1
/**@}*/
#else
#else /** !EVENT_IN_DOXYGEN_ && !_WIN32 */
#define EVUTIL_SOCKET_ERROR() (errno)
#define EVUTIL_SET_SOCKET_ERROR(errcode) \
do { errno = (errcode); } while (0)
#define evutil_socket_geterror(sock) (errno)
#define evutil_socket_error_to_string(errcode) (strerror(errcode))
#endif
#define EVUTIL_INVALID_SOCKET -1
#endif /** !_WIN32 */
/**
@ -598,6 +612,12 @@ int evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
/** Replacement for inet_ntop for platforms which lack it. */
EVENT2_EXPORT_SYMBOL
const char *evutil_inet_ntop(int af, const void *src, char *dst, size_t len);
/** Variation of inet_pton that also parses IPv6 scopes. Public for
unit tests. No reason to call this directly.
*/
EVENT2_EXPORT_SYMBOL
int evutil_inet_pton_scope(int af, const char *src, void *dst,
unsigned *indexp);
/** Replacement for inet_pton for platforms which lack it. */
EVENT2_EXPORT_SYMBOL
int evutil_inet_pton(int af, const char *src, void *dst);
@ -842,6 +862,7 @@ int evutil_secure_rng_init(void);
EVENT2_EXPORT_SYMBOL
int evutil_secure_rng_set_urandom_device_file(char *fname);
#if !defined(EVENT__HAVE_ARC4RANDOM) || defined(EVENT__HAVE_ARC4RANDOM_ADDRANDOM)
/** Seed the random number generator with extra random bytes.
You should almost never need to call this function; it should be
@ -858,6 +879,7 @@ int evutil_secure_rng_set_urandom_device_file(char *fname);
*/
EVENT2_EXPORT_SYMBOL
void evutil_secure_rng_add_bytes(const char *dat, size_t datlen);
#endif
#ifdef __cplusplus
}

View File

@ -29,22 +29,39 @@
#include <event2/event-config.h>
#if defined(event_EXPORTS) || defined(event_extra_EXPORTS) || defined(event_core_EXPORTS)
#if defined(event_shared_EXPORTS) || \
defined(event_extra_shared_EXPORTS) || \
defined(event_core_shared_EXPORTS) || \
defined(event_pthreads_shared_EXPORTS) || \
defined(event_openssl_shared_EXPORTS)
# if defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
# define EVENT2_EXPORT_SYMBOL __global
# elif defined __GNUC__
# define EVENT2_EXPORT_SYMBOL __attribute__ ((visibility("default")))
# elif defined(_MSC_VER)
# define EVENT2_EXPORT_SYMBOL extern __declspec(dllexport)
# define EVENT2_EXPORT_SYMBOL __declspec(dllexport)
# else
# define EVENT2_EXPORT_SYMBOL /* unknown compiler */
# endif
#else
# if defined(EVENT__NEED_DLLIMPORT) && defined(_MSC_VER) && !defined(EVENT_BUILDING_REGRESS_TEST)
# define EVENT2_EXPORT_SYMBOL extern __declspec(dllimport)
# else
# define EVENT2_EXPORT_SYMBOL
#else /* event_*_EXPORTS */
# define EVENT2_EXPORT_SYMBOL
#endif /* event_*_EXPORTS */
/** We need to dllimport event_debug_logging_mask_ into event_extra */
#if defined(_MSC_VER)
# if defined(event_core_shared_EXPORTS) /** from core export */
# define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllexport)
# elif defined(event_extra_shared_EXPORTS) || /** from extra import */ \
defined(EVENT_VISIBILITY_WANT_DLLIMPORT)
# define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllimport)
# endif
#endif /* _MSC_VER */
#if !defined(EVENT2_CORE_EXPORT_SYMBOL)
# define EVENT2_CORE_EXPORT_SYMBOL EVENT2_EXPORT_SYMBOL
#endif
#endif /* EVENT2_VISIBILITY_H_INCLUDED_ */

View File

@ -1,4 +1,4 @@
# include/Makefile.am for libevent
# include/include.am for libevent
# Copyright 2000-2007 Niels Provos
# Copyright 2007-2012 Niels Provos and Nick Mathewson
#
@ -11,7 +11,6 @@ EVENT2_EXPORT = \
include/event2/buffer_compat.h \
include/event2/bufferevent.h \
include/event2/bufferevent_compat.h \
include/event2/bufferevent_ssl.h \
include/event2/bufferevent_struct.h \
include/event2/dns.h \
include/event2/dns_compat.h \
@ -33,6 +32,10 @@ EVENT2_EXPORT = \
include/event2/util.h \
include/event2/visibility.h
if OPENSSL
EVENT2_EXPORT += include/event2/bufferevent_ssl.h
endif
## Without the nobase_ prefixing, Automake would strip "include/event2/" from
## the source header filename to derive the installed header filename.
## With nobase_ the installed path is $(includedir)/include/event2/ev*.h.

View File

@ -92,6 +92,7 @@ struct event_iocp_port {
HANDLE *shutdownSemaphore;
};
EVENT2_EXPORT_SYMBOL
const struct win32_extension_fns *event_get_win32_extension_fns_(void);
#else
/* Dummy definition so we can test-compile more things on unix. */
@ -106,12 +107,14 @@ struct event_overlapped {
@param cb The callback that should be invoked once the IO operation has
finished.
*/
EVENT2_EXPORT_SYMBOL
void event_overlapped_init_(struct event_overlapped *, iocp_callback cb);
/** Allocate and return a new evbuffer that supports overlapped IO on a given
socket. The socket must be associated with an IO completion port using
event_iocp_port_associate_.
*/
EVENT2_EXPORT_SYMBOL
struct evbuffer *evbuffer_overlapped_new_(evutil_socket_t fd);
/** XXXX Document (nickm) */
@ -131,6 +134,7 @@ void evbuffer_overlapped_set_fd_(struct evbuffer *buf, evutil_socket_t fd);
@param ol Overlapped object with associated completion callback.
@return 0 on success, -1 on error.
*/
EVENT2_EXPORT_SYMBOL
int evbuffer_launch_read_(struct evbuffer *buf, size_t n, struct event_overlapped *ol);
/** Start writing data from the start of an evbuffer.
@ -145,21 +149,26 @@ int evbuffer_launch_read_(struct evbuffer *buf, size_t n, struct event_overlappe
@param ol Overlapped object with associated completion callback.
@return 0 on success, -1 on error.
*/
EVENT2_EXPORT_SYMBOL
int evbuffer_launch_write_(struct evbuffer *buf, ev_ssize_t n, struct event_overlapped *ol);
/** XXX document */
EVENT2_EXPORT_SYMBOL
void evbuffer_commit_read_(struct evbuffer *, ev_ssize_t);
EVENT2_EXPORT_SYMBOL
void evbuffer_commit_write_(struct evbuffer *, ev_ssize_t);
/** Create an IOCP, and launch its worker threads. Internal use only.
This interface is unstable, and will change.
*/
EVENT2_EXPORT_SYMBOL
struct event_iocp_port *event_iocp_port_launch_(int n_cpus);
/** Associate a file descriptor with an iocp, such that overlapped IO on the
fd will happen on one of the iocp's worker threads.
*/
EVENT2_EXPORT_SYMBOL
int event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd,
ev_uintptr_t key);
@ -169,22 +178,27 @@ int event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd,
0. Otherwise, return -1. If you get a -1 return value, it is safe to call
this function again.
*/
EVENT2_EXPORT_SYMBOL
int event_iocp_shutdown_(struct event_iocp_port *port, long waitMsec);
/* FIXME document. */
EVENT2_EXPORT_SYMBOL
int event_iocp_activate_overlapped_(struct event_iocp_port *port,
struct event_overlapped *o,
ev_uintptr_t key, ev_uint32_t n_bytes);
struct event_base;
/* FIXME document. */
EVENT2_EXPORT_SYMBOL
struct event_iocp_port *event_base_get_iocp_(struct event_base *base);
/* FIXME document. */
EVENT2_EXPORT_SYMBOL
int event_base_start_iocp_(struct event_base *base, int n_cpus);
void event_base_stop_iocp_(struct event_base *base);
/* FIXME document. */
EVENT2_EXPORT_SYMBOL
struct bufferevent *bufferevent_async_new_(struct event_base *base,
evutil_socket_t fd, int options);

View File

@ -37,6 +37,7 @@
#endif
#include <sys/queue.h>
#include <sys/event.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@ -50,7 +51,10 @@
/* Some platforms apparently define the udata field of struct kevent as
* intptr_t, whereas others define it as void*. There doesn't seem to be an
* easy way to tell them apart via autoconf, so we need to use OS macros. */
#if defined(EVENT__HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) && !defined(__CloudABI__)
#if defined(__NetBSD__)
#define PTR_TO_UDATA(x) ((typeof(((struct kevent *)0)->udata))(x))
#define INT_TO_UDATA(x) ((typeof(((struct kevent *)0)->udata))(intptr_t)(x))
#elif defined(EVENT__HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) && !defined(__CloudABI__)
#define PTR_TO_UDATA(x) ((intptr_t)(x))
#define INT_TO_UDATA(x) ((intptr_t)(x))
#else
@ -62,6 +66,7 @@
#include "log-internal.h"
#include "evmap-internal.h"
#include "event2/thread.h"
#include "event2/util.h"
#include "evthread-internal.h"
#include "changelist-internal.h"
@ -207,9 +212,17 @@ kq_build_changes_list(const struct event_changelist *changelist,
struct event_change *in_ch = &changelist->changes[i];
struct kevent *out_ch;
if (n_changes >= kqop->changes_size - 1) {
int newsize = kqop->changes_size * 2;
int newsize;
struct kevent *newchanges;
if (kqop->changes_size > INT_MAX / 2 ||
(size_t)kqop->changes_size * 2 > EV_SIZE_MAX /
sizeof(struct kevent)) {
event_warnx("%s: int overflow", __func__);
return (-1);
}
newsize = kqop->changes_size * 2;
newchanges = mm_realloc(kqop->changes,
newsize * sizeof(struct kevent));
if (newchanges == NULL) {

View File

@ -35,6 +35,7 @@
#define _WIN32_WINNT 0x0403
#endif
#include <winsock2.h>
#include <winerror.h>
#include <ws2tcpip.h>
#include <mswsock.h>
#endif
@ -245,6 +246,11 @@ evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
goto err;
}
if (flags & LEV_OPT_BIND_IPV6ONLY) {
if (evutil_make_listen_socket_ipv6only(fd) < 0)
goto err;
}
if (sa) {
if (bind(fd, sa, socklen)<0)
goto err;
@ -421,11 +427,14 @@ listener_read_cb(evutil_socket_t fd, short what, void *p)
if (lev->refcnt == 1) {
int freed = listener_decref_and_unlock(lev);
EVUTIL_ASSERT(freed);
evutil_closesocket(new_fd);
return;
}
--lev->refcnt;
if (!lev->enabled) {
/* the callback could have disabled the listener */
UNLOCK(lev);
return;
}
}
err = evutil_socket_geterror(fd);
if (EVUTIL_ERR_ACCEPT_RETRIABLE(err)) {
@ -504,7 +513,7 @@ new_accepting_socket(struct evconnlistener_iocp *lev, int family)
return NULL;
event_overlapped_init_(&res->overlapped, accepted_socket_cb);
res->s = INVALID_SOCKET;
res->s = EVUTIL_INVALID_SOCKET;
res->lev = lev;
res->buflen = buflen;
res->family = family;
@ -522,7 +531,7 @@ static void
free_and_unlock_accepting_socket(struct accepting_socket *as)
{
/* requires lock. */
if (as->s != INVALID_SOCKET)
if (as->s != EVUTIL_INVALID_SOCKET)
closesocket(as->s);
LeaveCriticalSection(&as->lock);
@ -542,7 +551,7 @@ start_accepting(struct accepting_socket *as)
if (!as->lev->base.enabled)
return 0;
if (s == INVALID_SOCKET) {
if (s == EVUTIL_INVALID_SOCKET) {
error = WSAGetLastError();
goto report_err;
}
@ -589,7 +598,7 @@ stop_accepting(struct accepting_socket *as)
{
/* requires lock. */
SOCKET s = as->s;
as->s = INVALID_SOCKET;
as->s = EVUTIL_INVALID_SOCKET;
closesocket(s);
}
@ -631,7 +640,7 @@ accepted_socket_invoke_user_cb(struct event_callback *dcb, void *arg)
&socklen_remote);
sock = as->s;
cb = lev->cb;
as->s = INVALID_SOCKET;
as->s = EVUTIL_INVALID_SOCKET;
/* We need to call this so getsockname, getpeername, and
* shutdown work correctly on the accepted socket. */
@ -679,7 +688,7 @@ accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, i
free_and_unlock_accepting_socket(as);
listener_decref_and_unlock(lev);
return;
} else if (as->s == INVALID_SOCKET) {
} else if (as->s == EVUTIL_INVALID_SOCKET) {
/* This is okay; we were disabled by iocp_listener_disable. */
LeaveCriticalSection(&as->lock);
} else {
@ -717,7 +726,7 @@ iocp_listener_enable(struct evconnlistener *lev)
if (!as)
continue;
EnterCriticalSection(&as->lock);
if (!as->free_on_cb && as->s == INVALID_SOCKET)
if (!as->free_on_cb && as->s == EVUTIL_INVALID_SOCKET)
start_accepting(as);
LeaveCriticalSection(&as->lock);
}
@ -739,7 +748,7 @@ iocp_listener_disable_impl(struct evconnlistener *lev, int shutdown)
if (!as)
continue;
EnterCriticalSection(&as->lock);
if (!as->free_on_cb && as->s != INVALID_SOCKET) {
if (!as->free_on_cb && as->s != EVUTIL_INVALID_SOCKET) {
if (shutdown)
as->free_on_cb = 1;
stop_accepting(as);

View File

@ -29,6 +29,10 @@
#include "event2/util.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
#define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
#define EV_NORETURN __attribute__((noreturn))
@ -39,32 +43,35 @@
#define EVENT_ERR_ABORT_ ((int)0xdeaddead)
#define USE_GLOBAL_FOR_DEBUG_LOGGING
#if !defined(EVENT__DISABLE_DEBUG_MODE) || defined(USE_DEBUG)
#define EVENT_DEBUG_LOGGING_ENABLED
#endif
#ifdef EVENT_DEBUG_LOGGING_ENABLED
#ifdef USE_GLOBAL_FOR_DEBUG_LOGGING
extern ev_uint32_t event_debug_logging_mask_;
EVENT2_CORE_EXPORT_SYMBOL extern ev_uint32_t event_debug_logging_mask_;
#define event_debug_get_logging_mask_() (event_debug_logging_mask_)
#else
ev_uint32_t event_debug_get_logging_mask_(void);
#endif
#else
#define event_debug_get_logging_mask_() (0)
#endif
EVENT2_EXPORT_SYMBOL
void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN;
EVENT2_EXPORT_SYMBOL
void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2);
EVENT2_EXPORT_SYMBOL
void event_sock_err(int eval, evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(3,4) EV_NORETURN;
EVENT2_EXPORT_SYMBOL
void event_sock_warn(evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(2,3);
EVENT2_EXPORT_SYMBOL
void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN;
EVENT2_EXPORT_SYMBOL
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
EVENT2_EXPORT_SYMBOL
void event_msgx(const char *fmt, ...) EV_CHECK_FMT(1,2);
EVENT2_EXPORT_SYMBOL
void event_debugx_(const char *fmt, ...) EV_CHECK_FMT(1,2);
EVENT2_EXPORT_SYMBOL
void event_logv_(int severity, const char *errstr, const char *fmt, va_list ap)
EV_CHECK_FMT(3,0);
@ -80,4 +87,8 @@ void event_logv_(int severity, const char *errstr, const char *fmt, va_list ap)
#undef EV_CHECK_FMT
#ifdef __cplusplus
}
#endif
#endif /* LOG_INTERNAL_H_INCLUDED_ */

View File

@ -69,16 +69,7 @@ static event_fatal_cb fatal_fn = NULL;
#define DEFAULT_MASK 0
#endif
#ifdef USE_GLOBAL_FOR_DEBUG_LOGGING
ev_uint32_t event_debug_logging_mask_ = DEFAULT_MASK;
#else
static ev_uint32_t event_debug_logging_mask_ = DEFAULT_MASK;
ev_uint32_t
event_debug_get_logging_mask_(void)
{
return event_debug_logging_mask_;
}
#endif
EVENT2_EXPORT_SYMBOL ev_uint32_t event_debug_logging_mask_ = DEFAULT_MASK;
#endif /* EVENT_DEBUG_LOGGING_ENABLED */
void

View File

@ -0,0 +1,22 @@
# Check if the function is available.
# HAVE_XXX will be defined if yes.
# $1: the name of function
# $2: the headers in where the function declared
AC_DEFUN([AX_CHECK_DECL_EX], [dnl
AS_IF([test "x$2" = "x"], [AC_MSG_ERROR([header not privided])])
AS_VAR_PUSHDEF([have_func_var], [HAVE_[]m4_toupper($1)])
AC_CHECK_DECL([$1],dnl
[AC_DEFINE([have_func_var], [1], [Define to 1 if you have the `$1' function.])],,dnl
[$2]dnl
)
AS_VAR_POPDEF([have_func_var])dnl
])
AC_DEFUN([AX_CHECK_DECLS_EX], [dnl
AS_IF([test "x$2" = "x"], [AC_MSG_ERROR([header not privided])])
m4_foreach([decl],dnl
m4_split(m4_normalize($1)),dnl
[AX_CHECK_DECL_EX([decl], [$2])]dnl
)
])

View File

@ -0,0 +1,600 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html
# ===========================================================================
#
# SYNOPSIS
#
# DX_INIT_DOXYGEN(PROJECT-NAME, [DOXYFILE-PATH], [OUTPUT-DIR], ...)
# DX_DOXYGEN_FEATURE(ON|OFF)
# DX_DOT_FEATURE(ON|OFF)
# DX_HTML_FEATURE(ON|OFF)
# DX_CHM_FEATURE(ON|OFF)
# DX_CHI_FEATURE(ON|OFF)
# DX_MAN_FEATURE(ON|OFF)
# DX_RTF_FEATURE(ON|OFF)
# DX_XML_FEATURE(ON|OFF)
# DX_PDF_FEATURE(ON|OFF)
# DX_PS_FEATURE(ON|OFF)
#
# DESCRIPTION
#
# The DX_*_FEATURE macros control the default setting for the given
# Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for
# generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML
# help (for MS users), 'CHI' for generating a separate .chi file by the
# .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate
# output formats. The environment variable DOXYGEN_PAPER_SIZE may be
# specified to override the default 'a4wide' paper size.
#
# By default, HTML, PDF and PS documentation is generated as this seems to
# be the most popular and portable combination. MAN pages created by
# Doxygen are usually problematic, though by picking an appropriate subset
# and doing some massaging they might be better than nothing. CHM and RTF
# are specific for MS (note that you can't generate both HTML and CHM at
# the same time). The XML is rather useless unless you apply specialized
# post-processing to it.
#
# The macros mainly control the default state of the feature. The use can
# override the default by specifying --enable or --disable. The macros
# ensure that contradictory flags are not given (e.g.,
# --enable-doxygen-html and --enable-doxygen-chm,
# --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each
# feature will be automatically disabled (with a warning) if the required
# programs are missing.
#
# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN
# with the following parameters: a one-word name for the project for use
# as a filename base etc., an optional configuration file name (the
# default is '$(srcdir)/Doxyfile', the same as Doxygen's default), and an
# optional output directory name (the default is 'doxygen-doc'). To run
# doxygen multiple times for different configuration files and output
# directories provide more parameters: the second, forth, sixth, etc
# parameter are configuration file names and the third, fifth, seventh,
# etc parameter are output directories. No checking is done to catch
# duplicates.
#
# Automake Support
#
# The DX_RULES substitution can be used to add all needed rules to the
# Makefile. Note that this is a substitution without being a variable:
# only the @DX_RULES@ syntax will work.
#
# The provided targets are:
#
# doxygen-doc: Generate all doxygen documentation.
#
# doxygen-run: Run doxygen, which will generate some of the
# documentation (HTML, CHM, CHI, MAN, RTF, XML)
# but will not do the post processing required
# for the rest of it (PS, PDF).
#
# doxygen-ps: Generate doxygen PostScript documentation.
#
# doxygen-pdf: Generate doxygen PDF documentation.
#
# Note that by default these are not integrated into the automake targets.
# If doxygen is used to generate man pages, you can achieve this
# integration by setting man3_MANS to the list of man pages generated and
# then adding the dependency:
#
# $(man3_MANS): doxygen-doc
#
# This will cause make to run doxygen and generate all the documentation.
#
# The following variable is intended for use in Makefile.am:
#
# DX_CLEANFILES = everything to clean.
#
# Then add this variable to MOSTLYCLEANFILES.
#
# LICENSE
#
# Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>
# Copyright (c) 2015 Olaf Mandel <olaf@mandel.name>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 24
## ----------##
## Defaults. ##
## ----------##
DX_ENV=""
AC_DEFUN([DX_FEATURE_doc], OFF)
AC_DEFUN([DX_FEATURE_dot], OFF)
AC_DEFUN([DX_FEATURE_man], OFF)
AC_DEFUN([DX_FEATURE_html], ON)
AC_DEFUN([DX_FEATURE_chm], OFF)
AC_DEFUN([DX_FEATURE_chi], OFF)
AC_DEFUN([DX_FEATURE_rtf], OFF)
AC_DEFUN([DX_FEATURE_xml], OFF)
AC_DEFUN([DX_FEATURE_pdf], ON)
AC_DEFUN([DX_FEATURE_ps], ON)
## --------------- ##
## Private macros. ##
## --------------- ##
# DX_ENV_APPEND(VARIABLE, VALUE)
# ------------------------------
# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen and add it
# as a substitution (but not a Makefile variable). The substitution
# is skipped if the variable name is VERSION.
AC_DEFUN([DX_ENV_APPEND],
[AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])dnl
m4_if([$1], [VERSION], [], [AC_SUBST([$1], [$2])dnl
AM_SUBST_NOTMAKE([$1])])dnl
])
# DX_DIRNAME_EXPR
# ---------------
# Expand into a shell expression prints the directory part of a path.
AC_DEFUN([DX_DIRNAME_EXPR],
[[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
# -------------------------------------
# Expands according to the M4 (static) status of the feature.
AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
# ----------------------------------
# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
AC_DEFUN([DX_REQUIRE_PROG], [
AC_PATH_TOOL([$1], [$2])
if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
if test "x$2" = "xdoxygen"; then
AC_MSG_ERROR([$2 not found - will not DX_CURRENT_DESCRIPTION])
else
AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
fi
AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
fi
])
# DX_TEST_FEATURE(FEATURE)
# ------------------------
# Expand to a shell expression testing whether the feature is active.
AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
# -------------------------------------------------
# Verify that a required features has the right state before trying to turn on
# the DX_CURRENT_FEATURE.
AC_DEFUN([DX_CHECK_DEPEND], [
test "$DX_FLAG_$1" = "$2" \
|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
requires, contradicts) doxygen-$1])
])
# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
# ----------------------------------------------------------
# Turn off the DX_CURRENT_FEATURE if the required feature is off.
AC_DEFUN([DX_CLEAR_DEPEND], [
test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
])
# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
# CHECK_DEPEND, CLEAR_DEPEND,
# REQUIRE, DO-IF-ON, DO-IF-OFF)
# --------------------------------------------
# Parse the command-line option controlling a feature. CHECK_DEPEND is called
# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
# otherwise CLEAR_DEPEND is called to turn off the default state if a required
# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
AC_DEFUN([DX_ARG_ABLE], [
AC_DEFUN([DX_CURRENT_FEATURE], [$1])
AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
AC_ARG_ENABLE(doxygen-$1,
[AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
[--enable-doxygen-$1]),
DX_IF_FEATURE([$1], [don't $2], [$2]))],
[
case "$enableval" in
#(
y|Y|yes|Yes|YES)
AC_SUBST([DX_FLAG_$1], 1)
$3
;; #(
n|N|no|No|NO)
AC_SUBST([DX_FLAG_$1], 0)
;; #(
*)
AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
;;
esac
], [
AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
$4
])
if DX_TEST_FEATURE([$1]); then
$5
:
fi
if DX_TEST_FEATURE([$1]); then
$6
:
else
$7
:
fi
])
## -------------- ##
## Public macros. ##
## -------------- ##
# DX_XXX_FEATURE(DEFAULT_STATE)
# -----------------------------
AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])])
AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])])
AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])])
AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])])
AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])])
AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])])
AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])])
AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])])
# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR], ...)
# --------------------------------------------------------------
# PROJECT also serves as the base name for the documentation files.
# The default CONFIG-FILE is "$(srcdir)/Doxyfile" and OUTPUT-DOC-DIR is
# "doxygen-doc".
# More arguments are interpreted as interleaved CONFIG-FILE and
# OUTPUT-DOC-DIR values.
AC_DEFUN([DX_INIT_DOXYGEN], [
# Files:
AC_SUBST([DX_PROJECT], [$1])
AC_SUBST([DX_CONFIG], ['ifelse([$2], [], [$(srcdir)/Doxyfile], [$2])'])
AC_SUBST([DX_DOCDIR], ['ifelse([$3], [], [doxygen-doc], [$3])'])
m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 4, m4_count($@), 2,
[AC_SUBST([DX_CONFIG]m4_eval(DX_i[/2]),
'm4_default_nblank_quoted(m4_argn(DX_i, $@),
[$(srcdir)/Doxyfile])')])])dnl
m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 5, m4_count($@,), 2,
[AC_SUBST([DX_DOCDIR]m4_eval([(]DX_i[-1)/2]),
'm4_default_nblank_quoted(m4_argn(DX_i, $@),
[doxygen-doc])')])])dnl
m4_define([DX_loop], m4_dquote(m4_if(m4_eval(3 < m4_count($@)), 1,
[m4_for([DX_i], 4, m4_count($@), 2, [, m4_eval(DX_i[/2])])],
[])))dnl
# Environment variables used inside doxygen.cfg:
DX_ENV_APPEND(SRCDIR, $srcdir)
DX_ENV_APPEND(PROJECT, $DX_PROJECT)
DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
# Doxygen itself:
DX_ARG_ABLE(doc, [generate any doxygen documentation],
[],
[],
[DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
DX_REQUIRE_PROG([DX_PERL], perl)],
[DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
# Dot for graphics:
DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_DOT], dot)],
[DX_ENV_APPEND(HAVE_DOT, YES)
DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
[DX_ENV_APPEND(HAVE_DOT, NO)])
# Man pages generation:
DX_ARG_ABLE(man, [generate doxygen manual pages],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_MAN, YES)],
[DX_ENV_APPEND(GENERATE_MAN, NO)])
# RTF file generation:
DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_RTF, YES)],
[DX_ENV_APPEND(GENERATE_RTF, NO)])
# XML file generation:
DX_ARG_ABLE(xml, [generate doxygen XML documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_XML, YES)],
[DX_ENV_APPEND(GENERATE_XML, NO)])
# (Compressed) HTML help generation:
DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_HHC], hhc)],
[DX_ENV_APPEND(HHC_PATH, $DX_HHC)
DX_ENV_APPEND(GENERATE_HTML, YES)
DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
[DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
# Separate CHI file generation.
DX_ARG_ABLE(chi, [generate doxygen separate compressed HTML help index file],
[DX_CHECK_DEPEND(chm, 1)],
[DX_CLEAR_DEPEND(chm, 1)],
[],
[DX_ENV_APPEND(GENERATE_CHI, YES)],
[DX_ENV_APPEND(GENERATE_CHI, NO)])
# Plain HTML pages generation:
DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
[DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
[DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
[],
[DX_ENV_APPEND(GENERATE_HTML, YES)],
[DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
# PostScript file generation:
DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_LATEX], latex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_DVIPS], dvips)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# PDF file generation:
DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# LaTeX generation for PS and/or PDF:
if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
DX_ENV_APPEND(GENERATE_LATEX, YES)
else
DX_ENV_APPEND(GENERATE_LATEX, NO)
fi
# Paper size for PS and/or PDF:
AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
[a4wide (default), a4, letter, legal or executive])
case "$DOXYGEN_PAPER_SIZE" in
#(
"")
AC_SUBST(DOXYGEN_PAPER_SIZE, "")
;; #(
a4wide|a4|letter|legal|executive)
DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
;; #(
*)
AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
;;
esac
# Rules:
AS_IF([[test $DX_FLAG_html -eq 1]],
[[DX_SNIPPET_html="## ------------------------------- ##
## Rules specific for HTML output. ##
## ------------------------------- ##
DX_CLEAN_HTML = \$(DX_DOCDIR)/html]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/html]])[
"]],
[[DX_SNIPPET_html=""]])
AS_IF([[test $DX_FLAG_chi -eq 1]],
[[DX_SNIPPET_chi="
DX_CLEAN_CHI = \$(DX_DOCDIR)/\$(PACKAGE).chi]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).chi]])["]],
[[DX_SNIPPET_chi=""]])
AS_IF([[test $DX_FLAG_chm -eq 1]],
[[DX_SNIPPET_chm="## ------------------------------ ##
## Rules specific for CHM output. ##
## ------------------------------ ##
DX_CLEAN_CHM = \$(DX_DOCDIR)/chm]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/chm]])[\
${DX_SNIPPET_chi}
"]],
[[DX_SNIPPET_chm=""]])
AS_IF([[test $DX_FLAG_man -eq 1]],
[[DX_SNIPPET_man="## ------------------------------ ##
## Rules specific for MAN output. ##
## ------------------------------ ##
DX_CLEAN_MAN = \$(DX_DOCDIR)/man]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/man]])[
"]],
[[DX_SNIPPET_man=""]])
AS_IF([[test $DX_FLAG_rtf -eq 1]],
[[DX_SNIPPET_rtf="## ------------------------------ ##
## Rules specific for RTF output. ##
## ------------------------------ ##
DX_CLEAN_RTF = \$(DX_DOCDIR)/rtf]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/rtf]])[
"]],
[[DX_SNIPPET_rtf=""]])
AS_IF([[test $DX_FLAG_xml -eq 1]],
[[DX_SNIPPET_xml="## ------------------------------ ##
## Rules specific for XML output. ##
## ------------------------------ ##
DX_CLEAN_XML = \$(DX_DOCDIR)/xml]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/xml]])[
"]],
[[DX_SNIPPET_xml=""]])
AS_IF([[test $DX_FLAG_ps -eq 1]],
[[DX_SNIPPET_ps="## ----------------------------- ##
## Rules specific for PS output. ##
## ----------------------------- ##
DX_CLEAN_PS = \$(DX_DOCDIR)/\$(PACKAGE).ps]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps]])[
DX_PS_GOAL = doxygen-ps
doxygen-ps: \$(DX_CLEAN_PS)
]m4_foreach([DX_i], [DX_loop],
[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
\$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
\$(DX_LATEX) refman.tex; \\
\$(DX_MAKEINDEX) refman.idx; \\
\$(DX_LATEX) refman.tex; \\
countdown=5; \\
while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
refman.log > /dev/null 2>&1 \\
&& test \$\$countdown -gt 0; do \\
\$(DX_LATEX) refman.tex; \\
countdown=\`expr \$\$countdown - 1\`; \\
done; \\
\$(DX_DVIPS) -o ../\$(PACKAGE).ps refman.dvi
]])["]],
[[DX_SNIPPET_ps=""]])
AS_IF([[test $DX_FLAG_pdf -eq 1]],
[[DX_SNIPPET_pdf="## ------------------------------ ##
## Rules specific for PDF output. ##
## ------------------------------ ##
DX_CLEAN_PDF = \$(DX_DOCDIR)/\$(PACKAGE).pdf]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf]])[
DX_PDF_GOAL = doxygen-pdf
doxygen-pdf: \$(DX_CLEAN_PDF)
]m4_foreach([DX_i], [DX_loop],
[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
\$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
\$(DX_PDFLATEX) refman.tex; \\
\$(DX_MAKEINDEX) refman.idx; \\
\$(DX_PDFLATEX) refman.tex; \\
countdown=5; \\
while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
refman.log > /dev/null 2>&1 \\
&& test \$\$countdown -gt 0; do \\
\$(DX_PDFLATEX) refman.tex; \\
countdown=\`expr \$\$countdown - 1\`; \\
done; \\
mv refman.pdf ../\$(PACKAGE).pdf
]])["]],
[[DX_SNIPPET_pdf=""]])
AS_IF([[test $DX_FLAG_ps -eq 1 -o $DX_FLAG_pdf -eq 1]],
[[DX_SNIPPET_latex="## ------------------------------------------------- ##
## Rules specific for LaTeX (shared for PS and PDF). ##
## ------------------------------------------------- ##
DX_V_LATEX = \$(_DX_v_LATEX_\$(V))
_DX_v_LATEX_ = \$(_DX_v_LATEX_\$(AM_DEFAULT_VERBOSITY))
_DX_v_LATEX_0 = @echo \" LATEX \" \$][@;
DX_CLEAN_LATEX = \$(DX_DOCDIR)/latex]dnl
m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
\$(DX_DOCDIR]DX_i[)/latex]])[
"]],
[[DX_SNIPPET_latex=""]])
AS_IF([[test $DX_FLAG_doc -eq 1]],
[[DX_SNIPPET_doc="## --------------------------------- ##
## Format-independent Doxygen rules. ##
## --------------------------------- ##
${DX_SNIPPET_html}\
${DX_SNIPPET_chm}\
${DX_SNIPPET_man}\
${DX_SNIPPET_rtf}\
${DX_SNIPPET_xml}\
${DX_SNIPPET_ps}\
${DX_SNIPPET_pdf}\
${DX_SNIPPET_latex}\
DX_V_DXGEN = \$(_DX_v_DXGEN_\$(V))
_DX_v_DXGEN_ = \$(_DX_v_DXGEN_\$(AM_DEFAULT_VERBOSITY))
_DX_v_DXGEN_0 = @echo \" DXGEN \" \$<;
.PHONY: doxygen-run doxygen-doc \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
.INTERMEDIATE: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
doxygen-run:]m4_foreach([DX_i], [DX_loop],
[[ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag]])[
doxygen-doc: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
]m4_foreach([DX_i], [DX_loop],
[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag: \$(DX_CONFIG]DX_i[) \$(pkginclude_HEADERS)
\$(A""M_V_at)rm -rf \$(DX_DOCDIR]DX_i[)
\$(DX_V_DXGEN)\$(DX_ENV) DOCDIR=\$(DX_DOCDIR]DX_i[) \$(DX_DOXYGEN) \$(DX_CONFIG]DX_i[)
\$(A""M_V_at)echo Timestamp >\$][@
]])dnl
[DX_CLEANFILES = \\]
m4_foreach([DX_i], [DX_loop],
[[ \$(DX_DOCDIR]DX_i[)/doxygen_sqlite3.db \\
\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \\
]])dnl
[ -r \\
\$(DX_CLEAN_HTML) \\
\$(DX_CLEAN_CHM) \\
\$(DX_CLEAN_CHI) \\
\$(DX_CLEAN_MAN) \\
\$(DX_CLEAN_RTF) \\
\$(DX_CLEAN_XML) \\
\$(DX_CLEAN_PS) \\
\$(DX_CLEAN_PDF) \\
\$(DX_CLEAN_LATEX)
DX_INSTALL_DOCS = \\
\$(DX_CLEAN_HTML) \\
\$(DX_CLEAN_CHM) \\
\$(DX_CLEAN_CHI) \\
\$(DX_CLEAN_RTF) \\
\$(DX_CLEAN_XML) \\
\$(DX_CLEAN_PS) \\
\$(DX_CLEAN_PDF) \\
\$(DX_CLEAN_LATEX)
"]],
[[DX_SNIPPET_doc=""]])
AC_SUBST([DX_RULES],
["${DX_SNIPPET_doc}"])dnl
AM_SUBST_NOTMAKE([DX_RULES])
#For debugging:
#echo DX_FLAG_doc=$DX_FLAG_doc
#echo DX_FLAG_dot=$DX_FLAG_dot
#echo DX_FLAG_man=$DX_FLAG_man
#echo DX_FLAG_html=$DX_FLAG_html
#echo DX_FLAG_chm=$DX_FLAG_chm
#echo DX_FLAG_chi=$DX_FLAG_chi
#echo DX_FLAG_rtf=$DX_FLAG_rtf
#echo DX_FLAG_xml=$DX_FLAG_xml
#echo DX_FLAG_pdf=$DX_FLAG_pdf
#echo DX_FLAG_ps=$DX_FLAG_ps
#echo DX_ENV=$DX_ENV
])

View File

@ -39,10 +39,19 @@ case "$enable_openssl" in
done
;;
esac
CPPFLAGS_SAVE=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $OPENSSL_INCS"
AC_CHECK_HEADERS([openssl/ssl.h], [], [have_openssl=no])
CPPFLAGS=$CPPFLAGS_SAVE
AC_SUBST(OPENSSL_INCS)
AC_SUBST(OPENSSL_LIBS)
case "$have_openssl" in
yes) AC_DEFINE(HAVE_OPENSSL, 1, [Define if the system has openssl]) ;;
*) AC_MSG_ERROR([openssl is a must but can not be found. You should add the \
directory containing `openssl.pc' to the `PKG_CONFIG_PATH' environment variable, \
or set `CFLAGS' and `LDFLAGS' directly for openssl, or use `--disable-openssl' \
to disable support for openssl encryption])
;;
esac
;;
esac

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