/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-1999 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* ev_connects.c - implement asynch connect/accept for the eventlib
* vix 16sep96 [initial]
*/
static void listener(evContext ctx, void *uap, int fd, int evmask);
static void connector(evContext ctx, void *uap, int fd, int evmask);
/* Public. */
int
evListen(evContext opaqueCtx, int fd, int maxconn,
evConnFunc func, void *uap, evConnID *id)
{
evContext_p *ctx = opaqueCtx.opaque;
evConn *new;
int mode;
OKNEW(new);
new->flags = EV_CONN_LISTEN;
OKFREE(mode = fcntl(fd, F_GETFL, NULL), new); /*%< side effect: validate fd. */
/*
* Remember the nonblocking status. We assume that either evSelectFD
* has not been done to this fd, or that if it has then the caller
* will evCancelConn before they evDeselectFD. If our assumptions
* are not met, then we might restore the old nonblocking status
* incorrectly.
*/
if ((mode & PORT_NONBLOCK) == 0) {
#ifdef USE_FIONBIO_IOCTL
int on = 1;
OKFREE(ioctl(fd, FIONBIO, (char *)&on), new);
#else
OKFREE(fcntl(fd, F_SETFL, mode | PORT_NONBLOCK), new);
#endif
new->flags |= EV_CONN_BLOCK;
}
OKFREE(listen(fd, maxconn), new);
if (evSelectFD(opaqueCtx, fd, EV_READ, listener, new, &new->file) < 0){
int save = errno;
int
evConnect(evContext opaqueCtx, int fd, const void *ra, int ralen,
evConnFunc func, void *uap, evConnID *id)
{
evContext_p *ctx = opaqueCtx.opaque;
evConn *new;
OKNEW(new);
new->flags = 0;
/* Do the select() first to get the socket into nonblocking mode. */
if (evSelectFD(opaqueCtx, fd, EV_MASK_ALL,
connector, new, &new->file) < 0) {
int save = errno;