Update to libevent-1.4.11-stable. This has been a long time coming and
fixes many bugs, particularly with signal handling. The regression tests have also been updated and complete successfully on amd64.
This commit is contained in:
parent
77a7c01d68
commit
e234ec7db5
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: md.amd64,v 1.56 2009/06/28 05:37:22 agc Exp $
|
||||
# $NetBSD: md.amd64,v 1.57 2009/07/08 21:23:52 tls Exp $
|
||||
./dev/lms0 base-obsolete obsolete
|
||||
./dev/mms0 base-obsolete obsolete
|
||||
./libexec/ld.elf_so-i386 base-sys-shlib compat,pic
|
||||
|
@ -80,7 +80,7 @@
|
|||
./usr/lib/i386/libedit.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libedit.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libevent.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libevent.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libevent.so.3.1 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libform.so.6 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libform.so.6.0 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libgcc_s.so.1 base-compat-shlib compat,pic
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: md.sparc64,v 1.50 2009/06/28 05:37:22 agc Exp $
|
||||
# $NetBSD: md.sparc64,v 1.51 2009/07/08 21:23:52 tls Exp $
|
||||
./libexec/ld.elf_so-sparc base-sysutil-bin compat,pic
|
||||
./sbin/edlabel base-sysutil-root
|
||||
./usr/bin/fdformat base-util-bin
|
||||
|
@ -79,7 +79,7 @@
|
|||
./usr/lib/sparc/libedit.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libedit.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libevent.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libevent.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libevent.so.3.1 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libform.so.6 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libform.so.6.0 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libgcc_s.so.1 base-compat-shlib compat,pic
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: shl.mi,v 1.477 2009/06/25 20:54:16 agc Exp $
|
||||
# $NetBSD: shl.mi,v 1.478 2009/07/08 21:23:52 tls Exp $
|
||||
#
|
||||
# Note: Don't delete entries from here - mark them as "obsolete" instead,
|
||||
# unless otherwise stated below.
|
||||
|
@ -18,7 +18,7 @@
|
|||
./lib/libcrypto.so.5.1 base-crypto-shlib crypto,dynamicroot
|
||||
./lib/libdevmapper.so.1.0 base-lvm-shlib lvm,dynamicroot
|
||||
./lib/libedit.so.3.0 base-sys-shlib dynamicroot
|
||||
./lib/libevent.so.3.0 base-sys-shlib dynamicroot
|
||||
./lib/libevent.so.3.1 base-sys-shlib dynamicroot
|
||||
./lib/libgcc_s.so.1.0 base-sys-shlib gcc
|
||||
./lib/libipsec.so.3.0 base-net-shlib dynamicroot
|
||||
./lib/libkvm.so.6.0 base-sys-shlib dynamicroot
|
||||
|
@ -69,7 +69,7 @@
|
|||
./usr/lib/libdevmapper.so.1.0 base-lvm-shlib lvm
|
||||
./usr/lib/libdns.so.3.0 base-bind-shlib
|
||||
./usr/lib/libedit.so.3.0 base-sys-shlib
|
||||
./usr/lib/libevent.so.3.0 base-sys-shlib
|
||||
./usr/lib/libevent.so.3.1 base-sys-shlib
|
||||
./usr/lib/libfetch.so.2.0 base-sys-shlib
|
||||
./usr/lib/libform.so.6.0 base-sys-shlib
|
||||
./usr/lib/libg2c.so.2.0 base-sys-shlib gcc=3
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.1276 2009/07/06 15:19:49 joerg Exp $
|
||||
# $NetBSD: mi,v 1.1277 2009/07/08 21:23:52 tls Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -611,6 +611,7 @@
|
|||
./usr/include/eti.h comp-c-include
|
||||
./usr/include/evdns.h comp-c-include
|
||||
./usr/include/event.h comp-c-include
|
||||
./usr/include/event-config.h comp-c-include
|
||||
./usr/include/evhttp.h comp-c-include
|
||||
./usr/include/evrpc.h comp-c-include
|
||||
./usr/include/evutil.h comp-c-include
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# $NetBSD: Makefile,v 1.4 2008/05/16 20:24:57 peter Exp $
|
||||
# $NetBSD: Makefile,v 1.5 2009/07/08 21:23:53 tls Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/4/93
|
||||
|
||||
NOLINT= # Until someone explains to me how to avoid lint stupidity
|
||||
USE_SHLIBDIR= yes
|
||||
|
||||
CPPFLAGS+=-DHAVE_CONFIG_H -I${.CURDIR}
|
||||
CPPFLAGS+=-I${.CURDIR}
|
||||
.include <bsd.own.mk>
|
||||
|
||||
LIB= event
|
||||
|
@ -14,6 +14,9 @@ SRCS= buffer.c evbuffer.c evdns.c event.c event_tagging.c evrpc.c evutil.c \
|
|||
INCS= evdns.h event.h evhttp.h evrpc.h evutil.h
|
||||
INCSDIR=/usr/include
|
||||
|
||||
INCS+= config.h
|
||||
INCSNAME_config.h= event-config.h
|
||||
|
||||
MAN= evdns.3 event.3
|
||||
|
||||
MLINKS+=event.3 event_init.3
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: buffer.c,v 1.4 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: buffer.c,v 1.5 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -26,10 +26,6 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -43,6 +39,8 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "config.h"
|
||||
#include "evutil.h"
|
||||
|
||||
struct evbuffer *
|
||||
evbuffer_new(void)
|
||||
|
@ -131,13 +129,13 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
|
|||
|
||||
va_copy(aq, ap);
|
||||
|
||||
sz = vsnprintf(buffer, space, fmt, aq);
|
||||
sz = evutil_vsnprintf(buffer, space, fmt, aq);
|
||||
|
||||
va_end(aq);
|
||||
|
||||
if (sz < 0)
|
||||
return (-1);
|
||||
if (sz < space) {
|
||||
if ((size_t)sz < space) {
|
||||
buf->off += sz;
|
||||
if (buf->cb != NULL)
|
||||
(*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
|
||||
|
@ -340,7 +338,7 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
|
|||
* about it. If the reader does not tell us how much
|
||||
* data we should read, we artifically limit it.
|
||||
*/
|
||||
if (n > buf->totallen << 2)
|
||||
if ((size_t)n > buf->totallen << 2)
|
||||
n = buf->totallen << 2;
|
||||
if (n < EVBUFFER_MAX_READ)
|
||||
n = EVBUFFER_MAX_READ;
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.4.4-stable"
|
||||
#define VERSION "1.4.11-stable"
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef pid_t */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evbuffer.c,v 1.4 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: evbuffer.c,v 1.5 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002-2004 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -389,6 +389,11 @@ bufferevent_settimeout(struct bufferevent *bufev,
|
|||
int timeout_read, int timeout_write) {
|
||||
bufev->timeout_read = timeout_read;
|
||||
bufev->timeout_write = timeout_write;
|
||||
|
||||
if (event_pending(&bufev->ev_read, EV_READ, NULL))
|
||||
bufferevent_add(&bufev->ev_read, timeout_read);
|
||||
if (event_pending(&bufev->ev_write, EV_WRITE, NULL))
|
||||
bufferevent_add(&bufev->ev_write, timeout_write);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evdns.c,v 1.2 2009/01/26 15:09:56 christos Exp $ */
|
||||
/* $NetBSD: evdns.c,v 1.3 2009/07/08 21:23:53 tls Exp $ */
|
||||
|
||||
/* The original version of this module was written by Adam Langley; for
|
||||
* a history of modifications, check out the subversion logs.
|
||||
|
@ -35,9 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef DNS_USE_FTIME_FOR_ID
|
||||
#include <sys/timeb.h>
|
||||
|
@ -334,7 +332,7 @@ debug_ntoa(u32 address)
|
|||
{
|
||||
static char buf[32];
|
||||
u32 a = ntohl(address);
|
||||
snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
|
||||
evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
|
||||
(int)(u8)((a>>24)&0xff),
|
||||
(int)(u8)((a>>16)&0xff),
|
||||
(int)(u8)((a>>8 )&0xff),
|
||||
|
@ -365,7 +363,7 @@ _evdns_log(int warn, const char *fmt, ...)
|
|||
if (!evdns_log_fn)
|
||||
return;
|
||||
va_start(args,fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
evutil_vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
evdns_log_fn(warn, buf);
|
||||
va_end(args);
|
||||
|
@ -630,7 +628,10 @@ reply_callback(struct request *const req, u32 ttl, u32 err, struct reply *reply)
|
|||
static void
|
||||
reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
|
||||
int error;
|
||||
static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED};
|
||||
static const int error_codes[] = {
|
||||
DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST,
|
||||
DNS_ERR_NOTIMPL, DNS_ERR_REFUSED
|
||||
};
|
||||
|
||||
if (flags & 0x020f || !reply || !reply->have_answer) {
|
||||
/* there was an error */
|
||||
|
@ -651,16 +652,18 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
|
|||
/* we regard these errors as marking a bad nameserver */
|
||||
if (req->reissue_count < global_max_reissues) {
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "Bad response %d (%s)",
|
||||
evutil_snprintf(msg, sizeof(msg),
|
||||
"Bad response %d (%s)",
|
||||
error, evdns_err_to_string(error));
|
||||
nameserver_failed(req->ns, msg);
|
||||
if (!request_reissue(req)) return;
|
||||
}
|
||||
break;
|
||||
case DNS_ERR_SERVERFAILED:
|
||||
/* rcode 2 (servfailed) sometimes means "we are broken" and
|
||||
* sometimes (with some binds) means "that request was very
|
||||
* confusing." Treat this as a timeout, not a failure.
|
||||
/* rcode 2 (servfailed) sometimes means "we
|
||||
* are broken" and sometimes (with some binds)
|
||||
* means "that request was very confusing."
|
||||
* Treat this as a timeout, not a failure.
|
||||
*/
|
||||
log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
|
||||
"will allow the request to time out.",
|
||||
|
@ -672,10 +675,13 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
|
|||
}
|
||||
|
||||
if (req->search_state && req->request_type != TYPE_PTR) {
|
||||
/* if we have a list of domains to search in, try the next one */
|
||||
/* if we have a list of domains to search in,
|
||||
* try the next one */
|
||||
if (!search_try_next(req)) {
|
||||
/* a new request was issued so this request is finished and */
|
||||
/* the user callback will be made when that request (or a */
|
||||
/* a new request was issued so this
|
||||
* request is finished and */
|
||||
/* the user callback will be made when
|
||||
* that request (or a */
|
||||
/* child of it) finishes. */
|
||||
request_finished(req, &req_head);
|
||||
return;
|
||||
|
@ -752,10 +758,10 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
|
|||
/* parses a raw request from a nameserver */
|
||||
static int
|
||||
reply_parse(u8 *packet, int length) {
|
||||
int j = 0; /* index into packet */
|
||||
int j = 0, k = 0; /* index into packet */
|
||||
u16 _t; /* used by the macros */
|
||||
u32 _t32; /* used by the macros */
|
||||
char tmp_name[256]; /* used by the macros */
|
||||
char tmp_name[256], cmp_name[256]; /* used by the macros */
|
||||
|
||||
u16 trans_id, questions, answers, authority, additional, datalength;
|
||||
u16 flags = 0;
|
||||
|
@ -788,10 +794,21 @@ reply_parse(u8 *packet, int length) {
|
|||
|
||||
/* This macro skips a name in the DNS reply. */
|
||||
#define SKIP_NAME \
|
||||
do { tmp_name[0] = '\0'; \
|
||||
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \
|
||||
goto err; \
|
||||
} while(0);
|
||||
do { tmp_name[0] = '\0'; \
|
||||
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\
|
||||
goto err; \
|
||||
} while(0)
|
||||
#define TEST_NAME \
|
||||
do { tmp_name[0] = '\0'; \
|
||||
cmp_name[0] = '\0'; \
|
||||
k = j; \
|
||||
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\
|
||||
goto err; \
|
||||
if (name_parse(req->request, req->request_len, &k, cmp_name, sizeof(cmp_name))<0) \
|
||||
goto err; \
|
||||
if (memcmp(tmp_name, cmp_name, strlen (tmp_name)) != 0) \
|
||||
return (-1); /* we ignore mismatching names */ \
|
||||
} while(0)
|
||||
|
||||
reply.type = req->request_type;
|
||||
|
||||
|
@ -800,7 +817,7 @@ reply_parse(u8 *packet, int length) {
|
|||
/* the question looks like
|
||||
* <label:name><u16:type><u16:class>
|
||||
*/
|
||||
SKIP_NAME;
|
||||
TEST_NAME;
|
||||
j += 4;
|
||||
if (j > length) goto err;
|
||||
}
|
||||
|
@ -974,12 +991,16 @@ default_transaction_id_fn(void)
|
|||
u16 trans_id;
|
||||
#ifdef DNS_USE_CPU_CLOCK_FOR_ID
|
||||
struct timespec ts;
|
||||
static int clkid = -1;
|
||||
if (clkid == -1) {
|
||||
clkid = CLOCK_REALTIME;
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
||||
#else
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1)
|
||||
clkid = CLOCK_MONOTONIC;
|
||||
#endif
|
||||
event_err(1, "clock_gettime");
|
||||
}
|
||||
if (clock_gettime(clkid, &ts) == -1)
|
||||
event_err(1, "clock_gettime");
|
||||
trans_id = ts.tv_nsec & 0xffff;
|
||||
#endif
|
||||
|
||||
|
@ -1509,7 +1530,7 @@ evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_a
|
|||
assert(!(in && inaddr_name));
|
||||
if (in) {
|
||||
a = ntohl(in->s_addr);
|
||||
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
|
||||
evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
|
||||
(int)(u8)((a )&0xff),
|
||||
(int)(u8)((a>>8 )&0xff),
|
||||
(int)(u8)((a>>16)&0xff),
|
||||
|
@ -1526,7 +1547,7 @@ int
|
|||
evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl)
|
||||
{
|
||||
return evdns_server_request_add_reply(
|
||||
req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
|
||||
req, EVDNS_ANSWER_SECTION, name, TYPE_CNAME, CLASS_INET,
|
||||
ttl, -1, 1, cname);
|
||||
}
|
||||
|
||||
|
@ -2222,13 +2243,13 @@ int evdns_resolve_ipv6(const char *name, int flags,
|
|||
}
|
||||
}
|
||||
|
||||
int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
|
||||
int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
|
||||
char buf[32];
|
||||
struct request *req;
|
||||
u32 a;
|
||||
assert(in);
|
||||
a = ntohl(in->s_addr);
|
||||
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
|
||||
evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
|
||||
(int)(u8)((a )&0xff),
|
||||
(int)(u8)((a>>8 )&0xff),
|
||||
(int)(u8)((a>>16)&0xff),
|
||||
|
@ -2240,7 +2261,7 @@ int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type cal
|
|||
return 0;
|
||||
}
|
||||
|
||||
int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
|
||||
int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
|
||||
/* 32 nybbles, 32 periods, "ip6.arpa", NUL. */
|
||||
char buf[73];
|
||||
char *cp;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evdns.h,v 1.1 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: evdns.h,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -346,7 +346,7 @@ struct in6_addr;
|
|||
@return 0 if successful, or -1 if an error occurred
|
||||
@see evdns_resolve_reverse_ipv6()
|
||||
*/
|
||||
int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr);
|
||||
int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -359,7 +359,7 @@ int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type cal
|
|||
@return 0 if successful, or -1 if an error occurred
|
||||
@see evdns_resolve_reverse_ipv6()
|
||||
*/
|
||||
int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
|
||||
int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: event.c,v 1.9 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: event.c,v 1.10 2009/07/08 21:23:53 tls Exp $ */
|
||||
/* $OpenBSD: event.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -30,9 +30,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
|
@ -69,7 +67,7 @@ extern const struct eventop kqops;
|
|||
#endif
|
||||
|
||||
/* In order of preference */
|
||||
const struct eventop *eventops[] = {
|
||||
static const struct eventop *eventops[] = {
|
||||
#ifdef HAVE_EVENT_PORTS
|
||||
&evportops,
|
||||
#endif
|
||||
|
@ -168,7 +166,6 @@ event_base_new(void)
|
|||
|
||||
min_heap_ctor(&base->timeheap);
|
||||
TAILQ_INIT(&base->eventqueue);
|
||||
TAILQ_INIT(&base->sig.signalqueue);
|
||||
base->sig.ev_signal_pair[0] = -1;
|
||||
base->sig.ev_signal_pair[1] = -1;
|
||||
|
||||
|
@ -219,9 +216,20 @@ event_base_free(struct event_base *base)
|
|||
++n_deleted;
|
||||
}
|
||||
|
||||
for (i = 0; i < base->nactivequeues; ++i) {
|
||||
for (ev = TAILQ_FIRST(base->activequeues[i]); ev; ) {
|
||||
struct event *next = TAILQ_NEXT(ev, ev_active_next);
|
||||
if (!(ev->ev_flags & EVLIST_INTERNAL)) {
|
||||
event_del(ev);
|
||||
++n_deleted;
|
||||
}
|
||||
ev = next;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_deleted)
|
||||
event_debug(("%s: %d events were still set in base",
|
||||
__func__, n_deleted));
|
||||
__func__, n_deleted));
|
||||
|
||||
if (base->evsel->dealloc != NULL)
|
||||
base->evsel->dealloc(base, base->evbase);
|
||||
|
@ -254,6 +262,17 @@ event_reinit(struct event_base *base)
|
|||
if (!evsel->need_reinit)
|
||||
return (0);
|
||||
|
||||
if (base->sig.ev_signal_added) {
|
||||
/* we cannot call event_del here because the base has
|
||||
* not been reinitialized yet. */
|
||||
event_queue_remove(base, &base->sig.ev_signal,
|
||||
EVLIST_INSERTED);
|
||||
if (base->sig.ev_signal.ev_flags & EVLIST_ACTIVE)
|
||||
event_queue_remove(base, &base->sig.ev_signal,
|
||||
EVLIST_ACTIVE);
|
||||
base->sig.ev_signal_added = 0;
|
||||
}
|
||||
|
||||
if (base->evsel->dealloc != NULL)
|
||||
base->evsel->dealloc(base, base->evbase);
|
||||
evbase = base->evbase = evsel->init(base);
|
||||
|
@ -387,14 +406,14 @@ event_loopexit_cb(int fd, short what, void *arg)
|
|||
|
||||
/* not thread safe */
|
||||
int
|
||||
event_loopexit(struct timeval *tv)
|
||||
event_loopexit(const struct timeval *tv)
|
||||
{
|
||||
return (event_once(-1, EV_TIMEOUT, event_loopexit_cb,
|
||||
current_base, tv));
|
||||
}
|
||||
|
||||
int
|
||||
event_base_loopexit(struct event_base *event_base, struct timeval *tv)
|
||||
event_base_loopexit(struct event_base *event_base, const struct timeval *tv)
|
||||
{
|
||||
return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb,
|
||||
event_base, tv));
|
||||
|
@ -436,7 +455,10 @@ event_base_loop(struct event_base *base, int flags)
|
|||
struct timeval *tv_p;
|
||||
int res, done;
|
||||
|
||||
if(!TAILQ_EMPTY(&base->sig.signalqueue))
|
||||
/* clear time cache */
|
||||
base->tv_cache.tv_sec = 0;
|
||||
|
||||
if (base->sig.ev_signal_added)
|
||||
evsignal_base = base;
|
||||
done = 0;
|
||||
while (!done) {
|
||||
|
@ -504,6 +526,9 @@ event_base_loop(struct event_base *base, int flags)
|
|||
done = 1;
|
||||
}
|
||||
|
||||
/* clear time cache */
|
||||
base->tv_cache.tv_sec = 0;
|
||||
|
||||
event_debug(("%s: asked to terminate loop.", __func__));
|
||||
return (0);
|
||||
}
|
||||
|
@ -531,7 +556,7 @@ event_once_cb(int fd, short events, void *arg)
|
|||
/* not threadsafe, event scheduled once. */
|
||||
int
|
||||
event_once(int fd, short events,
|
||||
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
|
||||
void (*callback)(int, short, void *), void *arg, const struct timeval *tv)
|
||||
{
|
||||
return event_base_once(current_base, fd, events, callback, arg, tv);
|
||||
}
|
||||
|
@ -539,7 +564,7 @@ event_once(int fd, short events,
|
|||
/* Schedules an event once */
|
||||
int
|
||||
event_base_once(struct event_base *base, int fd, short events,
|
||||
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
|
||||
void (*callback)(int, short, void *), void *arg, const struct timeval *tv)
|
||||
{
|
||||
struct event_once *eonce;
|
||||
struct timeval etv;
|
||||
|
@ -648,13 +673,11 @@ event_pending(struct event *ev, short event, struct timeval *tv)
|
|||
int flags = 0;
|
||||
|
||||
if (ev->ev_flags & EVLIST_INSERTED)
|
||||
flags |= (ev->ev_events & (EV_READ|EV_WRITE));
|
||||
flags |= (ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL));
|
||||
if (ev->ev_flags & EVLIST_ACTIVE)
|
||||
flags |= ev->ev_res;
|
||||
if (ev->ev_flags & EVLIST_TIMEOUT)
|
||||
flags |= EV_TIMEOUT;
|
||||
if (ev->ev_flags & EVLIST_SIGNAL)
|
||||
flags |= EV_SIGNAL;
|
||||
|
||||
event &= (EV_TIMEOUT|EV_READ|EV_WRITE|EV_SIGNAL);
|
||||
|
||||
|
@ -671,11 +694,12 @@ event_pending(struct event *ev, short event, struct timeval *tv)
|
|||
}
|
||||
|
||||
int
|
||||
event_add(struct event *ev, struct timeval *tv)
|
||||
event_add(struct event *ev, const struct timeval *tv)
|
||||
{
|
||||
struct event_base *base = ev->ev_base;
|
||||
const struct eventop *evsel = base->evsel;
|
||||
void *evbase = base->evbase;
|
||||
int res = 0;
|
||||
|
||||
event_debug((
|
||||
"event_add: event: %p, %s%s%scall %p",
|
||||
|
@ -687,14 +711,36 @@ event_add(struct event *ev, struct timeval *tv)
|
|||
|
||||
assert(!(ev->ev_flags & ~EVLIST_ALL));
|
||||
|
||||
if (tv != NULL) {
|
||||
/*
|
||||
* prepare for timeout insertion further below, if we get a
|
||||
* failure on any step, we should not change any state.
|
||||
*/
|
||||
if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) {
|
||||
if (min_heap_reserve(&base->timeheap,
|
||||
1 + min_heap_size(&base->timeheap)) == -1)
|
||||
return (-1); /* ENOMEM == errno */
|
||||
}
|
||||
|
||||
if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) &&
|
||||
!(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) {
|
||||
res = evsel->add(evbase, ev);
|
||||
if (res != -1)
|
||||
event_queue_insert(base, ev, EVLIST_INSERTED);
|
||||
}
|
||||
|
||||
/*
|
||||
* we should change the timout state only if the previous event
|
||||
* addition succeeded.
|
||||
*/
|
||||
if (res != -1 && tv != NULL) {
|
||||
struct timeval now;
|
||||
|
||||
/*
|
||||
* we already reserved memory above for the case where we
|
||||
* are not replacing an exisiting timeout.
|
||||
*/
|
||||
if (ev->ev_flags & EVLIST_TIMEOUT)
|
||||
event_queue_remove(base, ev, EVLIST_TIMEOUT);
|
||||
else if (min_heap_reserve(&base->timeheap,
|
||||
1 + min_heap_size(&base->timeheap)) == -1)
|
||||
return (-1); /* ENOMEM == errno */
|
||||
|
||||
/* Check if it is active due to a timeout. Rescheduling
|
||||
* this timeout before the callback can be executed
|
||||
|
@ -716,29 +762,13 @@ event_add(struct event *ev, struct timeval *tv)
|
|||
evutil_timeradd(&now, tv, &ev->ev_timeout);
|
||||
|
||||
event_debug((
|
||||
"event_add: timeout in %d seconds, call %p",
|
||||
"event_add: timeout in %ld seconds, call %p",
|
||||
tv->tv_sec, ev->ev_callback));
|
||||
|
||||
event_queue_insert(base, ev, EVLIST_TIMEOUT);
|
||||
}
|
||||
|
||||
if ((ev->ev_events & (EV_READ|EV_WRITE)) &&
|
||||
!(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) {
|
||||
int res = evsel->add(evbase, ev);
|
||||
if (res != -1)
|
||||
event_queue_insert(base, ev, EVLIST_INSERTED);
|
||||
|
||||
return (res);
|
||||
} else if ((ev->ev_events & EV_SIGNAL) &&
|
||||
!(ev->ev_flags & EVLIST_SIGNAL)) {
|
||||
int res = evsel->add(evbase, ev);
|
||||
if (res != -1)
|
||||
event_queue_insert(base, ev, EVLIST_SIGNAL);
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
return (0);
|
||||
return (res);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -776,9 +806,6 @@ event_del(struct event *ev)
|
|||
if (ev->ev_flags & EVLIST_INSERTED) {
|
||||
event_queue_remove(base, ev, EVLIST_INSERTED);
|
||||
return (evsel->del(evbase, ev));
|
||||
} else if (ev->ev_flags & EVLIST_SIGNAL) {
|
||||
event_queue_remove(base, ev, EVLIST_SIGNAL);
|
||||
return (evsel->del(evbase, ev));
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -825,7 +852,7 @@ timeout_next(struct event_base *base, struct timeval **tv_p)
|
|||
assert(tv->tv_sec >= 0);
|
||||
assert(tv->tv_usec >= 0);
|
||||
|
||||
event_debug(("timeout_next: in %d seconds", tv->tv_sec));
|
||||
event_debug(("timeout_next: in %ld seconds", tv->tv_sec));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -915,9 +942,6 @@ event_queue_remove(struct event_base *base, struct event *ev, int queue)
|
|||
case EVLIST_TIMEOUT:
|
||||
min_heap_erase(&base->timeheap, ev);
|
||||
break;
|
||||
case EVLIST_SIGNAL:
|
||||
TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next);
|
||||
break;
|
||||
default:
|
||||
event_errx(1, "%s: unknown queue %x", __func__, queue);
|
||||
}
|
||||
|
@ -952,9 +976,6 @@ event_queue_insert(struct event_base *base, struct event *ev, int queue)
|
|||
min_heap_push(&base->timeheap, ev);
|
||||
break;
|
||||
}
|
||||
case EVLIST_SIGNAL:
|
||||
TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next);
|
||||
break;
|
||||
default:
|
||||
event_errx(1, "%s: unknown queue %x", __func__, queue);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: event.h,v 1.5 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: event.h,v 1.6 2009/07/08 21:23:53 tls Exp $ */
|
||||
/* $OpenBSD: event.h,v 1.4 2002/07/12 18:50:48 provos Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -391,7 +391,7 @@ int event_base_loop(struct event_base *, int);
|
|||
@return 0 if successful, or -1 if an error occurred
|
||||
@see event_loop(), event_base_loop(), event_base_loopexit()
|
||||
*/
|
||||
int event_loopexit(struct timeval *);
|
||||
int event_loopexit(const struct timeval *);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -408,7 +408,7 @@ int event_loopexit(struct timeval *);
|
|||
@return 0 if successful, or -1 if an error occurred
|
||||
@see event_loopexit()
|
||||
*/
|
||||
int event_base_loopexit(struct event_base *, struct timeval *);
|
||||
int event_base_loopexit(struct event_base *, const struct timeval *);
|
||||
|
||||
/**
|
||||
Abort the active event_loop() immediately.
|
||||
|
@ -550,7 +550,8 @@ void event_set(struct event *, int, short, void (*)(int, short, void *), void *)
|
|||
@see event_set()
|
||||
|
||||
*/
|
||||
int event_once(int, short, void (*)(int, short, void *), void *, struct timeval *);
|
||||
int event_once(int, short, void (*)(int, short, void *), void *,
|
||||
const struct timeval *);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -571,7 +572,9 @@ int event_once(int, short, void (*)(int, short, void *), void *, struct timeval
|
|||
@return 0 if successful, or -1 if an error occurred
|
||||
@see event_once()
|
||||
*/
|
||||
int event_base_once(struct event_base *, int, short, void (*)(int, short, void *), void *, struct timeval *);
|
||||
int event_base_once(struct event_base *base, int fd, short events,
|
||||
void (*callback)(int, short, void *), void *arg,
|
||||
const struct timeval *timeout);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -592,7 +595,7 @@ int event_base_once(struct event_base *, int, short, void (*)(int, short, void *
|
|||
@return 0 if successful, or -1 if an error occurred
|
||||
@see event_del(), event_set()
|
||||
*/
|
||||
int event_add(struct event *, struct timeval *);
|
||||
int event_add(struct event *ev, const struct timeval *timeout);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -622,7 +625,7 @@ void event_active(struct event *, int, short);
|
|||
@return 1 if the event is pending, or 0 if the event has not occurred
|
||||
|
||||
*/
|
||||
int event_pending(struct event *, short, struct timeval *);
|
||||
int event_pending(struct event *ev, short event, struct timeval *tv);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1053,7 +1056,6 @@ int evbuffer_add_vprintf(struct evbuffer *, const char *fmt, va_list ap);
|
|||
|
||||
@param buf the evbuffer to be drained
|
||||
@param len the number of bytes to drain from the beginning of the buffer
|
||||
@return 0 if successful, or -1 if an error occurred
|
||||
*/
|
||||
void evbuffer_drain(struct evbuffer *, size_t);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: event_tagging.c,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: event_tagging.c,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -26,9 +26,7 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evhttp.h,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: evhttp.h,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -210,7 +210,6 @@ struct {
|
|||
char major; /* HTTP Major number */
|
||||
char minor; /* HTTP Minor number */
|
||||
|
||||
int got_firstline;
|
||||
int response_code; /* HTTP Response code */
|
||||
char *response_code_line; /* Readable response */
|
||||
|
||||
|
@ -262,6 +261,10 @@ void evhttp_connection_free(struct evhttp_connection *evcon);
|
|||
void evhttp_connection_set_local_address(struct evhttp_connection *evcon,
|
||||
const char *address);
|
||||
|
||||
/** sets the local port from which http connections are made */
|
||||
void evhttp_connection_set_local_port(struct evhttp_connection *evcon,
|
||||
unsigned short port);
|
||||
|
||||
/** Sets the timeout for events related to this connection */
|
||||
void evhttp_connection_set_timeout(struct evhttp_connection *evcon,
|
||||
int timeout_in_secs);
|
||||
|
@ -326,10 +329,20 @@ char *evhttp_decode_uri(const char *uri);
|
|||
|
||||
/**
|
||||
* Helper function to parse out arguments in a query.
|
||||
* The arguments are separated by key and value.
|
||||
* URI should already be decoded.
|
||||
*
|
||||
* Parsing a uri like
|
||||
*
|
||||
* http://foo.com/?q=test&s=some+thing
|
||||
*
|
||||
* will result in two entries in the key value queue.
|
||||
|
||||
* The first entry is: key="q", value="test"
|
||||
* The second entry is: key="s", value="some thing"
|
||||
*
|
||||
* @param uri the request URI
|
||||
* @param headers the head of the evkeyval queue
|
||||
*/
|
||||
void evhttp_parse_query(const char *uri, struct evkeyvalq *);
|
||||
void evhttp_parse_query(const char *uri, struct evkeyvalq *headers);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evrpc.c,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: evrpc.c,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -25,9 +25,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -78,10 +76,10 @@ evrpc_free(struct evrpc_base *base)
|
|||
assert(evrpc_unregister_rpc(base, rpc->uri));
|
||||
}
|
||||
while ((hook = TAILQ_FIRST(&base->input_hooks)) != NULL) {
|
||||
assert(evrpc_remove_hook(base, INPUT, hook));
|
||||
assert(evrpc_remove_hook(base, EVRPC_INPUT, hook));
|
||||
}
|
||||
while ((hook = TAILQ_FIRST(&base->output_hooks)) != NULL) {
|
||||
assert(evrpc_remove_hook(base, OUTPUT, hook));
|
||||
assert(evrpc_remove_hook(base, EVRPC_OUTPUT, hook));
|
||||
}
|
||||
free(base);
|
||||
}
|
||||
|
@ -96,14 +94,14 @@ evrpc_add_hook(void *vbase,
|
|||
struct evrpc_hook_list *head = NULL;
|
||||
struct evrpc_hook *hook = NULL;
|
||||
switch (hook_type) {
|
||||
case INPUT:
|
||||
case EVRPC_INPUT:
|
||||
head = &base->in_hooks;
|
||||
break;
|
||||
case OUTPUT:
|
||||
case EVRPC_OUTPUT:
|
||||
head = &base->out_hooks;
|
||||
break;
|
||||
default:
|
||||
assert(hook_type == INPUT || hook_type == OUTPUT);
|
||||
assert(hook_type == EVRPC_INPUT || hook_type == EVRPC_OUTPUT);
|
||||
}
|
||||
|
||||
hook = calloc(1, sizeof(struct evrpc_hook));
|
||||
|
@ -141,14 +139,14 @@ evrpc_remove_hook(void *vbase, enum EVRPC_HOOK_TYPE hook_type, void *handle)
|
|||
struct _evrpc_hooks *base = vbase;
|
||||
struct evrpc_hook_list *head = NULL;
|
||||
switch (hook_type) {
|
||||
case INPUT:
|
||||
case EVRPC_INPUT:
|
||||
head = &base->in_hooks;
|
||||
break;
|
||||
case OUTPUT:
|
||||
case EVRPC_OUTPUT:
|
||||
head = &base->out_hooks;
|
||||
break;
|
||||
default:
|
||||
assert(hook_type == INPUT || hook_type == OUTPUT);
|
||||
assert(hook_type == EVRPC_INPUT || hook_type == EVRPC_OUTPUT);
|
||||
}
|
||||
|
||||
return (evrpc_remove_hook_internal(head, handle));
|
||||
|
@ -414,11 +412,11 @@ evrpc_pool_free(struct evrpc_pool *pool)
|
|||
}
|
||||
|
||||
while ((hook = TAILQ_FIRST(&pool->input_hooks)) != NULL) {
|
||||
assert(evrpc_remove_hook(pool, INPUT, hook));
|
||||
assert(evrpc_remove_hook(pool, EVRPC_INPUT, hook));
|
||||
}
|
||||
|
||||
while ((hook = TAILQ_FIRST(&pool->output_hooks)) != NULL) {
|
||||
assert(evrpc_remove_hook(pool, OUTPUT, hook));
|
||||
assert(evrpc_remove_hook(pool, EVRPC_OUTPUT, hook));
|
||||
}
|
||||
|
||||
free(pool);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evrpc.h,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: evrpc.h,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -437,10 +437,19 @@ void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs);
|
|||
*/
|
||||
|
||||
enum EVRPC_HOOK_TYPE {
|
||||
INPUT, /**< apply the function to an input hook */
|
||||
OUTPUT /**< apply the function to an output hook */
|
||||
EVRPC_INPUT, /**< apply the function to an input hook */
|
||||
EVRPC_OUTPUT /**< apply the function to an output hook */
|
||||
};
|
||||
|
||||
#ifndef WIN32
|
||||
/** Deprecated alias for EVRPC_INPUT. Not available on windows, where it
|
||||
* conflicts with platform headers. */
|
||||
#define INPUT EVRPC_INPUT
|
||||
/** Deprecated alias for EVRPC_OUTPUT. Not available on windows, where it
|
||||
* conflicts with platform headers. */
|
||||
#define OUTPUT EVRPC_OUTPUT
|
||||
#endif
|
||||
|
||||
/** adds a processing hook to either an rpc base or rpc pool
|
||||
*
|
||||
* If a hook returns -1, the processing is aborted.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evsignal.h,v 1.3 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: evsignal.h,v 1.4 2009/07/08 21:23:53 tls Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2000-2002 Niels Provos <provos@citi.umich.edu>
|
||||
|
@ -35,11 +35,11 @@
|
|||
typedef void (*ev_sighandler_t)(int);
|
||||
|
||||
struct evsignal_info {
|
||||
struct event_list signalqueue;
|
||||
struct event ev_signal;
|
||||
int ev_signal_pair[2];
|
||||
int ev_signal_added;
|
||||
volatile sig_atomic_t evsignal_caught;
|
||||
struct event_list evsigevents[NSIG];
|
||||
sig_atomic_t evsigcaught[NSIG];
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction **sh_old;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evutil.c,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: evutil.c,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2007 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -25,9 +25,8 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
|
@ -75,3 +74,21 @@ evutil_strtoll(const char *s, char **endptr, int base)
|
|||
#error "I don't know how to parse 64-bit integers."
|
||||
#endif
|
||||
}
|
||||
int
|
||||
evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
|
||||
{
|
||||
int r;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
r = evutil_vsnprintf(buf, buflen, format, ap);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
|
||||
{
|
||||
int r = vsnprintf(buf, buflen, format, ap);
|
||||
buf[buflen-1] = '\0';
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evutil.h,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: evutil.h,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2007 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -38,6 +38,7 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -79,6 +80,13 @@ ev_int64_t evutil_strtoll(const char *s, char **endptr, int base);
|
|||
|
||||
#define evutil_gettimeofday(tv, tz) gettimeofday((tv), (tz))
|
||||
|
||||
int evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 3, 4)))
|
||||
#endif
|
||||
;
|
||||
int evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: http-internal.h,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: http-internal.h,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -18,6 +18,13 @@
|
|||
#define HTTP_PREFIX "http://"
|
||||
#define HTTP_DEFAULTPORT 80
|
||||
|
||||
enum message_read_status {
|
||||
ALL_DATA_READ = 1,
|
||||
MORE_DATA_EXPECTED = 0,
|
||||
DATA_CORRUPTED = -1,
|
||||
REQUEST_CANCELED = -2
|
||||
};
|
||||
|
||||
enum evhttp_connection_error {
|
||||
EVCON_HTTP_TIMEOUT,
|
||||
EVCON_HTTP_EOF,
|
||||
|
@ -31,9 +38,15 @@ struct evhttp_request;
|
|||
/* A stupid connection object - maybe make this a bufferevent later */
|
||||
|
||||
enum evhttp_connection_state {
|
||||
EVCON_DISCONNECTED, /* not currently connected not trying either */
|
||||
EVCON_CONNECTING, /* tries to currently connect */
|
||||
EVCON_CONNECTED /* connection is established */
|
||||
EVCON_DISCONNECTED, /**< not currently connected not trying either*/
|
||||
EVCON_CONNECTING, /**< tries to currently connect */
|
||||
EVCON_IDLE, /**< connection is established */
|
||||
EVCON_READING_FIRSTLINE,/**< reading Request-Line (incoming conn) or
|
||||
**< Status-Line (outgoing conn) */
|
||||
EVCON_READING_HEADERS, /**< reading request/response headers */
|
||||
EVCON_READING_BODY, /**< reading request/response body */
|
||||
EVCON_READING_TRAILER, /**< reading request/response chunked trailer */
|
||||
EVCON_WRITING /**< writing request/response headers/body */
|
||||
};
|
||||
|
||||
struct event_base;
|
||||
|
@ -49,6 +62,7 @@ struct evhttp_connection {
|
|||
struct evbuffer *output_buffer;
|
||||
|
||||
char *bind_address; /* address to use for binding the src */
|
||||
u_short bind_port; /* local port for binding the src */
|
||||
|
||||
char *address; /* address to connect to */
|
||||
u_short port;
|
||||
|
@ -125,10 +139,10 @@ void evhttp_get_request(struct evhttp *, int, struct sockaddr *, socklen_t);
|
|||
|
||||
int evhttp_hostportfile(char *, char **, u_short *, char **);
|
||||
|
||||
int evhttp_parse_lines(struct evhttp_request *, struct evbuffer*);
|
||||
int evhttp_parse_firstline(struct evhttp_request *, struct evbuffer*);
|
||||
int evhttp_parse_headers(struct evhttp_request *, struct evbuffer*);
|
||||
|
||||
void evhttp_start_read(struct evhttp_connection *);
|
||||
void evhttp_read_header(int, short, void *);
|
||||
void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
|
||||
|
||||
void evhttp_write_buffer(struct evhttp_connection *,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kqueue.c,v 1.6 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: kqueue.c,v 1.7 2009/07/08 21:23:53 tls Exp $ */
|
||||
/* $OpenBSD: kqueue.c,v 1.5 2002/07/10 14:41:31 art Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -30,9 +30,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
|
@ -48,6 +46,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
@ -66,6 +65,7 @@ struct kqop {
|
|||
struct kevent *changes;
|
||||
int nchanges;
|
||||
struct kevent *events;
|
||||
struct event_list evsigevents[NSIG];
|
||||
int nevents;
|
||||
int kq;
|
||||
pid_t pid;
|
||||
|
@ -91,7 +91,7 @@ const struct eventop kqops = {
|
|||
static void *
|
||||
kq_init(struct event_base *base)
|
||||
{
|
||||
int kq;
|
||||
int i, kq;
|
||||
struct kqop *kqueueop;
|
||||
|
||||
/* Disable kqueue when this environment variable is set */
|
||||
|
@ -127,6 +127,11 @@ kq_init(struct event_base *base)
|
|||
}
|
||||
kqueueop->nevents = NEVENT;
|
||||
|
||||
/* we need to keep track of multiple events per signal */
|
||||
for (i = 0; i < NSIG; ++i) {
|
||||
TAILQ_INIT(&kqueueop->evsigevents[i]);
|
||||
}
|
||||
|
||||
return (kqueueop);
|
||||
}
|
||||
|
||||
|
@ -168,9 +173,9 @@ kq_insert(struct kqop *kqop, struct kevent *kev)
|
|||
memcpy(&kqop->changes[kqop->nchanges++], kev, sizeof(struct kevent));
|
||||
|
||||
event_debug(("%s: fd %d %s%s",
|
||||
__func__, kev->ident,
|
||||
kev->filter == EVFILT_READ ? "EVFILT_READ" : "EVFILT_WRITE",
|
||||
kev->flags == EV_DELETE ? " (del)" : ""));
|
||||
__func__, (int)kev->ident,
|
||||
kev->filter == EVFILT_READ ? "EVFILT_READ" : "EVFILT_WRITE",
|
||||
kev->flags == EV_DELETE ? " (del)" : ""));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -234,8 +239,6 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
ev = (struct event *)events[i].udata;
|
||||
|
||||
if (events[i].filter == EVFILT_READ) {
|
||||
which |= EV_READ;
|
||||
} else if (events[i].filter == EVFILT_WRITE) {
|
||||
|
@ -247,11 +250,20 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||
if (!which)
|
||||
continue;
|
||||
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
||||
if (events[i].filter == EVFILT_SIGNAL) {
|
||||
struct event_list *head =
|
||||
(struct event_list *)events[i].udata;
|
||||
TAILQ_FOREACH(ev, head, ev_signal_next) {
|
||||
event_active(ev, which, events[i].data);
|
||||
}
|
||||
} else {
|
||||
ev = (struct event *)events[i].udata;
|
||||
|
||||
event_active(ev, which,
|
||||
ev->ev_events & EV_SIGNAL ? events[i].data : 1);
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
||||
|
||||
event_active(ev, which, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -266,25 +278,30 @@ kq_add(void *arg, struct event *ev)
|
|||
|
||||
if (ev->ev_events & EV_SIGNAL) {
|
||||
int nsignal = EVENT_SIGNAL(ev);
|
||||
struct timespec timeout = { 0, 0 };
|
||||
|
||||
memset(&kev, 0, sizeof(kev));
|
||||
kev.ident = nsignal;
|
||||
kev.filter = EVFILT_SIGNAL;
|
||||
kev.flags = EV_ADD;
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
kev.flags |= EV_ONESHOT;
|
||||
kev.udata = PTR_TO_UDATA(ev);
|
||||
assert(nsignal >= 0 && nsignal < NSIG);
|
||||
if (TAILQ_EMPTY(&kqop->evsigevents[nsignal])) {
|
||||
struct timespec timeout = { 0, 0 };
|
||||
|
||||
/* Be ready for the signal if it is sent any time between
|
||||
* now and the next call to kq_dispatch. */
|
||||
if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
|
||||
return (-1);
|
||||
memset(&kev, 0, sizeof(kev));
|
||||
kev.ident = nsignal;
|
||||
kev.filter = EVFILT_SIGNAL;
|
||||
kev.flags = EV_ADD;
|
||||
kev.udata = PTR_TO_UDATA(&kqop->evsigevents[nsignal]);
|
||||
|
||||
if (_evsignal_set_handler(ev->ev_base, nsignal,
|
||||
kq_sighandler) == -1)
|
||||
return (-1);
|
||||
/* Be ready for the signal if it is sent any
|
||||
* time between now and the next call to
|
||||
* kq_dispatch. */
|
||||
if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
|
||||
return (-1);
|
||||
|
||||
if (_evsignal_set_handler(ev->ev_base, nsignal,
|
||||
kq_sighandler) == -1)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&kqop->evsigevents[nsignal], ev,
|
||||
ev_signal_next);
|
||||
ev->ev_flags |= EVLIST_X_KQINKERNEL;
|
||||
return (0);
|
||||
}
|
||||
|
@ -337,17 +354,26 @@ kq_del(void *arg, struct event *ev)
|
|||
|
||||
if (ev->ev_events & EV_SIGNAL) {
|
||||
int nsignal = EVENT_SIGNAL(ev);
|
||||
struct timespec timeout = { 0, 0 };
|
||||
|
||||
memset(&kev, 0, sizeof(kev));
|
||||
kev.ident = nsignal;
|
||||
kev.filter = EVFILT_SIGNAL;
|
||||
kev.flags = EV_DELETE;
|
||||
assert(nsignal >= 0 && nsignal < NSIG);
|
||||
TAILQ_REMOVE(&kqop->evsigevents[nsignal], ev, ev_signal_next);
|
||||
if (TAILQ_EMPTY(&kqop->evsigevents[nsignal])) {
|
||||
memset(&kev, 0, sizeof(kev));
|
||||
kev.ident = nsignal;
|
||||
kev.filter = EVFILT_SIGNAL;
|
||||
kev.flags = EV_DELETE;
|
||||
|
||||
if (kq_insert(kqop, &kev) == -1)
|
||||
return (-1);
|
||||
/* Because we insert signal events
|
||||
* immediately, we need to delete them
|
||||
* immediately, too */
|
||||
if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
|
||||
return (-1);
|
||||
|
||||
if (_evsignal_restore_handler(ev->ev_base, nsignal) == -1)
|
||||
return (-1);
|
||||
if (_evsignal_restore_handler(ev->ev_base,
|
||||
nsignal) == -1)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
||||
return (0);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: log.c,v 1.2 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: log.c,v 1.3 2009/07/08 21:23:53 tls Exp $ */
|
||||
/* $OpenBSD: err.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -48,6 +48,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "event.h"
|
||||
#include "evutil.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
|
@ -55,33 +56,6 @@ static void _warn_helper(int severity, int log_errno, const char *fmt,
|
|||
va_list ap);
|
||||
static void event_log(int severity, const char *msg);
|
||||
|
||||
static int
|
||||
event_vsnprintf(char *str, size_t size, const char *format, va_list args)
|
||||
{
|
||||
int r;
|
||||
if (size == 0)
|
||||
return -1;
|
||||
r = vsnprintf(str, size, format, args);
|
||||
str[size-1] = '\0';
|
||||
if (r < 0 || ((size_t)r) >= size) {
|
||||
/* different platforms behave differently on overflow;
|
||||
* handle both kinds. */
|
||||
return -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
event_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int r;
|
||||
va_start(ap, format);
|
||||
r = event_vsnprintf(str, size, format, ap);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
event_err(int eval, const char *fmt, ...)
|
||||
{
|
||||
|
@ -151,14 +125,14 @@ _warn_helper(int severity, int log_errno, const char *fmt, va_list ap)
|
|||
size_t len;
|
||||
|
||||
if (fmt != NULL)
|
||||
event_vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
evutil_vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
else
|
||||
buf[0] = '\0';
|
||||
|
||||
if (log_errno >= 0) {
|
||||
len = strlen(buf);
|
||||
if (len < sizeof(buf) - 3) {
|
||||
event_snprintf(buf + len, sizeof(buf) - len, ": %s",
|
||||
evutil_snprintf(buf + len, sizeof(buf) - len, ": %s",
|
||||
strerror(log_errno));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: min_heap.h,v 1.1 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: min_heap.h,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Maxim Yegorushkin <maxim.yegorushkin@gmail.com>
|
||||
* All rights reserved.
|
||||
|
@ -76,8 +76,8 @@ struct event* min_heap_pop(min_heap_t* s)
|
|||
if(s->n)
|
||||
{
|
||||
struct event* e = *s->p;
|
||||
e->min_heap_idx = -1;
|
||||
min_heap_shift_down_(s, 0u, s->p[--s->n]);
|
||||
e->min_heap_idx = -1;
|
||||
return e;
|
||||
}
|
||||
return 0;
|
||||
|
@ -87,7 +87,17 @@ int min_heap_erase(min_heap_t* s, struct event* e)
|
|||
{
|
||||
if(((unsigned int)-1) != e->min_heap_idx)
|
||||
{
|
||||
min_heap_shift_down_(s, e->min_heap_idx, s->p[--s->n]);
|
||||
struct event *last = s->p[--s->n];
|
||||
unsigned parent = (e->min_heap_idx - 1) / 2;
|
||||
/* we replace e with the last element in the heap. We might need to
|
||||
shift it upward if it is less than its parent, or downward if it is
|
||||
greater than one or both its children. Since the children are known
|
||||
to be less than the parent, it can't need to shift both up and
|
||||
down. */
|
||||
if (e->min_heap_idx > 0 && min_heap_elem_greater(s->p[parent], last))
|
||||
min_heap_shift_up_(s, e->min_heap_idx, last);
|
||||
else
|
||||
min_heap_shift_down_(s, e->min_heap_idx, last);
|
||||
e->min_heap_idx = -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: poll.c,v 1.7 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: poll.c,v 1.8 2009/07/08 21:23:53 tls Exp $ */
|
||||
/* $OpenBSD: poll.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -30,9 +30,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# $NetBSD: shlib_version,v 1.5 2009/01/11 03:07:48 christos Exp $
|
||||
# $NetBSD: shlib_version,v 1.6 2009/07/08 21:23:53 tls Exp $
|
||||
# Remember to update distrib/sets/lists/base/shl.* when changing
|
||||
#
|
||||
major=3
|
||||
minor=0
|
||||
minor=1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: signal.c,v 1.6 2008/05/16 20:24:58 peter Exp $ */
|
||||
/* $NetBSD: signal.c,v 1.7 2009/07/08 21:23:53 tls Exp $ */
|
||||
/* $OpenBSD: select.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -30,9 +30,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
|
@ -69,7 +67,7 @@ static void evsignal_handler(int sig);
|
|||
static void
|
||||
evsignal_cb(int fd, short what, void *arg)
|
||||
{
|
||||
static char signals[100];
|
||||
static char signals[1];
|
||||
ssize_t n;
|
||||
|
||||
n = recv(fd, signals, sizeof(signals), 0);
|
||||
|
@ -89,12 +87,15 @@ evsignal_cb(int fd, short what, void *arg)
|
|||
void
|
||||
evsignal_init(struct event_base *base)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Our signal handler is going to write to one end of the socket
|
||||
* pair to wake up our event loop. The event loop then scans for
|
||||
* signals that got delivered.
|
||||
*/
|
||||
if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
||||
if (evutil_socketpair(
|
||||
AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
||||
event_err(1, "%s: socketpair", __func__);
|
||||
|
||||
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
|
||||
|
@ -103,6 +104,9 @@ evsignal_init(struct event_base *base)
|
|||
base->sig.sh_old_max = 0;
|
||||
base->sig.evsignal_caught = 0;
|
||||
memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
|
||||
/* initialize the queues for all events */
|
||||
for (i = 0; i < NSIG; ++i)
|
||||
TAILQ_INIT(&base->sig.evsigevents[i]);
|
||||
|
||||
evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]);
|
||||
|
||||
|
@ -131,14 +135,19 @@ _evsignal_set_handler(struct event_base *base,
|
|||
* a dynamic array is used to keep footprint on the low side.
|
||||
*/
|
||||
if (evsignal >= sig->sh_old_max) {
|
||||
int new_max = evsignal + 1;
|
||||
event_debug(("%s: evsignal (%d) >= sh_old_max (%d), resizing",
|
||||
__func__, evsignal, sig->sh_old_max));
|
||||
sig->sh_old_max = evsignal + 1;
|
||||
p = realloc(sig->sh_old, sig->sh_old_max * sizeof *sig->sh_old);
|
||||
p = realloc(sig->sh_old, new_max * sizeof(*sig->sh_old));
|
||||
if (p == NULL) {
|
||||
event_warn("realloc");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
memset((char *)p + sig->sh_old_max * sizeof(*sig->sh_old),
|
||||
0, (new_max - sig->sh_old_max) * sizeof(*sig->sh_old));
|
||||
|
||||
sig->sh_old_max = new_max;
|
||||
sig->sh_old = p;
|
||||
}
|
||||
|
||||
|
@ -183,19 +192,26 @@ evsignal_add(struct event *ev)
|
|||
if (ev->ev_events & (EV_READ|EV_WRITE))
|
||||
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
|
||||
evsignal = EVENT_SIGNAL(ev);
|
||||
assert(evsignal >= 0 && evsignal < NSIG);
|
||||
if (TAILQ_EMPTY(&sig->evsigevents[evsignal])) {
|
||||
event_debug(("%s: %p: changing signal handler", __func__, ev));
|
||||
if (_evsignal_set_handler(
|
||||
base, evsignal, evsignal_handler) == -1)
|
||||
return (-1);
|
||||
|
||||
event_debug(("%s: %p: changing signal handler", __func__, ev));
|
||||
if (_evsignal_set_handler(base, evsignal, evsignal_handler) == -1)
|
||||
return (-1);
|
||||
/* catch signals if they happen quickly */
|
||||
evsignal_base = base;
|
||||
|
||||
/* catch signals if they happen quickly */
|
||||
evsignal_base = base;
|
||||
|
||||
if (!sig->ev_signal_added) {
|
||||
sig->ev_signal_added = 1;
|
||||
event_add(&sig->ev_signal, NULL);
|
||||
if (!sig->ev_signal_added) {
|
||||
if (event_add(&sig->ev_signal, NULL))
|
||||
return (-1);
|
||||
sig->ev_signal_added = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* multiple events may listen to the same signal */
|
||||
TAILQ_INSERT_TAIL(&sig->evsigevents[evsignal], ev, ev_signal_next);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -232,8 +248,21 @@ _evsignal_restore_handler(struct event_base *base, int evsignal)
|
|||
int
|
||||
evsignal_del(struct event *ev)
|
||||
{
|
||||
struct event_base *base = ev->ev_base;
|
||||
struct evsignal_info *sig = &base->sig;
|
||||
int evsignal = EVENT_SIGNAL(ev);
|
||||
|
||||
assert(evsignal >= 0 && evsignal < NSIG);
|
||||
|
||||
/* multiple events may listen to the same signal */
|
||||
TAILQ_REMOVE(&sig->evsigevents[evsignal], ev, ev_signal_next);
|
||||
|
||||
if (!TAILQ_EMPTY(&sig->evsigevents[evsignal]))
|
||||
return (0);
|
||||
|
||||
event_debug(("%s: %p: restoring signal handler", __func__, ev));
|
||||
return _evsignal_restore_handler(ev->ev_base, EVENT_SIGNAL(ev));
|
||||
|
||||
return (_evsignal_restore_handler(ev->ev_base, EVENT_SIGNAL(ev)));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -241,7 +270,7 @@ evsignal_handler(int sig)
|
|||
{
|
||||
int save_errno = errno;
|
||||
|
||||
if(evsignal_base == NULL) {
|
||||
if (evsignal_base == NULL) {
|
||||
event_warn(
|
||||
"%s: received signal %d, but have no base configured",
|
||||
__func__, sig);
|
||||
|
@ -263,29 +292,41 @@ evsignal_handler(int sig)
|
|||
void
|
||||
evsignal_process(struct event_base *base)
|
||||
{
|
||||
struct event *ev;
|
||||
struct evsignal_info *sig = &base->sig;
|
||||
struct event *ev, *next_ev;
|
||||
sig_atomic_t ncalls;
|
||||
|
||||
int i;
|
||||
|
||||
base->sig.evsignal_caught = 0;
|
||||
TAILQ_FOREACH(ev, &base->sig.signalqueue, ev_signal_next) {
|
||||
ncalls = base->sig.evsigcaught[EVENT_SIGNAL(ev)];
|
||||
if (ncalls) {
|
||||
for (i = 1; i < NSIG; ++i) {
|
||||
ncalls = sig->evsigcaught[i];
|
||||
if (ncalls == 0)
|
||||
continue;
|
||||
sig->evsigcaught[i] -= ncalls;
|
||||
|
||||
for (ev = TAILQ_FIRST(&sig->evsigevents[i]);
|
||||
ev != NULL; ev = next_ev) {
|
||||
next_ev = TAILQ_NEXT(ev, ev_signal_next);
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
event_del(ev);
|
||||
event_active(ev, EV_SIGNAL, ncalls);
|
||||
base->sig.evsigcaught[EVENT_SIGNAL(ev)] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
evsignal_dealloc(struct event_base *base)
|
||||
{
|
||||
if(base->sig.ev_signal_added) {
|
||||
int i = 0;
|
||||
if (base->sig.ev_signal_added) {
|
||||
event_del(&base->sig.ev_signal);
|
||||
base->sig.ev_signal_added = 0;
|
||||
}
|
||||
assert(TAILQ_EMPTY(&base->sig.signalqueue));
|
||||
for (i = 0; i < NSIG; ++i) {
|
||||
if (i < base->sig.sh_old_max && base->sig.sh_old[i] != NULL)
|
||||
_evsignal_restore_handler(base, i);
|
||||
}
|
||||
|
||||
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
|
||||
base->sig.ev_signal_pair[0] = -1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: regress.c,v 1.1 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: regress.c,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -83,6 +83,9 @@ simple_read_cb(int fd, short event, void *arg)
|
|||
char buf[256];
|
||||
int len;
|
||||
|
||||
if (arg == NULL)
|
||||
return;
|
||||
|
||||
len = read(fd, buf, sizeof(buf));
|
||||
|
||||
if (len) {
|
||||
|
@ -101,6 +104,9 @@ simple_write_cb(int fd, short event, void *arg)
|
|||
{
|
||||
int len;
|
||||
|
||||
if (arg == NULL)
|
||||
return;
|
||||
|
||||
len = write(fd, TEST1, strlen(TEST1) + 1);
|
||||
if (len == -1)
|
||||
test_ok = 0;
|
||||
|
@ -169,7 +175,7 @@ timeout_cb(int fd, short event, void *arg)
|
|||
struct timeval tv;
|
||||
int diff;
|
||||
|
||||
gettimeofday(&tcalled, NULL);
|
||||
evutil_gettimeofday(&tcalled, NULL);
|
||||
if (evutil_timercmp(&tcalled, &tset, >))
|
||||
evutil_timersub(&tcalled, &tset, &tv);
|
||||
else
|
||||
|
@ -287,6 +293,52 @@ cleanup_test(void)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_registerfds(void)
|
||||
{
|
||||
int i, j;
|
||||
int pair[2];
|
||||
struct event read_evs[512];
|
||||
struct event write_evs[512];
|
||||
|
||||
struct event_base *base = event_base_new();
|
||||
|
||||
fprintf(stdout, "Testing register fds: ");
|
||||
|
||||
for (i = 0; i < 512; ++i) {
|
||||
if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
|
||||
/* run up to the limit of file descriptors */
|
||||
break;
|
||||
}
|
||||
event_set(&read_evs[i], pair[0],
|
||||
EV_READ|EV_PERSIST, simple_read_cb, NULL);
|
||||
event_base_set(base, &read_evs[i]);
|
||||
event_add(&read_evs[i], NULL);
|
||||
event_set(&write_evs[i], pair[1],
|
||||
EV_WRITE|EV_PERSIST, simple_write_cb, NULL);
|
||||
event_base_set(base, &write_evs[i]);
|
||||
event_add(&write_evs[i], NULL);
|
||||
|
||||
/* just loop once */
|
||||
event_base_loop(base, EVLOOP_ONCE);
|
||||
}
|
||||
|
||||
/* now delete everything */
|
||||
for (j = 0; j < i; ++j) {
|
||||
event_del(&read_evs[j]);
|
||||
event_del(&write_evs[j]);
|
||||
close(read_evs[j].ev_fd);
|
||||
close(write_evs[j].ev_fd);
|
||||
|
||||
/* just loop once */
|
||||
event_base_loop(base, EVLOOP_ONCE);
|
||||
}
|
||||
|
||||
event_base_free(base);
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_simpleread(void)
|
||||
{
|
||||
|
@ -428,18 +480,32 @@ test_simpletimeout(void)
|
|||
evtimer_set(&ev, timeout_cb, NULL);
|
||||
evtimer_add(&ev, &tv);
|
||||
|
||||
gettimeofday(&tset, NULL);
|
||||
evutil_gettimeofday(&tset, NULL);
|
||||
event_dispatch();
|
||||
|
||||
cleanup_test();
|
||||
}
|
||||
|
||||
extern struct event_base *current_base;
|
||||
|
||||
static void
|
||||
child_signal_cb(int fd, short event, void *arg)
|
||||
{
|
||||
struct timeval tv;
|
||||
int *pint = arg;
|
||||
|
||||
*pint = 1;
|
||||
|
||||
tv.tv_usec = 500000;
|
||||
tv.tv_sec = 0;
|
||||
event_loopexit(&tv);
|
||||
}
|
||||
|
||||
static void
|
||||
test_fork(void)
|
||||
{
|
||||
int status;
|
||||
struct event ev;
|
||||
int status, got_sigchld = 0;
|
||||
struct event ev, sig_ev;
|
||||
pid_t pid;
|
||||
|
||||
setup_test("After fork: ");
|
||||
|
@ -450,6 +516,9 @@ test_fork(void)
|
|||
if (event_add(&ev, NULL) == -1)
|
||||
exit(1);
|
||||
|
||||
signal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld);
|
||||
signal_add(&sig_ev, NULL);
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
/* in the child */
|
||||
if (event_reinit(current_base) == -1) {
|
||||
|
@ -457,6 +526,8 @@ test_fork(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
signal_del(&sig_ev);
|
||||
|
||||
called = 0;
|
||||
|
||||
event_dispatch();
|
||||
|
@ -488,6 +559,13 @@ test_fork(void)
|
|||
|
||||
event_dispatch();
|
||||
|
||||
if (!got_sigchld) {
|
||||
fprintf(stdout, "FAILED (sigchld)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
signal_del(&sig_ev);
|
||||
|
||||
cleanup_test();
|
||||
}
|
||||
|
||||
|
@ -500,6 +578,9 @@ test_simplesignal(void)
|
|||
setup_test("Simple signal: ");
|
||||
signal_set(&ev, SIGALRM, signal_cb, &ev);
|
||||
signal_add(&ev, NULL);
|
||||
/* find bugs in which operations are re-ordered */
|
||||
signal_del(&ev);
|
||||
signal_add(&ev, NULL);
|
||||
|
||||
memset(&itv, 0, sizeof(itv));
|
||||
itv.it_value.tv_sec = 1;
|
||||
|
@ -514,6 +595,36 @@ test_simplesignal(void)
|
|||
cleanup_test();
|
||||
}
|
||||
|
||||
static void
|
||||
test_multiplesignal(void)
|
||||
{
|
||||
struct event ev_one, ev_two;
|
||||
struct itimerval itv;
|
||||
|
||||
setup_test("Multiple signal: ");
|
||||
|
||||
signal_set(&ev_one, SIGALRM, signal_cb, &ev_one);
|
||||
signal_add(&ev_one, NULL);
|
||||
|
||||
signal_set(&ev_two, SIGALRM, signal_cb, &ev_two);
|
||||
signal_add(&ev_two, NULL);
|
||||
|
||||
memset(&itv, 0, sizeof(itv));
|
||||
itv.it_value.tv_sec = 1;
|
||||
if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
|
||||
goto skip_simplesignal;
|
||||
|
||||
event_dispatch();
|
||||
|
||||
skip_simplesignal:
|
||||
if (signal_del(&ev_one) == -1)
|
||||
test_ok = 0;
|
||||
if (signal_del(&ev_two) == -1)
|
||||
test_ok = 0;
|
||||
|
||||
cleanup_test();
|
||||
}
|
||||
|
||||
static void
|
||||
test_immediatesignal(void)
|
||||
{
|
||||
|
@ -689,6 +800,52 @@ out:
|
|||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_swp(int sig, short event, void *arg)
|
||||
{
|
||||
called++;
|
||||
if (called < 5)
|
||||
raise(sig);
|
||||
else
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
static void
|
||||
timeout_cb_swp(int fd, short event, void *arg)
|
||||
{
|
||||
if (called == -1) {
|
||||
struct timeval tv = {5, 0};
|
||||
|
||||
called = 0;
|
||||
evtimer_add((struct event *)arg, &tv);
|
||||
raise(SIGUSR1);
|
||||
return;
|
||||
}
|
||||
test_ok = 0;
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_signal_while_processing(void)
|
||||
{
|
||||
struct event_base *base = event_init();
|
||||
struct event ev, ev_timer;
|
||||
struct timeval tv = {0, 0};
|
||||
|
||||
setup_test("Receiving a signal while processing other signal: ");
|
||||
|
||||
called = -1;
|
||||
test_ok = 1;
|
||||
signal_set(&ev, SIGUSR1, signal_cb_swp, NULL);
|
||||
signal_add(&ev, NULL);
|
||||
evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer);
|
||||
evtimer_add(&ev_timer, &tv);
|
||||
event_dispatch();
|
||||
|
||||
event_base_free(base);
|
||||
cleanup_test();
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
test_free_active_base(void)
|
||||
{
|
||||
|
@ -744,9 +901,9 @@ test_loopexit(void)
|
|||
tv.tv_sec = 1;
|
||||
event_loopexit(&tv);
|
||||
|
||||
gettimeofday(&tv_start, NULL);
|
||||
evutil_gettimeofday(&tv_start, NULL);
|
||||
event_dispatch();
|
||||
gettimeofday(&tv_end, NULL);
|
||||
evutil_gettimeofday(&tv_end, NULL);
|
||||
evutil_timersub(&tv_end, &tv_start, &tv_end);
|
||||
|
||||
evtimer_del(&ev);
|
||||
|
@ -1046,7 +1203,7 @@ test_priorities(int npriorities)
|
|||
struct test_pri_event one, two;
|
||||
struct timeval tv;
|
||||
|
||||
snprintf(buf, sizeof(buf), "Testing Priorities %d: ", npriorities);
|
||||
evutil_snprintf(buf, sizeof(buf), "Testing Priorities %d: ", npriorities);
|
||||
setup_test(buf);
|
||||
|
||||
event_base_priority_init(global_base, npriorities);
|
||||
|
@ -1336,7 +1493,7 @@ rpc_test(void)
|
|||
EVTAG_ASSIGN(attack, weapon, "feather");
|
||||
EVTAG_ASSIGN(attack, action, "tickle");
|
||||
|
||||
gettimeofday(&tv_start, NULL);
|
||||
evutil_gettimeofday(&tv_start, NULL);
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
run = EVTAG_ADD(msg, run);
|
||||
if (run == NULL) {
|
||||
|
@ -1344,6 +1501,8 @@ rpc_test(void)
|
|||
exit(1);
|
||||
}
|
||||
EVTAG_ASSIGN(run, how, "very fast but with some data in it");
|
||||
EVTAG_ASSIGN(run, fixed_bytes,
|
||||
(unsigned char*)"012345678901234567890123");
|
||||
}
|
||||
|
||||
if (msg_complete(msg) == -1) {
|
||||
|
@ -1369,7 +1528,7 @@ rpc_test(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
gettimeofday(&tv_end, NULL);
|
||||
evutil_gettimeofday(&tv_end, NULL);
|
||||
evutil_timersub(&tv_end, &tv_start, &tv_end);
|
||||
fprintf(stderr, "(%.1f us/add) ",
|
||||
(float)tv_end.tv_sec/(float)i * 1000000.0 +
|
||||
|
@ -1425,11 +1584,15 @@ int
|
|||
main (int argc, char **argv)
|
||||
{
|
||||
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
return (1);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
/* Initalize the event library */
|
||||
global_base = event_init();
|
||||
|
||||
test_registerfds();
|
||||
|
||||
test_evutil_strtoll();
|
||||
|
||||
/* use the global event base and need to be called first */
|
||||
|
@ -1467,6 +1630,7 @@ main (int argc, char **argv)
|
|||
|
||||
test_simpletimeout();
|
||||
test_simplesignal();
|
||||
test_multiplesignal();
|
||||
test_immediatesignal();
|
||||
|
||||
test_loopexit();
|
||||
|
@ -1487,6 +1651,7 @@ main (int argc, char **argv)
|
|||
test_signal_switchbase();
|
||||
test_signal_restore();
|
||||
test_signal_assert();
|
||||
test_signal_while_processing();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* $NetBSD: regress.gen.c,v 1.1 2008/05/16 20:24:57 peter Exp $ */
|
||||
/*
|
||||
* Automatically generated from ./regress.rpc
|
||||
* Automatically generated from regress.rpc
|
||||
* by event_rpcgen.py/0.1. DO NOT EDIT THIS FILE.
|
||||
*/
|
||||
|
||||
|
@ -12,7 +11,7 @@
|
|||
#include <event.h>
|
||||
|
||||
|
||||
#include "./regress.gen.h"
|
||||
#include "regress.gen.h"
|
||||
|
||||
void event_err(int eval, const char *fmt, ...);
|
||||
void event_warn(const char *fmt, ...);
|
||||
|
@ -640,6 +639,10 @@ evtag_marshal_kill(struct evbuffer *evbuf, uint32_t tag, const struct kill *msg)
|
|||
static struct run_access_ __run_base = {
|
||||
run_how_assign,
|
||||
run_how_get,
|
||||
run_some_bytes_assign,
|
||||
run_some_bytes_get,
|
||||
run_fixed_bytes_assign,
|
||||
run_fixed_bytes_get,
|
||||
};
|
||||
|
||||
struct run *
|
||||
|
@ -655,10 +658,19 @@ run_new(void)
|
|||
tmp->how_data = NULL;
|
||||
tmp->how_set = 0;
|
||||
|
||||
tmp->some_bytes_data = NULL;
|
||||
tmp->some_bytes_length = 0;
|
||||
tmp->some_bytes_set = 0;
|
||||
|
||||
memset(tmp->fixed_bytes_data, 0, sizeof(tmp->fixed_bytes_data));
|
||||
tmp->fixed_bytes_set = 0;
|
||||
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
run_how_assign(struct run *msg,
|
||||
const char * value)
|
||||
|
@ -671,6 +683,28 @@ run_how_assign(struct run *msg,
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
run_some_bytes_assign(struct run *msg, const uint8_t * value, uint32_t len)
|
||||
{
|
||||
if (msg->some_bytes_data != NULL)
|
||||
free (msg->some_bytes_data);
|
||||
msg->some_bytes_data = malloc(len);
|
||||
if (msg->some_bytes_data == NULL)
|
||||
return (-1);
|
||||
msg->some_bytes_set = 1;
|
||||
msg->some_bytes_length = len;
|
||||
memcpy(msg->some_bytes_data, value, len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
run_fixed_bytes_assign(struct run *msg, const uint8_t *value)
|
||||
{
|
||||
msg->fixed_bytes_set = 1;
|
||||
memcpy(msg->fixed_bytes_data, value, 24);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
run_how_get(struct run *msg, char * *value)
|
||||
{
|
||||
|
@ -680,6 +714,25 @@ run_how_get(struct run *msg, char * *value)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
run_some_bytes_get(struct run *msg, uint8_t * *value, uint32_t *plen)
|
||||
{
|
||||
if (msg->some_bytes_set != 1)
|
||||
return (-1);
|
||||
*value = msg->some_bytes_data;
|
||||
*plen = msg->some_bytes_length;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
run_fixed_bytes_get(struct run *msg, uint8_t **value)
|
||||
{
|
||||
if (msg->fixed_bytes_set != 1)
|
||||
return (-1);
|
||||
*value = msg->fixed_bytes_data;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
run_clear(struct run *tmp)
|
||||
{
|
||||
|
@ -688,6 +741,14 @@ run_clear(struct run *tmp)
|
|||
tmp->how_data = NULL;
|
||||
tmp->how_set = 0;
|
||||
}
|
||||
if (tmp->some_bytes_set == 1) {
|
||||
free (tmp->some_bytes_data);
|
||||
tmp->some_bytes_data = NULL;
|
||||
tmp->some_bytes_length = 0;
|
||||
tmp->some_bytes_set = 0;
|
||||
}
|
||||
tmp->fixed_bytes_set = 0;
|
||||
memset(tmp->fixed_bytes_data, 0, sizeof(tmp->fixed_bytes_data));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -695,12 +756,18 @@ run_free(struct run *tmp)
|
|||
{
|
||||
if (tmp->how_data != NULL)
|
||||
free (tmp->how_data);
|
||||
if (tmp->some_bytes_data != NULL)
|
||||
free (tmp->some_bytes_data);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void
|
||||
run_marshal(struct evbuffer *evbuf, const struct run *tmp){
|
||||
evtag_marshal_string(evbuf, RUN_HOW, tmp->how_data);
|
||||
if (tmp->some_bytes_set) {
|
||||
evtag_marshal(evbuf, RUN_SOME_BYTES, tmp->some_bytes_data, tmp->some_bytes_length);
|
||||
}
|
||||
evtag_marshal(evbuf, RUN_FIXED_BYTES, tmp->fixed_bytes_data, sizeof(tmp->fixed_bytes_data));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -723,6 +790,34 @@ run_unmarshal(struct run *tmp, struct evbuffer *evbuf)
|
|||
tmp->how_set = 1;
|
||||
break;
|
||||
|
||||
case RUN_SOME_BYTES:
|
||||
|
||||
if (tmp->some_bytes_set)
|
||||
return (-1);
|
||||
if (evtag_payload_length(evbuf, &tmp->some_bytes_length) == -1)
|
||||
return (-1);
|
||||
if (tmp->some_bytes_length > EVBUFFER_LENGTH(evbuf))
|
||||
return (-1);
|
||||
if ((tmp->some_bytes_data = malloc(tmp->some_bytes_length)) == NULL)
|
||||
return (-1);
|
||||
if (evtag_unmarshal_fixed(evbuf, RUN_SOME_BYTES, tmp->some_bytes_data, tmp->some_bytes_length) == -1) {
|
||||
event_warnx("%s: failed to unmarshal some_bytes", __func__);
|
||||
return (-1);
|
||||
}
|
||||
tmp->some_bytes_set = 1;
|
||||
break;
|
||||
|
||||
case RUN_FIXED_BYTES:
|
||||
|
||||
if (tmp->fixed_bytes_set)
|
||||
return (-1);
|
||||
if (evtag_unmarshal_fixed(evbuf, RUN_FIXED_BYTES, tmp->fixed_bytes_data, sizeof(tmp->fixed_bytes_data)) == -1) {
|
||||
event_warnx("%s: failed to unmarshal fixed_bytes", __func__);
|
||||
return (-1);
|
||||
}
|
||||
tmp->fixed_bytes_set = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -738,6 +833,8 @@ run_complete(struct run *msg)
|
|||
{
|
||||
if (!msg->how_set)
|
||||
return (-1);
|
||||
if (!msg->fixed_bytes_set)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/* $NetBSD: regress.gen.h,v 1.1 2008/05/16 20:24:57 peter Exp $ */
|
||||
/*
|
||||
* Automatically generated from ./regress.rpc
|
||||
* Automatically generated from regress.rpc
|
||||
*/
|
||||
|
||||
#ifndef ___REGRESS_RPC_
|
||||
#define ___REGRESS_RPC_
|
||||
#ifndef _REGRESS_RPC_
|
||||
#define _REGRESS_RPC_
|
||||
|
||||
#include <event-config.h>
|
||||
#ifdef _EVENT_HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#define EVTAG_HAS(msg, member) ((msg)->member##_set == 1)
|
||||
#define EVTAG_ASSIGN(msg, member, args...) (*(msg)->base->member##_assign)(msg, ## args)
|
||||
#define EVTAG_GET(msg, member, args...) (*(msg)->base->member##_get)(msg, ## args)
|
||||
|
@ -127,6 +129,8 @@ int kill_how_often_get(struct kill *, uint32_t *);
|
|||
/* Tag definition for run */
|
||||
enum run_ {
|
||||
RUN_HOW=1,
|
||||
RUN_SOME_BYTES=2,
|
||||
RUN_FIXED_BYTES=3,
|
||||
RUN_MAX_TAGS
|
||||
};
|
||||
|
||||
|
@ -134,14 +138,23 @@ enum run_ {
|
|||
struct run_access_ {
|
||||
int (*how_assign)(struct run *, const char *);
|
||||
int (*how_get)(struct run *, char * *);
|
||||
int (*some_bytes_assign)(struct run *, const uint8_t *, uint32_t);
|
||||
int (*some_bytes_get)(struct run *, uint8_t * *, uint32_t *);
|
||||
int (*fixed_bytes_assign)(struct run *, const uint8_t *);
|
||||
int (*fixed_bytes_get)(struct run *, uint8_t **);
|
||||
};
|
||||
|
||||
struct run {
|
||||
struct run_access_ *base;
|
||||
|
||||
char *how_data;
|
||||
uint8_t *some_bytes_data;
|
||||
uint32_t some_bytes_length;
|
||||
uint8_t fixed_bytes_data[24];
|
||||
|
||||
uint8_t how_set;
|
||||
uint8_t some_bytes_set;
|
||||
uint8_t fixed_bytes_set;
|
||||
};
|
||||
|
||||
struct run *run_new(void);
|
||||
|
@ -156,6 +169,10 @@ int evtag_unmarshal_run(struct evbuffer *, uint32_t,
|
|||
struct run *);
|
||||
int run_how_assign(struct run *, const char *);
|
||||
int run_how_get(struct run *, char * *);
|
||||
int run_some_bytes_assign(struct run *, const uint8_t *, uint32_t);
|
||||
int run_some_bytes_get(struct run *, uint8_t * *, uint32_t *);
|
||||
int run_fixed_bytes_assign(struct run *, const uint8_t *);
|
||||
int run_fixed_bytes_get(struct run *, uint8_t **);
|
||||
/* --- run done --- */
|
||||
|
||||
#endif /* ___REGRESS_RPC_ */
|
||||
#endif /* _REGRESS_RPC_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: regress_dns.c,v 1.1 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: regress_dns.c,v 1.2 2009/07/08 21:23:53 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
@ -83,7 +83,7 @@ dns_gethostbyname_cb(int result, char type, int count, int ttl,
|
|||
|
||||
switch (type) {
|
||||
case DNS_IPv6_AAAA: {
|
||||
#if defined(HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_NTOP)
|
||||
#if defined(HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
|
||||
struct in6_addr *in6_addrs = addresses;
|
||||
char buf[INET6_ADDRSTRLEN+1];
|
||||
int i;
|
||||
|
@ -252,7 +252,7 @@ dns_server_gethostbyname_cb(int result, char type, int count, int ttl,
|
|||
break;
|
||||
}
|
||||
case DNS_IPv6_AAAA: {
|
||||
#if defined (HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_NTOP)
|
||||
#if defined (HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
|
||||
struct in6_addr *in6_addrs = addresses;
|
||||
char buf[INET6_ADDRSTRLEN+1];
|
||||
if (memcmp(&in6_addrs[0].s6_addr, "abcdefghijklmnop", 16)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: regress_http.c,v 1.1 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: regress_http.c,v 1.2 2009/07/08 21:23:54 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -61,8 +61,10 @@ static struct event_base *base;
|
|||
void http_suite(void);
|
||||
|
||||
void http_basic_cb(struct evhttp_request *req, void *arg);
|
||||
static void http_chunked_cb(struct evhttp_request *req, void *arg);
|
||||
void http_post_cb(struct evhttp_request *req, void *arg);
|
||||
void http_dispatcher_cb(struct evhttp_request *req, void *arg);
|
||||
static void http_large_delay_cb(struct evhttp_request *req, void *arg);
|
||||
|
||||
static struct evhttp *
|
||||
http_setup(short *pport, struct event_base *base)
|
||||
|
@ -85,7 +87,9 @@ http_setup(short *pport, struct event_base *base)
|
|||
|
||||
/* Register a callback for certain types of requests */
|
||||
evhttp_set_cb(myhttp, "/test", http_basic_cb, NULL);
|
||||
evhttp_set_cb(myhttp, "/chunked", http_chunked_cb, NULL);
|
||||
evhttp_set_cb(myhttp, "/postit", http_post_cb, NULL);
|
||||
evhttp_set_cb(myhttp, "/largedelay", http_large_delay_cb, NULL);
|
||||
evhttp_set_cb(myhttp, "/", http_dispatcher_cb, NULL);
|
||||
|
||||
*pport = port;
|
||||
|
@ -139,15 +143,23 @@ http_readcb(struct bufferevent *bev, void *arg)
|
|||
if (evbuffer_find(bev->input,
|
||||
(const unsigned char*) what, strlen(what)) != NULL) {
|
||||
struct evhttp_request *req = evhttp_request_new(NULL, NULL);
|
||||
int done;
|
||||
enum message_read_status done;
|
||||
|
||||
req->kind = EVHTTP_RESPONSE;
|
||||
done = evhttp_parse_lines(req, bev->input);
|
||||
done = evhttp_parse_firstline(req, bev->input);
|
||||
if (done != ALL_DATA_READ)
|
||||
goto out;
|
||||
|
||||
done = evhttp_parse_headers(req, bev->input);
|
||||
if (done != ALL_DATA_READ)
|
||||
goto out;
|
||||
|
||||
if (done == 1 &&
|
||||
evhttp_find_header(req->input_headers,
|
||||
"Content-Type") != NULL)
|
||||
test_ok++;
|
||||
|
||||
out:
|
||||
evhttp_request_free(req);
|
||||
bufferevent_disable(bev, EV_READ);
|
||||
if (base)
|
||||
|
@ -181,6 +193,23 @@ http_basic_cb(struct evhttp_request *req, void *arg)
|
|||
int empty = evhttp_find_header(req->input_headers, "Empty") != NULL;
|
||||
event_debug(("%s: called\n", __func__));
|
||||
evbuffer_add_printf(evb, "This is funny");
|
||||
|
||||
/* For multi-line headers test */
|
||||
{
|
||||
const char *multi =
|
||||
evhttp_find_header(req->input_headers,"X-multi");
|
||||
if (multi) {
|
||||
if (strcmp("END", multi + strlen(multi) - 3) == 0)
|
||||
test_ok++;
|
||||
if (evhttp_find_header(req->input_headers, "X-Last"))
|
||||
test_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
/* injecting a bad content-length */
|
||||
if (evhttp_find_header(req->input_headers, "X-Negative"))
|
||||
evhttp_add_header(req->output_headers,
|
||||
"Content-Length", "-100");
|
||||
|
||||
/* allow sending of an empty reply */
|
||||
evhttp_send_reply(req, HTTP_OK, "Everything is fine",
|
||||
|
@ -189,9 +218,69 @@ http_basic_cb(struct evhttp_request *req, void *arg)
|
|||
evbuffer_free(evb);
|
||||
}
|
||||
|
||||
static char const* const CHUNKS[] = {
|
||||
"This is funny",
|
||||
"but not hilarious.",
|
||||
"bwv 1052"
|
||||
};
|
||||
|
||||
struct chunk_req_state {
|
||||
struct evhttp_request *req;
|
||||
int i;
|
||||
};
|
||||
|
||||
static void
|
||||
http_chunked_trickle_cb(int fd, short events, void *arg)
|
||||
{
|
||||
struct evbuffer *evb = evbuffer_new();
|
||||
struct chunk_req_state *state = arg;
|
||||
struct timeval when = { 0, 0 };
|
||||
|
||||
evbuffer_add_printf(evb, "%s", CHUNKS[state->i]);
|
||||
evhttp_send_reply_chunk(state->req, evb);
|
||||
evbuffer_free(evb);
|
||||
|
||||
if (++state->i < sizeof(CHUNKS)/sizeof(CHUNKS[0])) {
|
||||
event_once(-1, EV_TIMEOUT,
|
||||
http_chunked_trickle_cb, state, &when);
|
||||
} else {
|
||||
evhttp_send_reply_end(state->req);
|
||||
free(state);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
http_chunked_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
struct timeval when = { 0, 0 };
|
||||
struct chunk_req_state *state = malloc(sizeof(struct chunk_req_state));
|
||||
event_debug(("%s: called\n", __func__));
|
||||
|
||||
memset(state, 0, sizeof(struct chunk_req_state));
|
||||
state->req = req;
|
||||
|
||||
/* generate a chunked reply */
|
||||
evhttp_send_reply_start(req, HTTP_OK, "Everything is fine");
|
||||
|
||||
/* but trickle it across several iterations to ensure we're not
|
||||
* assuming it comes all at once */
|
||||
event_once(-1, EV_TIMEOUT, http_chunked_trickle_cb, state, &when);
|
||||
}
|
||||
|
||||
static void
|
||||
http_complete_write(int fd, short what, void *arg)
|
||||
{
|
||||
struct bufferevent *bev = arg;
|
||||
const char *http_request = "host\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
bufferevent_write(bev, http_request, strlen(http_request));
|
||||
}
|
||||
|
||||
static void
|
||||
http_basic_test(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct bufferevent *bev;
|
||||
int fd;
|
||||
const char *http_request;
|
||||
|
@ -214,24 +303,26 @@ http_basic_test(void)
|
|||
bev = bufferevent_new(fd, http_readcb, http_writecb,
|
||||
http_errorcb, NULL);
|
||||
|
||||
/* first half of the http request */
|
||||
http_request =
|
||||
"GET /test HTTP/1.1\r\n"
|
||||
"Host: somehost\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
"Host: some";
|
||||
|
||||
bufferevent_write(bev, http_request, strlen(http_request));
|
||||
timerclear(&tv);
|
||||
tv.tv_usec = 10000;
|
||||
event_once(-1, EV_TIMEOUT, http_complete_write, bev, &tv);
|
||||
|
||||
event_dispatch();
|
||||
|
||||
if (test_ok != 2) {
|
||||
if (test_ok != 3) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* connect to the second port */
|
||||
bufferevent_free(bev);
|
||||
close(fd);
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
|
||||
fd = http_connect("127.0.0.1", port + 1);
|
||||
|
||||
|
@ -250,11 +341,11 @@ http_basic_test(void)
|
|||
event_dispatch();
|
||||
|
||||
bufferevent_free(bev);
|
||||
close(fd);
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
if (test_ok != 4) {
|
||||
if (test_ok != 5) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -262,6 +353,31 @@ http_basic_test(void)
|
|||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
static struct evhttp_connection *delayed_client;
|
||||
|
||||
static void
|
||||
http_delay_reply(int fd, short what, void *arg)
|
||||
{
|
||||
struct evhttp_request *req = arg;
|
||||
|
||||
evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL);
|
||||
|
||||
++test_ok;
|
||||
}
|
||||
|
||||
static void
|
||||
http_large_delay_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
struct timeval tv;
|
||||
timerclear(&tv);
|
||||
tv.tv_sec = 3;
|
||||
|
||||
event_once(-1, EV_TIMEOUT, http_delay_reply, req, &tv);
|
||||
|
||||
/* here we close the client connection which will cause an EOF */
|
||||
evhttp_connection_fail(delayed_client, EVCON_HTTP_EOF);
|
||||
}
|
||||
|
||||
void http_request_done(struct evhttp_request *, void *);
|
||||
void http_request_empty_done(struct evhttp_request *, void *);
|
||||
|
||||
|
@ -691,7 +807,7 @@ http_failure_test(void)
|
|||
event_dispatch();
|
||||
|
||||
bufferevent_free(bev);
|
||||
close(fd);
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
|
@ -706,6 +822,7 @@ http_failure_test(void)
|
|||
static void
|
||||
close_detect_done(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
struct timeval tv;
|
||||
if (req == NULL || req->response_code != HTTP_OK) {
|
||||
|
||||
fprintf(stderr, "FAILED\n");
|
||||
|
@ -713,7 +830,11 @@ close_detect_done(struct evhttp_request *req, void *arg)
|
|||
}
|
||||
|
||||
test_ok = 1;
|
||||
event_loopexit(NULL);
|
||||
|
||||
timerclear(&tv);
|
||||
tv.tv_sec = 3; /* longer than the http time out */
|
||||
|
||||
event_loopexit(&tv);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -740,7 +861,7 @@ close_detect_cb(struct evhttp_request *req, void *arg)
|
|||
struct evhttp_connection *evcon = arg;
|
||||
struct timeval tv;
|
||||
|
||||
if (req->response_code != HTTP_OK) {
|
||||
if (req != NULL && req->response_code != HTTP_OK) {
|
||||
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
|
@ -755,14 +876,15 @@ close_detect_cb(struct evhttp_request *req, void *arg)
|
|||
|
||||
|
||||
static void
|
||||
http_close_detection(void)
|
||||
http_close_detection(int with_delay)
|
||||
{
|
||||
short port = -1;
|
||||
struct evhttp_connection *evcon = NULL;
|
||||
struct evhttp_request *req = NULL;
|
||||
|
||||
test_ok = 0;
|
||||
fprintf(stdout, "Testing Connection Close Detection: ");
|
||||
fprintf(stdout, "Testing Connection Close Detection%s: ",
|
||||
with_delay ? " (with delay)" : "");
|
||||
|
||||
http = http_setup(&port, NULL);
|
||||
|
||||
|
@ -775,6 +897,8 @@ http_close_detection(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
delayed_client = evcon;
|
||||
|
||||
/*
|
||||
* At this point, we want to schedule a request to the HTTP
|
||||
* server using our make request method.
|
||||
|
@ -786,7 +910,8 @@ http_close_detection(void)
|
|||
evhttp_add_header(req->output_headers, "Host", "somehost");
|
||||
|
||||
/* We give ownership of the request to the connection */
|
||||
if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
|
||||
if (evhttp_make_request(evcon,
|
||||
req, EVHTTP_REQ_GET, with_delay ? "/largedelay" : "/test") == -1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -798,6 +923,12 @@ http_close_detection(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/* at this point, the http server should have no connection */
|
||||
if (TAILQ_FIRST(&http->connections) != NULL) {
|
||||
fprintf(stdout, "FAILED (left connections)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
evhttp_connection_free(evcon);
|
||||
evhttp_free(http);
|
||||
|
||||
|
@ -840,13 +971,16 @@ http_bad_header_test(void)
|
|||
|
||||
if (evhttp_add_header(&headers, "One\r", "Two") != -1)
|
||||
goto fail;
|
||||
|
||||
if (evhttp_add_header(&headers, "One", "Two") != 0)
|
||||
goto fail;
|
||||
if (evhttp_add_header(&headers, "One", "Two\r\n Three") != 0)
|
||||
goto fail;
|
||||
if (evhttp_add_header(&headers, "One\r", "Two") != -1)
|
||||
goto fail;
|
||||
if (evhttp_add_header(&headers, "One\n", "Two") != -1)
|
||||
goto fail;
|
||||
|
||||
if (evhttp_add_header(&headers, "One", "Two\r") != -1)
|
||||
goto fail;
|
||||
|
||||
if (evhttp_add_header(&headers, "One", "Two\n") != -1)
|
||||
goto fail;
|
||||
|
||||
|
@ -859,6 +993,61 @@ fail:
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static int validate_header(
|
||||
const struct evkeyvalq* headers,
|
||||
const char *key, const char *value)
|
||||
{
|
||||
const char *real_val = evhttp_find_header(headers, key);
|
||||
if (real_val == NULL)
|
||||
return (-1);
|
||||
if (strcmp(real_val, value) != 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
http_parse_query_test(void)
|
||||
{
|
||||
struct evkeyvalq headers;
|
||||
|
||||
fprintf(stdout, "Testing HTTP query parsing: ");
|
||||
|
||||
TAILQ_INIT(&headers);
|
||||
|
||||
evhttp_parse_query("http://www.test.com/?q=test", &headers);
|
||||
if (validate_header(&headers, "q", "test") != 0)
|
||||
goto fail;
|
||||
evhttp_clear_headers(&headers);
|
||||
|
||||
evhttp_parse_query("http://www.test.com/?q=test&foo=bar", &headers);
|
||||
if (validate_header(&headers, "q", "test") != 0)
|
||||
goto fail;
|
||||
if (validate_header(&headers, "foo", "bar") != 0)
|
||||
goto fail;
|
||||
evhttp_clear_headers(&headers);
|
||||
|
||||
evhttp_parse_query("http://www.test.com/?q=test+foo", &headers);
|
||||
if (validate_header(&headers, "q", "test foo") != 0)
|
||||
goto fail;
|
||||
evhttp_clear_headers(&headers);
|
||||
|
||||
evhttp_parse_query("http://www.test.com/?q=test%0Afoo", &headers);
|
||||
if (validate_header(&headers, "q", "test\nfoo") != 0)
|
||||
goto fail;
|
||||
evhttp_clear_headers(&headers);
|
||||
|
||||
evhttp_parse_query("http://www.test.com/?q=test%0Dfoo", &headers);
|
||||
if (validate_header(&headers, "q", "test\rfoo") != 0)
|
||||
goto fail;
|
||||
evhttp_clear_headers(&headers);
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
return;
|
||||
fail:
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
http_base_test(void)
|
||||
{
|
||||
|
@ -898,7 +1087,7 @@ http_base_test(void)
|
|||
event_base_dispatch(base);
|
||||
|
||||
bufferevent_free(bev);
|
||||
close(fd);
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
|
@ -913,17 +1102,351 @@ http_base_test(void)
|
|||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* the server is going to reply with chunked data.
|
||||
*/
|
||||
|
||||
static void
|
||||
http_chunked_readcb(struct bufferevent *bev, void *arg)
|
||||
{
|
||||
/* nothing here */
|
||||
}
|
||||
|
||||
static void
|
||||
http_chunked_errorcb(struct bufferevent *bev, short what, void *arg)
|
||||
{
|
||||
if (!test_ok)
|
||||
goto out;
|
||||
|
||||
test_ok = -1;
|
||||
|
||||
if ((what & EVBUFFER_EOF) != 0) {
|
||||
struct evhttp_request *req = evhttp_request_new(NULL, NULL);
|
||||
const char *header;
|
||||
enum message_read_status done;
|
||||
|
||||
req->kind = EVHTTP_RESPONSE;
|
||||
done = evhttp_parse_firstline(req, EVBUFFER_INPUT(bev));
|
||||
if (done != ALL_DATA_READ)
|
||||
goto out;
|
||||
|
||||
done = evhttp_parse_headers(req, EVBUFFER_INPUT(bev));
|
||||
if (done != ALL_DATA_READ)
|
||||
goto out;
|
||||
|
||||
header = evhttp_find_header(req->input_headers, "Transfer-Encoding");
|
||||
if (header == NULL || strcmp(header, "chunked"))
|
||||
goto out;
|
||||
|
||||
header = evhttp_find_header(req->input_headers, "Connection");
|
||||
if (header == NULL || strcmp(header, "close"))
|
||||
goto out;
|
||||
|
||||
header = evbuffer_readline(EVBUFFER_INPUT(bev));
|
||||
if (header == NULL)
|
||||
goto out;
|
||||
/* 13 chars */
|
||||
if (strcmp(header, "d"))
|
||||
goto out;
|
||||
free((char*)header);
|
||||
|
||||
if (strncmp((char *)EVBUFFER_DATA(EVBUFFER_INPUT(bev)),
|
||||
"This is funny", 13))
|
||||
goto out;
|
||||
|
||||
evbuffer_drain(EVBUFFER_INPUT(bev), 13 + 2);
|
||||
|
||||
header = evbuffer_readline(EVBUFFER_INPUT(bev));
|
||||
if (header == NULL)
|
||||
goto out;
|
||||
/* 18 chars */
|
||||
if (strcmp(header, "12"))
|
||||
goto out;
|
||||
free((char *)header);
|
||||
|
||||
if (strncmp((char *)EVBUFFER_DATA(EVBUFFER_INPUT(bev)),
|
||||
"but not hilarious.", 18))
|
||||
goto out;
|
||||
|
||||
evbuffer_drain(EVBUFFER_INPUT(bev), 18 + 2);
|
||||
|
||||
header = evbuffer_readline(EVBUFFER_INPUT(bev));
|
||||
if (header == NULL)
|
||||
goto out;
|
||||
/* 8 chars */
|
||||
if (strcmp(header, "8"))
|
||||
goto out;
|
||||
free((char *)header);
|
||||
|
||||
if (strncmp((char *)EVBUFFER_DATA(EVBUFFER_INPUT(bev)),
|
||||
"bwv 1052.", 8))
|
||||
goto out;
|
||||
|
||||
evbuffer_drain(EVBUFFER_INPUT(bev), 8 + 2);
|
||||
|
||||
header = evbuffer_readline(EVBUFFER_INPUT(bev));
|
||||
if (header == NULL)
|
||||
goto out;
|
||||
/* 0 chars */
|
||||
if (strcmp(header, "0"))
|
||||
goto out;
|
||||
free((char *)header);
|
||||
|
||||
test_ok = 2;
|
||||
}
|
||||
|
||||
out:
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
http_chunked_writecb(struct bufferevent *bev, void *arg)
|
||||
{
|
||||
if (EVBUFFER_LENGTH(EVBUFFER_OUTPUT(bev)) == 0) {
|
||||
/* enable reading of the reply */
|
||||
bufferevent_enable(bev, EV_READ);
|
||||
test_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
http_chunked_request_done(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
if (req->response_code != HTTP_OK) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (evhttp_find_header(req->input_headers,
|
||||
"Transfer-Encoding") == NULL) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (EVBUFFER_LENGTH(req->input_buffer) != 13 + 18 + 8) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strncmp((char *)EVBUFFER_DATA(req->input_buffer),
|
||||
"This is funnybut not hilarious.bwv 1052",
|
||||
13 + 18 + 8)) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
test_ok = 1;
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
http_chunked_test(void)
|
||||
{
|
||||
struct bufferevent *bev;
|
||||
int fd;
|
||||
const char *http_request;
|
||||
short port = -1;
|
||||
struct timeval tv_start, tv_end;
|
||||
struct evhttp_connection *evcon = NULL;
|
||||
struct evhttp_request *req = NULL;
|
||||
int i;
|
||||
|
||||
test_ok = 0;
|
||||
fprintf(stdout, "Testing Chunked HTTP Reply: ");
|
||||
|
||||
http = http_setup(&port, NULL);
|
||||
|
||||
fd = http_connect("127.0.0.1", port);
|
||||
|
||||
/* Stupid thing to send a request */
|
||||
bev = bufferevent_new(fd,
|
||||
http_chunked_readcb, http_chunked_writecb,
|
||||
http_chunked_errorcb, NULL);
|
||||
|
||||
http_request =
|
||||
"GET /chunked HTTP/1.1\r\n"
|
||||
"Host: somehost\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
|
||||
bufferevent_write(bev, http_request, strlen(http_request));
|
||||
|
||||
evutil_gettimeofday(&tv_start, NULL);
|
||||
|
||||
event_dispatch();
|
||||
|
||||
evutil_gettimeofday(&tv_end, NULL);
|
||||
evutil_timersub(&tv_end, &tv_start, &tv_end);
|
||||
|
||||
if (tv_end.tv_sec >= 1) {
|
||||
fprintf(stdout, "FAILED (time)\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
if (test_ok != 2) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* now try again with the regular connection object */
|
||||
evcon = evhttp_connection_new("127.0.0.1", port);
|
||||
if (evcon == NULL) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* make two requests to check the keepalive behavior */
|
||||
for (i = 0; i < 2; i++) {
|
||||
test_ok = 0;
|
||||
req = evhttp_request_new(http_chunked_request_done, NULL);
|
||||
|
||||
/* Add the information that we care about */
|
||||
evhttp_add_header(req->output_headers, "Host", "somehost");
|
||||
|
||||
/* We give ownership of the request to the connection */
|
||||
if (evhttp_make_request(evcon, req,
|
||||
EVHTTP_REQ_GET, "/chunked") == -1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
event_dispatch();
|
||||
|
||||
if (test_ok != 1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
evhttp_connection_free(evcon);
|
||||
evhttp_free(http);
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
static void
|
||||
http_multi_line_header_test(void)
|
||||
{
|
||||
struct bufferevent *bev;
|
||||
int fd;
|
||||
const char *http_start_request;
|
||||
short port = -1;
|
||||
|
||||
test_ok = 0;
|
||||
fprintf(stdout, "Testing HTTP Server with multi line: ");
|
||||
|
||||
http = http_setup(&port, NULL);
|
||||
|
||||
fd = http_connect("127.0.0.1", port);
|
||||
|
||||
/* Stupid thing to send a request */
|
||||
bev = bufferevent_new(fd, http_readcb, http_writecb,
|
||||
http_errorcb, NULL);
|
||||
|
||||
http_start_request =
|
||||
"GET /test HTTP/1.1\r\n"
|
||||
"Host: somehost\r\n"
|
||||
"Connection: close\r\n"
|
||||
"X-Multi: aaaaaaaa\r\n"
|
||||
" a\r\n"
|
||||
"\tEND\r\n"
|
||||
"X-Last: last\r\n"
|
||||
"\r\n";
|
||||
|
||||
bufferevent_write(bev, http_start_request, strlen(http_start_request));
|
||||
|
||||
event_dispatch();
|
||||
|
||||
bufferevent_free(bev);
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
if (test_ok != 4) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
static void
|
||||
http_request_bad(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
if (req != NULL) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
test_ok = 1;
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
http_negative_content_length_test(void)
|
||||
{
|
||||
short port = -1;
|
||||
struct evhttp_connection *evcon = NULL;
|
||||
struct evhttp_request *req = NULL;
|
||||
|
||||
test_ok = 0;
|
||||
fprintf(stdout, "Testing HTTP Negative Content Length: ");
|
||||
|
||||
http = http_setup(&port, NULL);
|
||||
|
||||
evcon = evhttp_connection_new("127.0.0.1", port);
|
||||
if (evcon == NULL) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we want to schedule a request to the HTTP
|
||||
* server using our make request method.
|
||||
*/
|
||||
|
||||
req = evhttp_request_new(http_request_bad, NULL);
|
||||
|
||||
/* Cause the response to have a negative content-length */
|
||||
evhttp_add_header(req->output_headers, "X-Negative", "makeitso");
|
||||
|
||||
/* We give ownership of the request to the connection */
|
||||
if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
event_dispatch();
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
if (test_ok != 1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
http_suite(void)
|
||||
{
|
||||
http_base_test();
|
||||
http_bad_header_test();
|
||||
http_parse_query_test();
|
||||
http_basic_test();
|
||||
http_connection_test(0 /* not-persistent */);
|
||||
http_connection_test(1 /* persistent */);
|
||||
http_close_detection();
|
||||
http_close_detection(0 /* with delay */);
|
||||
http_close_detection(1 /* with delay */);
|
||||
http_post_test();
|
||||
http_failure_test();
|
||||
http_highport_test();
|
||||
http_dispatcher_test();
|
||||
|
||||
http_multi_line_header_test();
|
||||
http_negative_content_length_test();
|
||||
|
||||
http_chunked_test();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: regress_rpc.c,v 1.1 2008/05/16 20:24:57 peter Exp $ */
|
||||
/* $NetBSD: regress_rpc.c,v 1.2 2009/07/08 21:23:54 tls Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -444,14 +444,14 @@ rpc_basic_client(void)
|
|||
need_input_hook = 1;
|
||||
need_output_hook = 1;
|
||||
|
||||
assert(evrpc_add_hook(base, INPUT, rpc_hook_add_header, (void*)"input")
|
||||
assert(evrpc_add_hook(base, EVRPC_INPUT, rpc_hook_add_header, (void*)"input")
|
||||
!= NULL);
|
||||
assert(evrpc_add_hook(base, OUTPUT, rpc_hook_add_header, (void*)"output")
|
||||
assert(evrpc_add_hook(base, EVRPC_OUTPUT, rpc_hook_add_header, (void*)"output")
|
||||
!= NULL);
|
||||
|
||||
pool = rpc_pool_with_connection(port);
|
||||
|
||||
assert(evrpc_add_hook(pool, INPUT, rpc_hook_remove_header, (void*)"output"));
|
||||
assert(evrpc_add_hook(pool, EVRPC_INPUT, rpc_hook_remove_header, (void*)"output"));
|
||||
|
||||
/* set up the basic message */
|
||||
msg = msg_new();
|
||||
|
|
Loading…
Reference in New Issue