/*****************************************************************************\
* Copyright (c) 2002-2004 Pelle Johansson. *
* All rights reserved. *
* *
* This file is part of the moftpd package. Use and distribution of *
* this software is governed by the terms in the file LICENCE, which *
* should have come with this package. *
\*****************************************************************************/
/* $moftpd: events_select.c 1251 2005-03-06 22:24:29Z morth $ */
#include "system.h"
#include "events.h"
static fd_set readSet, writeSet;
static int maxFd = 0;
extern int urgData;
void events_einit (void)
{
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
maxFd = 0;
}
int events_earf (int fd, void *data)
{
if (fd >= FD_SETSIZE)
{
// We're restricted by FD_SETSIZE in select().
errno = EINVAL;
return -1;
}
if (!FD_ISSET (fd, &readSet))
{
/* Update maxFd if appropriate. */
if(fd >= maxFd)
maxFd = fd + 1;
FD_SET(fd, &readSet);
}
return 0;
}
int events_eawf (int fd, void *data)
{
if (fd >= FD_SETSIZE)
{
// We're restricted by FD_SETSIZE in select().
errno = EINVAL;
return -1;
}
if (!FD_ISSET (fd, &writeSet))
{
/* Update maxFd if appropriate. */
if(fd >= maxFd)
maxFd = fd + 1;
FD_SET(fd, &writeSet);
}
return 0;
}
void events_errf (int fd)
{
if(fd < 0 || fd >= FD_SETSIZE)
return;
if (FD_ISSET (fd, &readSet))
{
FD_CLR(fd, &readSet);
/* We might be able to lower maxFd. Check! */
if(fd == maxFd - 1)
{
int fdIter, newMax = -1;
for(fdIter = maxFd - 2; fdIter >= 0; fdIter--)
{
if(FD_ISSET(fdIter, &readSet) || FD_ISSET(fdIter, &writeSet))
{
newMax = fdIter;
break;
}
}
maxFd = newMax + 1;
}
}
}
void events_erwf (int fd)
{
if(fd < 0 || fd >= FD_SETSIZE)
return;
if (FD_ISSET (fd, &writeSet))
{
FD_CLR(fd, &writeSet);
/* We might be able to lower maxFd. Check! */
if(fd == maxFd - 1)
{
int fdIter, newMax = -1;
for(fdIter = maxFd - 2; fdIter >= 0; fdIter--)
{
if(FD_ISSET(fdIter, &readSet) || FD_ISSET(fdIter, &writeSet))
{
newMax = fdIter;
break;
}
}
maxFd = newMax + 1;
}
}
}
int run_events (void)
{
fd_set rSet, wSet, eSet;
int fdIter;
struct timeval tv;
rSet = readSet;
wSet = writeSet;
eSet = readSet;
tv.tv_sec = 10;
tv.tv_usec = 0;
if(select(maxFd, &rSet, &wSet, &eSet, &tv) < 0)
{
if(errno == EINTR)
return 0;
syslog (LOG_ERR, "select: %m");
return -1;
}
urgData = 0;
for(fdIter = 0; fdIter < maxFd; fdIter++)
{
/*
* Cheack readSet and writeSet as well as they might have been removed
* by an earlier handler.
*/
if(FD_ISSET(fdIter, &eSet) && FD_ISSET(fdIter, &readSet))
{
/*
* "Exceptional state" means urgent data available on sockets.
* Hopefully that's the only thing that activates it, not completely
* sure.
*/
if (events_run_handler (fdIter, 0, 1))
break;
}
if(FD_ISSET(fdIter, &rSet) && FD_ISSET(fdIter, &readSet))
{
if (events_run_handler (fdIter, 0, 0))
break;
}
if(FD_ISSET(fdIter, &wSet) && FD_ISSET(fdIter, &writeSet))
{
if (events_run_handler (fdIter, 1, 0))
break;
}
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1