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:
tls 2009-07-08 21:23:52 +00:00
parent 77a7c01d68
commit e234ec7db5
33 changed files with 1668 additions and 479 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}
/*

View File

@ -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;

View File

@ -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);
/**

View File

@ -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);
}

View File

@ -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);

View File

@ -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>

View File

@ -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);
/**

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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));
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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)

View File

@ -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();
}

View File

@ -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();