Merge local changes from libevent 2.1.8 and 2.1.12
This commit is contained in:
parent
6a94664822
commit
7e68cdd730
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile.inc,v 1.3 2017/01/31 23:17:39 christos Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.4 2021/04/07 03:36:48 christos Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
|
@ -10,7 +10,7 @@ CPPFLAGS+= -I${LIBEVENT_DIST} -I${LIBEVENT_DIR}/include
|
|||
CPPFLAGS+= -I${LIBEVENT_DIST}/include
|
||||
|
||||
SHLIB_MAJOR= 4
|
||||
SHLIB_MINOR= 1
|
||||
SHLIB_MINOR= 2
|
||||
|
||||
WARNS?= 4
|
||||
|
||||
|
|
|
@ -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 = YES
|
||||
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)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: buffer.c,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: buffer.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -28,7 +29,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: buffer.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: buffer.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -98,6 +99,7 @@ __RCSID("$NetBSD: buffer.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
|||
#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
|
||||
|
@ -525,8 +527,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);
|
||||
|
@ -706,13 +708,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;
|
||||
|
@ -1149,7 +1155,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;
|
||||
}
|
||||
|
@ -1301,7 +1307,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);
|
||||
|
@ -1419,9 +1425,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)
|
||||
|
@ -1537,11 +1545,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;
|
||||
|
||||
|
@ -1827,6 +1835,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;
|
||||
}
|
||||
|
@ -1880,7 +1892,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;
|
||||
|
@ -2230,11 +2242,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)
|
||||
|
@ -2468,7 +2482,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);
|
||||
|
@ -3201,7 +3215,6 @@ evbuffer_add_file_segment(struct evbuffer *buf,
|
|||
}
|
||||
}
|
||||
}
|
||||
++seg->refcnt;
|
||||
EVLOCK_UNLOCK(seg->lock, 0);
|
||||
|
||||
if (buf->freeze_end)
|
||||
|
@ -3265,6 +3278,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);
|
||||
|
@ -3296,7 +3312,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);
|
||||
|
@ -3307,10 +3323,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 *
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: bufferevent-internal.h,v 1.3 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: bufferevent-internal.h,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -307,6 +308,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)
|
||||
|
@ -315,13 +323,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
|
||||
|
@ -348,16 +359,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
|
||||
|
@ -366,17 +380,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
|
||||
|
@ -400,6 +418,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);
|
||||
|
||||
/* =========
|
||||
|
@ -409,19 +428,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) \
|
||||
|
@ -466,11 +499,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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: bufferevent.c,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: bufferevent.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos, Nick Mathewson
|
||||
|
@ -28,7 +29,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bufferevent.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: bufferevent.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -69,8 +70,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);
|
||||
|
@ -81,8 +81,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))
|
||||
|
@ -93,8 +92,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);
|
||||
|
@ -105,8 +103,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))
|
||||
|
@ -114,6 +111,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. */
|
||||
|
@ -150,6 +169,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;
|
||||
|
@ -190,6 +210,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;
|
||||
|
@ -224,8 +245,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) {
|
||||
|
@ -233,6 +253,7 @@ bufferevent_run_readcb_(struct bufferevent *bufev, int options)
|
|||
SCHEDULE_DEFERRED(p);
|
||||
} else {
|
||||
bufev->readcb(bufev, bufev->cbarg);
|
||||
bufferevent_inbuf_wm_check(bufev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,8 +261,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) {
|
||||
|
@ -269,8 +289,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) {
|
||||
|
@ -300,14 +319,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;
|
||||
|
@ -319,7 +336,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
|
||||
|
@ -330,20 +348,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_(
|
||||
|
@ -364,6 +376,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
|
||||
|
@ -462,8 +485,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;
|
||||
|
||||
|
@ -477,6 +499,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;
|
||||
|
@ -536,8 +560,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;
|
||||
|
@ -560,6 +583,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;
|
||||
|
@ -573,8 +598,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) {
|
||||
|
@ -659,8 +683,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;
|
||||
}
|
||||
|
@ -686,8 +709,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];
|
||||
|
@ -730,8 +752,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);
|
||||
|
@ -797,8 +818,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
|
||||
|
@ -854,6 +874,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;
|
||||
}
|
||||
|
@ -867,6 +889,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;
|
||||
}
|
||||
|
@ -874,8 +898,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);
|
||||
|
@ -951,8 +974,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))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bufferevent_openssl.c,v 1.1.1.3 2021/04/07 02:43:14 christos Exp $ */
|
||||
/* $NetBSD: bufferevent_openssl.c,v 1.2 2021/04/07 03:36:48 christos Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bufferevent_openssl.c,v 1.1.1.3 2021/04/07 02:43:14 christos Exp $");
|
||||
__RCSID("$NetBSD: bufferevent_openssl.c,v 1.2 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -1466,7 +1466,7 @@ bufferevent_openssl_socket_new(struct event_base *base,
|
|||
This is probably an error on our part. Fail. */
|
||||
goto err;
|
||||
}
|
||||
BIO_set_close(bio, 0);
|
||||
(void)BIO_set_close(bio, 0);
|
||||
} else {
|
||||
/* The SSL isn't configured with a BIO with an fd. */
|
||||
if (fd >= 0) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: bufferevent_ratelim.c,v 1.3 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: bufferevent_ratelim.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
* Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu>
|
||||
|
@ -561,8 +562,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;
|
||||
|
@ -738,8 +738,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) {
|
||||
|
@ -790,8 +789,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 =
|
||||
|
|
|
@ -1,347 +0,0 @@
|
|||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-10-14.11; # UTC
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# 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/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,791 +0,0 @@
|
|||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2013-05-30.07; # UTC
|
||||
|
||||
# Copyright (C) 1999-2014 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
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# 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/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by 'PROGRAMS ARGS'.
|
||||
object Object file output by 'PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputting dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get the directory component of the given path, and save it in the
|
||||
# global variables '$dir'. Note that this directory component will
|
||||
# be either empty or ending with a '/' character. This is deliberate.
|
||||
set_dir_from ()
|
||||
{
|
||||
case $1 in
|
||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||
*) dir=;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the suffix-stripped basename of the given path, and save it the
|
||||
# global variable '$base'.
|
||||
set_base_from ()
|
||||
{
|
||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||
}
|
||||
|
||||
# If no dependency file was actually created by the compiler invocation,
|
||||
# we still have to create a dummy depfile, to avoid errors with the
|
||||
# Makefile "include basename.Plo" scheme.
|
||||
make_dummy_depfile ()
|
||||
{
|
||||
echo "#dummy" > "$depfile"
|
||||
}
|
||||
|
||||
# Factor out some common post-processing of the generated depfile.
|
||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||
aix_post_process_depfile ()
|
||||
{
|
||||
# If the compiler actually managed to produce a dependency file,
|
||||
# post-process it.
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependency.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# $object: dependency.h
|
||||
# and one to simply output
|
||||
# dependency.h:
|
||||
# which is needed to avoid the deleted-header problem.
|
||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||
} > "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
}
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
# Character ranges might be problematic outside the C locale.
|
||||
# These definitions help.
|
||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
lower=abcdefghijklmnopqrstuvwxyz
|
||||
digits=0123456789
|
||||
alpha=${upper}${lower}
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Avoid interferences from the environment.
|
||||
gccflag= dashmflag=
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
if test "$depmode" = msvc7msys; then
|
||||
# This is just like msvc7 but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||
## (see the conditional assignment to $gccflag above).
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||
## supported by the other compilers which use the 'gcc' depmode.
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The second -e expression handles DOS-style file names with drive
|
||||
# letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the "deleted header file" problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
## Some versions of gcc put a space before the ':'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||
| tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
tcc)
|
||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||
# FIXME: That version still under development at the moment of writing.
|
||||
# Make that this statement remains true also for stable, released
|
||||
# versions.
|
||||
# It will wrap lines (doesn't matter whether long or short) with a
|
||||
# trailing '\', as in:
|
||||
#
|
||||
# foo.o : \
|
||||
# foo.c \
|
||||
# foo.h \
|
||||
#
|
||||
# It will put a trailing '\' even on the last line, and will use leading
|
||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||
# "Emit spaces for -MD").
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||
# We have to change lines of the first kind to '$object: \'.
|
||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||
# dummy dependency, to avoid the deleted-header problem.
|
||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
## The order of this option in the case statement is important, since the
|
||||
## shell code in configure will try each of these formats in the order
|
||||
## listed in this file. A plain '-MD' option would be understood by many
|
||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||
pgcc)
|
||||
# Portland's C compiler understands '-MD'.
|
||||
# Will always output deps to 'file.d' where file is the root name of the
|
||||
# source file under compilation, even if file resides in a subdirectory.
|
||||
# The object file name does not affect the name of the '.d' file.
|
||||
# pgcc 10.2 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\' :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
set_dir_from "$object"
|
||||
# Use the source, not the object, to determine the base name, since
|
||||
# that's sadly what pgcc will do too.
|
||||
set_base_from "$source"
|
||||
tmpdepfile=$base.d
|
||||
|
||||
# For projects that build the same source file twice into different object
|
||||
# files, the pgcc approach of using the *source* file root name can cause
|
||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||
# the same $tmpdepfile.
|
||||
lockdir=$base.d-lock
|
||||
trap "
|
||||
echo '$0: caught signal, cleaning up...' >&2
|
||||
rmdir '$lockdir'
|
||||
exit 1
|
||||
" 1 2 13 15
|
||||
numtries=100
|
||||
i=$numtries
|
||||
while test $i -gt 0; do
|
||||
# mkdir is a portable test-and-set.
|
||||
if mkdir "$lockdir" 2>/dev/null; then
|
||||
# This process acquired the lock.
|
||||
"$@" -MD
|
||||
stat=$?
|
||||
# Release the lock.
|
||||
rmdir "$lockdir"
|
||||
break
|
||||
else
|
||||
# If the lock is being held by a different process, wait
|
||||
# until the winning process is done or we timeout.
|
||||
while test -d "$lockdir" && test $i -gt 0; do
|
||||
sleep 1
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
fi
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
trap - 1 2 13 15
|
||||
if test $i -le 0; then
|
||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||
echo "$0: check lockdir '$lockdir'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in 'foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||
# two compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
# Same post-processing that is required for AIX mode.
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
showIncludes=-Wc,-showIncludes
|
||||
else
|
||||
showIncludes=-showIncludes
|
||||
fi
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The first sed program below extracts the file names and escapes
|
||||
# backslashes for cygpath. The second sed program outputs the file
|
||||
# name when reading, but also accumulates all include files in the
|
||||
# hold buffer in order to output them again at the end. This only
|
||||
# works with sed implementations that can handle large buffers.
|
||||
sed < "$tmpdepfile" -n '
|
||||
/^Note: including file: *\(.*\)/ {
|
||||
s//\1/
|
||||
s/\\/\\\\/g
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7msys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for ':'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed '1,2d' "$tmpdepfile" \
|
||||
| tr ' ' "$nl" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E \
|
||||
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
| sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evbuffer-internal.h,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: evbuffer-internal.h,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -93,7 +94,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.
|
||||
*/
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/* $NetBSD: evconfig-private.h,v 1.1.1.1 2017/01/31 21:14:52 christos Exp $ */
|
||||
/* evconfig-private.h. Generated from evconfig-private.h.in by configure. */
|
||||
/* evconfig-private.h template - see "Configuration Header Templates" */
|
||||
/* in AC manual. Kevin Bowling <kevin.bowling@kev009.com */
|
||||
#ifndef EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
#define EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#ifndef _MINIX
|
||||
/* #undef _MINIX */
|
||||
#endif
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#ifndef _POSIX_1_SOURCE
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#ifndef _POSIX_SOURCE
|
||||
/* #undef _POSIX_SOURCE */
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evdns.c,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: evdns.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/* Copyright 2006-2007 Niels Provos
|
||||
* Copyright 2007-2012 Nick Mathewson and Niels Provos
|
||||
*
|
||||
|
@ -51,7 +52,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: evdns.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: evdns.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -80,6 +81,7 @@ __RCSID("$NetBSD: evdns.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
|||
#include <stdarg.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <winerror.h>
|
||||
#include <ws2tcpip.h>
|
||||
#ifndef _WIN32_IE
|
||||
#define _WIN32_IE 0x400
|
||||
|
@ -349,6 +351,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;
|
||||
|
@ -866,6 +871,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) {
|
||||
|
@ -879,12 +897,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 {
|
||||
|
@ -1049,8 +1067,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;
|
||||
}
|
||||
|
@ -1239,8 +1257,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;
|
||||
|
@ -1280,7 +1298,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;
|
||||
}
|
||||
|
@ -1289,14 +1307,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
|
||||
|
@ -1754,6 +1770,7 @@ evdns_close_server_port(struct evdns_server_port *port)
|
|||
server_port_free(port);
|
||||
} else {
|
||||
port->closing = 1;
|
||||
EVDNS_UNLOCK(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1907,7 +1924,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);
|
||||
|
@ -2268,10 +2285,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,
|
||||
|
@ -2528,6 +2546,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;
|
||||
|
@ -3316,10 +3351,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
|
||||
|
@ -3494,6 +3535,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:")) {
|
||||
|
@ -3515,6 +3557,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;
|
||||
}
|
||||
|
@ -3615,9 +3669,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);
|
||||
|
@ -3625,6 +3684,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. */
|
||||
|
@ -3648,7 +3712,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;
|
||||
|
@ -3949,7 +4013,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,
|
||||
|
@ -3960,12 +4029,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;
|
||||
}
|
||||
|
@ -4039,6 +4113,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)
|
||||
|
@ -4046,11 +4125,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) {
|
||||
|
@ -4639,6 +4713,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;
|
||||
|
@ -4717,6 +4792,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);
|
||||
|
@ -4743,7 +4820,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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: event-internal.h,v 1.3 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: event-internal.h,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -220,7 +221,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 */
|
||||
|
@ -369,6 +370,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
|
||||
|
@ -415,23 +420,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,
|
||||
|
@ -442,6 +450,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);
|
||||
|
||||
|
@ -451,6 +460,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);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: event.c,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: event.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -27,7 +28,7 @@
|
|||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: event.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: event.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -55,6 +56,9 @@ __RCSID("$NetBSD: event.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
|||
#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"
|
||||
|
@ -126,6 +130,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_
|
||||
|
||||
|
@ -231,133 +236,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 (/*CONSTCOND*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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) \
|
||||
|
@ -593,7 +634,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);
|
||||
|
@ -865,7 +908,8 @@ event_base_free_(struct event_base *base, int run_finalizers)
|
|||
* A simple case is bufferevent with underlying (i.e. filters).
|
||||
*/
|
||||
int ii = event_base_free_queues_(base, run_finalizers);
|
||||
if (!ii) {
|
||||
event_debug(("%s: %d events freed", __func__, ii));
|
||||
if (!i) {
|
||||
break;
|
||||
}
|
||||
n_deleted += ii;
|
||||
|
@ -1643,10 +1687,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: {
|
||||
|
@ -1664,8 +1710,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);
|
||||
}
|
||||
|
@ -2014,6 +2060,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))
|
||||
|
@ -2072,6 +2121,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;
|
||||
|
@ -2722,17 +2773,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);
|
||||
}
|
||||
|
@ -2782,21 +2832,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));
|
||||
|
||||
|
@ -2835,6 +2871,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 */
|
||||
|
@ -2843,6 +2883,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);
|
||||
}
|
||||
|
||||
|
@ -2963,6 +3018,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;
|
||||
|
@ -3151,10 +3207,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
|
||||
|
@ -3162,13 +3214,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)
|
||||
|
||||
|
@ -3700,13 +3752,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",
|
||||
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;
|
||||
|
@ -3777,7 +3830,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: event_tagging.c,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: event_tagging.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2009 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -28,7 +29,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: event_tagging.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: event_tagging.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef EVENT__HAVE_SYS_TYPES_H
|
||||
|
@ -96,9 +97,13 @@ __RCSID("$NetBSD: event_tagging.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
|||
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
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evmap.c,v 1.3 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: evmap.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -26,7 +27,7 @@
|
|||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: evmap.c,v 1.3 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: evmap.c,v 1.4 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -46,6 +47,7 @@ __RCSID("$NetBSD: evmap.c,v 1.3 2017/01/31 23:17:39 christos Exp $");
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
@ -210,9 +212,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);
|
||||
|
@ -396,7 +404,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;
|
||||
|
@ -427,7 +436,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);
|
||||
}
|
||||
}
|
||||
|
@ -448,6 +457,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)
|
||||
|
@ -474,7 +486,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);
|
||||
|
@ -861,6 +873,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);
|
||||
|
||||
|
@ -872,18 +885,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);
|
||||
|
@ -896,6 +903,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);
|
||||
|
@ -922,19 +930,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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evrpc.c,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: evrpc.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -27,7 +28,7 @@
|
|||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: evrpc.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: evrpc.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -332,7 +333,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;
|
||||
}
|
||||
|
@ -894,8 +896,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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evthread-internal.h,v 1.3 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: evthread-internal.h,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Niels Provos, Nick Mathewson
|
||||
*
|
||||
|
@ -39,7 +40,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.
|
||||
|
@ -50,9 +51,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. */
|
||||
|
@ -183,14 +187,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);
|
||||
|
||||
|
@ -356,6 +369,7 @@ EVLOCK_TRY_LOCK_(void *lock)
|
|||
EVLOCK_UNLOCK(lock1_tmplock_,mode1); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evthread_is_debug_lock_held_(void *lock);
|
||||
void *evthread_debug_get_real_lock_(void *lock);
|
||||
|
||||
|
@ -378,6 +392,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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evthread.c,v 1.2 2017/03/02 15:43:14 christos Exp $ */
|
||||
/* $NetBSD: evthread.c,v 1.3 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Niels Provos, Nick Mathewson
|
||||
*
|
||||
|
@ -27,7 +28,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: evthread.c,v 1.2 2017/03/02 15:43:14 christos Exp $");
|
||||
__RCSID("$NetBSD: evthread.c,v 1.3 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
|
@ -49,7 +50,7 @@ __RCSID("$NetBSD: evthread.c,v 1.2 2017/03/02 15:43:14 christos Exp $");
|
|||
#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
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evutil.c,v 1.6 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: evutil.c,v 1.7 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -27,11 +28,12 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: evutil.c,v 1.6 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: evutil.c,v 1.7 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <winerror.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
@ -43,6 +45,7 @@ __RCSID("$NetBSD: evutil.c,v 1.6 2017/01/31 23:17:39 christos Exp $");
|
|||
/* For structs needed by GetAdaptersAddresses */
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <iphlpapi.h>
|
||||
#include <netioapi.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -76,6 +79,9 @@ __RCSID("$NetBSD: evutil.c,v 1.6 2017/01/31 23:17:39 christos Exp $");
|
|||
#endif
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef _WIN32
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_IFADDRS_H
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
@ -388,6 +394,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)
|
||||
{
|
||||
|
@ -598,45 +615,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 = (const 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 =
|
||||
(const struct sockaddr_in6 *)sa;
|
||||
const unsigned char *addr =
|
||||
(const 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 {
|
||||
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
|
||||
if (!evutil_v6addr_is_local_(&sin6->sin6_addr)) {
|
||||
event_debug(("Detected an IPv6 interface"));
|
||||
had_ipv6_address = 1;
|
||||
}
|
||||
|
@ -674,7 +702,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;
|
||||
|
@ -731,7 +759,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;
|
||||
|
@ -739,9 +767,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;
|
||||
|
@ -967,6 +998,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)
|
||||
|
@ -1040,10 +1072,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)
|
||||
|
@ -1057,7 +1091,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,
|
||||
|
@ -1209,8 +1243,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) {
|
||||
|
@ -1959,6 +1992,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)
|
||||
{
|
||||
|
@ -2075,6 +2143,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;
|
||||
|
@ -2144,10 +2213,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);
|
||||
|
@ -2301,7 +2373,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)
|
||||
|
@ -2597,7 +2669,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
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: evutil_rand.c,v 1.5 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: evutil_rand.c,v 1.6 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -35,7 +36,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: evutil_rand.c,v 1.5 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: evutil_rand.c,v 1.6 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
@ -177,9 +178,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;
|
||||
}
|
||||
|
@ -198,12 +197,14 @@ 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)
|
||||
{
|
||||
arc4random_addrandom(__UNCONST(buf),
|
||||
n>(size_t)INT_MAX ? INT_MAX : (int)n);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
evutil_free_secure_rng_globals_(void)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: http.c,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: http.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -28,7 +29,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: http.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: http.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef EVENT__HAVE_SYS_PARAM_H
|
||||
|
@ -54,9 +55,16 @@ __RCSID("$NetBSD: http.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
|||
#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>
|
||||
|
@ -81,7 +89,7 @@ __RCSID("$NetBSD: http.c,v 1.4 2017/01/31 23:17:39 christos Exp $");
|
|||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#endif /* !_WIN32 */
|
||||
#include <signal.h>
|
||||
#ifdef EVENT__HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
|
@ -173,9 +181,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(
|
||||
|
@ -353,6 +362,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);
|
||||
}
|
||||
|
||||
|
@ -371,15 +381,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
|
||||
|
@ -473,6 +483,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);
|
||||
|
@ -773,6 +786,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
|
||||
|
@ -1173,7 +1191,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
|
||||
|
@ -1205,6 +1225,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) {
|
||||
|
@ -1231,21 +1252,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)
|
||||
|
@ -1290,6 +1312,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);
|
||||
|
||||
|
@ -1312,6 +1336,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
|
||||
|
@ -1337,7 +1363,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);
|
||||
|
@ -1356,7 +1383,6 @@ static void
|
|||
evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
|
||||
{
|
||||
evcon->flags |= EVHTTP_CON_CLOSEDETECT;
|
||||
|
||||
bufferevent_enable(evcon->bufev, EV_READ);
|
||||
}
|
||||
|
||||
|
@ -1364,7 +1390,6 @@ static void
|
|||
evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
|
||||
{
|
||||
evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
|
||||
|
||||
bufferevent_disable(evcon->bufev, EV_READ);
|
||||
}
|
||||
|
||||
|
@ -1529,6 +1554,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 {
|
||||
|
@ -1686,8 +1719,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;
|
||||
|
@ -1696,16 +1730,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_;
|
||||
|
@ -1825,16 +1867,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
|
||||
|
@ -1848,7 +1896,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 *
|
||||
|
@ -1983,9 +2031,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)
|
||||
|
@ -1994,17 +2042,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:
|
||||
|
@ -2057,12 +2104,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) {
|
||||
|
@ -2126,11 +2173,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 {
|
||||
|
@ -2158,16 +2201,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;
|
||||
}
|
||||
|
@ -2547,9 +2589,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 */
|
||||
|
@ -2565,7 +2609,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;
|
||||
|
||||
|
@ -2631,6 +2676,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);
|
||||
|
@ -2641,7 +2690,7 @@ evhttp_make_request(struct evhttp_connection *evcon,
|
|||
if (res != 0)
|
||||
TAILQ_REMOVE(&evcon->requests, req, next);
|
||||
|
||||
return res;
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2823,6 +2872,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)) {
|
||||
|
@ -3062,16 +3115,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;
|
||||
|
@ -3080,11 +3132,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;
|
||||
|
@ -3106,9 +3158,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 *
|
||||
|
@ -3237,6 +3290,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;
|
||||
|
@ -3252,8 +3306,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;
|
||||
|
@ -3419,6 +3475,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;
|
||||
|
@ -3506,13 +3564,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);
|
||||
}
|
||||
|
||||
|
@ -4172,6 +4233,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);
|
||||
|
@ -4203,11 +4271,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
|
||||
|
@ -4316,9 +4392,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;
|
||||
|
||||
|
@ -4392,14 +4467,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);
|
||||
|
||||
|
@ -4824,6 +4899,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)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: rpc.h,v 1.4 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: rpc.h,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -28,6 +29,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
|
||||
|
@ -179,6 +184,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 *, \
|
||||
|
@ -188,6 +194,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,
|
||||
|
@ -258,10 +265,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
|
||||
|
@ -286,9 +296,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);
|
||||
|
||||
/**
|
||||
|
@ -299,6 +310,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
|
||||
|
@ -320,10 +332,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)
|
||||
|
@ -335,6 +347,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 *);
|
||||
|
||||
|
@ -348,6 +361,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);
|
||||
|
||||
/*
|
||||
|
@ -386,6 +400,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
|
||||
|
@ -395,15 +410,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);
|
||||
|
||||
/**
|
||||
|
@ -414,6 +432,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);
|
||||
|
||||
|
@ -425,6 +444,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);
|
||||
|
||||
|
@ -443,6 +463,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);
|
||||
|
||||
/**
|
||||
|
@ -490,6 +511,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 *),
|
||||
|
@ -503,6 +525,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);
|
||||
|
@ -512,8 +535,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
|
||||
*
|
||||
|
@ -526,6 +549,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);
|
||||
|
||||
|
@ -539,6 +563,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);
|
||||
|
||||
|
@ -546,8 +571,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);
|
||||
|
||||
/**
|
||||
|
@ -557,6 +584,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 *),
|
||||
|
@ -573,8 +601,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 *),
|
||||
|
@ -583,9 +611,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);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: util.h,v 1.4 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: util.h,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -59,9 +60,6 @@ extern "C" {
|
|||
#endif
|
||||
#include <stdarg.h>
|
||||
#ifdef EVENT__HAVE_NETDB_H
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
|
@ -260,6 +258,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
|
||||
|
@ -426,6 +425,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.
|
||||
|
||||
|
@ -439,7 +450,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);
|
||||
|
@ -471,6 +483,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
|
||||
|
@ -494,14 +507,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 */
|
||||
|
||||
|
||||
/**
|
||||
|
@ -599,6 +614,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);
|
||||
|
@ -843,6 +864,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
|
||||
|
@ -859,6 +881,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
|
||||
}
|
||||
|
|
|
@ -1,501 +0,0 @@
|
|||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
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"`
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/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"`
|
||||
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"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_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") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kqueue.c,v 1.2 2019/10/03 22:16:52 kamil Exp $ */
|
||||
/* $NetBSD: kqueue.c,v 1.3 2021/04/07 03:36:48 christos Exp $ */
|
||||
/* $OpenBSD: kqueue.c,v 1.5 2002/07/10 14:41:31 art Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: kqueue.c,v 1.2 2019/10/03 22:16:52 kamil Exp $");
|
||||
__RCSID("$NetBSD: kqueue.c,v 1.3 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef EVENT__HAVE_KQUEUE
|
||||
|
@ -40,6 +40,7 @@ __RCSID("$NetBSD: kqueue.c,v 1.2 2019/10/03 22:16:52 kamil Exp $");
|
|||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <sys/event.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -68,6 +69,7 @@ __RCSID("$NetBSD: kqueue.c,v 1.2 2019/10/03 22:16:52 kamil Exp $");
|
|||
#include "log-internal.h"
|
||||
#include "evmap-internal.h"
|
||||
#include "event2/thread.h"
|
||||
#include "event2/util.h"
|
||||
#include "evthread-internal.h"
|
||||
#include "changelist-internal.h"
|
||||
|
||||
|
@ -213,9 +215,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) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: log-internal.h,v 1.5 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: log-internal.h,v 1.6 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -30,6 +31,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))
|
||||
|
@ -40,32 +45,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);
|
||||
|
||||
|
@ -81,4 +89,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_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: log.c,v 1.5 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: log.c,v 1.6 2021/04/07 03:36:48 christos Exp $ */
|
||||
/* $OpenBSD: err.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: log.c,v 1.5 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: log.c,v 1.6 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -72,16 +72,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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: minheap-internal.h,v 1.3 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: minheap-internal.h,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -71,7 +71,7 @@ struct event* min_heap_top_(min_heap_t* s) { return s->n ? *s->p : 0; }
|
|||
|
||||
int min_heap_push_(min_heap_t* s, struct event* e)
|
||||
{
|
||||
if (min_heap_reserve_(s, s->n + 1))
|
||||
if (s->n == UINT32_MAX || min_heap_reserve_(s, s->n + 1))
|
||||
return -1;
|
||||
min_heap_shift_up_(s, s->n++, e);
|
||||
return 0;
|
||||
|
@ -139,6 +139,10 @@ int min_heap_reserve_(min_heap_t* s, unsigned n)
|
|||
unsigned a = s->a ? s->a * 2 : 8;
|
||||
if (a < n)
|
||||
a = n;
|
||||
#if (SIZE_MAX == UINT32_MAX)
|
||||
if (a > SIZE_MAX / sizeof *p)
|
||||
return -1;
|
||||
#endif
|
||||
if (!(p = (struct event**)mm_realloc(s->p, a * sizeof *p)))
|
||||
return -1;
|
||||
s->p = p;
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2013-10-28.13; # UTC
|
||||
|
||||
# Copyright (C) 1996-2014 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
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# 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/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: unknown '$1' option"
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=http://www.perl.org/
|
||||
flex_URL=http://flex.sourceforge.net/
|
||||
gnu_software_URL=http://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'autom4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: select.c,v 1.3 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: select.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
/* $OpenBSD: select.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: select.c,v 1.3 2017/01/31 23:17:39 christos Exp $");
|
||||
__RCSID("$NetBSD: select.c,v 1.4 2021/04/07 03:36:48 christos Exp $");
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef EVENT__HAVE_SELECT
|
||||
|
@ -101,7 +101,7 @@ const struct eventop selectops = {
|
|||
select_del,
|
||||
select_dispatch,
|
||||
select_dealloc,
|
||||
0, /* doesn't need reinit. */
|
||||
1, /* need_reinit. */
|
||||
EV_FEATURE_FDS,
|
||||
0,
|
||||
};
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
#! /bin/sh
|
||||
# test-driver - basic testsuite driver script.
|
||||
|
||||
scriptversion=2013-07-13.22; # UTC
|
||||
|
||||
# Copyright (C) 2011-2014 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
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# 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/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
# Make unconditional expansion of undefined variables an error. This
|
||||
# helps a lot in preventing typo-related bugs.
|
||||
set -u
|
||||
|
||||
usage_error ()
|
||||
{
|
||||
echo "$0: $*" >&2
|
||||
print_usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
print_usage ()
|
||||
{
|
||||
cat <<END
|
||||
Usage:
|
||||
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
|
||||
[--expect-failure={yes|no}] [--color-tests={yes|no}]
|
||||
[--enable-hard-errors={yes|no}] [--]
|
||||
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
|
||||
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
|
||||
END
|
||||
}
|
||||
|
||||
test_name= # Used for reporting.
|
||||
log_file= # Where to save the output of the test script.
|
||||
trs_file= # Where to save the metadata of the test run.
|
||||
expect_failure=no
|
||||
color_tests=no
|
||||
enable_hard_errors=yes
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--help) print_usage; exit $?;;
|
||||
--version) echo "test-driver $scriptversion"; exit $?;;
|
||||
--test-name) test_name=$2; shift;;
|
||||
--log-file) log_file=$2; shift;;
|
||||
--trs-file) trs_file=$2; shift;;
|
||||
--color-tests) color_tests=$2; shift;;
|
||||
--expect-failure) expect_failure=$2; shift;;
|
||||
--enable-hard-errors) enable_hard_errors=$2; shift;;
|
||||
--) shift; break;;
|
||||
-*) usage_error "invalid option: '$1'";;
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
missing_opts=
|
||||
test x"$test_name" = x && missing_opts="$missing_opts --test-name"
|
||||
test x"$log_file" = x && missing_opts="$missing_opts --log-file"
|
||||
test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
|
||||
if test x"$missing_opts" != x; then
|
||||
usage_error "the following mandatory options are missing:$missing_opts"
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
usage_error "missing argument"
|
||||
fi
|
||||
|
||||
if test $color_tests = yes; then
|
||||
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
|
||||
red='[0;31m' # Red.
|
||||
grn='[0;32m' # Green.
|
||||
lgn='[1;32m' # Light green.
|
||||
blu='[1;34m' # Blue.
|
||||
mgn='[0;35m' # Magenta.
|
||||
std='[m' # No color.
|
||||
else
|
||||
red= grn= lgn= blu= mgn= std=
|
||||
fi
|
||||
|
||||
do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
|
||||
trap "st=129; $do_exit" 1
|
||||
trap "st=130; $do_exit" 2
|
||||
trap "st=141; $do_exit" 13
|
||||
trap "st=143; $do_exit" 15
|
||||
|
||||
# Test script is run here.
|
||||
"$@" >$log_file 2>&1
|
||||
estatus=$?
|
||||
|
||||
if test $enable_hard_errors = no && test $estatus -eq 99; then
|
||||
tweaked_estatus=1
|
||||
else
|
||||
tweaked_estatus=$estatus
|
||||
fi
|
||||
|
||||
case $tweaked_estatus:$expect_failure in
|
||||
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
|
||||
0:*) col=$grn res=PASS recheck=no gcopy=no;;
|
||||
77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
|
||||
99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
|
||||
*:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
|
||||
*:*) col=$red res=FAIL recheck=yes gcopy=yes;;
|
||||
esac
|
||||
|
||||
# Report the test outcome and exit status in the logs, so that one can
|
||||
# know whether the test passed or failed simply by looking at the '.log'
|
||||
# file, without the need of also peaking into the corresponding '.trs'
|
||||
# file (automake bug#11814).
|
||||
echo "$res $test_name (exit status: $estatus)" >>$log_file
|
||||
|
||||
# Report outcome to console.
|
||||
echo "${col}${res}${std}: $test_name"
|
||||
|
||||
# Register the test result, and other relevant metadata.
|
||||
echo ":test-result: $res" > $trs_file
|
||||
echo ":global-test-result: $res" >> $trs_file
|
||||
echo ":recheck: $recheck" >> $trs_file
|
||||
echo ":copy-in-global-log: $gcopy" >> $trs_file
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress.c,v 1.9 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress.c,v 1.10 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -32,13 +33,9 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef EVENT__HAVE_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress.c,v 1.9 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress.c,v 1.10 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -49,6 +46,7 @@ __RCSID("$NetBSD: regress.c,v 1.9 2017/01/31 23:17:40 christos Exp $");
|
|||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
@ -75,6 +73,7 @@ __RCSID("$NetBSD: regress.c,v 1.9 2017/01/31 23:17:40 christos Exp $");
|
|||
#include "time-internal.h"
|
||||
|
||||
#include "regress.h"
|
||||
#include "regress_thread.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "regress.gen.h"
|
||||
|
@ -392,7 +391,7 @@ record_event_cb(evutil_socket_t s, short what, void *ptr)
|
|||
}
|
||||
|
||||
static void
|
||||
test_simpleclose(void *ptr)
|
||||
test_simpleclose_rw(void *ptr)
|
||||
{
|
||||
/* Test that a close of FD is detected as a read and as a write. */
|
||||
struct event_base *base = event_base_new();
|
||||
|
@ -474,6 +473,56 @@ end:
|
|||
event_base_free(base);
|
||||
}
|
||||
|
||||
static void
|
||||
test_simpleclose(void *ptr)
|
||||
{
|
||||
struct basic_test_data *data = ptr;
|
||||
struct event_base *base = data->base;
|
||||
evutil_socket_t *xpair = data->pair;
|
||||
const char *flags = (const char *)data->setup_data;
|
||||
int et = !!strstr(flags, "ET");
|
||||
int persist = !!strstr(flags, "persist");
|
||||
short events = EV_CLOSED | (et ? EV_ET : 0) | (persist ? EV_PERSIST : 0);
|
||||
struct event *ev = NULL;
|
||||
short got_event;
|
||||
|
||||
if (!(event_base_get_features(data->base) & EV_FEATURE_EARLY_CLOSE))
|
||||
tt_skip();
|
||||
|
||||
/* XXX: should this code moved to regress_et.c ? */
|
||||
if (et && !(event_base_get_features(data->base) & EV_FEATURE_ET))
|
||||
tt_skip();
|
||||
|
||||
ev = event_new(base, xpair[0], events, record_event_cb, &got_event);
|
||||
tt_assert(ev);
|
||||
tt_assert(!event_add(ev, NULL));
|
||||
|
||||
got_event = 0;
|
||||
if (strstr(flags, "close")) {
|
||||
tt_assert(!evutil_closesocket(xpair[1]));
|
||||
/* avoid closing in setup routines */
|
||||
xpair[1] = -1;
|
||||
} else if (strstr(flags, "shutdown")) {
|
||||
tt_assert(!shutdown(xpair[1], EVUTIL_SHUT_WR));
|
||||
} else {
|
||||
tt_abort_msg("unknown flags");
|
||||
}
|
||||
|
||||
/* w/o edge-triggerd but w/ persist it will not stop */
|
||||
if (!et && persist) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
tt_assert(!event_base_loopexit(base, &tv));
|
||||
}
|
||||
|
||||
tt_int_op(event_base_loop(base, EVLOOP_NONBLOCK), ==, !persist);
|
||||
tt_int_op(got_event, ==, (events & ~EV_PERSIST));
|
||||
|
||||
end:
|
||||
if (ev)
|
||||
event_free(ev);
|
||||
}
|
||||
|
||||
static void
|
||||
test_multiple(void)
|
||||
|
@ -851,18 +900,36 @@ simple_child_read_cb(evutil_socket_t fd, short event, void *arg)
|
|||
|
||||
called++;
|
||||
}
|
||||
|
||||
#define TEST_FORK_EXIT_SUCCESS 76
|
||||
static void fork_wait_check(int pid)
|
||||
{
|
||||
int status;
|
||||
|
||||
TT_BLATHER(("Before waitpid"));
|
||||
|
||||
#ifdef WNOWAIT
|
||||
if ((waitpid(pid, &status, WNOWAIT) == -1 && errno == EINVAL) &&
|
||||
#else
|
||||
if (
|
||||
#endif
|
||||
waitpid(pid, &status, 0) == -1) {
|
||||
perror("waitpid");
|
||||
exit(1);
|
||||
}
|
||||
TT_BLATHER(("After waitpid"));
|
||||
|
||||
if (WEXITSTATUS(status) != TEST_FORK_EXIT_SUCCESS) {
|
||||
fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
static void
|
||||
test_fork(void)
|
||||
{
|
||||
char c;
|
||||
int status;
|
||||
struct event ev, sig_ev, usr_ev, existing_ev;
|
||||
pid_t pid;
|
||||
int wait_flags = 0;
|
||||
|
||||
#ifdef EVENT__HAVE_WAITPID_WITH_WNOWAIT
|
||||
wait_flags |= WNOWAIT;
|
||||
#endif
|
||||
|
||||
setup_test("After fork: ");
|
||||
|
||||
|
@ -913,8 +980,8 @@ test_fork(void)
|
|||
|
||||
evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev);
|
||||
evsignal_add(&usr_ev, NULL);
|
||||
raise(SIGUSR1);
|
||||
raise(SIGUSR2);
|
||||
kill(getpid(), SIGUSR1);
|
||||
kill(getpid(), SIGUSR2);
|
||||
|
||||
called = 0;
|
||||
|
||||
|
@ -925,7 +992,7 @@ test_fork(void)
|
|||
/* we do not send an EOF; simple_read_cb requires an EOF
|
||||
* to set test_ok. we just verify that the callback was
|
||||
* called. */
|
||||
exit(test_ok != 0 || called != 2 ? -2 : 76);
|
||||
exit(test_ok != 0 || called != 2 ? -2 : TEST_FORK_EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/** wait until client read first message */
|
||||
|
@ -936,17 +1003,7 @@ test_fork(void)
|
|||
tt_fail_perror("write");
|
||||
}
|
||||
|
||||
TT_BLATHER(("Before waitpid"));
|
||||
if (waitpid(pid, &status, wait_flags) == -1) {
|
||||
perror("waitpid");
|
||||
exit(1);
|
||||
}
|
||||
TT_BLATHER(("After waitpid"));
|
||||
|
||||
if (WEXITSTATUS(status) != 76) {
|
||||
fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
|
||||
exit(1);
|
||||
}
|
||||
fork_wait_check(pid);
|
||||
|
||||
/* test that the current event loop still works */
|
||||
if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
|
||||
|
@ -957,8 +1014,8 @@ test_fork(void)
|
|||
|
||||
evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev);
|
||||
evsignal_add(&usr_ev, NULL);
|
||||
raise(SIGUSR1);
|
||||
raise(SIGUSR2);
|
||||
kill(getpid(), SIGUSR1);
|
||||
kill(getpid(), SIGUSR2);
|
||||
|
||||
event_dispatch();
|
||||
|
||||
|
@ -973,7 +1030,7 @@ test_fork(void)
|
|||
evutil_closesocket(child_pair[1]);
|
||||
}
|
||||
|
||||
#ifdef EVENT__HAVE_PTHREADS
|
||||
#ifdef EVTHREAD_USE_PTHREADS_IMPLEMENTED
|
||||
static void* del_wait_thread(void *arg)
|
||||
{
|
||||
struct timeval tv_start, tv_end;
|
||||
|
@ -992,23 +1049,23 @@ static void
|
|||
del_wait_cb(evutil_socket_t fd, short event, void *arg)
|
||||
{
|
||||
struct timeval delay = { 0, 300*1000 };
|
||||
TT_BLATHER(("Sleeping"));
|
||||
TT_BLATHER(("Sleeping: %i", test_ok));
|
||||
evutil_usleep_(&delay);
|
||||
test_ok = 1;
|
||||
++test_ok;
|
||||
}
|
||||
|
||||
static void
|
||||
test_del_wait(void)
|
||||
{
|
||||
struct event ev;
|
||||
pthread_t thread;
|
||||
THREAD_T thread;
|
||||
|
||||
setup_test("event_del will wait: ");
|
||||
|
||||
event_set(&ev, pair[1], EV_READ, del_wait_cb, &ev);
|
||||
event_set(&ev, pair[1], EV_READ|EV_PERSIST, del_wait_cb, &ev);
|
||||
event_add(&ev, NULL);
|
||||
|
||||
pthread_create(&thread, NULL, del_wait_thread, NULL);
|
||||
THREAD_START(thread, del_wait_thread, NULL);
|
||||
|
||||
if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
|
||||
tt_fail_perror("write");
|
||||
|
@ -1027,11 +1084,41 @@ test_del_wait(void)
|
|||
test_timeval_diff_eq(&tv_start, &tv_end, 270);
|
||||
}
|
||||
|
||||
pthread_join(thread, NULL);
|
||||
THREAD_JOIN(thread);
|
||||
|
||||
tt_int_op(test_ok, ==, 1);
|
||||
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
static void null_cb(evutil_socket_t fd, short what, void *arg) {}
|
||||
static void* test_del_notify_thread(void *arg)
|
||||
{
|
||||
event_dispatch();
|
||||
return NULL;
|
||||
}
|
||||
static void
|
||||
test_del_notify(void)
|
||||
{
|
||||
struct event ev;
|
||||
THREAD_T thread;
|
||||
|
||||
test_ok = 1;
|
||||
|
||||
event_set(&ev, -1, EV_READ, null_cb, &ev);
|
||||
event_add(&ev, NULL);
|
||||
|
||||
THREAD_START(thread, test_del_notify_thread, NULL);
|
||||
|
||||
{
|
||||
struct timeval delay = { 0, 1000 };
|
||||
evutil_usleep_(&delay);
|
||||
}
|
||||
|
||||
event_del(&ev);
|
||||
THREAD_JOIN(thread);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
|
@ -1130,7 +1217,7 @@ test_immediatesignal(void)
|
|||
test_ok = 0;
|
||||
evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
|
||||
evsignal_add(&ev, NULL);
|
||||
raise(SIGUSR1);
|
||||
kill(getpid(), SIGUSR1);
|
||||
event_loop(EVLOOP_NONBLOCK);
|
||||
evsignal_del(&ev);
|
||||
cleanup_test();
|
||||
|
@ -1203,7 +1290,7 @@ test_signal_switchbase(void)
|
|||
|
||||
test_ok = 0;
|
||||
/* can handle signal before loop is called */
|
||||
raise(SIGUSR1);
|
||||
kill(getpid(), SIGUSR1);
|
||||
event_base_loop(base2, EVLOOP_NONBLOCK);
|
||||
if (is_kqueue) {
|
||||
if (!test_ok)
|
||||
|
@ -1216,7 +1303,7 @@ test_signal_switchbase(void)
|
|||
|
||||
/* set base1 to handle signals */
|
||||
event_base_loop(base1, EVLOOP_NONBLOCK);
|
||||
raise(SIGUSR1);
|
||||
kill(getpid(), SIGUSR1);
|
||||
event_base_loop(base1, EVLOOP_NONBLOCK);
|
||||
event_base_loop(base2, EVLOOP_NONBLOCK);
|
||||
}
|
||||
|
@ -1245,7 +1332,7 @@ test_signal_assert(void)
|
|||
*/
|
||||
evsignal_del(&ev);
|
||||
|
||||
raise(SIGCONT);
|
||||
kill(getpid(), SIGCONT);
|
||||
#if 0
|
||||
/* only way to verify we were in evsig_handler() */
|
||||
/* XXXX Now there's no longer a good way. */
|
||||
|
@ -1289,7 +1376,7 @@ test_signal_restore(void)
|
|||
evsignal_add(&ev, NULL);
|
||||
evsignal_del(&ev);
|
||||
|
||||
raise(SIGUSR1);
|
||||
kill(getpid(), SIGUSR1);
|
||||
/* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */
|
||||
if (test_ok != 2)
|
||||
test_ok = 0;
|
||||
|
@ -1304,7 +1391,7 @@ signal_cb_swp(int sig, short event, void *arg)
|
|||
{
|
||||
called++;
|
||||
if (called < 5)
|
||||
raise(sig);
|
||||
kill(getpid(), sig);
|
||||
else
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
@ -1316,7 +1403,7 @@ timeout_cb_swp(evutil_socket_t fd, short event, void *arg)
|
|||
|
||||
called = 0;
|
||||
evtimer_add((struct event *)arg, &tv);
|
||||
raise(SIGUSR1);
|
||||
kill(getpid(), SIGUSR1);
|
||||
return;
|
||||
}
|
||||
test_ok = 0;
|
||||
|
@ -1354,18 +1441,14 @@ test_free_active_base(void *ptr)
|
|||
struct event ev1;
|
||||
|
||||
base1 = event_init();
|
||||
if (base1) {
|
||||
event_assign(&ev1, base1, data->pair[1], EV_READ,
|
||||
dummy_read_cb, NULL);
|
||||
event_add(&ev1, NULL);
|
||||
event_base_free(base1); /* should not crash */
|
||||
} else {
|
||||
tt_fail_msg("failed to create event_base for test");
|
||||
}
|
||||
tt_assert(base1);
|
||||
event_assign(&ev1, base1, data->pair[1], EV_READ, dummy_read_cb, NULL);
|
||||
event_add(&ev1, NULL);
|
||||
event_base_free(base1); /* should not crash */
|
||||
|
||||
base1 = event_init();
|
||||
tt_assert(base1);
|
||||
event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL);
|
||||
event_assign(&ev1, base1, data->pair[0], 0, dummy_read_cb, NULL);
|
||||
event_active(&ev1, EV_READ, 1);
|
||||
event_base_free(base1);
|
||||
end:
|
||||
|
@ -1843,7 +1926,8 @@ static void send_a_byte_cb(evutil_socket_t fd, short what, void *arg)
|
|||
{
|
||||
evutil_socket_t *sockp = arg;
|
||||
(void) fd; (void) what;
|
||||
(void) write(*sockp, "A", 1);
|
||||
if (write(*sockp, "A", 1) < 0)
|
||||
tt_fail_perror("write");
|
||||
}
|
||||
struct read_not_timeout_param
|
||||
{
|
||||
|
@ -2073,60 +2157,48 @@ re_add_read_cb(evutil_socket_t fd, short event, void *arg)
|
|||
if (n_read < 0) {
|
||||
tt_fail_perror("read");
|
||||
event_base_loopbreak(event_get_base(ev_other));
|
||||
return;
|
||||
} else {
|
||||
event_add(ev_other, NULL);
|
||||
++test_ok;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_nonpersist_readd(void)
|
||||
test_nonpersist_readd(void *_data)
|
||||
{
|
||||
struct event ev1, ev2;
|
||||
struct basic_test_data *data = _data;
|
||||
|
||||
setup_test("Re-add nonpersistent events: ");
|
||||
event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2);
|
||||
event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1);
|
||||
memset(&ev1, 0, sizeof(ev1));
|
||||
memset(&ev2, 0, sizeof(ev2));
|
||||
|
||||
if (write(pair[0], "Hello", 5) < 0) {
|
||||
tt_fail_perror("write(pair[0])");
|
||||
}
|
||||
tt_assert(!event_assign(&ev1, data->base, data->pair[0], EV_READ, re_add_read_cb, &ev2));
|
||||
tt_assert(!event_assign(&ev2, data->base, data->pair[1], EV_READ, re_add_read_cb, &ev1));
|
||||
|
||||
if (write(pair[1], "Hello", 5) < 0) {
|
||||
tt_fail_perror("write(pair[1])\n");
|
||||
}
|
||||
tt_int_op(write(data->pair[0], "Hello", 5), ==, 5);
|
||||
tt_int_op(write(data->pair[1], "Hello", 5), ==, 5);
|
||||
|
||||
tt_int_op(event_add(&ev1, NULL), ==, 0);
|
||||
tt_int_op(event_add(&ev2, NULL), ==, 0);
|
||||
tt_int_op(event_base_loop(data->base, EVLOOP_ONCE), ==, 0);
|
||||
tt_int_op(test_ok, ==, 2);
|
||||
|
||||
if (event_add(&ev1, NULL) == -1 ||
|
||||
event_add(&ev2, NULL) == -1) {
|
||||
test_ok = 0;
|
||||
}
|
||||
if (test_ok != 0)
|
||||
exit(1);
|
||||
event_loop(EVLOOP_ONCE);
|
||||
if (test_ok != 2)
|
||||
exit(1);
|
||||
/* At this point, we executed both callbacks. Whichever one got
|
||||
* called first added the second, but the second then immediately got
|
||||
* deleted before its callback was called. At this point, though, it
|
||||
* re-added the first.
|
||||
*/
|
||||
if (!readd_test_event_last_added) {
|
||||
test_ok = 0;
|
||||
} else if (readd_test_event_last_added == &ev1) {
|
||||
if (!event_pending(&ev1, EV_READ, NULL) ||
|
||||
event_pending(&ev2, EV_READ, NULL))
|
||||
test_ok = 0;
|
||||
tt_assert(readd_test_event_last_added);
|
||||
if (readd_test_event_last_added == &ev1) {
|
||||
tt_assert(event_pending(&ev1, EV_READ, NULL) && !event_pending(&ev2, EV_READ, NULL));
|
||||
} else {
|
||||
if (event_pending(&ev1, EV_READ, NULL) ||
|
||||
!event_pending(&ev2, EV_READ, NULL))
|
||||
test_ok = 0;
|
||||
tt_assert(event_pending(&ev2, EV_READ, NULL) && !event_pending(&ev1, EV_READ, NULL));
|
||||
}
|
||||
|
||||
event_del(&ev1);
|
||||
event_del(&ev2);
|
||||
|
||||
cleanup_test();
|
||||
end:
|
||||
if (event_initialized(&ev1))
|
||||
event_del(&ev1);
|
||||
if (event_initialized(&ev2))
|
||||
event_del(&ev2);
|
||||
}
|
||||
|
||||
struct test_pri_event {
|
||||
|
@ -3044,6 +3116,7 @@ test_many_events(void *arg)
|
|||
* instance of that. */
|
||||
sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
tt_assert(sock[i] >= 0);
|
||||
tt_assert(!evutil_make_socket_nonblocking(sock[i]));
|
||||
xcalled[i] = 0;
|
||||
ev[i] = event_new(base, sock[i], EV_WRITE|evflags,
|
||||
many_event_cb, &xcalled[i]);
|
||||
|
@ -3098,7 +3171,7 @@ test_get_assignment(void *arg)
|
|||
event_get_assignment(ev1, &b, &s, &what, &cb, &cb_arg);
|
||||
|
||||
tt_ptr_op(b, ==, base);
|
||||
tt_int_op(s, ==, data->pair[1]);
|
||||
tt_fd_op(s, ==, data->pair[1]);
|
||||
tt_int_op(what, ==, EV_READ);
|
||||
tt_ptr_op(cb, ==, dummy_read_cb);
|
||||
tt_ptr_op(cb_arg, ==, str);
|
||||
|
@ -3283,6 +3356,46 @@ tabf_cb(evutil_socket_t fd, short what, void *arg)
|
|||
*ptr += 0x10000;
|
||||
}
|
||||
|
||||
static void
|
||||
test_evmap_invalid_slots(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
struct event *ev1 = NULL, *ev2 = NULL;
|
||||
int e1, e2;
|
||||
#ifndef _WIN32
|
||||
struct event *ev3 = NULL, *ev4 = NULL;
|
||||
int e3, e4;
|
||||
#endif
|
||||
|
||||
ev1 = evsignal_new(base, -1, dummy_read_cb, (void *)base);
|
||||
ev2 = evsignal_new(base, NSIG, dummy_read_cb, (void *)base);
|
||||
tt_assert(ev1);
|
||||
tt_assert(ev2);
|
||||
e1 = event_add(ev1, NULL);
|
||||
e2 = event_add(ev2, NULL);
|
||||
tt_int_op(e1, !=, 0);
|
||||
tt_int_op(e2, !=, 0);
|
||||
#ifndef _WIN32
|
||||
ev3 = event_new(base, INT_MAX, EV_READ, dummy_read_cb, (void *)base);
|
||||
ev4 = event_new(base, INT_MAX / 2, EV_READ, dummy_read_cb, (void *)base);
|
||||
tt_assert(ev3);
|
||||
tt_assert(ev4);
|
||||
e3 = event_add(ev3, NULL);
|
||||
e4 = event_add(ev4, NULL);
|
||||
tt_int_op(e3, !=, 0);
|
||||
tt_int_op(e4, !=, 0);
|
||||
#endif
|
||||
|
||||
end:
|
||||
event_free(ev1);
|
||||
event_free(ev2);
|
||||
#ifndef _WIN32
|
||||
event_free(ev3);
|
||||
event_free(ev4);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
test_active_by_fd(void *arg)
|
||||
{
|
||||
|
@ -3334,6 +3447,7 @@ test_active_by_fd(void *arg)
|
|||
/* Trigger 2, 3, 4 */
|
||||
event_base_active_by_fd(base, data->pair[0], EV_WRITE);
|
||||
event_base_active_by_fd(base, data->pair[1], EV_READ);
|
||||
event_base_active_by_fd(base, data->pair[1], EV_TIMEOUT);
|
||||
#ifndef _WIN32
|
||||
event_base_active_by_signal(base, SIGHUP);
|
||||
#endif
|
||||
|
@ -3346,7 +3460,7 @@ test_active_by_fd(void *arg)
|
|||
tt_int_op(e2, ==, EV_WRITE | 0x10000);
|
||||
tt_int_op(e3, ==, EV_READ | 0x10000);
|
||||
/* Mask out EV_WRITE here, since it could be genuinely writeable. */
|
||||
tt_int_op((e4 & ~EV_WRITE), ==, EV_READ | 0x10000);
|
||||
tt_int_op((e4 & ~EV_WRITE), ==, EV_READ | EV_TIMEOUT | 0x10000);
|
||||
#ifndef _WIN32
|
||||
tt_int_op(es, ==, EV_SIGNAL | 0x10000);
|
||||
#endif
|
||||
|
@ -3381,17 +3495,18 @@ struct testcase_t main_testcases[] = {
|
|||
BASIC(event_assign_selfarg, TT_FORK|TT_NEED_BASE),
|
||||
BASIC(event_base_get_num_events, TT_FORK|TT_NEED_BASE),
|
||||
BASIC(event_base_get_max_events, TT_FORK|TT_NEED_BASE),
|
||||
BASIC(evmap_invalid_slots, TT_FORK|TT_NEED_BASE),
|
||||
|
||||
BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
|
||||
BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
|
||||
BASIC(active_later, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
|
||||
BASIC(active_later, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR|TT_RETRIABLE),
|
||||
BASIC(event_remove_timeout, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
|
||||
|
||||
/* These are still using the old API */
|
||||
LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE),
|
||||
{ "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
{ "persistent_active_timeout", test_persistent_active_timeout,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
TT_FORK|TT_NEED_BASE|TT_RETRIABLE, &basic_setup, NULL },
|
||||
LEGACY(priorities, TT_FORK|TT_NEED_BASE),
|
||||
BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE),
|
||||
{ "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE,
|
||||
|
@ -3401,8 +3516,35 @@ struct testcase_t main_testcases[] = {
|
|||
LEGACY(simpleread, TT_ISOLATED),
|
||||
LEGACY(simpleread_multiple, TT_ISOLATED),
|
||||
LEGACY(simplewrite, TT_ISOLATED),
|
||||
{ "simpleclose", test_simpleclose, TT_FORK, &basic_setup,
|
||||
NULL },
|
||||
{ "simpleclose_rw", test_simpleclose_rw, TT_FORK, &basic_setup, NULL },
|
||||
/* simpleclose */
|
||||
{ "simpleclose_close", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("close") },
|
||||
{ "simpleclose_shutdown", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("shutdown") },
|
||||
/* simpleclose_*_persist */
|
||||
{ "simpleclose_close_persist", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("close_persist") },
|
||||
{ "simpleclose_shutdown_persist", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("shutdown_persist") },
|
||||
/* simpleclose_*_et */
|
||||
{ "simpleclose_close_et", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("close_ET") },
|
||||
{ "simpleclose_shutdown_et", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("shutdown_ET") },
|
||||
/* simpleclose_*_persist_et */
|
||||
{ "simpleclose_close_persist_et", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("close_persist_ET") },
|
||||
{ "simpleclose_shutdown_persist_et", test_simpleclose,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
|
||||
&basic_setup, __UNCONST("shutdown_persist_ET") },
|
||||
LEGACY(multiple, TT_ISOLATED),
|
||||
LEGACY(persistent, TT_ISOLATED),
|
||||
LEGACY(combined, TT_ISOLATED),
|
||||
|
@ -3410,7 +3552,7 @@ struct testcase_t main_testcases[] = {
|
|||
LEGACY(loopbreak, TT_ISOLATED),
|
||||
LEGACY(loopexit, TT_ISOLATED),
|
||||
LEGACY(loopexit_multiple, TT_ISOLATED),
|
||||
LEGACY(nonpersist_readd, TT_ISOLATED),
|
||||
{ "nonpersist_readd", test_nonpersist_readd, TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE, &basic_setup, NULL },
|
||||
LEGACY(multiple_events_for_same_fd, TT_ISOLATED),
|
||||
LEGACY(want_only_once, TT_ISOLATED),
|
||||
{ "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL },
|
||||
|
@ -3442,9 +3584,10 @@ struct testcase_t main_testcases[] = {
|
|||
#ifndef _WIN32
|
||||
LEGACY(fork, TT_ISOLATED),
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_PTHREADS
|
||||
/** TODO: support win32 */
|
||||
LEGACY(del_wait, TT_ISOLATED|TT_NEED_THREADS),
|
||||
|
||||
#ifdef EVTHREAD_USE_PTHREADS_IMPLEMENTED
|
||||
LEGACY(del_wait, TT_ISOLATED|TT_NEED_THREADS|TT_RETRIABLE),
|
||||
LEGACY(del_notify, TT_ISOLATED|TT_NEED_THREADS),
|
||||
#endif
|
||||
|
||||
END_OF_TESTCASES
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress.h,v 1.6 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress.h,v 1.7 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -44,6 +45,7 @@ extern struct testcase_t bufferevent_iocp_testcases[];
|
|||
extern struct testcase_t util_testcases[];
|
||||
extern struct testcase_t signal_testcases[];
|
||||
extern struct testcase_t http_testcases[];
|
||||
extern struct testcase_t http_iocp_testcases[];
|
||||
extern struct testcase_t dns_testcases[];
|
||||
extern struct testcase_t rpc_testcases[];
|
||||
extern struct testcase_t edgetriggered_testcases[];
|
||||
|
@ -95,6 +97,7 @@ extern int libevent_tests_running_in_debug_mode;
|
|||
#define TT_NO_LOGS (TT_FIRST_USER_FLAG<<5)
|
||||
#define TT_ENABLE_IOCP_FLAG (TT_FIRST_USER_FLAG<<6)
|
||||
#define TT_ENABLE_IOCP (TT_ENABLE_IOCP_FLAG|TT_NEED_THREADS)
|
||||
#define TT_ENABLE_DEBUG_MODE (TT_ENABLE_IOCP_FLAG<<7)
|
||||
|
||||
/* All the flags that a legacy test needs. */
|
||||
#define TT_ISOLATED TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE
|
||||
|
@ -133,11 +136,14 @@ pid_t regress_fork(void);
|
|||
#ifdef EVENT__HAVE_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
EVP_PKEY *ssl_getkey(void);
|
||||
X509 *ssl_getcert(void);
|
||||
X509 *ssl_getcert(EVP_PKEY *key);
|
||||
SSL_CTX *get_ssl_ctx(void);
|
||||
void init_ssl(void);
|
||||
#endif
|
||||
|
||||
void * basic_test_setup(const struct testcase_t *testcase);
|
||||
int basic_test_cleanup(const struct testcase_t *testcase, void *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_buffer.c,v 1.6 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_buffer.c,v 1.7 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -34,7 +35,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_buffer.c,v 1.6 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_buffer.c,v 1.7 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -66,6 +67,8 @@ __RCSID("$NetBSD: regress_buffer.c,v 1.6 2017/01/31 23:17:40 christos Exp $");
|
|||
|
||||
#include "regress.h"
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
/* Validates that an evbuffer is good. Returns false if it isn't, true if it
|
||||
* is*/
|
||||
static int
|
||||
|
@ -297,33 +300,39 @@ no_cleanup(const void *data, size_t datalen, void *extra)
|
|||
static void
|
||||
test_evbuffer_remove_buffer_with_empty(void *ptr)
|
||||
{
|
||||
struct evbuffer *src = evbuffer_new();
|
||||
struct evbuffer *dst = evbuffer_new();
|
||||
char buf[2];
|
||||
struct evbuffer *src = evbuffer_new();
|
||||
struct evbuffer *dst = evbuffer_new();
|
||||
char buf[2] = { 'A', 'A' };
|
||||
|
||||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
|
||||
/* setup the buffers */
|
||||
/* we need more data in src than we will move later */
|
||||
evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
|
||||
evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
|
||||
/* we need one buffer in dst and one empty buffer at the end */
|
||||
evbuffer_add(dst, buf, sizeof(buf));
|
||||
evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
|
||||
/* setup the buffers */
|
||||
/* we need more data in src than we will move later */
|
||||
evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
|
||||
evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
|
||||
/* we need one buffer in dst and one empty buffer at the end */
|
||||
evbuffer_add(dst, buf, sizeof(buf));
|
||||
evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
|
||||
|
||||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
|
||||
/* move three bytes over */
|
||||
evbuffer_remove_buffer(src, dst, 3);
|
||||
tt_mem_op(evbuffer_pullup(src, -1), ==, "AAAA", 4);
|
||||
tt_mem_op(evbuffer_pullup(dst, -1), ==, "AA", 2);
|
||||
|
||||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
/* move three bytes over */
|
||||
evbuffer_remove_buffer(src, dst, 3);
|
||||
|
||||
end:
|
||||
evbuffer_free(src);
|
||||
evbuffer_free(dst);
|
||||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
|
||||
tt_mem_op(evbuffer_pullup(src, -1), ==, "A", 1);
|
||||
tt_mem_op(evbuffer_pullup(dst, -1), ==, "AAAAA", 5);
|
||||
|
||||
end:
|
||||
evbuffer_free(src);
|
||||
evbuffer_free(dst);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -353,6 +362,9 @@ test_evbuffer_remove_buffer_with_empty2(void *ptr)
|
|||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
|
||||
tt_mem_op(evbuffer_pullup(src, -1), ==, "foofoofoo", 9);
|
||||
tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoofoo", 9);
|
||||
|
||||
evbuffer_remove_buffer(src, dst, 8);
|
||||
|
||||
evbuffer_validate(src);
|
||||
|
@ -361,6 +373,9 @@ test_evbuffer_remove_buffer_with_empty2(void *ptr)
|
|||
tt_int_op(evbuffer_get_length(src), ==, 1);
|
||||
tt_int_op(evbuffer_get_length(dst), ==, 17);
|
||||
|
||||
tt_mem_op(evbuffer_pullup(src, -1), ==, "o", 1);
|
||||
tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoofoofoofoofo", 17);
|
||||
|
||||
end:
|
||||
evbuffer_free(src);
|
||||
evbuffer_free(dst);
|
||||
|
@ -394,6 +409,9 @@ test_evbuffer_remove_buffer_with_empty3(void *ptr)
|
|||
evbuffer_validate(src);
|
||||
evbuffer_validate(dst);
|
||||
|
||||
tt_mem_op(evbuffer_pullup(src, -1), ==, "foofoo", 6);
|
||||
tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoo", 6);
|
||||
|
||||
evbuffer_remove_buffer(src, dst, 5);
|
||||
|
||||
evbuffer_validate(src);
|
||||
|
@ -402,12 +420,128 @@ test_evbuffer_remove_buffer_with_empty3(void *ptr)
|
|||
tt_int_op(evbuffer_get_length(src), ==, 1);
|
||||
tt_int_op(evbuffer_get_length(dst), ==, 11);
|
||||
|
||||
tt_mem_op(evbuffer_pullup(src, -1), ==, "o", 1);
|
||||
tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoofoofo", 11);
|
||||
|
||||
end:
|
||||
evbuffer_free(src);
|
||||
evbuffer_free(dst);
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_pullup_with_empty(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf = NULL;
|
||||
|
||||
buf = evbuffer_new();
|
||||
evbuffer_add(buf, "foo", 3);
|
||||
evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
|
||||
evbuffer_validate(buf);
|
||||
tt_int_op(evbuffer_get_length(buf), ==, 3);
|
||||
tt_mem_op(evbuffer_pullup(buf, -1), ==, "foo", 3);
|
||||
|
||||
evbuffer_free(buf);
|
||||
buf = evbuffer_new();
|
||||
evbuffer_validate(buf);
|
||||
tt_int_op(evbuffer_get_length(buf), ==, 0);
|
||||
tt_int_op(evbuffer_pullup(buf, -1), ==, NULL);
|
||||
|
||||
evbuffer_free(buf);
|
||||
buf = evbuffer_new();
|
||||
evbuffer_add(buf, "foo", 3);
|
||||
evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
|
||||
evbuffer_validate(buf);
|
||||
tt_mem_op(evbuffer_pullup(buf, 3), ==, "foo", 3);
|
||||
|
||||
end:
|
||||
if (buf)
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_remove_buffer_with_empty_front(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf1 = NULL, *buf2 = NULL;
|
||||
|
||||
buf1 = evbuffer_new();
|
||||
tt_assert(buf1);
|
||||
|
||||
buf2 = evbuffer_new();
|
||||
tt_assert(buf2);
|
||||
|
||||
tt_int_op(evbuffer_add_reference(buf1, "foo", 3, NULL, NULL), ==, 0);
|
||||
tt_int_op(evbuffer_prepend(buf1, "", 0), ==, 0);
|
||||
tt_int_op(evbuffer_remove_buffer(buf1, buf2, 1), ==, 1);
|
||||
tt_int_op(evbuffer_add(buf1, "bar", 3), ==, 0);
|
||||
tt_mem_op(evbuffer_pullup(buf1, -1), ==, "oobar", 5);
|
||||
|
||||
evbuffer_validate(buf1);
|
||||
evbuffer_validate(buf2);
|
||||
|
||||
end:
|
||||
if (buf1)
|
||||
evbuffer_free(buf1);
|
||||
if (buf2)
|
||||
evbuffer_free(buf2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_remove_buffer_adjust_last_with_datap_with_empty(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf1 = NULL, *buf2 = NULL;
|
||||
|
||||
buf1 = evbuffer_new();
|
||||
tt_assert(buf1);
|
||||
|
||||
buf2 = evbuffer_new();
|
||||
tt_assert(buf2);
|
||||
|
||||
tt_int_op(evbuffer_add(buf1, "aaaaaa", 6), ==, 0);
|
||||
|
||||
// buf1: aaaaaab
|
||||
// buf2:
|
||||
{
|
||||
struct evbuffer_iovec iovecs[2];
|
||||
/** we want two chains, to leave one chain empty */
|
||||
tt_int_op(evbuffer_reserve_space(buf1, 971, iovecs, 2), ==, 2);
|
||||
tt_int_op(iovecs[0].iov_len, >=, 1);
|
||||
tt_int_op(iovecs[1].iov_len, >=, 1);
|
||||
tt_assert(*(char *)(iovecs[0].iov_base) = 'b');
|
||||
tt_assert(iovecs[0].iov_len = 1);
|
||||
tt_int_op(evbuffer_commit_space(buf1, iovecs, 1), ==, 0);
|
||||
}
|
||||
|
||||
// buf1: aaaaaab
|
||||
// buf2: dddcc
|
||||
tt_int_op(evbuffer_add(buf2, "cc", 2), ==, 0);
|
||||
tt_int_op(evbuffer_prepend(buf2, "ddd", 3), ==, 0);
|
||||
|
||||
// buf1:
|
||||
// buf2: aaaaaabdddcc
|
||||
tt_int_op(evbuffer_prepend_buffer(buf2, buf1), ==, 0);
|
||||
|
||||
// buf1: aaaaaabdddcc
|
||||
// buf2:
|
||||
tt_int_op(evbuffer_add_buffer(buf1, buf2), ==, 0);
|
||||
|
||||
// buf1: c
|
||||
// buf2: aaaaaabdddc
|
||||
tt_int_op(evbuffer_remove_buffer(buf1, buf2, 11), ==, 11);
|
||||
|
||||
// This fails today, we observe "aaaaaabcddd" instead!
|
||||
tt_mem_op(evbuffer_pullup(buf2, -1), ==, "aaaaaabdddc", 11);
|
||||
|
||||
evbuffer_validate(buf1);
|
||||
evbuffer_validate(buf2);
|
||||
|
||||
end:
|
||||
if (buf1)
|
||||
evbuffer_free(buf1);
|
||||
if (buf2)
|
||||
evbuffer_free(buf2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_add_buffer_with_empty(void *ptr)
|
||||
{
|
||||
|
@ -637,6 +771,63 @@ end:
|
|||
evbuffer_free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_reserve_with_empty(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf;
|
||||
struct evbuffer_iovec v[2];
|
||||
|
||||
tt_assert(buf = evbuffer_new());
|
||||
evbuffer_add(buf, "a", 1);
|
||||
tt_int_op(evbuffer_reserve_space(buf, 1<<12, v, 2), ==, 2);
|
||||
v[0].iov_len = 1;
|
||||
*(char *)v[0].iov_base = 'b';
|
||||
tt_int_op(evbuffer_commit_space(buf, v, 1), ==, 0);
|
||||
evbuffer_add(buf, "c", 1);
|
||||
tt_mem_op(evbuffer_pullup(buf, -1), ==, "abc", 2);
|
||||
|
||||
evbuffer_validate(buf);
|
||||
|
||||
end:
|
||||
if (buf)
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
|
||||
/* regression for evbuffer_expand_fast_() with invalid last_with_datap that has
|
||||
* been left after evbuffer_prepend() with empty chain in it */
|
||||
static void
|
||||
test_evbuffer_reserve_invalid_last_with_datap(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf = NULL;
|
||||
struct evbuffer_iovec vec[2];
|
||||
const int nvec = ARRAY_SIZE(vec);
|
||||
int i, avec;
|
||||
|
||||
buf = evbuffer_new();
|
||||
tt_assert(buf);
|
||||
|
||||
/* prepend with an empty chain */
|
||||
evbuffer_add_reference(buf, "", 0, NULL, NULL);
|
||||
evbuffer_prepend(buf, "foo", 3);
|
||||
/* after invalid last_with_datap will create new chain */
|
||||
evbuffer_add(buf, "", 0);
|
||||
/* we need to create at least 2 "used" (in evbuffer_expand_fast_()) chains */
|
||||
tt_int_op(avec = evbuffer_reserve_space(buf, 1<<12, vec, nvec), >=, 1);
|
||||
for (i = 0; i < avec; ++i)
|
||||
vec[i].iov_len = 0;
|
||||
tt_int_op(evbuffer_commit_space(buf, vec, avec), ==, 0);
|
||||
|
||||
/* and an actual problem, that triggers an assert(chain == buf->first) in
|
||||
* evbuffer_expand_fast_() */
|
||||
tt_int_op(evbuffer_reserve_space(buf, 1<<13, vec, nvec), >=, 1);
|
||||
|
||||
evbuffer_validate(buf);
|
||||
|
||||
end:
|
||||
if (buf)
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_expand(void *ptr)
|
||||
{
|
||||
|
@ -1799,12 +1990,12 @@ test_evbuffer_callbacks(void *ptr)
|
|||
tt_assert(cb1 != NULL);
|
||||
cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
|
||||
tt_assert(cb2 != NULL);
|
||||
evbuffer_setcb(buf, self_draining_callback, NULL);
|
||||
tt_int_op(evbuffer_setcb(buf, self_draining_callback, NULL), ==, 0);
|
||||
evbuffer_add_printf(buf, "This should get drained right away.");
|
||||
tt_uint_op(evbuffer_get_length(buf), ==, 0);
|
||||
tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
|
||||
tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
|
||||
evbuffer_setcb(buf, NULL, NULL);
|
||||
tt_int_op(evbuffer_setcb(buf, NULL, NULL), ==, 0);
|
||||
evbuffer_add_printf(buf, "This will not.");
|
||||
tt_str_op((const char *) evbuffer_pullup(buf, -1), ==, "This will not.");
|
||||
evbuffer_validate(buf);
|
||||
|
@ -1830,6 +2021,14 @@ test_evbuffer_callbacks(void *ptr)
|
|||
"0->15; 15->11; 11->0; ");
|
||||
#endif
|
||||
|
||||
/* the next call to readline should fail */
|
||||
#ifndef EVENT__DISABLE_MM_REPLACEMENT
|
||||
event_set_mem_functions(failing_malloc, realloc, free);
|
||||
tt_int_op(evbuffer_setcb(buf, self_draining_callback, NULL), ==, -1);
|
||||
evbuffer_validate(buf);
|
||||
event_set_mem_functions(malloc, realloc, free);
|
||||
#endif
|
||||
|
||||
end:
|
||||
if (buf)
|
||||
evbuffer_free(buf);
|
||||
|
@ -2120,6 +2319,58 @@ end:
|
|||
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_empty_reference_prepend(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf = NULL;
|
||||
|
||||
buf = evbuffer_new();
|
||||
tt_assert(buf);
|
||||
|
||||
/** empty chain could leave invalid last_with_datap */
|
||||
evbuffer_add_reference(buf, "", 0, NULL, NULL);
|
||||
evbuffer_validate(buf);
|
||||
evbuffer_prepend(buf, "foo", 3);
|
||||
|
||||
evbuffer_validate(buf);
|
||||
tt_assert(!strncmp((char *)evbuffer_pullup(buf, -1), "foo", 3));
|
||||
evbuffer_validate(buf);
|
||||
|
||||
end:
|
||||
if (buf)
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
static void
|
||||
test_evbuffer_empty_reference_prepend_buffer(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf1 = NULL, *buf2 = NULL;
|
||||
|
||||
buf1 = evbuffer_new();
|
||||
tt_assert(buf1);
|
||||
buf2 = evbuffer_new();
|
||||
tt_assert(buf2);
|
||||
|
||||
/** empty chain could leave invalid last_with_datap */
|
||||
evbuffer_add_reference(buf1, "", 0, NULL, NULL);
|
||||
evbuffer_validate(buf1);
|
||||
evbuffer_add(buf2, "foo", 3);
|
||||
evbuffer_validate(buf2);
|
||||
evbuffer_prepend_buffer(buf2, buf1);
|
||||
evbuffer_validate(buf2);
|
||||
|
||||
tt_assert(!strncmp((char *)evbuffer_pullup(buf2, -1), "foo", 3));
|
||||
evbuffer_validate(buf2);
|
||||
|
||||
tt_assert(evbuffer_pullup(buf1, -1) == NULL);
|
||||
evbuffer_validate(buf2);
|
||||
|
||||
end:
|
||||
if (buf1)
|
||||
evbuffer_free(buf1);
|
||||
if (buf2)
|
||||
evbuffer_free(buf2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_peek_first_gt(void *info)
|
||||
{
|
||||
|
@ -2277,28 +2528,37 @@ end:
|
|||
static void
|
||||
test_evbuffer_freeze(void *ptr)
|
||||
{
|
||||
struct evbuffer *buf = NULL, *tmp_buf=NULL;
|
||||
struct basic_test_data *testdata = ptr;
|
||||
evutil_socket_t *xpair = testdata->pair;
|
||||
struct evbuffer *buf = NULL, *buf_two = NULL, *tmp_buf = NULL;
|
||||
const char string[] = /* Year's End, Richard Wilbur */
|
||||
"I've known the wind by water banks to shake\n"
|
||||
"The late leaves down, which frozen where they fell\n"
|
||||
"And held in ice as dancers in a spell\n"
|
||||
"Fluttered all winter long into a lake...";
|
||||
const int start = !strcmp(ptr, "start");
|
||||
const int start = !strcmp(testdata->setup_data, "start");
|
||||
const char tmpfilecontent[] = "file_freeze_test_file";
|
||||
char *cp;
|
||||
char charbuf[128];
|
||||
char *tmpfilename = NULL;
|
||||
int fd = -1;
|
||||
int r;
|
||||
size_t orig_length;
|
||||
size_t orig_length, len;
|
||||
struct evbuffer_iovec v[1];
|
||||
|
||||
if (!start)
|
||||
tt_str_op(ptr, ==, "end");
|
||||
tt_str_op(testdata->setup_data, ==, "end");
|
||||
|
||||
buf = evbuffer_new();
|
||||
buf_two = evbuffer_new();
|
||||
tmp_buf = evbuffer_new();
|
||||
tt_assert(tmp_buf);
|
||||
|
||||
evbuffer_add(buf, string, strlen(string));
|
||||
evbuffer_add(buf_two, "abc", 3);
|
||||
evbuffer_add(tmp_buf, "xyz", 3);
|
||||
evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
|
||||
evbuffer_freeze(buf_two, start);
|
||||
|
||||
#define FREEZE_EQ(a, startcase, endcase) \
|
||||
do { \
|
||||
|
@ -2327,7 +2587,22 @@ test_evbuffer_freeze(void *ptr)
|
|||
FREEZE_EQ(r, 0, -1);
|
||||
r = evbuffer_add_printf(buf, "Hello %s", "world");
|
||||
FREEZE_EQ(r, 11, -1);
|
||||
/* TODO: test add_buffer, add_file, read */
|
||||
|
||||
r = evbuffer_add_buffer(buf, tmp_buf);
|
||||
FREEZE_EQ(r, 0, -1);
|
||||
len = strlen(tmpfilecontent);
|
||||
fd = regress_make_tmpfile(tmpfilecontent, len, &tmpfilename);
|
||||
r = evbuffer_add_file(buf, fd, 0, len);
|
||||
FREEZE_EQ(r, 0, -1);
|
||||
|
||||
if (start)
|
||||
evbuffer_add(tmp_buf, "xyz", 3);
|
||||
|
||||
tt_assert(evbuffer_get_length(tmp_buf));
|
||||
len = evbuffer_get_length(tmp_buf);
|
||||
evbuffer_write(tmp_buf, xpair[0]);
|
||||
r = evbuffer_read(buf, xpair[1], -1);
|
||||
FREEZE_EQ(r, len, -1);
|
||||
|
||||
if (!start)
|
||||
tt_int_op(orig_length, ==, evbuffer_get_length(buf));
|
||||
|
@ -2345,7 +2620,24 @@ test_evbuffer_freeze(void *ptr)
|
|||
FREEZE_EQ(cp==NULL, 1, 0);
|
||||
if (cp)
|
||||
free(cp);
|
||||
/* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
|
||||
|
||||
evbuffer_add(tmp_buf, "xyz", 3);
|
||||
tt_assert(evbuffer_get_length(tmp_buf));
|
||||
r = evbuffer_remove_buffer(buf, tmp_buf, 3);
|
||||
FREEZE_EQ(r, -1, 3);
|
||||
r = evbuffer_drain(buf, 3);
|
||||
FREEZE_EQ(r, -1, 0);
|
||||
r = evbuffer_prepend_buffer(buf, tmp_buf);
|
||||
FREEZE_EQ(r, -1, 0);
|
||||
|
||||
len = evbuffer_get_length(buf);
|
||||
r = evbuffer_write(buf, xpair[0]);
|
||||
evbuffer_read(tmp_buf, xpair[1], -1);
|
||||
FREEZE_EQ(r, -1, len);
|
||||
len = evbuffer_get_length(buf_two);
|
||||
r = evbuffer_write_atmost(buf_two, xpair[0], -1);
|
||||
evbuffer_read(tmp_buf, xpair[1], -1);
|
||||
FREEZE_EQ(r, -1, len);
|
||||
|
||||
if (start)
|
||||
tt_int_op(orig_length, ==, evbuffer_get_length(buf));
|
||||
|
@ -2354,8 +2646,16 @@ end:
|
|||
if (buf)
|
||||
evbuffer_free(buf);
|
||||
|
||||
if (buf_two)
|
||||
evbuffer_free(buf_two);
|
||||
|
||||
if (tmp_buf)
|
||||
evbuffer_free(tmp_buf);
|
||||
|
||||
if (tmpfilename) {
|
||||
unlink(tmpfilename);
|
||||
free(tmpfilename);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2507,12 +2807,17 @@ struct testcase_t evbuffer_testcases[] = {
|
|||
{ "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
|
||||
{ "remove_buffer_with_empty2", test_evbuffer_remove_buffer_with_empty2, 0, NULL, NULL },
|
||||
{ "remove_buffer_with_empty3", test_evbuffer_remove_buffer_with_empty3, 0, NULL, NULL },
|
||||
{ "remove_buffer_with_empty_front", test_evbuffer_remove_buffer_with_empty_front, 0, NULL, NULL },
|
||||
{ "remove_buffer_adjust_last_with_datap_with_empty",
|
||||
test_evbuffer_remove_buffer_adjust_last_with_datap_with_empty, 0, NULL, NULL },
|
||||
{ "add_buffer_with_empty", test_evbuffer_add_buffer_with_empty, 0, NULL, NULL },
|
||||
{ "add_buffer_with_empty2", test_evbuffer_add_buffer_with_empty2, 0, NULL, NULL },
|
||||
{ "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
|
||||
{ "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
|
||||
{ "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, __UNCONST("add") },
|
||||
{ "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, __UNCONST("fill") },
|
||||
{ "reserve_with_empty", test_evbuffer_reserve_with_empty, 0, NULL, NULL },
|
||||
{ "reserve_invalid_last_with_datap", test_evbuffer_reserve_invalid_last_with_datap, TT_FORK, NULL, NULL },
|
||||
{ "expand", test_evbuffer_expand, 0, NULL, NULL },
|
||||
{ "expand_overflow", test_evbuffer_expand_overflow, 0, NULL, NULL },
|
||||
{ "add1", test_evbuffer_add1, 0, NULL, NULL },
|
||||
|
@ -2530,13 +2835,16 @@ struct testcase_t evbuffer_testcases[] = {
|
|||
{ "multicast", test_evbuffer_multicast, 0, NULL, NULL },
|
||||
{ "multicast_drain", test_evbuffer_multicast_drain, 0, NULL, NULL },
|
||||
{ "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
|
||||
{ "empty_reference_prepend", test_evbuffer_empty_reference_prepend, TT_FORK, NULL, NULL },
|
||||
{ "empty_reference_prepend_buffer", test_evbuffer_empty_reference_prepend_buffer, TT_FORK, NULL, NULL },
|
||||
{ "peek", test_evbuffer_peek, 0, NULL, NULL },
|
||||
{ "peek_first_gt", test_evbuffer_peek_first_gt, 0, NULL, NULL },
|
||||
{ "freeze_start", test_evbuffer_freeze, 0, &nil_setup, __UNCONST("start") },
|
||||
{ "freeze_end", test_evbuffer_freeze, 0, &nil_setup, __UNCONST("end") },
|
||||
{ "freeze_start", test_evbuffer_freeze, TT_NEED_SOCKETPAIR, &basic_setup, __UNCONST("start") },
|
||||
{ "freeze_end", test_evbuffer_freeze, TT_NEED_SOCKETPAIR, &basic_setup, __UNCONST("end") },
|
||||
{ "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
|
||||
{ "copyout", test_evbuffer_copyout, 0, NULL, NULL},
|
||||
{ "file_segment_add_cleanup_cb", test_evbuffer_file_segment_add_cleanup_cb, 0, NULL, NULL },
|
||||
{ "pullup_with_empty", test_evbuffer_pullup_with_empty, 0, NULL, NULL },
|
||||
|
||||
#define ADDFILE_TEST(name, parameters) \
|
||||
{ name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE, \
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_bufferevent.c,v 1.3 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_bufferevent.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -30,6 +31,19 @@
|
|||
/* The old tests here need assertions to work. */
|
||||
#undef NDEBUG
|
||||
|
||||
/**
|
||||
* - clang supports __has_feature
|
||||
* - gcc supports __SANITIZE_ADDRESS__
|
||||
*
|
||||
* Let's set __SANITIZE_ADDRESS__ if __has_feature(address_sanitizer)
|
||||
*/
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
#if !defined(__SANITIZE_ADDRESS__) && __has_feature(address_sanitizer)
|
||||
#define __SANITIZE_ADDRESS__
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
@ -37,7 +51,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_bufferevent.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_bufferevent.c,v 1.4 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -66,8 +80,6 @@ __RCSID("$NetBSD: regress_bufferevent.c,v 1.3 2017/01/31 23:17:40 christos Exp $
|
|||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_bufferevent.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
||||
#include "event2/event.h"
|
||||
#include "event2/event_struct.h"
|
||||
#include "event2/event_compat.h"
|
||||
|
@ -142,14 +154,14 @@ test_bufferevent_impl(int use_pair, int flush)
|
|||
bev2 = xpair[1];
|
||||
bufferevent_setcb(bev1, readcb, writecb, errorcb, bev1);
|
||||
bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL);
|
||||
tt_int_op(bufferevent_getfd(bev1), ==, -1);
|
||||
tt_fd_op(bufferevent_getfd(bev1), ==, EVUTIL_INVALID_SOCKET);
|
||||
tt_ptr_op(bufferevent_get_underlying(bev1), ==, NULL);
|
||||
tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, bev2);
|
||||
tt_ptr_op(bufferevent_pair_get_partner(bev2), ==, bev1);
|
||||
} else {
|
||||
bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL);
|
||||
bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL);
|
||||
tt_int_op(bufferevent_getfd(bev1), ==, pair[0]);
|
||||
tt_fd_op(bufferevent_getfd(bev1), ==, pair[0]);
|
||||
tt_ptr_op(bufferevent_get_underlying(bev1), ==, NULL);
|
||||
tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, NULL);
|
||||
tt_ptr_op(bufferevent_pair_get_partner(bev2), ==, NULL);
|
||||
|
@ -208,7 +220,7 @@ static void test_bufferevent_pair_flush_normal(void) { test_bufferevent_impl(1,
|
|||
static void test_bufferevent_pair_flush_flush(void) { test_bufferevent_impl(1, BEV_FLUSH); }
|
||||
static void test_bufferevent_pair_flush_finished(void) { test_bufferevent_impl(1, BEV_FINISHED); }
|
||||
|
||||
#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED)
|
||||
#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) && !defined(__SANITIZE_ADDRESS__)
|
||||
/**
|
||||
* Trace lock/unlock/alloc/free for locks.
|
||||
* (More heavier then evthread_debug*)
|
||||
|
@ -574,8 +586,8 @@ test_bufferevent_filters_impl(int use_pair, int disable)
|
|||
|
||||
tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev1_base);
|
||||
tt_ptr_op(bufferevent_get_underlying(bev2), ==, bev2_base);
|
||||
tt_int_op(bufferevent_getfd(bev1), ==, -1);
|
||||
tt_int_op(bufferevent_getfd(bev2), ==, -1);
|
||||
tt_fd_op(bufferevent_getfd(bev1), ==, bufferevent_getfd(bev1_base));
|
||||
tt_fd_op(bufferevent_getfd(bev2), ==, bufferevent_getfd(bev2_base));
|
||||
|
||||
bufferevent_disable(bev1, EV_READ);
|
||||
bufferevent_enable(bev2, EV_READ);
|
||||
|
@ -645,7 +657,7 @@ end:
|
|||
;
|
||||
}
|
||||
|
||||
static int
|
||||
static evutil_socket_t
|
||||
fake_listener_create(struct sockaddr_in *localhost)
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)localhost;
|
||||
|
@ -792,16 +804,29 @@ end:
|
|||
bufferevent_free(bev2);
|
||||
}
|
||||
|
||||
static void
|
||||
close_socket_cb(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
evutil_socket_t *fdp = arg;
|
||||
if (*fdp >= 0) {
|
||||
evutil_closesocket(*fdp);
|
||||
*fdp = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_bufferevent_connect_fail_eventcb(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
int flags = BEV_OPT_CLOSE_ON_FREE | (long)data->setup_data;
|
||||
struct event close_listener_event;
|
||||
struct bufferevent *bev = NULL;
|
||||
struct evconnlistener *lev = NULL;
|
||||
struct sockaddr_in localhost;
|
||||
struct timeval close_timeout = { 0, 300000 };
|
||||
ev_socklen_t slen = sizeof(localhost);
|
||||
evutil_socket_t fake_listener = -1;
|
||||
int r;
|
||||
|
||||
fake_listener = fake_listener_create(&localhost);
|
||||
|
||||
|
@ -814,10 +839,22 @@ test_bufferevent_connect_fail_eventcb(void *arg)
|
|||
bufferevent_enable(bev, EV_READ|EV_WRITE);
|
||||
tt_int_op(n_events_invoked, ==, 0);
|
||||
tt_int_op(n_reads_invoked, ==, 0);
|
||||
|
||||
/** @see also test_bufferevent_connect_fail() */
|
||||
bufferevent_socket_connect(bev, (struct sockaddr *)&localhost, slen);
|
||||
r = bufferevent_socket_connect(bev, (struct sockaddr *)&localhost, slen);
|
||||
/* XXXX we'd like to test the '0' case everywhere, but FreeBSD tells
|
||||
* detects the error immediately, which is not really wrong of it. */
|
||||
tt_want(r == 0 || r == -1);
|
||||
|
||||
tt_int_op(n_events_invoked, ==, 0);
|
||||
tt_int_op(n_reads_invoked, ==, 0);
|
||||
|
||||
/* Close the listener socket after a delay. This should trigger
|
||||
"connection refused" on some other platforms, including OSX. */
|
||||
evtimer_assign(&close_listener_event, data->base, close_socket_cb,
|
||||
&fake_listener);
|
||||
event_add(&close_listener_event, &close_timeout);
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
tt_int_op(n_events_invoked, ==, 1);
|
||||
tt_int_op(n_reads_invoked, ==, 0);
|
||||
|
@ -851,16 +888,6 @@ want_fail_eventcb(struct bufferevent *bev, short what, void *ctx)
|
|||
event_base_loopexit(base, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
close_socket_cb(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
evutil_socket_t *fdp = arg;
|
||||
if (*fdp >= 0) {
|
||||
evutil_closesocket(*fdp);
|
||||
*fdp = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_bufferevent_connect_fail(void *arg)
|
||||
{
|
||||
|
@ -868,7 +895,7 @@ test_bufferevent_connect_fail(void *arg)
|
|||
struct bufferevent *bev=NULL;
|
||||
struct event close_listener_event;
|
||||
int close_listener_event_added = 0;
|
||||
struct timeval one_second = { 1, 0 };
|
||||
struct timeval close_timeout = { 0, 300000 };
|
||||
struct sockaddr_in localhost;
|
||||
ev_socklen_t slen = sizeof(localhost);
|
||||
evutil_socket_t fake_listener = -1;
|
||||
|
@ -887,11 +914,11 @@ test_bufferevent_connect_fail(void *arg)
|
|||
* detects the error immediately, which is not really wrong of it. */
|
||||
tt_want(r == 0 || r == -1);
|
||||
|
||||
/* Close the listener socket after a second. This should trigger
|
||||
/* Close the listener socket after a delay. This should trigger
|
||||
"connection refused" on some other platforms, including OSX. */
|
||||
evtimer_assign(&close_listener_event, data->base, close_socket_cb,
|
||||
&fake_listener);
|
||||
event_add(&close_listener_event, &one_second);
|
||||
event_add(&close_listener_event, &close_timeout);
|
||||
close_listener_event_added = 1;
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
|
@ -913,18 +940,24 @@ struct timeout_cb_result {
|
|||
struct timeval read_timeout_at;
|
||||
struct timeval write_timeout_at;
|
||||
struct timeval last_wrote_at;
|
||||
struct timeval last_read_at;
|
||||
int n_read_timeouts;
|
||||
int n_write_timeouts;
|
||||
int total_calls;
|
||||
};
|
||||
|
||||
static void
|
||||
bev_timeout_read_cb(struct bufferevent *bev, void *arg)
|
||||
{
|
||||
struct timeout_cb_result *res = arg;
|
||||
evutil_gettimeofday(&res->last_read_at, NULL);
|
||||
}
|
||||
static void
|
||||
bev_timeout_write_cb(struct bufferevent *bev, void *arg)
|
||||
{
|
||||
struct timeout_cb_result *res = arg;
|
||||
evutil_gettimeofday(&res->last_wrote_at, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
bev_timeout_event_cb(struct bufferevent *bev, short what, void *arg)
|
||||
{
|
||||
|
@ -952,7 +985,6 @@ test_bufferevent_timeouts(void *arg)
|
|||
int use_pair = 0, use_filter = 0;
|
||||
struct timeval tv_w, tv_r, started_at;
|
||||
struct timeout_cb_result res1, res2;
|
||||
char buf[1024];
|
||||
|
||||
memset(&res1, 0, sizeof(res1));
|
||||
memset(&res2, 0, sizeof(res2));
|
||||
|
@ -971,7 +1003,6 @@ test_bufferevent_timeouts(void *arg)
|
|||
bev1 = bufferevent_socket_new(data->base, data->pair[0], 0);
|
||||
bev2 = bufferevent_socket_new(data->base, data->pair[1], 0);
|
||||
}
|
||||
|
||||
tt_assert(bev1);
|
||||
tt_assert(bev2);
|
||||
|
||||
|
@ -995,30 +1026,14 @@ test_bufferevent_timeouts(void *arg)
|
|||
tv_w.tv_sec = tv_r.tv_sec = 0;
|
||||
tv_w.tv_usec = 100*1000;
|
||||
tv_r.tv_usec = 150*1000;
|
||||
bufferevent_setcb(bev1, NULL, bev_timeout_write_cb,
|
||||
bufferevent_setcb(bev1, bev_timeout_read_cb, bev_timeout_write_cb,
|
||||
bev_timeout_event_cb, &res1);
|
||||
bufferevent_setwatermark(bev1, EV_WRITE, 1024*1024+10, 0);
|
||||
bufferevent_set_timeouts(bev1, &tv_r, &tv_w);
|
||||
if (use_pair) {
|
||||
/* For a pair, the fact that the other side isn't reading
|
||||
* makes the writer stall */
|
||||
bufferevent_write(bev1, "ABCDEFG", 7);
|
||||
} else {
|
||||
/* For a real socket, the kernel's TCP buffers can eat a
|
||||
* fair number of bytes; make sure that at some point we
|
||||
* have some bytes that will stall. */
|
||||
struct evbuffer *output = bufferevent_get_output(bev1);
|
||||
int i;
|
||||
memset(buf, 0xbb, sizeof(buf));
|
||||
for (i=0;i<1024;++i) {
|
||||
evbuffer_add_reference(output, buf, sizeof(buf),
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
bufferevent_write(bev1, "ABCDEFG", 7);
|
||||
bufferevent_enable(bev1, EV_READ|EV_WRITE);
|
||||
|
||||
/* bev2 has nothing to say, and isn't listening. */
|
||||
bufferevent_setcb(bev2, NULL, bev_timeout_write_cb,
|
||||
bufferevent_setcb(bev2, bev_timeout_read_cb, bev_timeout_write_cb,
|
||||
bev_timeout_event_cb, &res2);
|
||||
tv_w.tv_sec = tv_r.tv_sec = 0;
|
||||
tv_w.tv_usec = 200*1000;
|
||||
|
@ -1035,15 +1050,26 @@ test_bufferevent_timeouts(void *arg)
|
|||
/* XXXX Test that actually reading or writing a little resets the
|
||||
* timeouts. */
|
||||
|
||||
/* Each buf1 timeout happens, and happens only once. */
|
||||
tt_want(res1.n_read_timeouts);
|
||||
tt_want(res1.n_write_timeouts);
|
||||
tt_want(res1.total_calls == 2);
|
||||
tt_want(res1.n_read_timeouts == 1);
|
||||
tt_want(res1.n_write_timeouts == 1);
|
||||
tt_want(res2.total_calls == !(use_pair && !use_filter));
|
||||
tt_want(res2.n_write_timeouts == !(use_pair && !use_filter));
|
||||
tt_want(!res2.n_read_timeouts);
|
||||
|
||||
test_timeval_diff_eq(&started_at, &res1.read_timeout_at, 150);
|
||||
test_timeval_diff_eq(&started_at, &res1.write_timeout_at, 100);
|
||||
|
||||
#define tt_assert_timeval_empty(tv) do { \
|
||||
tt_int_op((tv).tv_sec, ==, 0); \
|
||||
tt_int_op((tv).tv_usec, ==, 0); \
|
||||
} while(0)
|
||||
tt_assert_timeval_empty(res1.last_read_at);
|
||||
tt_assert_timeval_empty(res2.last_read_at);
|
||||
tt_assert_timeval_empty(res2.last_wrote_at);
|
||||
tt_assert_timeval_empty(res2.last_wrote_at);
|
||||
#undef tt_assert_timeval_empty
|
||||
|
||||
end:
|
||||
if (bev1)
|
||||
bufferevent_free(bev1);
|
||||
|
@ -1342,9 +1368,9 @@ struct testcase_t bufferevent_testcases[] = {
|
|||
LEGACY(bufferevent_pair_flush_normal, TT_ISOLATED),
|
||||
LEGACY(bufferevent_pair_flush_flush, TT_ISOLATED),
|
||||
LEGACY(bufferevent_pair_flush_finished, TT_ISOLATED),
|
||||
#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED)
|
||||
#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) && !defined(__SANITIZE_ADDRESS__)
|
||||
{ "bufferevent_pair_release_lock", test_bufferevent_pair_release_lock,
|
||||
TT_FORK|TT_ISOLATED|TT_NEED_THREADS|TT_NEED_BASE|TT_LEGACY,
|
||||
TT_FORK|TT_ISOLATED|TT_NEED_THREADS|TT_NEED_BASE|TT_LEGACY|TT_NO_LOGS,
|
||||
&basic_setup, NULL },
|
||||
#endif
|
||||
LEGACY(bufferevent_watermarks, TT_ISOLATED),
|
||||
|
@ -1368,7 +1394,7 @@ struct testcase_t bufferevent_testcases[] = {
|
|||
{ "bufferevent_connect_fail", test_bufferevent_connect_fail,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
{ "bufferevent_timeout", test_bufferevent_timeouts,
|
||||
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, __UNCONST("") },
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, __UNCONST("") },
|
||||
{ "bufferevent_timeout_pair", test_bufferevent_timeouts,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, __UNCONST("pair") },
|
||||
{ "bufferevent_timeout_filter", test_bufferevent_timeouts,
|
||||
|
@ -1411,38 +1437,35 @@ struct testcase_t bufferevent_testcases[] = {
|
|||
END_OF_TESTCASES,
|
||||
};
|
||||
|
||||
#define TT_IOCP (TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP)
|
||||
#define TT_IOCP_LEGACY (TT_ISOLATED|TT_ENABLE_IOCP)
|
||||
struct testcase_t bufferevent_iocp_testcases[] = {
|
||||
|
||||
LEGACY(bufferevent, TT_ISOLATED|TT_ENABLE_IOCP),
|
||||
LEGACY(bufferevent, TT_IOCP_LEGACY),
|
||||
LEGACY(bufferevent_flush_normal, TT_ISOLATED),
|
||||
LEGACY(bufferevent_flush_flush, TT_ISOLATED),
|
||||
LEGACY(bufferevent_flush_finished, TT_ISOLATED),
|
||||
LEGACY(bufferevent_watermarks, TT_ISOLATED|TT_ENABLE_IOCP),
|
||||
LEGACY(bufferevent_filters, TT_ISOLATED|TT_ENABLE_IOCP),
|
||||
LEGACY(bufferevent_filters_disable, TT_ISOLATED|TT_ENABLE_IOCP),
|
||||
LEGACY(bufferevent_watermarks, TT_IOCP_LEGACY),
|
||||
LEGACY(bufferevent_filters, TT_IOCP_LEGACY),
|
||||
LEGACY(bufferevent_filters_disable, TT_IOCP_LEGACY),
|
||||
|
||||
{ "bufferevent_connect", test_bufferevent_connect,
|
||||
TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, __UNCONST("") },
|
||||
TT_IOCP, &basic_setup, __UNCONST("") },
|
||||
{ "bufferevent_connect_defer", test_bufferevent_connect,
|
||||
TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, __UNCONST("defer") },
|
||||
TT_IOCP, &basic_setup, __UNCONST("defer") },
|
||||
{ "bufferevent_connect_lock", test_bufferevent_connect,
|
||||
TT_FORK|TT_NEED_BASE|TT_NEED_THREADS|TT_ENABLE_IOCP, &basic_setup,
|
||||
__UNCONST("lock") },
|
||||
TT_IOCP, &basic_setup, __UNCONST("lock") },
|
||||
{ "bufferevent_connect_lock_defer", test_bufferevent_connect,
|
||||
TT_FORK|TT_NEED_BASE|TT_NEED_THREADS|TT_ENABLE_IOCP, &basic_setup,
|
||||
__UNCONST("defer lock") },
|
||||
TT_IOCP, &basic_setup, __UNCONST("defer lock") },
|
||||
{ "bufferevent_connect_fail", test_bufferevent_connect_fail,
|
||||
TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL },
|
||||
TT_IOCP, &basic_setup, NULL },
|
||||
{ "bufferevent_connect_nonblocking", test_bufferevent_connect,
|
||||
TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup,
|
||||
__UNCONST("unset_connectex") },
|
||||
TT_IOCP, &basic_setup, __UNCONST("unset_connectex") },
|
||||
|
||||
{ "bufferevent_connect_fail_eventcb_defer",
|
||||
test_bufferevent_connect_fail_eventcb,
|
||||
TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup,
|
||||
(void*)BEV_OPT_DEFER_CALLBACKS },
|
||||
TT_IOCP, &basic_setup, (void*)BEV_OPT_DEFER_CALLBACKS },
|
||||
{ "bufferevent_connect_fail_eventcb",
|
||||
test_bufferevent_connect_fail_eventcb,
|
||||
TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL },
|
||||
test_bufferevent_connect_fail_eventcb, TT_IOCP, &basic_setup, NULL },
|
||||
|
||||
END_OF_TESTCASES,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_dns.c,v 1.5 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_dns.c,v 1.6 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -35,7 +36,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_dns.c,v 1.5 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_dns.c,v 1.6 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -62,6 +63,10 @@ __RCSID("$NetBSD: regress_dns.c,v 1.5 2017/01/31 23:17:40 christos Exp $");
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef EVENT__HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "event2/dns.h"
|
||||
#include "event2/dns_compat.h"
|
||||
#include "event2/dns_struct.h"
|
||||
|
@ -71,9 +76,12 @@ __RCSID("$NetBSD: regress_dns.c,v 1.5 2017/01/31 23:17:40 christos Exp $");
|
|||
#include "event2/util.h"
|
||||
#include "event2/listener.h"
|
||||
#include "event2/bufferevent.h"
|
||||
#include <event2/thread.h>
|
||||
#include "log-internal.h"
|
||||
#include "evthread-internal.h"
|
||||
#include "regress.h"
|
||||
#include "regress_testutils.h"
|
||||
#include "regress_thread.h"
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
|
@ -200,7 +208,7 @@ dns_resolve_reverse(void *ptr)
|
|||
{
|
||||
struct in_addr in;
|
||||
struct event_base *base = event_base_new();
|
||||
struct evdns_base *dns = evdns_base_new(base, 1/* init name servers */);
|
||||
struct evdns_base *dns = evdns_base_new(base, EVDNS_BASE_INITIALIZE_NAMESERVERS);
|
||||
struct evdns_request *req = NULL;
|
||||
|
||||
tt_assert(base);
|
||||
|
@ -615,16 +623,8 @@ end:
|
|||
if (dns)
|
||||
evdns_base_free(dns, 0);
|
||||
}
|
||||
static void
|
||||
dns_search_test(void *arg)
|
||||
{
|
||||
return dns_search_test_impl(arg, 0);
|
||||
}
|
||||
static void
|
||||
dns_search_lower_test(void *arg)
|
||||
{
|
||||
return dns_search_test_impl(arg, 1);
|
||||
}
|
||||
static void dns_search_test(void *arg) { dns_search_test_impl(arg, 0); }
|
||||
static void dns_search_lower_test(void *arg) { dns_search_test_impl(arg, 1); }
|
||||
|
||||
static int request_count = 0;
|
||||
static struct evdns_request *current_req = NULL;
|
||||
|
@ -1008,6 +1008,59 @@ end:
|
|||
event_base_free(inactive_base);
|
||||
}
|
||||
|
||||
static void
|
||||
dns_initialize_nameservers_test(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
struct evdns_base *dns = NULL;
|
||||
|
||||
dns = evdns_base_new(base, 0);
|
||||
tt_assert(dns);
|
||||
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, -1);
|
||||
evdns_base_free(dns, 0);
|
||||
|
||||
dns = evdns_base_new(base, EVDNS_BASE_INITIALIZE_NAMESERVERS);
|
||||
tt_assert(dns);
|
||||
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, sizeof(struct sockaddr));
|
||||
|
||||
end:
|
||||
if (dns)
|
||||
evdns_base_free(dns, 0);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
#define RESOLV_FILE "empty-resolv.conf"
|
||||
static void
|
||||
dns_nameservers_no_default_test(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
struct evdns_base *dns = NULL;
|
||||
int ok = access(RESOLV_FILE, R_OK);
|
||||
|
||||
tt_assert(ok);
|
||||
|
||||
dns = evdns_base_new(base, 0);
|
||||
tt_assert(dns);
|
||||
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, -1);
|
||||
|
||||
/* We cannot test
|
||||
* EVDNS_BASE_INITIALIZE_NAMESERVERS|EVDNS_BASE_NAMESERVERS_NO_DEFAULT
|
||||
* because we cannot mock "/etc/resolv.conf" (yet). */
|
||||
|
||||
evdns_base_resolv_conf_parse(dns,
|
||||
DNS_OPTIONS_ALL|DNS_OPTION_NAMESERVERS_NO_DEFAULT, RESOLV_FILE);
|
||||
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, -1);
|
||||
|
||||
evdns_base_resolv_conf_parse(dns, DNS_OPTIONS_ALL, RESOLV_FILE);
|
||||
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, sizeof(struct sockaddr));
|
||||
|
||||
end:
|
||||
if (dns)
|
||||
evdns_base_free(dns, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* === Test for bufferevent_socket_connect_hostname */
|
||||
|
||||
static int total_connected_or_failed = 0;
|
||||
|
@ -1024,7 +1077,7 @@ be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data)
|
|||
int added_any=0;
|
||||
++*n_got_p;
|
||||
|
||||
for (i=0;i<req->nquestions;++i) {
|
||||
for (i = 0; i < req->nquestions; ++i) {
|
||||
const int qtype = req->questions[i]->type;
|
||||
const int qclass = req->questions[i]->dns_question_class;
|
||||
const char *qname = req->questions[i]->name;
|
||||
|
@ -1168,27 +1221,36 @@ static void
|
|||
be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx)
|
||||
{
|
||||
struct be_conn_hostname_result *got = ctx;
|
||||
if (!got->what) {
|
||||
TT_BLATHER(("Got a bufferevent event %d", what));
|
||||
got->what = what;
|
||||
|
||||
if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
|
||||
int r;
|
||||
if ((r = bufferevent_socket_get_dns_error(bev))) {
|
||||
got->dnserr = r;
|
||||
TT_BLATHER(("DNS error %d: %s", r,
|
||||
evutil_gai_strerror(r)));
|
||||
} ++total_connected_or_failed;
|
||||
TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
|
||||
|
||||
if (total_n_accepted >= 3 && total_connected_or_failed >= 5)
|
||||
event_base_loopexit(be_connect_hostname_base,
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
if (got->what) {
|
||||
TT_FAIL(("Two events on one bufferevent. %d,%d",
|
||||
got->what, (int)what));
|
||||
}
|
||||
|
||||
TT_BLATHER(("Got a bufferevent event %d", what));
|
||||
got->what = what;
|
||||
|
||||
if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
|
||||
int expected = 3;
|
||||
int r = bufferevent_socket_get_dns_error(bev);
|
||||
|
||||
if (r) {
|
||||
got->dnserr = r;
|
||||
TT_BLATHER(("DNS error %d: %s", r,
|
||||
evutil_gai_strerror(r)));
|
||||
}
|
||||
++total_connected_or_failed;
|
||||
TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
|
||||
|
||||
/** emfile test */
|
||||
if (errno == EMFILE) {
|
||||
expected = 0;
|
||||
}
|
||||
|
||||
if (total_n_accepted >= expected && total_connected_or_failed >= 5)
|
||||
event_base_loopexit(be_connect_hostname_base,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1196,10 +1258,9 @@ test_bufferevent_connect_hostname(void *arg)
|
|||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct evconnlistener *listener = NULL;
|
||||
struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL;
|
||||
struct be_conn_hostname_result be1_outcome={0,0}, be2_outcome={0,0},
|
||||
be3_outcome={0,0}, be4_outcome={0,0}, be5_outcome={0,0};
|
||||
int expect_err5;
|
||||
struct bufferevent *be[5];
|
||||
struct be_conn_hostname_result be_outcome[ARRAY_SIZE(be)];
|
||||
int expect_err;
|
||||
struct evdns_base *dns=NULL;
|
||||
struct evdns_server_port *port=NULL;
|
||||
struct sockaddr_in sin;
|
||||
|
@ -1207,6 +1268,9 @@ test_bufferevent_connect_hostname(void *arg)
|
|||
ev_uint16_t dns_port=0;
|
||||
int n_accept=0, n_dns=0;
|
||||
char buf[128];
|
||||
int emfile = data->setup_data && !strcmp(data->setup_data, "emfile");
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
be_connect_hostname_base = data->base;
|
||||
|
||||
|
@ -1233,32 +1297,34 @@ test_bufferevent_connect_hostname(void *arg)
|
|||
evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)dns_port);
|
||||
evdns_base_nameserver_ip_add(dns, buf);
|
||||
|
||||
#ifdef EVENT__HAVE_SETRLIMIT
|
||||
if (emfile) {
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct rlimit file = { fd, fd };
|
||||
|
||||
tt_int_op(fd, >=, 0);
|
||||
tt_assert(!close(fd));
|
||||
|
||||
tt_assert(!setrlimit(RLIMIT_NOFILE, &file));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now, finally, at long last, launch the bufferevents. One should do
|
||||
* a failing lookup IP, one should do a successful lookup by IP,
|
||||
* and one should do a successful lookup by hostname. */
|
||||
be1 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
|
||||
be2 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
|
||||
be3 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
|
||||
be4 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
|
||||
be5 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
|
||||
|
||||
bufferevent_setcb(be1, NULL, NULL, be_connect_hostname_event_cb,
|
||||
&be1_outcome);
|
||||
bufferevent_setcb(be2, NULL, NULL, be_connect_hostname_event_cb,
|
||||
&be2_outcome);
|
||||
bufferevent_setcb(be3, NULL, NULL, be_connect_hostname_event_cb,
|
||||
&be3_outcome);
|
||||
bufferevent_setcb(be4, NULL, NULL, be_connect_hostname_event_cb,
|
||||
&be4_outcome);
|
||||
bufferevent_setcb(be5, NULL, NULL, be_connect_hostname_event_cb,
|
||||
&be5_outcome);
|
||||
for (i = 0; i < ARRAY_SIZE(be); ++i) {
|
||||
memset(&be_outcome[i], 0, sizeof(be_outcome[i]));
|
||||
be[i] = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
|
||||
bufferevent_setcb(be[i], NULL, NULL, be_connect_hostname_event_cb,
|
||||
&be_outcome[i]);
|
||||
}
|
||||
|
||||
/* Use the blocking resolver. This one will fail if your resolver
|
||||
* can't resolve localhost to 127.0.0.1 */
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be4, NULL, AF_INET,
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be[3], NULL, AF_INET,
|
||||
"localhost", listener_port));
|
||||
/* Use the blocking resolver with a nonexistent hostname. */
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be5, NULL, AF_INET,
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be[4], NULL, AF_INET,
|
||||
"nonesuch.nowhere.example.com", 80));
|
||||
{
|
||||
/* The blocking resolver will use the system nameserver, which
|
||||
|
@ -1269,35 +1335,53 @@ test_bufferevent_connect_hostname(void *arg)
|
|||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
expect_err5 = evutil_getaddrinfo(
|
||||
expect_err = evutil_getaddrinfo(
|
||||
"nonesuch.nowhere.example.com", "80", &hints, &ai);
|
||||
}
|
||||
/* Launch an async resolve that will fail. */
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be1, dns, AF_INET,
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be[0], dns, AF_INET,
|
||||
"nosuchplace.example.com", listener_port));
|
||||
/* Connect to the IP without resolving. */
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be2, dns, AF_INET,
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be[1], dns, AF_INET,
|
||||
"127.0.0.1", listener_port));
|
||||
/* Launch an async resolve that will succeed. */
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be3, dns, AF_INET,
|
||||
tt_assert(!bufferevent_socket_connect_hostname(be[2], dns, AF_INET,
|
||||
"nobodaddy.example.com", listener_port));
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
|
||||
tt_int_op(be1_outcome.what, ==, BEV_EVENT_ERROR);
|
||||
tt_int_op(be1_outcome.dnserr, ==, EVUTIL_EAI_NONAME);
|
||||
tt_int_op(be2_outcome.what, ==, BEV_EVENT_CONNECTED);
|
||||
tt_int_op(be2_outcome.dnserr, ==, 0);
|
||||
tt_int_op(be3_outcome.what, ==, BEV_EVENT_CONNECTED);
|
||||
tt_int_op(be3_outcome.dnserr, ==, 0);
|
||||
tt_int_op(be4_outcome.what, ==, BEV_EVENT_CONNECTED);
|
||||
tt_int_op(be4_outcome.dnserr, ==, 0);
|
||||
if (expect_err5) {
|
||||
tt_int_op(be5_outcome.what, ==, BEV_EVENT_ERROR);
|
||||
tt_int_op(be5_outcome.dnserr, ==, expect_err5);
|
||||
ret = event_base_dispatch(data->base);
|
||||
#ifdef __sun__
|
||||
if (emfile && !strcmp(event_base_get_method(data->base), "devpoll")) {
|
||||
tt_int_op(ret, ==, -1);
|
||||
/** DP_POLL failed */
|
||||
tt_skip();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
tt_int_op(ret, ==, 0);
|
||||
}
|
||||
|
||||
tt_int_op(n_accept, ==, 3);
|
||||
tt_int_op(be_outcome[0].what, ==, BEV_EVENT_ERROR);
|
||||
tt_int_op(be_outcome[0].dnserr, ==, EVUTIL_EAI_NONAME);
|
||||
tt_int_op(be_outcome[1].what, ==, !emfile ? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR);
|
||||
tt_int_op(be_outcome[1].dnserr, ==, 0);
|
||||
tt_int_op(be_outcome[2].what, ==, !emfile ? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR);
|
||||
tt_int_op(be_outcome[2].dnserr, ==, 0);
|
||||
tt_int_op(be_outcome[3].what, ==, !emfile ? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR);
|
||||
if (!emfile) {
|
||||
tt_int_op(be_outcome[3].dnserr, ==, 0);
|
||||
} else {
|
||||
tt_int_op(be_outcome[3].dnserr, !=, 0);
|
||||
}
|
||||
if (expect_err) {
|
||||
tt_int_op(be_outcome[4].what, ==, BEV_EVENT_ERROR);
|
||||
tt_int_op(be_outcome[4].dnserr, ==, expect_err);
|
||||
}
|
||||
|
||||
if (emfile) {
|
||||
tt_int_op(n_accept, ==, 0);
|
||||
} else {
|
||||
tt_int_op(n_accept, ==, 3);
|
||||
}
|
||||
tt_int_op(n_dns, ==, 2);
|
||||
|
||||
end:
|
||||
|
@ -1307,16 +1391,10 @@ end:
|
|||
evdns_close_server_port(port);
|
||||
if (dns)
|
||||
evdns_base_free(dns, 0);
|
||||
if (be1)
|
||||
bufferevent_free(be1);
|
||||
if (be2)
|
||||
bufferevent_free(be2);
|
||||
if (be3)
|
||||
bufferevent_free(be3);
|
||||
if (be4)
|
||||
bufferevent_free(be4);
|
||||
if (be5)
|
||||
bufferevent_free(be5);
|
||||
for (i = 0; i < ARRAY_SIZE(be); ++i) {
|
||||
if (be[i])
|
||||
bufferevent_free(be[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1355,7 +1433,7 @@ test_getaddrinfo_async(void *arg)
|
|||
struct evutil_addrinfo hints, *a;
|
||||
struct gai_outcome local_outcome;
|
||||
struct gai_outcome a_out[12];
|
||||
int i;
|
||||
unsigned i;
|
||||
struct evdns_getaddrinfo_request *r;
|
||||
char buf[128];
|
||||
struct evdns_server_port *port = NULL;
|
||||
|
@ -1713,7 +1791,7 @@ test_getaddrinfo_async(void *arg)
|
|||
end:
|
||||
if (local_outcome.ai)
|
||||
evutil_freeaddrinfo(local_outcome.ai);
|
||||
for (i=0;i<(int)ARRAY_SIZE(a_out);++i) {
|
||||
for (i = 0; i < ARRAY_SIZE(a_out); ++i) {
|
||||
if (a_out[i].ai)
|
||||
evutil_freeaddrinfo(a_out[i].ai);
|
||||
}
|
||||
|
@ -1734,7 +1812,8 @@ struct gaic_request_status {
|
|||
|
||||
#define GAIC_MAGIC 0x1234abcd
|
||||
|
||||
static int pending = 0;
|
||||
static int gaic_pending = 0;
|
||||
static int gaic_freed = 0;
|
||||
|
||||
static void
|
||||
gaic_cancel_request_cb(evutil_socket_t fd, short what, void *arg)
|
||||
|
@ -1779,7 +1858,13 @@ gaic_getaddrinfo_cb(int result, struct evutil_addrinfo *res, void *arg)
|
|||
free(status);
|
||||
|
||||
end:
|
||||
if (--pending <= 0)
|
||||
if (res)
|
||||
{
|
||||
TT_BLATHER(("evutil_freeaddrinfo(%p)", res));
|
||||
evutil_freeaddrinfo(res);
|
||||
++gaic_freed;
|
||||
}
|
||||
if (--gaic_pending <= 0)
|
||||
event_base_loopexit(base, NULL);
|
||||
}
|
||||
|
||||
|
@ -1797,7 +1882,7 @@ gaic_launch(struct event_base *base, struct evdns_base *dns_base)
|
|||
"foobar.bazquux.example.com", "80", NULL, gaic_getaddrinfo_cb,
|
||||
status);
|
||||
event_add(&status->cancel_event, &tv);
|
||||
++pending;
|
||||
++gaic_pending;
|
||||
}
|
||||
|
||||
#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
|
||||
|
@ -1987,7 +2072,7 @@ test_getaddrinfo_async_cancel_stress(void *ptr)
|
|||
struct sockaddr_in sin;
|
||||
struct sockaddr_storage ss;
|
||||
ev_socklen_t slen;
|
||||
int i;
|
||||
unsigned i;
|
||||
|
||||
base = event_base_new();
|
||||
dns_base = evdns_base_new(base, 0);
|
||||
|
@ -2020,6 +2105,9 @@ test_getaddrinfo_async_cancel_stress(void *ptr)
|
|||
|
||||
event_base_dispatch(base);
|
||||
|
||||
// at least some was canceled via external event
|
||||
tt_int_op(gaic_freed, !=, 1000);
|
||||
|
||||
end:
|
||||
if (dns_base)
|
||||
evdns_base_free(dns_base, 1);
|
||||
|
@ -2036,13 +2124,14 @@ dns_client_fail_requests_test(void *arg)
|
|||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
int limit_inflight = data->setup_data && !strcmp(data->setup_data, "limit-inflight");
|
||||
struct evdns_base *dns = NULL;
|
||||
struct evdns_server_port *dns_port = NULL;
|
||||
ev_uint16_t portnum = 0;
|
||||
char buf[64];
|
||||
|
||||
struct generic_dns_callback_result r[20];
|
||||
int i;
|
||||
unsigned i;
|
||||
|
||||
dns_port = regress_get_dnsserver(base, &portnum, NULL,
|
||||
regress_dns_server_cb, reissue_table);
|
||||
|
@ -2053,6 +2142,9 @@ dns_client_fail_requests_test(void *arg)
|
|||
dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE);
|
||||
tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
|
||||
|
||||
if (limit_inflight)
|
||||
tt_assert(!evdns_base_set_option(dns, "max-inflight:", "11"));
|
||||
|
||||
for (i = 0; i < 20; ++i)
|
||||
evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r[i]);
|
||||
|
||||
|
@ -2099,7 +2191,7 @@ dns_client_fail_requests_getaddrinfo_test(void *arg)
|
|||
tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
|
||||
|
||||
for (i = 0; i < 20; ++i)
|
||||
tt_assert(evdns_getaddrinfo(dns, "foof.example.com", "ssh", NULL, getaddrinfo_cb, &r[i]));
|
||||
tt_assert(evdns_getaddrinfo(dns, "foof.example.com", "80", NULL, getaddrinfo_cb, &r[i]));
|
||||
|
||||
n_replies_left = 20;
|
||||
exit_base = base;
|
||||
|
@ -2116,6 +2208,242 @@ end:
|
|||
evdns_close_server_port(dns_port);
|
||||
}
|
||||
|
||||
#ifdef EVTHREAD_USE_PTHREADS_IMPLEMENTED
|
||||
struct race_param
|
||||
{
|
||||
void *lock;
|
||||
void *reqs_cmpl_cond;
|
||||
int bw_threads;
|
||||
void *bw_threads_exited_cond;
|
||||
volatile int stopping;
|
||||
void *base;
|
||||
void *dns;
|
||||
|
||||
int locked;
|
||||
};
|
||||
static void *
|
||||
race_base_run(void *arg)
|
||||
{
|
||||
struct race_param *rp = (struct race_param *)arg;
|
||||
event_base_loop(rp->base, EVLOOP_NO_EXIT_ON_EMPTY);
|
||||
THREAD_RETURN();
|
||||
}
|
||||
static void *
|
||||
race_busywait_run(void *arg)
|
||||
{
|
||||
struct race_param *rp = (struct race_param *)arg;
|
||||
struct sockaddr_storage ss;
|
||||
while (!rp->stopping)
|
||||
evdns_base_get_nameserver_addr(rp->dns, 0, (struct sockaddr *)&ss, sizeof(ss));
|
||||
EVLOCK_LOCK(rp->lock, 0);
|
||||
if (--rp->bw_threads == 0)
|
||||
EVTHREAD_COND_SIGNAL(rp->bw_threads_exited_cond);
|
||||
EVLOCK_UNLOCK(rp->lock, 0);
|
||||
THREAD_RETURN();
|
||||
}
|
||||
static void
|
||||
race_gai_cb(int result, struct evutil_addrinfo *res, void *arg)
|
||||
{
|
||||
struct race_param *rp = arg;
|
||||
(void)result;
|
||||
(void)res;
|
||||
|
||||
--n_replies_left;
|
||||
if (n_replies_left == 0) {
|
||||
EVLOCK_LOCK(rp->lock, 0);
|
||||
EVTHREAD_COND_SIGNAL(rp->reqs_cmpl_cond);
|
||||
EVLOCK_UNLOCK(rp->lock, 0);
|
||||
}
|
||||
}
|
||||
static void
|
||||
getaddrinfo_race_gotresolve_test(void *arg)
|
||||
{
|
||||
struct race_param rp;
|
||||
struct evdns_server_port *dns_port = NULL;
|
||||
ev_uint16_t portnum = 0;
|
||||
char buf[64];
|
||||
int i;
|
||||
|
||||
// Some stress is needed to yield inside getaddrinfo between resolve_ipv4 and resolve_ipv6
|
||||
int n_reqs = 16384;
|
||||
#ifdef _SC_NPROCESSORS_ONLN
|
||||
int n_threads = sysconf(_SC_NPROCESSORS_ONLN) + 1;
|
||||
#else
|
||||
int n_threads = 17;
|
||||
#endif
|
||||
THREAD_T *thread;
|
||||
struct timeval tv;
|
||||
|
||||
(void)arg;
|
||||
|
||||
thread = calloc(n_threads, sizeof(*thread));
|
||||
tt_assert(thread);
|
||||
|
||||
evthread_use_pthreads();
|
||||
|
||||
rp.base = event_base_new();
|
||||
tt_assert(rp.base);
|
||||
if (evthread_make_base_notifiable(rp.base) < 0)
|
||||
tt_abort_msg("Couldn't make base notifiable!");
|
||||
|
||||
dns_port = regress_get_dnsserver(rp.base, &portnum, NULL,
|
||||
regress_dns_server_cb, reissue_table);
|
||||
tt_assert(dns_port);
|
||||
|
||||
evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
|
||||
|
||||
rp.dns = evdns_base_new(rp.base, 0);
|
||||
tt_assert(!evdns_base_nameserver_ip_add(rp.dns, buf));
|
||||
|
||||
n_replies_left = n_reqs;
|
||||
|
||||
EVTHREAD_ALLOC_LOCK(rp.lock, 0);
|
||||
EVTHREAD_ALLOC_COND(rp.reqs_cmpl_cond);
|
||||
EVTHREAD_ALLOC_COND(rp.bw_threads_exited_cond);
|
||||
tt_assert(rp.lock);
|
||||
tt_assert(rp.reqs_cmpl_cond);
|
||||
tt_assert(rp.bw_threads_exited_cond);
|
||||
rp.bw_threads = 0;
|
||||
rp.stopping = 0;
|
||||
|
||||
// Run resolver thread
|
||||
THREAD_START(thread[0], race_base_run, &rp);
|
||||
// Run busy-wait threads used to force yield this thread
|
||||
for (i = 1; i < n_threads; i++) {
|
||||
rp.bw_threads++;
|
||||
THREAD_START(thread[i], race_busywait_run, &rp);
|
||||
}
|
||||
|
||||
EVLOCK_LOCK(rp.lock, 0);
|
||||
rp.locked = 1;
|
||||
|
||||
for (i = 0; i < n_reqs; ++i) {
|
||||
tt_assert(evdns_getaddrinfo(rp.dns, "foof.example.com", "80", NULL, race_gai_cb, &rp));
|
||||
// This magic along with busy-wait threads make this thread yield frequently
|
||||
if (i % 100 == 0) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
evutil_usleep_(&tv);
|
||||
}
|
||||
}
|
||||
|
||||
exit_base = rp.base;
|
||||
|
||||
// Wait for some time
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
EVTHREAD_COND_WAIT_TIMED(rp.reqs_cmpl_cond, rp.lock, &tv);
|
||||
|
||||
// Stop busy-wait threads
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
rp.stopping = 1;
|
||||
tt_assert(EVTHREAD_COND_WAIT_TIMED(rp.bw_threads_exited_cond, rp.lock, &tv) == 0);
|
||||
|
||||
EVLOCK_UNLOCK(rp.lock, 0);
|
||||
rp.locked = 0;
|
||||
|
||||
evdns_base_free(rp.dns, 1 /** fail requests */);
|
||||
|
||||
tt_int_op(n_replies_left, ==, 0);
|
||||
|
||||
end:
|
||||
if (rp.locked)
|
||||
EVLOCK_UNLOCK(rp.lock, 0);
|
||||
EVTHREAD_FREE_LOCK(rp.lock, 0);
|
||||
EVTHREAD_FREE_COND(rp.reqs_cmpl_cond);
|
||||
EVTHREAD_FREE_COND(rp.bw_threads_exited_cond);
|
||||
evdns_close_server_port(dns_port);
|
||||
event_base_loopbreak(rp.base);
|
||||
event_base_free(rp.base);
|
||||
free(thread);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_set_so_rcvbuf_so_sndbuf(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct evdns_base *dns_base;
|
||||
|
||||
dns_base = evdns_base_new(data->base, 0);
|
||||
tt_assert(dns_base);
|
||||
|
||||
tt_assert(!evdns_base_set_option(dns_base, "so-rcvbuf", "10240"));
|
||||
tt_assert(!evdns_base_set_option(dns_base, "so-sndbuf", "10240"));
|
||||
|
||||
/* actually check SO_RCVBUF/SO_SNDBUF not fails */
|
||||
tt_assert(!evdns_base_nameserver_ip_add(dns_base, "127.0.0.1"));
|
||||
|
||||
end:
|
||||
if (dns_base)
|
||||
evdns_base_free(dns_base, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_option(void *arg)
|
||||
{
|
||||
#define SUCCESS 0
|
||||
#define FAIL -1
|
||||
struct basic_test_data *data = arg;
|
||||
struct evdns_base *dns_base;
|
||||
size_t i;
|
||||
/* Option names are allowed to have ':' at the end.
|
||||
* So all test option names come in pairs.
|
||||
*/
|
||||
const char *int_options[] = {
|
||||
"ndots", "ndots:",
|
||||
"max-timeouts", "max-timeouts:",
|
||||
"max-inflight", "max-inflight:",
|
||||
"attempts", "attempts:",
|
||||
"randomize-case", "randomize-case:",
|
||||
"so-rcvbuf", "so-rcvbuf:",
|
||||
"so-sndbuf", "so-sndbuf:",
|
||||
};
|
||||
const char *timeval_options[] = {
|
||||
"timeout", "timeout:",
|
||||
"getaddrinfo-allow-skew", "getaddrinfo-allow-skew:",
|
||||
"initial-probe-timeout", "initial-probe-timeout:",
|
||||
};
|
||||
const char *addr_port_options[] = {
|
||||
"bind-to", "bind-to:",
|
||||
};
|
||||
|
||||
dns_base = evdns_base_new(data->base, 0);
|
||||
tt_assert(dns_base);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(int_options); ++i) {
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, int_options[i], "0"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, int_options[i], "1"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, int_options[i], "10000"));
|
||||
tt_assert(FAIL == evdns_base_set_option(dns_base, int_options[i], "foo"));
|
||||
tt_assert(FAIL == evdns_base_set_option(dns_base, int_options[i], "3.14"));
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(timeval_options); ++i) {
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "1"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "0.001"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "3.14"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "10000"));
|
||||
tt_assert(FAIL == evdns_base_set_option(dns_base, timeval_options[i], "0"));
|
||||
tt_assert(FAIL == evdns_base_set_option(dns_base, timeval_options[i], "foo"));
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(addr_port_options); ++i) {
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "8.8.8.8:80"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "1.2.3.4"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "::1:82"));
|
||||
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "3::4"));
|
||||
tt_assert(FAIL == evdns_base_set_option(dns_base, addr_port_options[i], "3.14"));
|
||||
tt_assert(FAIL == evdns_base_set_option(dns_base, addr_port_options[i], "foo"));
|
||||
}
|
||||
|
||||
#undef SUCCESS
|
||||
#undef FAIL
|
||||
end:
|
||||
if (dns_base)
|
||||
evdns_base_free(dns_base, 0);
|
||||
}
|
||||
|
||||
#define DNS_LEGACY(name, flags) \
|
||||
{ #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \
|
||||
|
@ -2141,10 +2469,21 @@ struct testcase_t dns_testcases[] = {
|
|||
{ "inflight", dns_inflight_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
{ "bufferevent_connect_hostname", test_bufferevent_connect_hostname,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
#ifdef EVENT__HAVE_SETRLIMIT
|
||||
{ "bufferevent_connect_hostname_emfile", test_bufferevent_connect_hostname,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, __UNCONST("emfile") },
|
||||
#endif
|
||||
{ "disable_when_inactive", dns_disable_when_inactive_test,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
{ "disable_when_inactive_no_ns", dns_disable_when_inactive_no_ns_test,
|
||||
TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL },
|
||||
|
||||
{ "initialize_nameservers", dns_initialize_nameservers_test,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
#ifndef _WIN32
|
||||
{ "nameservers_no_default", dns_nameservers_no_default_test,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
#endif
|
||||
|
||||
{ "getaddrinfo_async", test_getaddrinfo_async,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, __UNCONST("") },
|
||||
|
@ -2165,9 +2504,21 @@ struct testcase_t dns_testcases[] = {
|
|||
#endif
|
||||
|
||||
{ "client_fail_requests", dns_client_fail_requests_test,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL },
|
||||
{ "client_fail_waiting_requests", dns_client_fail_requests_test,
|
||||
TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, __UNCONST("limit-inflight") },
|
||||
{ "client_fail_requests_getaddrinfo",
|
||||
dns_client_fail_requests_getaddrinfo_test,
|
||||
TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL },
|
||||
#ifdef EVTHREAD_USE_PTHREADS_IMPLEMENTED
|
||||
{ "getaddrinfo_race_gotresolve",
|
||||
getaddrinfo_race_gotresolve_test,
|
||||
TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL },
|
||||
#endif
|
||||
|
||||
{ "set_SO_RCVBUF_SO_SNDBUF", test_set_so_rcvbuf_so_sndbuf,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
{ "set_options", test_set_option,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
|
||||
END_OF_TESTCASES
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_et.c,v 1.3 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_et.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -27,7 +28,7 @@
|
|||
#include "../util-internal.h"
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_et.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_et.c,v 1.4 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
|
@ -54,6 +55,14 @@ __RCSID("$NetBSD: regress_et.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
|||
|
||||
static int was_et = 0;
|
||||
|
||||
static int base_supports_et(struct event_base *base)
|
||||
{
|
||||
return
|
||||
(!strcmp(event_base_get_method(base), "epoll") ||
|
||||
!strcmp(event_base_get_method(base), "epoll (with changelist)") ||
|
||||
!strcmp(event_base_get_method(base), "kqueue"));
|
||||
}
|
||||
|
||||
static void
|
||||
read_cb(evutil_socket_t fd, short event, void *arg)
|
||||
{
|
||||
|
@ -70,19 +79,14 @@ read_cb(evutil_socket_t fd, short event, void *arg)
|
|||
event_del(arg);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define LOCAL_SOCKETPAIR_AF AF_INET
|
||||
#else
|
||||
#define LOCAL_SOCKETPAIR_AF AF_UNIX
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_edgetriggered(void *et)
|
||||
test_edgetriggered(void *data_)
|
||||
{
|
||||
struct basic_test_data *data = data_;
|
||||
struct event_base *base = data->base;
|
||||
evutil_socket_t *xpair = data->pair;
|
||||
struct event *ev = NULL;
|
||||
struct event_base *base = NULL;
|
||||
const char *test = "test string";
|
||||
evutil_socket_t xpair[2] = {-1,-1};
|
||||
int supports_et;
|
||||
|
||||
/* On Linux 3.2.1 (at least, as patched by Fedora and tested by Nick),
|
||||
|
@ -91,39 +95,21 @@ test_edgetriggered(void *et)
|
|||
* get edge-triggered behavior. Yuck! Linux 3.1.9 didn't have this
|
||||
* problem.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, xpair) == -1) {
|
||||
tt_abort_perror("socketpair");
|
||||
}
|
||||
#else
|
||||
if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, xpair) == -1) {
|
||||
tt_abort_perror("socketpair");
|
||||
}
|
||||
#endif
|
||||
|
||||
called = was_et = 0;
|
||||
|
||||
tt_int_op(send(xpair[0], test, (int)strlen(test)+1, 0), >, 0);
|
||||
shutdown(xpair[0], EVUTIL_SHUT_WR);
|
||||
|
||||
/* Initalize the event library */
|
||||
base = event_base_new();
|
||||
|
||||
if (!strcmp(event_base_get_method(base), "epoll") ||
|
||||
!strcmp(event_base_get_method(base), "epoll (with changelist)") ||
|
||||
!strcmp(event_base_get_method(base), "kqueue"))
|
||||
supports_et = 1;
|
||||
else
|
||||
supports_et = 0;
|
||||
tt_int_op(shutdown(xpair[0], EVUTIL_SHUT_WR), ==, 0);
|
||||
|
||||
supports_et = base_supports_et(base);
|
||||
TT_BLATHER(("Checking for edge-triggered events with %s, which should %s"
|
||||
"support edge-triggering", event_base_get_method(base),
|
||||
supports_et?"":"not "));
|
||||
|
||||
/* Initalize one event */
|
||||
/* Initialize one event */
|
||||
ev = event_new(base, xpair[1], EV_READ|EV_ET|EV_PERSIST, read_cb, &ev);
|
||||
|
||||
event_add(ev, NULL);
|
||||
tt_assert(ev != NULL);
|
||||
tt_int_op(event_add(ev, NULL), ==, 0);
|
||||
|
||||
/* We're going to call the dispatch function twice. The first invocation
|
||||
* will read a single byte from xpair[1] in either case. If we're edge
|
||||
|
@ -132,8 +118,8 @@ test_edgetriggered(void *et)
|
|||
* do nothing. If we're level triggered, the second invocation of
|
||||
* event_base_loop will also activate the event (because there's still
|
||||
* data to read). */
|
||||
event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE);
|
||||
event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE);
|
||||
tt_int_op(event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE), ==, 0);
|
||||
tt_int_op(event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE), ==, 0);
|
||||
|
||||
if (supports_et) {
|
||||
tt_int_op(called, ==, 1);
|
||||
|
@ -143,15 +129,11 @@ test_edgetriggered(void *et)
|
|||
tt_assert(!was_et);
|
||||
}
|
||||
|
||||
end:
|
||||
end:
|
||||
if (ev) {
|
||||
event_del(ev);
|
||||
event_free(ev);
|
||||
}
|
||||
if (base)
|
||||
event_base_free(base);
|
||||
evutil_closesocket(xpair[0]);
|
||||
evutil_closesocket(xpair[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -199,9 +181,94 @@ end:
|
|||
event_base_free(base);
|
||||
}
|
||||
|
||||
static int read_notification_count;
|
||||
static int last_read_notification_was_et;
|
||||
static void
|
||||
read_notification_cb(evutil_socket_t fd, short event, void *arg)
|
||||
{
|
||||
read_notification_count++;
|
||||
last_read_notification_was_et = (event & EV_ET);
|
||||
}
|
||||
|
||||
static int write_notification_count;
|
||||
static int last_write_notification_was_et;
|
||||
static void
|
||||
write_notification_cb(evutil_socket_t fd, short event, void *arg)
|
||||
{
|
||||
write_notification_count++;
|
||||
last_write_notification_was_et = (event & EV_ET);
|
||||
}
|
||||
|
||||
/* After two or more events have been registered for the same
|
||||
* file descriptor using EV_ET, if one of the events is
|
||||
* deleted, then the epoll_ctl() call issued by libevent drops
|
||||
* the EPOLLET flag resulting in level triggered
|
||||
* notifications.
|
||||
*/
|
||||
static void
|
||||
test_edge_triggered_multiple_events(void *data_)
|
||||
{
|
||||
struct basic_test_data *data = data_;
|
||||
struct event *read_ev = NULL;
|
||||
struct event *write_ev = NULL;
|
||||
const char c = 'A';
|
||||
struct event_base *base = data->base;
|
||||
evutil_socket_t *xpair = data->pair;
|
||||
|
||||
if (!base_supports_et(base)) {
|
||||
tt_skip();
|
||||
return;
|
||||
}
|
||||
|
||||
read_notification_count = 0;
|
||||
last_read_notification_was_et = 0;
|
||||
write_notification_count = 0;
|
||||
last_write_notification_was_et = 0;
|
||||
|
||||
/* Make xpair[1] readable */
|
||||
tt_int_op(send(xpair[0], &c, 1, 0), >, 0);
|
||||
|
||||
read_ev = event_new(base, xpair[1], EV_READ|EV_ET|EV_PERSIST,
|
||||
read_notification_cb, NULL);
|
||||
write_ev = event_new(base, xpair[1], EV_WRITE|EV_ET|EV_PERSIST,
|
||||
write_notification_cb, NULL);
|
||||
|
||||
event_add(read_ev, NULL);
|
||||
event_add(write_ev, NULL);
|
||||
event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
|
||||
event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
|
||||
|
||||
tt_assert(last_read_notification_was_et);
|
||||
tt_int_op(read_notification_count, ==, 1);
|
||||
tt_assert(last_write_notification_was_et);
|
||||
tt_int_op(write_notification_count, ==, 1);
|
||||
|
||||
event_del(read_ev);
|
||||
|
||||
/* trigger acitivity second time for the backend that can have multiple
|
||||
* events for one fd (like kqueue) */
|
||||
close(xpair[0]);
|
||||
xpair[0] = -1;
|
||||
|
||||
/* Verify that we are still edge-triggered for write notifications */
|
||||
event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
|
||||
event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
|
||||
tt_assert(last_write_notification_was_et);
|
||||
tt_int_op(write_notification_count, ==, 2);
|
||||
|
||||
end:
|
||||
if (read_ev)
|
||||
event_free(read_ev);
|
||||
if (write_ev)
|
||||
event_free(write_ev);
|
||||
}
|
||||
|
||||
struct testcase_t edgetriggered_testcases[] = {
|
||||
{ "et", test_edgetriggered, TT_FORK, NULL, NULL },
|
||||
{ "et", test_edgetriggered,
|
||||
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, NULL },
|
||||
{ "et_mix_error", test_edgetriggered_mix_error,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NO_LOGS, &basic_setup, NULL },
|
||||
{ "et_multiple_events", test_edge_triggered_multiple_events,
|
||||
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_listener.c,v 1.3 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_listener.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -81,8 +82,9 @@ regress_pick_a_port(void *arg)
|
|||
ev_socklen_t slen1 = sizeof(ss1), slen2 = sizeof(ss2);
|
||||
unsigned int flags =
|
||||
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC;
|
||||
evutil_socket_t fd1, fd2, fd3;
|
||||
|
||||
evutil_socket_t fd1 = -1, fd2 = -1, fd3 = -1;
|
||||
fd1 = fd2 = fd3 = EVUTIL_INVALID_SOCKET;
|
||||
|
||||
if (data->setup_data && strstr((char*)data->setup_data, "ts")) {
|
||||
flags |= LEV_OPT_THREADSAFE;
|
||||
|
@ -100,8 +102,8 @@ regress_pick_a_port(void *arg)
|
|||
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
|
||||
tt_assert(listener2);
|
||||
|
||||
tt_int_op(evconnlistener_get_fd(listener1), >=, 0);
|
||||
tt_int_op(evconnlistener_get_fd(listener2), >=, 0);
|
||||
tt_assert(evconnlistener_get_fd(listener1) != EVUTIL_INVALID_SOCKET);
|
||||
tt_assert(evconnlistener_get_fd(listener2) != EVUTIL_INVALID_SOCKET);
|
||||
tt_assert(getsockname(evconnlistener_get_fd(listener1),
|
||||
(struct sockaddr*)&ss1, &slen1) == 0);
|
||||
tt_assert(getsockname(evconnlistener_get_fd(listener2),
|
||||
|
@ -118,7 +120,7 @@ regress_pick_a_port(void *arg)
|
|||
tt_ptr_op(evconnlistener_get_base(listener1), ==, base);
|
||||
tt_ptr_op(evconnlistener_get_base(listener2), ==, base);
|
||||
|
||||
fd1 = fd2 = fd3 = -1;
|
||||
fd1 = fd2 = fd3 = EVUTIL_INVALID_SOCKET;
|
||||
evutil_socket_connect_(&fd1, (struct sockaddr*)&ss1, slen1);
|
||||
evutil_socket_connect_(&fd2, (struct sockaddr*)&ss1, slen1);
|
||||
evutil_socket_connect_(&fd3, (struct sockaddr*)&ss2, slen2);
|
||||
|
@ -186,6 +188,89 @@ end:
|
|||
evconnlistener_free(listener);
|
||||
}
|
||||
|
||||
static void
|
||||
acceptcb_free(struct evconnlistener *listener, evutil_socket_t fd,
|
||||
struct sockaddr *addr, int socklen, void *arg)
|
||||
{
|
||||
int *ptr = arg;
|
||||
--*ptr;
|
||||
TT_BLATHER(("Got one for %p", ptr));
|
||||
evutil_closesocket(fd);
|
||||
|
||||
if (! *ptr)
|
||||
evconnlistener_free(listener);
|
||||
}
|
||||
static void
|
||||
regress_listener_close_accepted_fd(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
struct evconnlistener *listener = NULL;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_storage ss;
|
||||
ev_socklen_t slen = sizeof(ss);
|
||||
int count = 1;
|
||||
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE;
|
||||
evutil_socket_t fd = EVUTIL_INVALID_SOCKET;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
|
||||
sin.sin_port = 0; /* "You pick!" */
|
||||
|
||||
/* Start a listener with a bogus socket. */
|
||||
listener = evconnlistener_new_bind(base, acceptcb_free, &count,
|
||||
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
|
||||
tt_assert(listener);
|
||||
|
||||
tt_assert(getsockname(evconnlistener_get_fd(listener),
|
||||
(struct sockaddr*)&ss, &slen) == 0);
|
||||
evutil_socket_connect_(&fd, (struct sockaddr*)&ss, slen);
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
regress_listener_immediate_close(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
struct evconnlistener *listener = NULL;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_storage ss;
|
||||
ev_socklen_t slen = sizeof(ss);
|
||||
int count = 1;
|
||||
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE;
|
||||
evutil_socket_t fd1 = EVUTIL_INVALID_SOCKET, fd2 = EVUTIL_INVALID_SOCKET;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
|
||||
sin.sin_port = 0; /* "You pick!" */
|
||||
|
||||
/* Start a listener with a bogus socket. */
|
||||
listener = evconnlistener_new_bind(base, acceptcb, &count,
|
||||
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
|
||||
tt_assert(listener);
|
||||
|
||||
tt_assert(getsockname(evconnlistener_get_fd(listener),
|
||||
(struct sockaddr*)&ss, &slen) == 0);
|
||||
|
||||
evutil_socket_connect_(&fd1, (struct sockaddr*)&ss, slen);
|
||||
evutil_socket_connect_(&fd2, (struct sockaddr*)&ss, slen);
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
tt_int_op(count, ==, 0);
|
||||
|
||||
end:
|
||||
if (listener)
|
||||
evconnlistener_free(listener);
|
||||
}
|
||||
|
||||
#ifdef EVENT__HAVE_SETRLIMIT
|
||||
static void
|
||||
regress_listener_error_unlock(void *arg)
|
||||
|
@ -231,7 +316,7 @@ struct testcase_t listener_testcases[] = {
|
|||
|
||||
#ifdef EVENT__HAVE_SETRLIMIT
|
||||
{ "error_unlock", regress_listener_error_unlock,
|
||||
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR,
|
||||
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR|TT_NO_LOGS,
|
||||
&basic_setup, NULL},
|
||||
#endif
|
||||
|
||||
|
@ -243,6 +328,12 @@ struct testcase_t listener_testcases[] = {
|
|||
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR,
|
||||
&basic_setup, __UNCONST("ts") },
|
||||
|
||||
{ "close_accepted_fd", regress_listener_close_accepted_fd,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL, },
|
||||
|
||||
{ "immediate_close", regress_listener_immediate_close,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL, },
|
||||
|
||||
END_OF_TESTCASES,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_main.c,v 1.3 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_main.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -34,6 +35,14 @@
|
|||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
/* move_pthread_to_realtime_scheduling_class() */
|
||||
#ifdef EVENT__HAVE_MACH_MACH_H
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_MACH_MACH_TIME_H
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
|
||||
#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \
|
||||
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
|
||||
|
@ -44,7 +53,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_main.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_main.c,v 1.4 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#if 0
|
||||
#include <sys/types.h>
|
||||
|
@ -84,12 +93,13 @@ __RCSID("$NetBSD: regress_main.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_main.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
||||
#include "regress.h"
|
||||
#include "regress_thread.h"
|
||||
#include "tinytest.h"
|
||||
#include "tinytest_macros.h"
|
||||
#include "../iocp-internal.h"
|
||||
#include "../event-internal.h"
|
||||
#include "../evthread-internal.h"
|
||||
|
||||
struct evutil_weakrand_state test_weakrand_state;
|
||||
|
||||
|
@ -191,18 +201,65 @@ ignore_log_cb(int s, const char *msg)
|
|||
{
|
||||
}
|
||||
|
||||
static void *
|
||||
/**
|
||||
* Put into the real time scheduling class for better timers latency.
|
||||
* https://developer.apple.com/library/archive/technotes/tn2169/_index.html#//apple_ref/doc/uid/DTS40013172-CH1-TNTAG6000
|
||||
*/
|
||||
#if defined(__APPLE__)
|
||||
static void move_pthread_to_realtime_scheduling_class(pthread_t pthread)
|
||||
{
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
|
||||
const uint64_t NANOS_PER_MSEC = 1000000ULL;
|
||||
double clock2abs =
|
||||
((double)info.denom / (double)info.numer) * NANOS_PER_MSEC;
|
||||
|
||||
thread_time_constraint_policy_data_t policy;
|
||||
policy.period = 0;
|
||||
policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work
|
||||
policy.constraint = (uint32_t)(10 * clock2abs);
|
||||
policy.preemptible = FALSE;
|
||||
|
||||
int kr = thread_policy_set(pthread_mach_thread_np(pthread),
|
||||
THREAD_TIME_CONSTRAINT_POLICY,
|
||||
(thread_policy_t)&policy,
|
||||
THREAD_TIME_CONSTRAINT_POLICY_COUNT);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
mach_error("thread_policy_set:", kr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void thread_setup(THREAD_T pthread)
|
||||
{
|
||||
move_pthread_to_realtime_scheduling_class(pthread);
|
||||
}
|
||||
#else /** \__APPLE__ */
|
||||
void thread_setup(THREAD_T pthread) {}
|
||||
#endif /** \!__APPLE__ */
|
||||
|
||||
|
||||
void *
|
||||
basic_test_setup(const struct testcase_t *testcase)
|
||||
{
|
||||
struct event_base *base = NULL;
|
||||
evutil_socket_t spair[2] = { -1, -1 };
|
||||
struct basic_test_data *data = NULL;
|
||||
|
||||
thread_setup(THREAD_SELF());
|
||||
|
||||
#ifndef _WIN32
|
||||
if (testcase->flags & TT_ENABLE_IOCP_FLAG)
|
||||
return (void*)TT_SKIP;
|
||||
#endif
|
||||
|
||||
if (testcase->flags & TT_ENABLE_DEBUG_MODE &&
|
||||
!libevent_tests_running_in_debug_mode) {
|
||||
event_enable_debug_mode();
|
||||
libevent_tests_running_in_debug_mode = 1;
|
||||
}
|
||||
|
||||
if (testcase->flags & TT_NEED_THREADS) {
|
||||
if (!(testcase->flags & TT_FORK))
|
||||
return NULL;
|
||||
|
@ -267,7 +324,7 @@ basic_test_setup(const struct testcase_t *testcase)
|
|||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
basic_test_cleanup(const struct testcase_t *testcase, void *ptr)
|
||||
{
|
||||
struct basic_test_data *data = ptr;
|
||||
|
@ -389,6 +446,7 @@ struct testgroup_t testgroups[] = {
|
|||
{ "iocp/", iocp_testcases },
|
||||
{ "iocp/bufferevent/", bufferevent_iocp_testcases },
|
||||
{ "iocp/listener/", listener_iocp_testcases },
|
||||
{ "iocp/http/", http_iocp_testcases },
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_OPENSSL
|
||||
{ "ssl/", ssl_testcases },
|
||||
|
@ -440,6 +498,7 @@ main(int argc, const char **argv)
|
|||
#ifdef _WIN32
|
||||
tinytest_skip(testgroups, "http/connection_retry");
|
||||
tinytest_skip(testgroups, "http/https_connection_retry");
|
||||
tinytest_skip(testgroups, "http/read_on_write_error");
|
||||
#endif
|
||||
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
|
@ -459,6 +518,11 @@ main(int argc, const char **argv)
|
|||
|
||||
evutil_weakrand_seed_(&test_weakrand_state, 0);
|
||||
|
||||
if (getenv("EVENT_NO_FILE_BUFFERING")) {
|
||||
setbuf(stdout, NULL);
|
||||
setbuf(stderr, NULL);
|
||||
}
|
||||
|
||||
if (tinytest_main(argc,argv,testgroups))
|
||||
return 1;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_rpc.c,v 1.4 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_rpc.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
|
@ -36,7 +37,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_rpc.c,v 1.4 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_rpc.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -64,7 +65,6 @@ __RCSID("$NetBSD: regress_rpc.c,v 1.4 2017/01/31 23:17:40 christos Exp $");
|
|||
#include "event2/http_compat.h"
|
||||
#include "event2/http_struct.h"
|
||||
#include "event2/rpc.h"
|
||||
#include "event2/rpc.h"
|
||||
#include "event2/rpc_struct.h"
|
||||
#include "event2/tag.h"
|
||||
#include "log-internal.h"
|
||||
|
@ -883,6 +883,53 @@ end:
|
|||
evbuffer_free(tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
rpc_invalid_type(void)
|
||||
{
|
||||
ev_uint16_t port;
|
||||
struct evhttp *http = NULL;
|
||||
struct evrpc_base *base = NULL;
|
||||
struct evhttp_connection *evcon = NULL;
|
||||
struct evhttp_request *req = NULL;
|
||||
|
||||
rpc_setup(&http, &port, &base);
|
||||
|
||||
evcon = evhttp_connection_new("127.0.0.1", port);
|
||||
tt_assert(evcon);
|
||||
|
||||
/*
|
||||
* At this point, we want to schedule an HTTP POST request
|
||||
* server using our make request method.
|
||||
*/
|
||||
|
||||
req = evhttp_request_new(rpc_postrequest_failure, NULL);
|
||||
tt_assert(req);
|
||||
|
||||
/* Add the information that we care about */
|
||||
evhttp_add_header(req->output_headers, "Host", "somehost");
|
||||
evbuffer_add_printf(req->output_buffer, "Some Nonsense");
|
||||
|
||||
if (evhttp_make_request(evcon, req,
|
||||
EVHTTP_REQ_GET,
|
||||
"/.rpc.Message") == -1) {
|
||||
tt_abort();
|
||||
}
|
||||
|
||||
test_ok = 0;
|
||||
|
||||
event_dispatch();
|
||||
|
||||
evhttp_connection_free(evcon);
|
||||
|
||||
rpc_teardown(base);
|
||||
|
||||
tt_assert(test_ok == 1);
|
||||
|
||||
end:
|
||||
evhttp_free(http);
|
||||
}
|
||||
|
||||
|
||||
#define RPC_LEGACY(name) \
|
||||
{ #name, run_legacy_test_fn, TT_FORK|TT_NEED_BASE|TT_LEGACY, \
|
||||
&legacy_setup, \
|
||||
|
@ -901,6 +948,7 @@ struct testcase_t rpc_testcases[] = {
|
|||
RPC_LEGACY(basic_client),
|
||||
RPC_LEGACY(basic_queued_client),
|
||||
RPC_LEGACY(basic_client_with_pause),
|
||||
RPC_LEGACY(invalid_type),
|
||||
RPC_LEGACY(client_timeout),
|
||||
RPC_LEGACY(test),
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_ssl.c,v 1.4 2020/02/21 00:26:21 joerg Exp $ */
|
||||
/* $NetBSD: regress_ssl.c,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -54,7 +55,6 @@
|
|||
#include "tinytest.h"
|
||||
#include "tinytest_macros.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include "openssl-compat.h"
|
||||
|
@ -121,14 +121,13 @@ end:
|
|||
}
|
||||
|
||||
X509 *
|
||||
ssl_getcert(void)
|
||||
ssl_getcert(EVP_PKEY *key)
|
||||
{
|
||||
/* Dummy code to make a quick-and-dirty valid certificate with
|
||||
OpenSSL. Don't copy this code into your own program! It does a
|
||||
number of things in a stupid and insecure way. */
|
||||
X509 *x509 = NULL;
|
||||
X509_NAME *name = NULL;
|
||||
EVP_PKEY *key = ssl_getkey();
|
||||
int nid;
|
||||
time_t now = time(NULL);
|
||||
|
||||
|
@ -150,16 +149,18 @@ ssl_getcert(void)
|
|||
|
||||
X509_set_subject_name(x509, name);
|
||||
X509_set_issuer_name(x509, name);
|
||||
X509_NAME_free(name);
|
||||
|
||||
X509_time_adj(X509_get_notBefore(x509), 0, &now);
|
||||
X509_time_adj(X509_getm_notBefore(x509), 0, &now);
|
||||
now += 3600;
|
||||
X509_time_adj(X509_get_notAfter(x509), 0, &now);
|
||||
X509_time_adj(X509_getm_notAfter(x509), 0, &now);
|
||||
X509_set_pubkey(x509, key);
|
||||
tt_assert(0 != X509_sign(x509, key, EVP_sha1()));
|
||||
|
||||
return x509;
|
||||
end:
|
||||
X509_free(x509);
|
||||
X509_NAME_free(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -185,35 +186,86 @@ get_ssl_ctx(void)
|
|||
return the_ssl_ctx;
|
||||
}
|
||||
|
||||
static int test_is_done;
|
||||
static int n_connected;
|
||||
static int got_close;
|
||||
static int got_error;
|
||||
static int got_timeout;
|
||||
static int renegotiate_at = -1;
|
||||
static int stop_when_connected;
|
||||
static int pending_connect_events;
|
||||
static struct event_base *exit_base;
|
||||
static X509 *the_cert;
|
||||
EVP_PKEY *the_key;
|
||||
|
||||
void
|
||||
init_ssl(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
SSL_library_init();
|
||||
ERR_load_crypto_strings();
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
if (SSLeay() != OPENSSL_VERSION_NUMBER) {
|
||||
TT_DECLARE("WARN", ("Version mismatch for openssl: compiled with %lx but running with %lx", (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long) SSLeay()));
|
||||
TT_DECLARE("WARN",
|
||||
("Version mismatch for openssl: compiled with %lx but running with %lx",
|
||||
(unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *
|
||||
ssl_test_setup(const struct testcase_t *testcase)
|
||||
{
|
||||
init_ssl();
|
||||
|
||||
the_key = ssl_getkey();
|
||||
EVUTIL_ASSERT(the_key);
|
||||
|
||||
the_cert = ssl_getcert(the_key);
|
||||
EVUTIL_ASSERT(the_cert);
|
||||
|
||||
disable_tls_11_and_12 = 0;
|
||||
|
||||
return basic_test_setup(testcase);
|
||||
}
|
||||
static int
|
||||
ssl_test_cleanup(const struct testcase_t *testcase, void *ptr)
|
||||
{
|
||||
int ret = basic_test_cleanup(testcase, ptr);
|
||||
if (!ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
test_is_done = 0;
|
||||
n_connected = 0;
|
||||
got_close = 0;
|
||||
got_error = 0;
|
||||
got_timeout = 0;
|
||||
renegotiate_at = -1;
|
||||
stop_when_connected = 0;
|
||||
pending_connect_events = 0;
|
||||
exit_base = NULL;
|
||||
|
||||
X509_free(the_cert);
|
||||
EVP_PKEY_free(the_key);
|
||||
|
||||
SSL_CTX_free(the_ssl_ctx);
|
||||
the_ssl_ctx = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
const struct testcase_setup_t ssl_setup = {
|
||||
ssl_test_setup, ssl_test_cleanup
|
||||
};
|
||||
|
||||
|
||||
/* ====================
|
||||
Here's a simple test: we read a number from the input, increment it, and
|
||||
reply, until we get to 1001.
|
||||
*/
|
||||
|
||||
static int test_is_done = 0;
|
||||
static int n_connected = 0;
|
||||
static int got_close = 0;
|
||||
static int got_error = 0;
|
||||
static int got_timeout = 0;
|
||||
static int renegotiate_at = -1;
|
||||
static int stop_when_connected = 0;
|
||||
static int pending_connect_events = 0;
|
||||
static struct event_base *exit_base = NULL;
|
||||
|
||||
enum regress_openssl_type
|
||||
{
|
||||
REGRESS_OPENSSL_SOCKETPAIR = 1,
|
||||
|
@ -231,17 +283,19 @@ enum regress_openssl_type
|
|||
REGRESS_OPENSSL_SLEEP = 1024,
|
||||
|
||||
REGRESS_OPENSSL_CLIENT_WRITE = 2048,
|
||||
|
||||
REGRESS_DEFERRED_CALLBACKS = 4096,
|
||||
};
|
||||
|
||||
static void
|
||||
bufferevent_openssl_check_fd(struct bufferevent *bev, int filter)
|
||||
{
|
||||
tt_int_op(bufferevent_getfd(bev), !=, -1);
|
||||
tt_int_op(bufferevent_setfd(bev, -1), ==, 0);
|
||||
tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET);
|
||||
tt_fd_op(bufferevent_setfd(bev, EVUTIL_INVALID_SOCKET), ==, 0);
|
||||
if (filter) {
|
||||
tt_int_op(bufferevent_getfd(bev), !=, -1);
|
||||
tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET);
|
||||
} else {
|
||||
tt_int_op(bufferevent_getfd(bev), ==, -1);
|
||||
tt_fd_op(bufferevent_getfd(bev), ==, EVUTIL_INVALID_SOCKET);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -257,6 +311,13 @@ end:
|
|||
;
|
||||
}
|
||||
|
||||
static void
|
||||
free_on_cb(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
TT_BLATHER(("free_on_cb: %p", bev));
|
||||
bufferevent_free(bev);
|
||||
}
|
||||
|
||||
static void
|
||||
respond_to_number(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
|
@ -305,13 +366,13 @@ done_writing_cb(struct bufferevent *bev, void *ctx)
|
|||
static void
|
||||
eventcb(struct bufferevent *bev, short what, void *ctx)
|
||||
{
|
||||
X509 *peer_cert = NULL;
|
||||
enum regress_openssl_type type;
|
||||
type = (enum regress_openssl_type)(uintptr_t)ctx;
|
||||
|
||||
TT_BLATHER(("Got event %d", (int)what));
|
||||
if (what & BEV_EVENT_CONNECTED) {
|
||||
SSL *ssl;
|
||||
X509 *peer_cert;
|
||||
++n_connected;
|
||||
ssl = bufferevent_openssl_get_ssl(bev);
|
||||
tt_assert(ssl);
|
||||
|
@ -359,8 +420,10 @@ eventcb(struct bufferevent *bev, short what, void *ctx)
|
|||
}
|
||||
bufferevent_free(bev);
|
||||
}
|
||||
|
||||
end:
|
||||
;
|
||||
if (peer_cert)
|
||||
X509_free(peer_cert);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -400,8 +463,6 @@ regress_bufferevent_openssl(void *arg)
|
|||
|
||||
struct bufferevent *bev1, *bev2;
|
||||
SSL *ssl1, *ssl2;
|
||||
X509 *cert = ssl_getcert();
|
||||
EVP_PKEY *key = ssl_getkey();
|
||||
int flags = BEV_OPT_DEFER_CALLBACKS;
|
||||
struct bufferevent *bev_ll[2] = { NULL, NULL };
|
||||
evutil_socket_t *fd_pair = NULL;
|
||||
|
@ -409,14 +470,9 @@ regress_bufferevent_openssl(void *arg)
|
|||
enum regress_openssl_type type;
|
||||
type = (enum regress_openssl_type)(uintptr_t)data->setup_data;
|
||||
|
||||
tt_assert(cert);
|
||||
tt_assert(key);
|
||||
|
||||
init_ssl();
|
||||
|
||||
if (type & REGRESS_OPENSSL_RENEGOTIATE) {
|
||||
if (SSLeay() >= 0x10001000 &&
|
||||
SSLeay() < 0x1000104f) {
|
||||
if (OPENSSL_VERSION_NUMBER >= 0x10001000 &&
|
||||
OPENSSL_VERSION_NUMBER < 0x1000104f) {
|
||||
/* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2
|
||||
* can't renegotiate with themselves. Disable. */
|
||||
disable_tls_11_and_12 = 1;
|
||||
|
@ -427,8 +483,8 @@ regress_bufferevent_openssl(void *arg)
|
|||
ssl1 = SSL_new(get_ssl_ctx());
|
||||
ssl2 = SSL_new(get_ssl_ctx());
|
||||
|
||||
SSL_use_certificate(ssl2, cert);
|
||||
SSL_use_PrivateKey(ssl2, key);
|
||||
SSL_use_certificate(ssl2, the_cert);
|
||||
SSL_use_PrivateKey(ssl2, the_key);
|
||||
|
||||
if (!(type & REGRESS_OPENSSL_OPEN))
|
||||
flags |= BEV_OPT_CLOSE_ON_FREE;
|
||||
|
@ -447,7 +503,7 @@ regress_bufferevent_openssl(void *arg)
|
|||
fd_pair, bev_ll, type);
|
||||
|
||||
if (!(type & REGRESS_OPENSSL_FILTER)) {
|
||||
tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]);
|
||||
tt_fd_op(bufferevent_getfd(bev1), ==, data->pair[0]);
|
||||
} else {
|
||||
tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]);
|
||||
}
|
||||
|
@ -506,7 +562,10 @@ regress_bufferevent_openssl(void *arg)
|
|||
tt_int_op(got_close, ==, 0);
|
||||
tt_int_op(got_error, ==, 0);
|
||||
tt_int_op(got_timeout, ==, 1);
|
||||
|
||||
bufferevent_free(bev2);
|
||||
}
|
||||
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
@ -528,15 +587,13 @@ acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
|
|||
|
||||
type = (enum regress_openssl_type)(uintptr_t)data->setup_data;
|
||||
|
||||
SSL_use_certificate(ssl, ssl_getcert());
|
||||
SSL_use_PrivateKey(ssl, ssl_getkey());
|
||||
SSL_use_certificate(ssl, the_cert);
|
||||
SSL_use_PrivateKey(ssl, the_key);
|
||||
|
||||
bev = bufferevent_openssl_socket_new(
|
||||
data->base,
|
||||
fd,
|
||||
ssl,
|
||||
BUFFEREVENT_SSL_ACCEPTING,
|
||||
data->base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING,
|
||||
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
|
||||
tt_assert(bev);
|
||||
|
||||
bufferevent_setcb(bev, respond_to_number, NULL, eventcb,
|
||||
(void*)(REGRESS_OPENSSL_SERVER));
|
||||
|
@ -552,11 +609,14 @@ acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
|
|||
|
||||
/* Only accept once, then disable ourself. */
|
||||
evconnlistener_disable(listener);
|
||||
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
struct rwcount
|
||||
{
|
||||
int fd;
|
||||
evutil_socket_t fd;
|
||||
size_t read;
|
||||
size_t write;
|
||||
};
|
||||
|
@ -570,6 +630,7 @@ bio_rwcount_new(BIO *b)
|
|||
static int
|
||||
bio_rwcount_free(BIO *b)
|
||||
{
|
||||
TT_BLATHER(("bio_rwcount_free: %p", b));
|
||||
if (!b)
|
||||
return 0;
|
||||
if (BIO_get_shutdown(b)) {
|
||||
|
@ -592,7 +653,6 @@ bio_rwcount_read(BIO *b, char *out, int outlen)
|
|||
static int
|
||||
bio_rwcount_write(BIO *b, const char *in, int inlen)
|
||||
{
|
||||
|
||||
struct rwcount *rw = BIO_get_data(b);
|
||||
ev_ssize_t ret = send(rw->fd, in, inlen, 0);
|
||||
++rw->write;
|
||||
|
@ -604,8 +664,12 @@ bio_rwcount_write(BIO *b, const char *in, int inlen)
|
|||
static long
|
||||
bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
{
|
||||
struct rwcount *rw = BIO_get_data(b);
|
||||
long ret = 0;
|
||||
switch (cmd) {
|
||||
case BIO_C_GET_FD:
|
||||
ret = rw->fd;
|
||||
break;
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
ret = BIO_get_shutdown(b);
|
||||
break;
|
||||
|
@ -674,14 +738,11 @@ regress_bufferevent_openssl_connect(void *arg)
|
|||
struct sockaddr_storage ss;
|
||||
ev_socklen_t slen;
|
||||
SSL *ssl;
|
||||
BIO *bio;
|
||||
struct rwcount rw = { -1, 0, 0 };
|
||||
enum regress_openssl_type type;
|
||||
|
||||
type = (enum regress_openssl_type)(uintptr_t)data->setup_data;
|
||||
|
||||
init_ssl();
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(0x7f000001);
|
||||
|
@ -705,7 +766,7 @@ regress_bufferevent_openssl_connect(void *arg)
|
|||
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
|
||||
tt_assert(bev);
|
||||
|
||||
bufferevent_setcb(bev, respond_to_number, NULL, eventcb,
|
||||
bufferevent_setcb(bev, respond_to_number, free_on_cb, eventcb,
|
||||
(void*)(REGRESS_OPENSSL_CLIENT));
|
||||
|
||||
tt_assert(getsockname(evconnlistener_get_fd(listener),
|
||||
|
@ -718,6 +779,8 @@ regress_bufferevent_openssl_connect(void *arg)
|
|||
/* Possible only when we have fd, since be_openssl can and will overwrite
|
||||
* bio otherwise before */
|
||||
if (type & REGRESS_OPENSSL_SLEEP) {
|
||||
BIO *bio;
|
||||
|
||||
rw.fd = bufferevent_getfd(bev);
|
||||
bio = BIO_new_rwcount(0);
|
||||
tt_assert(bio);
|
||||
|
@ -732,83 +795,284 @@ regress_bufferevent_openssl_connect(void *arg)
|
|||
tt_int_op(rw.read, <=, 100);
|
||||
tt_int_op(rw.write, <=, 100);
|
||||
end:
|
||||
;
|
||||
evconnlistener_free(listener);
|
||||
}
|
||||
|
||||
struct wm_context
|
||||
{
|
||||
int server;
|
||||
int flags;
|
||||
struct evbuffer *data;
|
||||
size_t to_read;
|
||||
size_t wm_high;
|
||||
size_t limit;
|
||||
size_t get;
|
||||
struct bufferevent *bev;
|
||||
struct wm_context *neighbour;
|
||||
};
|
||||
static void
|
||||
wm_transfer(struct bufferevent *bev, void *arg)
|
||||
{
|
||||
struct wm_context *ctx = arg;
|
||||
struct evbuffer *in = bufferevent_get_input(bev);
|
||||
struct evbuffer *out = bufferevent_get_output(bev);
|
||||
size_t len = evbuffer_get_length(in);
|
||||
size_t drain = len < ctx->to_read ? len : ctx->to_read;
|
||||
|
||||
if (ctx->get >= ctx->limit) {
|
||||
TT_BLATHER(("wm_transfer-%s(%p): break",
|
||||
ctx->server ? "server" : "client", bev));
|
||||
bufferevent_setcb(bev, NULL, NULL, NULL, NULL);
|
||||
bufferevent_disable(bev, EV_READ);
|
||||
if (ctx->neighbour->get >= ctx->neighbour->limit) {
|
||||
event_base_loopbreak(bufferevent_get_base(bev));
|
||||
}
|
||||
} else {
|
||||
ctx->get += drain;
|
||||
evbuffer_drain(in, drain);
|
||||
}
|
||||
|
||||
TT_BLATHER(("wm_transfer-%s(%p): "
|
||||
"in: " EV_SIZE_FMT ", "
|
||||
"out: " EV_SIZE_FMT ", "
|
||||
"got: " EV_SIZE_FMT "",
|
||||
ctx->server ? "server" : "client", bev,
|
||||
evbuffer_get_length(in),
|
||||
evbuffer_get_length(out),
|
||||
ctx->get));
|
||||
|
||||
evbuffer_add_buffer_reference(out, ctx->data);
|
||||
}
|
||||
static void
|
||||
wm_eventcb(struct bufferevent *bev, short what, void *arg)
|
||||
{
|
||||
struct wm_context *ctx = arg;
|
||||
TT_BLATHER(("wm_eventcb-%s(%p): %i",
|
||||
ctx->server ? "server" : "client", bev, what));
|
||||
if (what & BEV_EVENT_CONNECTED) {
|
||||
} else {
|
||||
ctx->get = 0;
|
||||
}
|
||||
}
|
||||
static void
|
||||
wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
|
||||
struct sockaddr *addr, int socklen, void *arg)
|
||||
{
|
||||
struct wm_context *ctx = arg;
|
||||
struct bufferevent *bev;
|
||||
struct event_base *base = evconnlistener_get_base(listener);
|
||||
SSL *ssl = SSL_new(get_ssl_ctx());
|
||||
|
||||
SSL_use_certificate(ssl, the_cert);
|
||||
SSL_use_PrivateKey(ssl, the_key);
|
||||
|
||||
bev = bufferevent_openssl_socket_new(
|
||||
base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, ctx->flags);
|
||||
|
||||
TT_BLATHER(("wm_transfer-%s(%p): accept",
|
||||
ctx->server ? "server" : "client", bev));
|
||||
|
||||
bufferevent_setwatermark(bev, EV_READ, 0, ctx->wm_high);
|
||||
bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, ctx);
|
||||
bufferevent_enable(bev, EV_READ|EV_WRITE);
|
||||
ctx->bev = bev;
|
||||
|
||||
/* Only accept once, then disable ourself. */
|
||||
evconnlistener_disable(listener);
|
||||
}
|
||||
static void
|
||||
regress_bufferevent_openssl_wm(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
|
||||
struct evconnlistener *listener;
|
||||
struct bufferevent *bev;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_storage ss;
|
||||
enum regress_openssl_type type =
|
||||
(enum regress_openssl_type)data->setup_data;
|
||||
int bev_flags = BEV_OPT_CLOSE_ON_FREE;
|
||||
ev_socklen_t slen;
|
||||
SSL *ssl;
|
||||
struct wm_context client, server;
|
||||
char *payload;
|
||||
size_t payload_len = 1<<10;
|
||||
size_t wm_high = 5<<10;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(0x7f000001);
|
||||
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
slen = sizeof(ss);
|
||||
|
||||
if (type & REGRESS_DEFERRED_CALLBACKS)
|
||||
bev_flags |= BEV_OPT_DEFER_CALLBACKS;
|
||||
|
||||
memset(&client, 0, sizeof(client));
|
||||
memset(&server, 0, sizeof(server));
|
||||
client.server = 0;
|
||||
server.server = 1;
|
||||
client.flags = server.flags = bev_flags;
|
||||
client.data = evbuffer_new();
|
||||
server.data = evbuffer_new();
|
||||
payload = calloc(1, payload_len);
|
||||
memset(payload, 'A', payload_len);
|
||||
evbuffer_add(server.data, payload, payload_len);
|
||||
evbuffer_add(client.data, payload, payload_len);
|
||||
client.wm_high = server.wm_high = wm_high;
|
||||
client.limit = server.limit = wm_high<<3;
|
||||
client.to_read = server.to_read = payload_len>>1;
|
||||
|
||||
TT_BLATHER(("openssl_wm: "
|
||||
"payload_len = " EV_SIZE_FMT ", "
|
||||
"wm_high = " EV_SIZE_FMT ", "
|
||||
"limit = " EV_SIZE_FMT ", "
|
||||
"to_read: " EV_SIZE_FMT "",
|
||||
payload_len,
|
||||
wm_high,
|
||||
server.limit,
|
||||
server.to_read));
|
||||
|
||||
listener = evconnlistener_new_bind(base, wm_acceptcb, &server,
|
||||
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
|
||||
-1, (struct sockaddr *)&sin, sizeof(sin));
|
||||
|
||||
tt_assert(listener);
|
||||
tt_assert(evconnlistener_get_fd(listener) >= 0);
|
||||
|
||||
ssl = SSL_new(get_ssl_ctx());
|
||||
tt_assert(ssl);
|
||||
|
||||
if (type & REGRESS_OPENSSL_FILTER) {
|
||||
bev = bufferevent_socket_new(data->base, -1, client.flags);
|
||||
tt_assert(bev);
|
||||
bev = bufferevent_openssl_filter_new(
|
||||
base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, client.flags);
|
||||
} else {
|
||||
bev = bufferevent_openssl_socket_new(
|
||||
data->base, -1, ssl,
|
||||
BUFFEREVENT_SSL_CONNECTING,
|
||||
client.flags);
|
||||
}
|
||||
tt_assert(bev);
|
||||
client.bev = bev;
|
||||
|
||||
server.neighbour = &client;
|
||||
client.neighbour = &server;
|
||||
|
||||
bufferevent_setwatermark(bev, EV_READ, 0, client.wm_high);
|
||||
bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, &client);
|
||||
|
||||
tt_assert(getsockname(evconnlistener_get_fd(listener),
|
||||
(struct sockaddr*)&ss, &slen) == 0);
|
||||
|
||||
tt_assert(!bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen));
|
||||
tt_assert(!evbuffer_add_buffer_reference(bufferevent_get_output(bev), client.data));
|
||||
tt_assert(!bufferevent_enable(bev, EV_READ|EV_WRITE));
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
tt_int_op(client.get, ==, client.limit);
|
||||
tt_int_op(server.get, ==, server.limit);
|
||||
|
||||
end:
|
||||
free(payload);
|
||||
evbuffer_free(client.data);
|
||||
evbuffer_free(server.data);
|
||||
evconnlistener_free(listener);
|
||||
bufferevent_free(client.bev);
|
||||
bufferevent_free(server.bev);
|
||||
|
||||
/* XXX: by some reason otherise there is a leak */
|
||||
if (!(type & REGRESS_OPENSSL_FILTER))
|
||||
event_base_loop(base, EVLOOP_ONCE);
|
||||
}
|
||||
|
||||
struct testcase_t ssl_testcases[] = {
|
||||
#define T(a) ((void *)(a))
|
||||
{ "bufferevent_socketpair", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_SOCKETPAIR) },
|
||||
TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR) },
|
||||
{ "bufferevent_socketpair_write_after_connect", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR|REGRESS_OPENSSL_CLIENT_WRITE) },
|
||||
{ "bufferevent_filter", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_FILTER) },
|
||||
TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER) },
|
||||
{ "bufferevent_filter_write_after_connect", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_FILTER|REGRESS_OPENSSL_CLIENT_WRITE) },
|
||||
{ "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE) },
|
||||
{ "bufferevent_renegotiate_filter", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE) },
|
||||
{ "bufferevent_socketpair_startopen", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN) },
|
||||
{ "bufferevent_filter_startopen", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN) },
|
||||
|
||||
{ "bufferevent_socketpair_dirty_shutdown", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_filter_dirty_shutdown", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_renegotiate_socketpair_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED,
|
||||
&basic_setup,
|
||||
&ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_renegotiate_filter_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED,
|
||||
&basic_setup,
|
||||
&ssl_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_socketpair_startopen_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_filter_startopen_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
|
||||
{ "bufferevent_socketpair_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FD) },
|
||||
{ "bufferevent_socketpair_freed", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED) },
|
||||
{ "bufferevent_socketpair_freed_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
|
||||
{ "bufferevent_filter_freed_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
|
||||
|
||||
{ "bufferevent_socketpair_timeout", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT) },
|
||||
{ "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
TT_ISOLATED, &ssl_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
|
||||
|
||||
{ "bufferevent_connect", regress_bufferevent_openssl_connect,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
TT_FORK|TT_NEED_BASE, &ssl_setup, NULL },
|
||||
{ "bufferevent_connect_sleep", regress_bufferevent_openssl_connect,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, T(REGRESS_OPENSSL_SLEEP) },
|
||||
TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_SLEEP) },
|
||||
|
||||
{ "bufferevent_wm", regress_bufferevent_openssl_wm,
|
||||
TT_FORK|TT_NEED_BASE, &ssl_setup, NULL },
|
||||
{ "bufferevent_wm_filter", regress_bufferevent_openssl_wm,
|
||||
TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER) },
|
||||
{ "bufferevent_wm_defer", regress_bufferevent_openssl_wm,
|
||||
TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_DEFERRED_CALLBACKS) },
|
||||
{ "bufferevent_wm_filter_defer", regress_bufferevent_openssl_wm,
|
||||
TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER|REGRESS_DEFERRED_CALLBACKS) },
|
||||
|
||||
#undef T
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_thread.c,v 1.5 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_thread.c,v 1.6 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -31,7 +32,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_thread.c,v 1.5 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_thread.c,v 1.6 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
@ -571,8 +572,8 @@ end:
|
|||
;
|
||||
}
|
||||
|
||||
#define TEST(name) \
|
||||
{ #name, thread_##name, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, \
|
||||
#define TEST(name, f) \
|
||||
{ #name, thread_##name, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE|(f), \
|
||||
&basic_setup, NULL }
|
||||
|
||||
struct testcase_t thread_testcases[] = {
|
||||
|
@ -583,7 +584,7 @@ struct testcase_t thread_testcases[] = {
|
|||
&basic_setup, __UNCONST("forking") },
|
||||
#endif
|
||||
#if 0
|
||||
TEST(conditions_simple),
|
||||
TEST(conditions_simple, TT_RETRIABLE),
|
||||
#endif
|
||||
{ "deferred_cb_skew", thread_deferred_cb_skew,
|
||||
TT_FORK|TT_NEED_THREADS|TT_OFF_BY_DEFAULT,
|
||||
|
@ -592,7 +593,7 @@ struct testcase_t thread_testcases[] = {
|
|||
/****** XXX TODO FIXME windows seems to be having some timing trouble,
|
||||
* looking into it now. / ellzey
|
||||
******/
|
||||
TEST(no_events),
|
||||
TEST(no_events, TT_RETRIABLE),
|
||||
#endif
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: regress_util.c,v 1.3 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: regress_util.c,v 1.4 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Nick Mathewson and Niels Provos
|
||||
*
|
||||
|
@ -24,6 +25,10 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** For event_debug() usage/coverage */
|
||||
#define EVENT_VISIBILITY_WANT_DLLIMPORT
|
||||
|
||||
#include "../util-internal.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -34,7 +39,7 @@
|
|||
|
||||
#include "event2/event-config.h"
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: regress_util.c,v 1.3 2017/01/31 23:17:40 christos Exp $");
|
||||
__RCSID("$NetBSD: regress_util.c,v 1.4 2021/04/07 03:36:48 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -211,6 +216,65 @@ regress_ipv6_parse(void *ptr)
|
|||
#endif
|
||||
}
|
||||
|
||||
static struct ipv6_entry_scope {
|
||||
const char *addr;
|
||||
ev_uint32_t res[4];
|
||||
unsigned scope;
|
||||
enum entry_status status;
|
||||
} ipv6_entries_scope[] = {
|
||||
{ "2001:DB8::", { 0x20010db8, 0, 0 }, 0, NORMAL },
|
||||
{ "2001:DB8::%0", { 0x20010db8, 0, 0, 0 }, 0, NORMAL },
|
||||
{ "2001:DB8::%1", { 0x20010db8, 0, 0, 0 }, 1, NORMAL },
|
||||
{ "foobar.", { 0, 0, 0, 0 }, 0, BAD },
|
||||
{ "2001:DB8::%does-not-exist", { 0, 0, 0, 0 }, 0, BAD },
|
||||
{ NULL, { 0, 0, 0, 0, }, 0, BAD },
|
||||
};
|
||||
static void
|
||||
regress_ipv6_parse_scope(void *ptr)
|
||||
{
|
||||
#ifdef AF_INET6
|
||||
int i, j;
|
||||
unsigned if_scope;
|
||||
|
||||
for (i = 0; ipv6_entries_scope[i].addr; ++i) {
|
||||
struct ipv6_entry_scope *ent = &ipv6_entries_scope[i];
|
||||
struct in6_addr in6;
|
||||
int r;
|
||||
r = evutil_inet_pton_scope(AF_INET6, ent->addr, &in6,
|
||||
&if_scope);
|
||||
if (r == 0) {
|
||||
if (ent->status != BAD)
|
||||
TT_FAIL(("%s did not parse, but it's a good address!",
|
||||
ent->addr));
|
||||
continue;
|
||||
}
|
||||
if (ent->status == BAD) {
|
||||
TT_FAIL(("%s parsed, but we expected an error", ent->addr));
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < 4; ++j) {
|
||||
/* Can't use s6_addr32 here; some don't have it. */
|
||||
ev_uint32_t u =
|
||||
((ev_uint32_t)in6.s6_addr[j*4 ] << 24) |
|
||||
((ev_uint32_t)in6.s6_addr[j*4+1] << 16) |
|
||||
((ev_uint32_t)in6.s6_addr[j*4+2] << 8) |
|
||||
((ev_uint32_t)in6.s6_addr[j*4+3]);
|
||||
if (u != ent->res[j]) {
|
||||
TT_FAIL(("%s did not parse as expected.", ent->addr));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (if_scope != ent->scope) {
|
||||
TT_FAIL(("%s did not parse as expected.", ent->addr));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#else
|
||||
TT_BLATHER(("Skipping IPv6 address parsing."));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static struct sa_port_ent {
|
||||
const char *parse;
|
||||
int safamily;
|
||||
|
@ -925,6 +989,16 @@ end:
|
|||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_EVUTIL_IS_(void *arg)
|
||||
{
|
||||
tt_int_op(EVUTIL_ISDIGIT_('0'), ==, 1);
|
||||
tt_int_op(EVUTIL_ISDIGIT_('a'), ==, 0);
|
||||
tt_int_op(EVUTIL_ISDIGIT_('\xff'), ==, 0);
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_evutil_getaddrinfo(void *arg)
|
||||
{
|
||||
|
@ -1121,6 +1195,41 @@ end:
|
|||
evutil_freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evutil_getaddrinfo_AI_ADDRCONFIG(void *arg)
|
||||
{
|
||||
struct evutil_addrinfo *ai = NULL;
|
||||
struct evutil_addrinfo hints;
|
||||
int r;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
|
||||
|
||||
/* IPv4 */
|
||||
r = evutil_getaddrinfo("127.0.0.1", "80", &hints, &ai);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_assert(ai);
|
||||
tt_ptr_op(ai->ai_next, ==, NULL);
|
||||
test_ai_eq(ai, "127.0.0.1:80", SOCK_STREAM, IPPROTO_TCP);
|
||||
evutil_freeaddrinfo(ai);
|
||||
ai = NULL;
|
||||
|
||||
/* IPv6 */
|
||||
r = evutil_getaddrinfo("::1", "80", &hints, &ai);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_assert(ai);
|
||||
tt_ptr_op(ai->ai_next, ==, NULL);
|
||||
test_ai_eq(ai, "[::1]:80", SOCK_STREAM, IPPROTO_TCP);
|
||||
evutil_freeaddrinfo(ai);
|
||||
ai = NULL;
|
||||
|
||||
end:
|
||||
if (ai)
|
||||
evutil_freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void
|
||||
test_evutil_loadsyslib(void *arg)
|
||||
|
@ -1416,10 +1525,12 @@ static struct date_rfc1123_case {
|
|||
{ 1289433600, "Thu, 11 Nov 2010 00:00:00 GMT"},
|
||||
{ 1323648000, "Mon, 12 Dec 2011 00:00:00 GMT"},
|
||||
#ifndef _WIN32
|
||||
#if EVENT__SIZEOF_TIME_T > 4
|
||||
/** In win32 case we have max "23:59:59 January 18, 2038, UTC" for time32 */
|
||||
{ 4294967296, "Sun, 07 Feb 2106 06:28:16 GMT"} /* 2^32 */,
|
||||
/** In win32 case we have max "23:59:59, December 31, 3000, UTC" for time64 */
|
||||
{253402300799, "Fri, 31 Dec 9999 23:59:59 GMT"} /* long long future no one can imagine */,
|
||||
#endif /* time_t != 32bit */
|
||||
{ 1456704000, "Mon, 29 Feb 2016 00:00:00 GMT"} /* leap year */,
|
||||
#endif
|
||||
{ 1435708800, "Wed, 01 Jul 2015 00:00:00 GMT"} /* leap second */,
|
||||
|
@ -1457,9 +1568,87 @@ end:
|
|||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_evutil_v4addr_is_local(void *arg)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
/* we use evutil_inet_pton() here to fill in network-byte order */
|
||||
#define LOCAL(str, yes) do { \
|
||||
tt_int_op(evutil_inet_pton(AF_INET, str, &sin.sin_addr), ==, 1); \
|
||||
tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, yes); \
|
||||
} while (0)
|
||||
|
||||
/** any */
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1);
|
||||
|
||||
/** loopback */
|
||||
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1);
|
||||
LOCAL("127.0.0.1", 1);
|
||||
LOCAL("127.255.255.255", 1);
|
||||
LOCAL("121.0.0.1", 0);
|
||||
|
||||
/** link-local */
|
||||
LOCAL("169.254.0.1", 1);
|
||||
LOCAL("169.254.255.255", 1);
|
||||
LOCAL("170.0.0.0", 0);
|
||||
|
||||
/** Multicast */
|
||||
LOCAL("224.0.0.0", 1);
|
||||
LOCAL("239.255.255.255", 1);
|
||||
LOCAL("240.0.0.0", 0);
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_evutil_v6addr_is_local(void *arg)
|
||||
{
|
||||
struct sockaddr_in6 sin6;
|
||||
struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
|
||||
struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
|
||||
|
||||
sin6.sin6_family = AF_INET6;
|
||||
#define LOCAL6(str, yes) do { \
|
||||
tt_int_op(evutil_inet_pton(AF_INET6, str, &sin6.sin6_addr), ==, 1);\
|
||||
tt_int_op(evutil_v6addr_is_local_(&sin6.sin6_addr), ==, yes); \
|
||||
} while (0)
|
||||
|
||||
/** any */
|
||||
tt_int_op(evutil_v6addr_is_local_(&anyaddr), ==, 1);
|
||||
LOCAL6("::0", 1);
|
||||
|
||||
/** loopback */
|
||||
tt_int_op(evutil_v6addr_is_local_(&loopback), ==, 1);
|
||||
LOCAL6("::1", 1);
|
||||
|
||||
/** IPV4 mapped */
|
||||
LOCAL6("::ffff:0:0", 1);
|
||||
/** IPv4 translated */
|
||||
LOCAL6("::ffff:0:0:0", 1);
|
||||
/** IPv4/IPv6 translation */
|
||||
LOCAL6("64:ff9b::", 0);
|
||||
/** Link-local */
|
||||
LOCAL6("fe80::", 1);
|
||||
/** Multicast */
|
||||
LOCAL6("ff00::", 1);
|
||||
/** Unspecified */
|
||||
LOCAL6("::", 1);
|
||||
|
||||
/** Global Internet */
|
||||
LOCAL6("2001::", 0);
|
||||
LOCAL6("2001:4860:4802:32::1b", 0);
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
struct testcase_t util_testcases[] = {
|
||||
{ "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL },
|
||||
{ "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL },
|
||||
{ "ipv6_parse_scope", regress_ipv6_parse_scope, 0, NULL, NULL },
|
||||
{ "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL },
|
||||
{ "sockaddr_port_format", regress_sockaddr_port_format, 0, NULL, NULL },
|
||||
{ "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL },
|
||||
|
@ -1472,22 +1661,26 @@ struct testcase_t util_testcases[] = {
|
|||
{ "upcast", test_evutil_upcast, 0, NULL, NULL },
|
||||
{ "integers", test_evutil_integers, 0, NULL, NULL },
|
||||
{ "rand", test_evutil_rand, TT_FORK, NULL, NULL },
|
||||
{ "EVUTIL_IS_", test_EVUTIL_IS_, 0, NULL, NULL },
|
||||
{ "getaddrinfo", test_evutil_getaddrinfo, TT_FORK, NULL, NULL },
|
||||
{ "getaddrinfo_live", test_evutil_getaddrinfo_live, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL },
|
||||
{ "getaddrinfo_AI_ADDRCONFIG", test_evutil_getaddrinfo_AI_ADDRCONFIG, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL },
|
||||
#ifdef _WIN32
|
||||
{ "loadsyslib", test_evutil_loadsyslib, TT_FORK, NULL, NULL },
|
||||
#endif
|
||||
{ "mm_malloc", test_event_malloc, 0, NULL, NULL },
|
||||
{ "mm_calloc", test_event_calloc, 0, NULL, NULL },
|
||||
{ "mm_strdup", test_event_strdup, 0, NULL, NULL },
|
||||
{ "usleep", test_evutil_usleep, 0, NULL, NULL },
|
||||
{ "usleep", test_evutil_usleep, TT_RETRIABLE, NULL, NULL },
|
||||
{ "monotonic_res", test_evutil_monotonic_res, 0, &basic_setup, __UNCONST("") },
|
||||
{ "monotonic_res_precise", test_evutil_monotonic_res, TT_OFF_BY_DEFAULT, &basic_setup, __UNCONST("precise") },
|
||||
{ "monotonic_res_fallback", test_evutil_monotonic_res, TT_OFF_BY_DEFAULT, &basic_setup, __UNCONST("fallback") },
|
||||
{ "monotonic_prc", test_evutil_monotonic_prc, 0, &basic_setup, __UNCONST("") },
|
||||
{ "monotonic_prc_precise", test_evutil_monotonic_prc, 0, &basic_setup, __UNCONST("precise") },
|
||||
{ "monotonic_prc_precise", test_evutil_monotonic_prc, TT_RETRIABLE, &basic_setup, __UNCONST("precise") },
|
||||
{ "monotonic_prc_fallback", test_evutil_monotonic_prc, 0, &basic_setup, __UNCONST("fallback") },
|
||||
{ "date_rfc1123", test_evutil_date_rfc1123, 0, NULL, NULL },
|
||||
{ "evutil_v4addr_is_local", test_evutil_v4addr_is_local, 0, NULL, NULL },
|
||||
{ "evutil_v6addr_is_local", test_evutil_v6addr_is_local, 0, NULL, NULL },
|
||||
END_OF_TESTCASES,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: tinytest_macros.h,v 1.4 2017/01/31 23:17:40 christos Exp $ */
|
||||
/* $NetBSD: tinytest_macros.h,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -114,8 +115,8 @@
|
|||
#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \
|
||||
setup_block,cleanup_block,die_on_fail) \
|
||||
TT_STMT_BEGIN \
|
||||
type val1_ = (a); \
|
||||
type val2_ = (b); \
|
||||
type val1_ = (type)(a); \
|
||||
type val2_ = (type)(b); \
|
||||
int tt_status_ = (test); \
|
||||
if (!tt_status_ || tinytest_get_verbosity_()>1) { \
|
||||
printf_type print_; \
|
||||
|
@ -159,6 +160,14 @@
|
|||
tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \
|
||||
"%ld",TT_EXIT_TEST_FUNCTION)
|
||||
|
||||
/** To compare SOCKET(windows)/fd */
|
||||
#define tt_fd_op(a,op,b) do { \
|
||||
int _a = (int)(a); \
|
||||
int _b = (int)(b); \
|
||||
tt_assert_test_type(_a,_b,#a" "#op" "#b,long,(val1_ op val2_), \
|
||||
"%ld",TT_EXIT_TEST_FUNCTION); \
|
||||
} while (0)
|
||||
|
||||
#define tt_uint_op(a,op,b) \
|
||||
tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \
|
||||
(val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: util-internal.h,v 1.4 2017/01/31 23:17:39 christos Exp $ */
|
||||
/* $NetBSD: util-internal.h,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
|
@ -51,12 +52,40 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* __has_attribute() wrapper */
|
||||
#ifdef __has_attribute
|
||||
# define EVUTIL_HAS_ATTRIBUTE __has_attribute
|
||||
#endif
|
||||
/** clang 3 __has_attribute misbehaves in some versions */
|
||||
#if defined(__clang__) && __clang__ == 1
|
||||
# if defined(__apple_build_version__)
|
||||
# if __clang_major__ <= 6
|
||||
# undef EVUTIL_HAS_ATTRIBUTE
|
||||
# endif
|
||||
# else /* !__apple_build_version__ */
|
||||
# if __clang_major__ == 3 && __clang_minor__ >= 2 && __clang_minor__ <= 5
|
||||
# undef EVUTIL_HAS_ATTRIBUTE
|
||||
# endif
|
||||
# endif /* __apple_build_version__ */
|
||||
#endif /*\ defined(__clang__) && __clang__ == 1 */
|
||||
#ifndef EVUTIL_HAS_ATTRIBUTE
|
||||
# define EVUTIL_HAS_ATTRIBUTE(x) 0
|
||||
#endif
|
||||
|
||||
/* If we need magic to say "inline", get it for free internally. */
|
||||
#ifdef EVENT__inline
|
||||
#define inline EVENT__inline
|
||||
#endif
|
||||
#if defined(EVENT____func__) && !defined(__func__)
|
||||
#define __func__ EVENT____func__
|
||||
|
||||
/* Define to appropriate substitute if compiler doesnt have __func__ */
|
||||
#if defined(EVENT__HAVE___func__)
|
||||
# ifndef __func__
|
||||
# define __func__ __func__
|
||||
# endif
|
||||
#elif defined(EVENT__HAVE___FUNCTION__)
|
||||
# define __func__ __FUNCTION__
|
||||
#else
|
||||
# define __func__ __FILE__
|
||||
#endif
|
||||
|
||||
/* A good no-op to use in macro definitions. */
|
||||
|
@ -220,19 +249,26 @@ extern "C" {
|
|||
* when you care about ASCII's notion of character types, because you are about
|
||||
* to send those types onto the wire.
|
||||
*/
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int EVUTIL_ISALPHA_(char c);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int EVUTIL_ISALNUM_(char c);
|
||||
int EVUTIL_ISSPACE_(char c);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int EVUTIL_ISDIGIT_(char c);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int EVUTIL_ISXDIGIT_(char c);
|
||||
int EVUTIL_ISPRINT_(char c);
|
||||
int EVUTIL_ISLOWER_(char c);
|
||||
int EVUTIL_ISUPPER_(char c);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
char EVUTIL_TOUPPER_(char c);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
char EVUTIL_TOLOWER_(char c);
|
||||
|
||||
/** Remove all trailing horizontal whitespace (space or tab) from the end of a
|
||||
* string */
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
void evutil_rtrim_lws_(char *);
|
||||
|
||||
|
||||
|
@ -259,13 +295,16 @@ void evutil_rtrim_lws_(char *);
|
|||
*/
|
||||
int evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode);
|
||||
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evutil_read_file_(const char *filename, char **content_out, size_t *len_out,
|
||||
int is_binary);
|
||||
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen);
|
||||
|
||||
int evutil_socket_finished_connecting_(evutil_socket_t fd);
|
||||
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evutil_ersatz_socketpair_(int, int , int, evutil_socket_t[]);
|
||||
|
||||
int evutil_resolve_(int family, const char *hostname, struct sockaddr *sa,
|
||||
|
@ -290,15 +329,18 @@ struct evutil_weakrand_state {
|
|||
* attacker can't predict, or which passes strong statistical tests, use the
|
||||
* evutil_secure_rng* functions instead.
|
||||
*/
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
ev_uint32_t evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed);
|
||||
/* Return a pseudorandom value between 0 and EVUTIL_WEAKRAND_MAX inclusive.
|
||||
* Updates the state in 'seed' as needed -- this value must be protected by a
|
||||
* lock.
|
||||
*/
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
ev_int32_t evutil_weakrand_(struct evutil_weakrand_state *seed);
|
||||
/* Return a pseudorandom value x such that 0 <= x < top. top must be no more
|
||||
* than EVUTIL_WEAKRAND_MAX. Updates the state in 'seed' as needed -- this
|
||||
* value must be proteced by a lock */
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
ev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t top);
|
||||
|
||||
/* Evaluates to the same boolean value as 'p', and hints to the compiler that
|
||||
|
@ -309,6 +351,12 @@ ev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t
|
|||
#define EVUTIL_UNLIKELY(p) (p)
|
||||
#endif
|
||||
|
||||
#if EVUTIL_HAS_ATTRIBUTE(fallthrough) && !defined(__lint__) // XXX: fixme
|
||||
#define EVUTIL_FALLTHROUGH __attribute__((fallthrough))
|
||||
#else
|
||||
#define EVUTIL_FALLTHROUGH /* fallthrough */
|
||||
#endif
|
||||
|
||||
/* Replacement for assert() that calls event_errx on failure. */
|
||||
#ifdef NDEBUG
|
||||
#define EVUTIL_ASSERT(cond) EVUTIL_NIL_CONDITION_(cond)
|
||||
|
@ -358,16 +406,22 @@ typedef struct evdns_getaddrinfo_request* (*evdns_getaddrinfo_fn)(
|
|||
const char *nodename, const char *servname,
|
||||
const struct evutil_addrinfo *hints_in,
|
||||
void (*cb)(int, struct evutil_addrinfo *, void *), void *arg);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
void evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn);
|
||||
typedef void (*evdns_getaddrinfo_cancel_fn)(
|
||||
struct evdns_getaddrinfo_request *req);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
void evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn);
|
||||
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
struct evutil_addrinfo *evutil_new_addrinfo_(struct sockaddr *sa,
|
||||
ev_socklen_t socklen, const struct evutil_addrinfo *hints);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
struct evutil_addrinfo *evutil_addrinfo_append_(struct evutil_addrinfo *first,
|
||||
struct evutil_addrinfo *append);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
void evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints);
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evutil_getaddrinfo_common_(const char *nodename, const char *servname,
|
||||
struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum);
|
||||
|
||||
|
@ -380,6 +434,7 @@ void evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data);
|
|||
|
||||
/** Return true iff sa is a looback address. (That is, it is 127.0.0.1/8, or
|
||||
* ::1). */
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evutil_sockaddr_is_loopback_(const struct sockaddr *sa);
|
||||
|
||||
|
||||
|
@ -388,6 +443,7 @@ int evutil_sockaddr_is_loopback_(const struct sockaddr *sa);
|
|||
Returns a pointer to out. Always writes something into out, so it's safe
|
||||
to use the output of this function without checking it for NULL.
|
||||
*/
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
const char *evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen);
|
||||
|
||||
int evutil_hex_char_to_int_(char c);
|
||||
|
@ -397,6 +453,7 @@ void evutil_free_secure_rng_globals_(void);
|
|||
void evutil_free_globals_(void);
|
||||
|
||||
#ifdef _WIN32
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
HMODULE evutil_load_windows_system_library_(const TCHAR *library_name);
|
||||
#endif
|
||||
|
||||
|
@ -445,6 +502,7 @@ HMODULE evutil_load_windows_system_library_(const TCHAR *library_name);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
evutil_socket_t evutil_socket_(int domain, int type, int protocol);
|
||||
evutil_socket_t evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
|
||||
ev_socklen_t *addrlen, int flags);
|
||||
|
@ -477,6 +535,17 @@ evutil_socket_t evutil_eventfd_(unsigned initval, int flags);
|
|||
|
||||
void evutil_memclear_(void *mem, size_t len);
|
||||
|
||||
struct in_addr;
|
||||
struct in6_addr;
|
||||
|
||||
/* This is a any, loopback, link-local, multicast */
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evutil_v4addr_is_local_(const struct in_addr *in);
|
||||
/* This is a reserved, ipv4compat, ipv4map, loopback,
|
||||
* link-local, multicast, or unspecified address. */
|
||||
EVENT2_EXPORT_SYMBOL
|
||||
int evutil_v6addr_is_local_(const struct in6_addr *in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: event-config.h,v 1.4 2017/02/01 01:15:34 christos Exp $ */
|
||||
/* $NetBSD: event-config.h,v 1.5 2021/04/07 03:36:48 christos Exp $ */
|
||||
/* event2/event-config.h
|
||||
*
|
||||
* This file was generated by autoconf when libevent was built, and post-
|
||||
|
@ -25,11 +25,17 @@
|
|||
/* #undef EVENT__DISABLE_THREAD_SUPPORT */
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
/* #undef EVENT__HAVE_ACCEPT4 */
|
||||
#define EVENT__HAVE_ACCEPT4 1
|
||||
|
||||
/* Define to 1 if you have the <afunix.h> header file. */
|
||||
/* #undef EVENT__HAVE_AFUNIX_H */
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#define EVENT__HAVE_ARC4RANDOM 1
|
||||
|
||||
/* Define to 1 if you have the `arc4random_addrandom' function. */
|
||||
#define EVENT__HAVE_ARC4RANDOM_ADDRANDOM 1
|
||||
|
||||
/* Define to 1 if you have the `arc4random_buf' function. */
|
||||
#define EVENT__HAVE_ARC4RANDOM_BUF 1
|
||||
|
||||
|
@ -47,14 +53,6 @@
|
|||
don't. */
|
||||
#define EVENT__HAVE_DECL_KERN_ARND 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_RANDOM', and to 0 if you
|
||||
don't. */
|
||||
#define EVENT__HAVE_DECL_KERN_RANDOM 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `RANDOM_UUID', and to 0 if you
|
||||
don't. */
|
||||
#define EVENT__HAVE_DECL_RANDOM_UUID 0
|
||||
|
||||
/* Define if /dev/poll is available */
|
||||
/* #undef EVENT__HAVE_DEVPOLL */
|
||||
|
||||
|
@ -73,9 +71,6 @@
|
|||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#define EVENT__HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have ERR_remove_thread_stat(). */
|
||||
#define EVENT__HAVE_ERR_REMOVE_THREAD_STATE 1
|
||||
|
||||
/* Define to 1 if you have the `eventfd' function. */
|
||||
/* #undef EVENT__HAVE_EVENTFD */
|
||||
|
||||
|
@ -121,6 +116,9 @@
|
|||
/* Define to 1 if you have the `getprotobynumber' function. */
|
||||
#define EVENT__HAVE_GETPROTOBYNUMBER 1
|
||||
|
||||
/* Define to 1 if you have the `getrandom' function. */
|
||||
#define EVENT__HAVE_GETRANDOM 1
|
||||
|
||||
/* Define to 1 if you have the `getservbyname' function. */
|
||||
#define EVENT__HAVE_GETSERVBYNAME 1
|
||||
|
||||
|
@ -145,12 +143,18 @@
|
|||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#define EVENT__HAVE_KQUEUE 1
|
||||
|
||||
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
|
||||
/* #undef EVENT__HAVE_LIBWS2_32 */
|
||||
|
||||
/* Define if the system has zlib */
|
||||
#define EVENT__HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if you have the `mach_absolute_time' function. */
|
||||
/* #undef EVENT__HAVE_MACH_ABSOLUTE_TIME */
|
||||
|
||||
/* Define to 1 if you have the <mach/mach.h> header file. */
|
||||
/* #undef EVENT__HAVE_MACH_MACH_H */
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_time.h> header file. */
|
||||
/* #undef EVENT__HAVE_MACH_MACH_TIME_H */
|
||||
|
||||
|
@ -178,6 +182,9 @@
|
|||
/* Define if the system has openssl */
|
||||
#define EVENT__HAVE_OPENSSL 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#define EVENT__HAVE_OPENSSL_SSL_H 1
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#define EVENT__HAVE_PIPE 1
|
||||
|
||||
|
@ -274,6 +281,9 @@
|
|||
/* Define to 1 if `s6_addr32' is a member of `struct in6_addr'. */
|
||||
/* #undef EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 */
|
||||
|
||||
/* Define to 1 if the system has the type `struct linger'. */
|
||||
#define EVENT__HAVE_STRUCT_LINGER 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
|
||||
|
@ -292,8 +302,8 @@
|
|||
/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
|
||||
/* #undef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */
|
||||
|
||||
/* Define to 1 if the system has the type `struct so_linger'. */
|
||||
/* #undef EVENT__HAVE_STRUCT_SO_LINGER */
|
||||
/* Define to 1 if the system has the type `struct sockaddr_un'. */
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_UN 1
|
||||
|
||||
/* Define to 1 if you have the `sysctl' function. */
|
||||
#define EVENT__HAVE_SYSCTL 1
|
||||
|
@ -322,6 +332,9 @@
|
|||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#define EVENT__HAVE_SYS_QUEUE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/random.h> header file. */
|
||||
#define EVENT__HAVE_SYS_RANDOM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define EVENT__HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
|
@ -352,6 +365,9 @@
|
|||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#define EVENT__HAVE_SYS_UIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||
#define EVENT__HAVE_SYS_UN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#define EVENT__HAVE_SYS_WAIT_H 1
|
||||
|
||||
|
@ -403,20 +419,29 @@
|
|||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#define EVENT__HAVE_VASPRINTF 1
|
||||
|
||||
/* Define if waitpid() supports WNOWAIT */
|
||||
#define EVENT__HAVE_WAITPID_WITH_WNOWAIT 1
|
||||
|
||||
/* Define if kqueue works correctly with pipes */
|
||||
#define EVENT__HAVE_WORKING_KQUEUE 1
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#define EVENT__HAVE_ZLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `_gmtime64' function. */
|
||||
/* #undef EVENT__HAVE__GMTIME64 */
|
||||
|
||||
/* Define to 1 if you have the `_gmtime64_s' function. */
|
||||
/* #undef EVENT__HAVE__GMTIME64_S */
|
||||
|
||||
/* Define to 1 if compiler have __FUNCTION__ */
|
||||
#define EVENT__HAVE___FUNCTION__ 1
|
||||
|
||||
/* Define to 1 if compiler have __func__ */
|
||||
#define EVENT__HAVE___func__ 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define EVENT__LT_OBJDIR ".libs/"
|
||||
|
||||
/* Numeric representation of the version */
|
||||
#define EVENT__NUMERIC_VERSION 0x02010800
|
||||
#define EVENT__NUMERIC_VERSION 0x02010c00
|
||||
|
||||
/* Name of package */
|
||||
#define EVENT__PACKAGE "libevent"
|
||||
|
@ -428,7 +453,7 @@
|
|||
#define EVENT__PACKAGE_NAME "libevent"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define EVENT__PACKAGE_STRING "libevent 2.1.8-stable"
|
||||
#define EVENT__PACKAGE_STRING "libevent 2.1.12-stable"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define EVENT__PACKAGE_TARNAME "libevent"
|
||||
|
@ -437,7 +462,7 @@
|
|||
#define EVENT__PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define EVENT__PACKAGE_VERSION "2.1.8-stable"
|
||||
#define EVENT__PACKAGE_VERSION "2.1.12-stable"
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
|
@ -476,6 +501,9 @@
|
|||
#define EVENT__SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* The size of `time_t', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_TIME_T 8
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#ifdef _LP64
|
||||
#define EVENT__SIZEOF_VOID_P 8
|
||||
|
@ -484,79 +512,76 @@
|
|||
#endif
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define EVENT__STDC_HEADERS 1
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define EVENT__TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef EVENT___ALL_SOURCE
|
||||
# define EVENT___ALL_SOURCE 1
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef EVENT___GNU_SOURCE
|
||||
# define EVENT___GNU_SOURCE 1
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef EVENT___POSIX_PTHREAD_SEMANTICS
|
||||
# define EVENT___POSIX_PTHREAD_SEMANTICS 1
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef EVENT___TANDEM_SOURCE
|
||||
# define EVENT___TANDEM_SOURCE 1
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef EVENT____EXTENSIONS__
|
||||
# define EVENT____EXTENSIONS__ 1
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define EVENT__VERSION "2.1.8-stable"
|
||||
#define EVENT__VERSION "2.1.12-stable"
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef EVENT___DARWIN_USE_64_BIT_INODE
|
||||
# define EVENT___DARWIN_USE_64_BIT_INODE 1
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef EVENT___FILE_OFFSET_BITS */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef EVENT___LARGE_FILES */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef EVENT___MINIX */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef EVENT___POSIX_1_SOURCE */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef EVENT___POSIX_SOURCE */
|
||||
|
||||
/* Define to appropriate substitue if compiler doesnt have __func__ */
|
||||
/* #undef EVENT____func__ */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef EVENT__const */
|
||||
/* #undef const */
|
||||
|
||||
/* 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
|
||||
/* #undef EVENT__inline */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef EVENT__pid_t */
|
||||
/* #undef pid_t */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef EVENT__size_t */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define to unsigned int if you dont have it */
|
||||
/* #undef EVENT__socklen_t */
|
||||
/* #undef socklen_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef EVENT__ssize_t */
|
||||
/* #undef ssize_t */
|
||||
|
||||
#endif /* event2/event-config.h */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
# $NetBSD: libevent2netbsd,v 1.2 2015/01/29 07:26:02 spz Exp $
|
||||
# $NetBSD: libevent2netbsd,v 1.3 2021/04/07 03:36:48 christos Exp $
|
||||
|
||||
# Extract the new tarball and rename the libevent-X.Y.Z directory
|
||||
# to dist. Run this script and check for additional files and
|
||||
|
@ -88,6 +88,7 @@ for f in $(grep -RL '\$NetBSD.*\$' $d include | grep -v CVS); do
|
|||
*.c)
|
||||
sed -e '1i\
|
||||
/* \$NetBSD\$ */
|
||||
|
||||
' -e '/#include "event2\/event-config.h"/ {
|
||||
a\
|
||||
#include <sys/cdefs.h>\
|
||||
|
|
Loading…
Reference in New Issue