xref: /minix3/external/bsd/libevent/dist/test/regress_zlib.c (revision e985b929927b5932e3b68f4b50587d458900107a)
1*e985b929SDavid van Moolenbroek /*	$NetBSD: regress_zlib.c,v 1.2 2013/04/11 16:56:42 christos Exp $	*/
2*e985b929SDavid van Moolenbroek /*
3*e985b929SDavid van Moolenbroek  * Copyright (c) 2008-2012 Niels Provos and Nick Mathewson
4*e985b929SDavid van Moolenbroek  *
5*e985b929SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*e985b929SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
7*e985b929SDavid van Moolenbroek  * are met:
8*e985b929SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
9*e985b929SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
10*e985b929SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
11*e985b929SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
12*e985b929SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
13*e985b929SDavid van Moolenbroek  * 3. The name of the author may not be used to endorse or promote products
14*e985b929SDavid van Moolenbroek  *    derived from this software without specific prior written permission.
15*e985b929SDavid van Moolenbroek  *
16*e985b929SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*e985b929SDavid van Moolenbroek  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*e985b929SDavid van Moolenbroek  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*e985b929SDavid van Moolenbroek  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*e985b929SDavid van Moolenbroek  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*e985b929SDavid van Moolenbroek  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*e985b929SDavid van Moolenbroek  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*e985b929SDavid van Moolenbroek  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*e985b929SDavid van Moolenbroek  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*e985b929SDavid van Moolenbroek  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*e985b929SDavid van Moolenbroek  */
27*e985b929SDavid van Moolenbroek 
28*e985b929SDavid van Moolenbroek /* The old tests here need assertions to work. */
29*e985b929SDavid van Moolenbroek #undef NDEBUG
30*e985b929SDavid van Moolenbroek 
31*e985b929SDavid van Moolenbroek #ifdef WIN32
32*e985b929SDavid van Moolenbroek #include <winsock2.h>
33*e985b929SDavid van Moolenbroek #include <windows.h>
34*e985b929SDavid van Moolenbroek #endif
35*e985b929SDavid van Moolenbroek 
36*e985b929SDavid van Moolenbroek #include "event2/event-config.h"
37*e985b929SDavid van Moolenbroek #include <sys/cdefs.h>
38*e985b929SDavid van Moolenbroek __RCSID("$NetBSD: regress_zlib.c,v 1.2 2013/04/11 16:56:42 christos Exp $");
39*e985b929SDavid van Moolenbroek 
40*e985b929SDavid van Moolenbroek #include <sys/types.h>
41*e985b929SDavid van Moolenbroek #ifndef WIN32
42*e985b929SDavid van Moolenbroek #include <sys/socket.h>
43*e985b929SDavid van Moolenbroek #include <sys/wait.h>
44*e985b929SDavid van Moolenbroek #include <unistd.h>
45*e985b929SDavid van Moolenbroek #include <netdb.h>
46*e985b929SDavid van Moolenbroek #endif
47*e985b929SDavid van Moolenbroek #include <signal.h>
48*e985b929SDavid van Moolenbroek #include <stdio.h>
49*e985b929SDavid van Moolenbroek #include <stdlib.h>
50*e985b929SDavid van Moolenbroek #include <string.h>
51*e985b929SDavid van Moolenbroek 
52*e985b929SDavid van Moolenbroek #include <assert.h>
53*e985b929SDavid van Moolenbroek #include <errno.h>
54*e985b929SDavid van Moolenbroek 
55*e985b929SDavid van Moolenbroek #include "event2/util.h"
56*e985b929SDavid van Moolenbroek #include "event2/event.h"
57*e985b929SDavid van Moolenbroek #include "event2/event_compat.h"
58*e985b929SDavid van Moolenbroek #include "event2/buffer.h"
59*e985b929SDavid van Moolenbroek #include "event2/bufferevent.h"
60*e985b929SDavid van Moolenbroek 
61*e985b929SDavid van Moolenbroek #include "regress.h"
62*e985b929SDavid van Moolenbroek 
63*e985b929SDavid van Moolenbroek /* zlib 1.2.4 and 1.2.5 do some "clever" things with macros.  Instead of
64*e985b929SDavid van Moolenbroek    saying "(defined(FOO) ? FOO : 0)" they like to say "FOO-0", on the theory
65*e985b929SDavid van Moolenbroek    that nobody will care if the compile outputs a no-such-identifier warning.
66*e985b929SDavid van Moolenbroek 
67*e985b929SDavid van Moolenbroek    Sorry, but we like -Werror over here, so I guess we need to define these.
68*e985b929SDavid van Moolenbroek    I hope that zlib 1.2.6 doesn't break these too.
69*e985b929SDavid van Moolenbroek */
70*e985b929SDavid van Moolenbroek #ifndef _LARGEFILE64_SOURCE
71*e985b929SDavid van Moolenbroek #define _LARGEFILE64_SOURCE 0
72*e985b929SDavid van Moolenbroek #endif
73*e985b929SDavid van Moolenbroek #ifndef _LFS64_LARGEFILE
74*e985b929SDavid van Moolenbroek #define _LFS64_LARGEFILE 0
75*e985b929SDavid van Moolenbroek #endif
76*e985b929SDavid van Moolenbroek #ifndef _FILE_OFFSET_BITS
77*e985b929SDavid van Moolenbroek #define _FILE_OFFSET_BITS 0
78*e985b929SDavid van Moolenbroek #endif
79*e985b929SDavid van Moolenbroek #ifndef off64_t
80*e985b929SDavid van Moolenbroek #define off64_t ev_int64_t
81*e985b929SDavid van Moolenbroek #endif
82*e985b929SDavid van Moolenbroek 
83*e985b929SDavid van Moolenbroek #include <zlib.h>
84*e985b929SDavid van Moolenbroek 
85*e985b929SDavid van Moolenbroek static int infilter_calls;
86*e985b929SDavid van Moolenbroek static int outfilter_calls;
87*e985b929SDavid van Moolenbroek static int readcb_finished;
88*e985b929SDavid van Moolenbroek static int writecb_finished;
89*e985b929SDavid van Moolenbroek static int errorcb_invoked;
90*e985b929SDavid van Moolenbroek 
91*e985b929SDavid van Moolenbroek /*
92*e985b929SDavid van Moolenbroek  * Zlib filters
93*e985b929SDavid van Moolenbroek  */
94*e985b929SDavid van Moolenbroek 
95*e985b929SDavid van Moolenbroek static void
zlib_deflate_free(void * ctx)96*e985b929SDavid van Moolenbroek zlib_deflate_free(void *ctx)
97*e985b929SDavid van Moolenbroek {
98*e985b929SDavid van Moolenbroek 	z_streamp p = ctx;
99*e985b929SDavid van Moolenbroek 
100*e985b929SDavid van Moolenbroek 	assert(deflateEnd(p) == Z_OK);
101*e985b929SDavid van Moolenbroek }
102*e985b929SDavid van Moolenbroek 
103*e985b929SDavid van Moolenbroek static void
zlib_inflate_free(void * ctx)104*e985b929SDavid van Moolenbroek zlib_inflate_free(void *ctx)
105*e985b929SDavid van Moolenbroek {
106*e985b929SDavid van Moolenbroek 	z_streamp p = ctx;
107*e985b929SDavid van Moolenbroek 
108*e985b929SDavid van Moolenbroek 	assert(inflateEnd(p) == Z_OK);
109*e985b929SDavid van Moolenbroek }
110*e985b929SDavid van Moolenbroek 
111*e985b929SDavid van Moolenbroek static int
getstate(enum bufferevent_flush_mode state)112*e985b929SDavid van Moolenbroek getstate(enum bufferevent_flush_mode state)
113*e985b929SDavid van Moolenbroek {
114*e985b929SDavid van Moolenbroek 	switch (state) {
115*e985b929SDavid van Moolenbroek 	case BEV_FINISHED:
116*e985b929SDavid van Moolenbroek 		return Z_FINISH;
117*e985b929SDavid van Moolenbroek 	case BEV_FLUSH:
118*e985b929SDavid van Moolenbroek 		return Z_SYNC_FLUSH;
119*e985b929SDavid van Moolenbroek 	case BEV_NORMAL:
120*e985b929SDavid van Moolenbroek 	default:
121*e985b929SDavid van Moolenbroek 		return Z_NO_FLUSH;
122*e985b929SDavid van Moolenbroek 	}
123*e985b929SDavid van Moolenbroek }
124*e985b929SDavid van Moolenbroek 
125*e985b929SDavid van Moolenbroek /*
126*e985b929SDavid van Moolenbroek  * The input filter is triggered only on new input read from the network.
127*e985b929SDavid van Moolenbroek  * That means all input data needs to be consumed or the filter needs to
128*e985b929SDavid van Moolenbroek  * initiate its own triggering via a timeout.
129*e985b929SDavid van Moolenbroek  */
130*e985b929SDavid van Moolenbroek static enum bufferevent_filter_result
zlib_input_filter(struct evbuffer * src,struct evbuffer * dst,ev_ssize_t lim,enum bufferevent_flush_mode state,void * ctx)131*e985b929SDavid van Moolenbroek zlib_input_filter(struct evbuffer *src, struct evbuffer *dst,
132*e985b929SDavid van Moolenbroek     ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
133*e985b929SDavid van Moolenbroek {
134*e985b929SDavid van Moolenbroek 	struct evbuffer_iovec v_in[1];
135*e985b929SDavid van Moolenbroek 	struct evbuffer_iovec v_out[1];
136*e985b929SDavid van Moolenbroek 	int nread, nwrite;
137*e985b929SDavid van Moolenbroek 	int res, n;
138*e985b929SDavid van Moolenbroek 
139*e985b929SDavid van Moolenbroek 	z_streamp p = ctx;
140*e985b929SDavid van Moolenbroek 
141*e985b929SDavid van Moolenbroek 	do {
142*e985b929SDavid van Moolenbroek 		/* let's do some decompression */
143*e985b929SDavid van Moolenbroek 		n = evbuffer_peek(src, -1, NULL, v_in, 1);
144*e985b929SDavid van Moolenbroek 		if (n) {
145*e985b929SDavid van Moolenbroek 			p->avail_in = v_in[0].iov_len;
146*e985b929SDavid van Moolenbroek 			p->next_in = v_in[0].iov_base;
147*e985b929SDavid van Moolenbroek 		} else {
148*e985b929SDavid van Moolenbroek 			p->avail_in = 0;
149*e985b929SDavid van Moolenbroek 			p->next_in = 0;
150*e985b929SDavid van Moolenbroek 		}
151*e985b929SDavid van Moolenbroek 
152*e985b929SDavid van Moolenbroek 		evbuffer_reserve_space(dst, 4096, v_out, 1);
153*e985b929SDavid van Moolenbroek 		p->next_out = v_out[0].iov_base;
154*e985b929SDavid van Moolenbroek 		p->avail_out = v_out[0].iov_len;
155*e985b929SDavid van Moolenbroek 
156*e985b929SDavid van Moolenbroek 		/* we need to flush zlib if we got a flush */
157*e985b929SDavid van Moolenbroek 		res = inflate(p, getstate(state));
158*e985b929SDavid van Moolenbroek 
159*e985b929SDavid van Moolenbroek 		/* let's figure out how much was compressed */
160*e985b929SDavid van Moolenbroek 		nread = v_in[0].iov_len - p->avail_in;
161*e985b929SDavid van Moolenbroek 		nwrite = v_out[0].iov_len - p->avail_out;
162*e985b929SDavid van Moolenbroek 
163*e985b929SDavid van Moolenbroek 		evbuffer_drain(src, nread);
164*e985b929SDavid van Moolenbroek 		v_out[0].iov_len = nwrite;
165*e985b929SDavid van Moolenbroek 		evbuffer_commit_space(dst, v_out, 1);
166*e985b929SDavid van Moolenbroek 
167*e985b929SDavid van Moolenbroek 		if (res==Z_BUF_ERROR) {
168*e985b929SDavid van Moolenbroek 			/* We're out of space, or out of decodeable input.
169*e985b929SDavid van Moolenbroek 			   Only if nwrite == 0 assume the latter.
170*e985b929SDavid van Moolenbroek 			 */
171*e985b929SDavid van Moolenbroek 			if (nwrite == 0)
172*e985b929SDavid van Moolenbroek 				return BEV_NEED_MORE;
173*e985b929SDavid van Moolenbroek 		} else {
174*e985b929SDavid van Moolenbroek 			assert(res == Z_OK || res == Z_STREAM_END);
175*e985b929SDavid van Moolenbroek 		}
176*e985b929SDavid van Moolenbroek 
177*e985b929SDavid van Moolenbroek 	} while (evbuffer_get_length(src) > 0);
178*e985b929SDavid van Moolenbroek 
179*e985b929SDavid van Moolenbroek 	++infilter_calls;
180*e985b929SDavid van Moolenbroek 
181*e985b929SDavid van Moolenbroek 	return (BEV_OK);
182*e985b929SDavid van Moolenbroek }
183*e985b929SDavid van Moolenbroek 
184*e985b929SDavid van Moolenbroek static enum bufferevent_filter_result
zlib_output_filter(struct evbuffer * src,struct evbuffer * dst,ev_ssize_t lim,enum bufferevent_flush_mode state,void * ctx)185*e985b929SDavid van Moolenbroek zlib_output_filter(struct evbuffer *src, struct evbuffer *dst,
186*e985b929SDavid van Moolenbroek     ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
187*e985b929SDavid van Moolenbroek {
188*e985b929SDavid van Moolenbroek 	struct evbuffer_iovec v_in[1];
189*e985b929SDavid van Moolenbroek 	struct evbuffer_iovec v_out[1];
190*e985b929SDavid van Moolenbroek 	int nread, nwrite;
191*e985b929SDavid van Moolenbroek 	int res, n;
192*e985b929SDavid van Moolenbroek 
193*e985b929SDavid van Moolenbroek 	z_streamp p = ctx;
194*e985b929SDavid van Moolenbroek 
195*e985b929SDavid van Moolenbroek 	do {
196*e985b929SDavid van Moolenbroek 		/* let's do some compression */
197*e985b929SDavid van Moolenbroek 		n = evbuffer_peek(src, -1, NULL, v_in, 1);
198*e985b929SDavid van Moolenbroek 		if (n) {
199*e985b929SDavid van Moolenbroek 			p->avail_in = v_in[0].iov_len;
200*e985b929SDavid van Moolenbroek 			p->next_in = v_in[0].iov_base;
201*e985b929SDavid van Moolenbroek 		} else {
202*e985b929SDavid van Moolenbroek 			p->avail_in = 0;
203*e985b929SDavid van Moolenbroek 			p->next_in = 0;
204*e985b929SDavid van Moolenbroek 		}
205*e985b929SDavid van Moolenbroek 
206*e985b929SDavid van Moolenbroek 		evbuffer_reserve_space(dst, 4096, v_out, 1);
207*e985b929SDavid van Moolenbroek 		p->next_out = v_out[0].iov_base;
208*e985b929SDavid van Moolenbroek 		p->avail_out = v_out[0].iov_len;
209*e985b929SDavid van Moolenbroek 
210*e985b929SDavid van Moolenbroek 		/* we need to flush zlib if we got a flush */
211*e985b929SDavid van Moolenbroek 		res = deflate(p, getstate(state));
212*e985b929SDavid van Moolenbroek 
213*e985b929SDavid van Moolenbroek 		/* let's figure out how much was decompressed */
214*e985b929SDavid van Moolenbroek 		nread = v_in[0].iov_len - p->avail_in;
215*e985b929SDavid van Moolenbroek 		nwrite = v_out[0].iov_len - p->avail_out;
216*e985b929SDavid van Moolenbroek 
217*e985b929SDavid van Moolenbroek 		evbuffer_drain(src, nread);
218*e985b929SDavid van Moolenbroek 		v_out[0].iov_len = nwrite;
219*e985b929SDavid van Moolenbroek 		evbuffer_commit_space(dst, v_out, 1);
220*e985b929SDavid van Moolenbroek 
221*e985b929SDavid van Moolenbroek 		if (res==Z_BUF_ERROR) {
222*e985b929SDavid van Moolenbroek 			/* We're out of space, or out of decodeable input.
223*e985b929SDavid van Moolenbroek 			   Only if nwrite == 0 assume the latter.
224*e985b929SDavid van Moolenbroek 			 */
225*e985b929SDavid van Moolenbroek 			if (nwrite == 0)
226*e985b929SDavid van Moolenbroek 				return BEV_NEED_MORE;
227*e985b929SDavid van Moolenbroek 		} else {
228*e985b929SDavid van Moolenbroek 			assert(res == Z_OK || res == Z_STREAM_END);
229*e985b929SDavid van Moolenbroek 		}
230*e985b929SDavid van Moolenbroek 
231*e985b929SDavid van Moolenbroek 	} while (evbuffer_get_length(src) > 0);
232*e985b929SDavid van Moolenbroek 
233*e985b929SDavid van Moolenbroek 	++outfilter_calls;
234*e985b929SDavid van Moolenbroek 
235*e985b929SDavid van Moolenbroek 	return (BEV_OK);
236*e985b929SDavid van Moolenbroek }
237*e985b929SDavid van Moolenbroek 
238*e985b929SDavid van Moolenbroek /*
239*e985b929SDavid van Moolenbroek  * simple bufferevent test (over transparent zlib treatment)
240*e985b929SDavid van Moolenbroek  */
241*e985b929SDavid van Moolenbroek 
242*e985b929SDavid van Moolenbroek static void
readcb(struct bufferevent * bev,void * arg)243*e985b929SDavid van Moolenbroek readcb(struct bufferevent *bev, void *arg)
244*e985b929SDavid van Moolenbroek {
245*e985b929SDavid van Moolenbroek 	if (evbuffer_get_length(bufferevent_get_input(bev)) == 8333) {
246*e985b929SDavid van Moolenbroek 		struct evbuffer *evbuf = evbuffer_new();
247*e985b929SDavid van Moolenbroek 		assert(evbuf != NULL);
248*e985b929SDavid van Moolenbroek 
249*e985b929SDavid van Moolenbroek 		/* gratuitous test of bufferevent_read_buffer */
250*e985b929SDavid van Moolenbroek 		bufferevent_read_buffer(bev, evbuf);
251*e985b929SDavid van Moolenbroek 
252*e985b929SDavid van Moolenbroek 		bufferevent_disable(bev, EV_READ);
253*e985b929SDavid van Moolenbroek 
254*e985b929SDavid van Moolenbroek 		if (evbuffer_get_length(evbuf) == 8333) {
255*e985b929SDavid van Moolenbroek 			++readcb_finished;
256*e985b929SDavid van Moolenbroek 		}
257*e985b929SDavid van Moolenbroek 
258*e985b929SDavid van Moolenbroek 		evbuffer_free(evbuf);
259*e985b929SDavid van Moolenbroek 	}
260*e985b929SDavid van Moolenbroek }
261*e985b929SDavid van Moolenbroek 
262*e985b929SDavid van Moolenbroek static void
writecb(struct bufferevent * bev,void * arg)263*e985b929SDavid van Moolenbroek writecb(struct bufferevent *bev, void *arg)
264*e985b929SDavid van Moolenbroek {
265*e985b929SDavid van Moolenbroek 	if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) {
266*e985b929SDavid van Moolenbroek 		++writecb_finished;
267*e985b929SDavid van Moolenbroek 	}
268*e985b929SDavid van Moolenbroek }
269*e985b929SDavid van Moolenbroek 
270*e985b929SDavid van Moolenbroek static void
errorcb(struct bufferevent * bev,short what,void * arg)271*e985b929SDavid van Moolenbroek errorcb(struct bufferevent *bev, short what, void *arg)
272*e985b929SDavid van Moolenbroek {
273*e985b929SDavid van Moolenbroek 	errorcb_invoked = 1;
274*e985b929SDavid van Moolenbroek }
275*e985b929SDavid van Moolenbroek 
276*e985b929SDavid van Moolenbroek void
test_bufferevent_zlib(void * arg)277*e985b929SDavid van Moolenbroek test_bufferevent_zlib(void *arg)
278*e985b929SDavid van Moolenbroek {
279*e985b929SDavid van Moolenbroek 	struct bufferevent *bev1=NULL, *bev2=NULL;
280*e985b929SDavid van Moolenbroek 	char buffer[8333];
281*e985b929SDavid van Moolenbroek 	z_stream z_input, z_output;
282*e985b929SDavid van Moolenbroek 	int i, r;
283*e985b929SDavid van Moolenbroek 	evutil_socket_t xpair[2] = {-1, -1};
284*e985b929SDavid van Moolenbroek 	(void)arg;
285*e985b929SDavid van Moolenbroek 
286*e985b929SDavid van Moolenbroek 	infilter_calls = outfilter_calls = readcb_finished = writecb_finished
287*e985b929SDavid van Moolenbroek 	    = errorcb_invoked = 0;
288*e985b929SDavid van Moolenbroek 
289*e985b929SDavid van Moolenbroek 	if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, xpair) == -1) {
290*e985b929SDavid van Moolenbroek 		tt_abort_perror("socketpair");
291*e985b929SDavid van Moolenbroek 	}
292*e985b929SDavid van Moolenbroek 
293*e985b929SDavid van Moolenbroek 	evutil_make_socket_nonblocking(xpair[0]);
294*e985b929SDavid van Moolenbroek 	evutil_make_socket_nonblocking(xpair[1]);
295*e985b929SDavid van Moolenbroek 
296*e985b929SDavid van Moolenbroek 	bev1 = bufferevent_socket_new(NULL, xpair[0], 0);
297*e985b929SDavid van Moolenbroek 	bev2 = bufferevent_socket_new(NULL, xpair[1], 0);
298*e985b929SDavid van Moolenbroek 
299*e985b929SDavid van Moolenbroek 	memset(&z_output, 0, sizeof(z_output));
300*e985b929SDavid van Moolenbroek 	r = deflateInit(&z_output, Z_DEFAULT_COMPRESSION);
301*e985b929SDavid van Moolenbroek 	tt_int_op(r, ==, Z_OK);
302*e985b929SDavid van Moolenbroek 	memset(&z_input, 0, sizeof(z_input));
303*e985b929SDavid van Moolenbroek 	r = inflateInit(&z_input);
304*e985b929SDavid van Moolenbroek 	tt_int_op(r, ==, Z_OK);
305*e985b929SDavid van Moolenbroek 
306*e985b929SDavid van Moolenbroek 	/* initialize filters */
307*e985b929SDavid van Moolenbroek 	bev1 = bufferevent_filter_new(bev1, NULL, zlib_output_filter,
308*e985b929SDavid van Moolenbroek 	    BEV_OPT_CLOSE_ON_FREE, zlib_deflate_free, &z_output);
309*e985b929SDavid van Moolenbroek 	bev2 = bufferevent_filter_new(bev2, zlib_input_filter,
310*e985b929SDavid van Moolenbroek 	    NULL, BEV_OPT_CLOSE_ON_FREE, zlib_inflate_free, &z_input);
311*e985b929SDavid van Moolenbroek 	bufferevent_setcb(bev1, readcb, writecb, errorcb, NULL);
312*e985b929SDavid van Moolenbroek 	bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL);
313*e985b929SDavid van Moolenbroek 
314*e985b929SDavid van Moolenbroek 	bufferevent_disable(bev1, EV_READ);
315*e985b929SDavid van Moolenbroek 	bufferevent_enable(bev1, EV_WRITE);
316*e985b929SDavid van Moolenbroek 
317*e985b929SDavid van Moolenbroek 	bufferevent_enable(bev2, EV_READ);
318*e985b929SDavid van Moolenbroek 
319*e985b929SDavid van Moolenbroek 	for (i = 0; i < (int)sizeof(buffer); i++)
320*e985b929SDavid van Moolenbroek 		buffer[i] = i;
321*e985b929SDavid van Moolenbroek 
322*e985b929SDavid van Moolenbroek 	/* break it up into multiple buffer chains */
323*e985b929SDavid van Moolenbroek 	bufferevent_write(bev1, buffer, 1800);
324*e985b929SDavid van Moolenbroek 	bufferevent_write(bev1, buffer + 1800, sizeof(buffer) - 1800);
325*e985b929SDavid van Moolenbroek 
326*e985b929SDavid van Moolenbroek 	/* we are done writing - we need to flush everything */
327*e985b929SDavid van Moolenbroek 	bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED);
328*e985b929SDavid van Moolenbroek 
329*e985b929SDavid van Moolenbroek 	event_dispatch();
330*e985b929SDavid van Moolenbroek 
331*e985b929SDavid van Moolenbroek 	tt_want(infilter_calls);
332*e985b929SDavid van Moolenbroek 	tt_want(outfilter_calls);
333*e985b929SDavid van Moolenbroek 	tt_want(readcb_finished);
334*e985b929SDavid van Moolenbroek 	tt_want(writecb_finished);
335*e985b929SDavid van Moolenbroek 	tt_want(!errorcb_invoked);
336*e985b929SDavid van Moolenbroek 
337*e985b929SDavid van Moolenbroek 	test_ok = 1;
338*e985b929SDavid van Moolenbroek end:
339*e985b929SDavid van Moolenbroek 	if (bev1)
340*e985b929SDavid van Moolenbroek 		bufferevent_free(bev1);
341*e985b929SDavid van Moolenbroek 	if (bev2)
342*e985b929SDavid van Moolenbroek 		bufferevent_free(bev2);
343*e985b929SDavid van Moolenbroek 
344*e985b929SDavid van Moolenbroek 	if (xpair[0] >= 0)
345*e985b929SDavid van Moolenbroek 		evutil_closesocket(xpair[0]);
346*e985b929SDavid van Moolenbroek 	if (xpair[1] >= 0)
347*e985b929SDavid van Moolenbroek 		evutil_closesocket(xpair[1]);
348*e985b929SDavid van Moolenbroek }
349