#ifndef EMPIO_H
#define EMPIO_H
-#include <sys/time.h>
+#include <time.h>
#define IO_READ 0x1
#define IO_WRITE 0x2
extern struct iop *io_open(int, int, int);
extern void io_init(void);
-extern void io_close(struct iop *, struct timeval *);
-extern void io_timeout(struct timeval *, time_t);
-extern int io_input(struct iop *, struct timeval *);
+extern void io_close(struct iop *, time_t);
+extern int io_input(struct iop *, time_t);
extern int io_inputwaiting(struct iop *);
extern int io_outputwaiting(struct iop *);
extern int io_output(struct iop *, int);
int last_out;
};
+static struct timeval *io_timeout(struct timeval *, time_t);
+
void
io_init(void)
{
}
void
-io_close(struct iop *iop, struct timeval *timeout)
+io_close(struct iop *iop, time_t deadline)
{
+ struct timeval timeout;
char buf[IO_BUFSIZE];
int ret;
while (io_output(iop, 1) > 0) ;
shutdown(iop->fd, SHUT_WR);
- while (empth_select(iop->fd, EMPTH_FD_READ, timeout) > 0) {
+ while (empth_select(iop->fd, EMPTH_FD_READ,
+ io_timeout(&timeout, deadline)) > 0) {
ret = read(iop->fd, buf, sizeof(buf));
if (ret <= 0)
break;
free(iop);
}
-void
+static struct timeval *
io_timeout(struct timeval *timeout, time_t deadline)
{
struct timeval now;
+ if (deadline == (time_t)-1)
+ return NULL; /* no deadline */
+
gettimeofday(&now, NULL);
if (now.tv_sec >= deadline) {
/* deadline reached already */
timeout->tv_usec = 999999 - now.tv_usec;
/* yes, this is 1usec early; sue me */
}
+
+ return timeout;
}
/*
* Read input from IOP and enqueue it.
- * If TIMEOUT is non-null, wait at most that long for input to arrive.
- * Does not yield the processor when timeout is zero.
+ * Wait at most until DEADLINE for input to arrive. (time_t)-1 means
+ * wait as long as it takes (no timeout).
+ * Does not yield the processor when DEADLINE is zero.
* A wait for input can be cut short by empth_wakeup().
* Return number of bytes read on success, -1 on error.
* In particular, return zero on timeout, early wakeup or EOF. Use
* io_eof() to distinguish timeout and early wakeup from EOF.
*/
int
-io_input(struct iop *iop, struct timeval *timeout)
+io_input(struct iop *iop, time_t deadline)
{
+ struct timeval timeout;
char buf[IO_BUFSIZE];
int cc;
int res;
if (iop->flags & IO_EOF)
return 0;
- if (!timeout || timeout->tv_sec || timeout->tv_usec) {
- res = empth_select(iop->fd, EMPTH_FD_READ, timeout);
+ if (deadline) {
+ res = empth_select(iop->fd, EMPTH_FD_READ,
+ io_timeout(&timeout, deadline));
if (res < 0) {
iop->flags |= IO_ERROR;
return -1;
void
player_login(void *ud)
{
- struct timeval timeout;
char buf[128];
char space[128];
int ac;
for (;;) {
io_output(player->iop, 1);
if (io_gets(player->iop, buf, sizeof(buf)) < 0) {
- io_timeout(&timeout, player->curup + minutes(max_idle));
- res = io_input(player->iop, &timeout);
+ res = io_input(player->iop, player->curup + minutes(max_idle));
if (res <= 0) {
if (res == 0 && !io_eof(player->iop))
pr_id(player, C_DATA, "idle connection terminated\n");