/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* ---
*
* recvclient.c: Receive input from the client
- *
+ *
* Known contributors to this file:
* Dave Pare, 1986
+ * Markus Armbruster, 2006-2008
*/
#include <config.h>
* Else receive one line and store it in CMD[SIZE].
* This may block for input, yielding the processor. Flush buffered
* output when blocking, to make sure player sees the prompt.
- * If the player's connection has the I/O error indicator set, or the
- * line is "aborted", set the player's aborted flag and return -2.
- * If the player's connection has the EOF indicator set, or the line
- * is "ctld", set the player's eof flag and return -1.
+ * If the player's connection has the I/O error or EOF indicator set,
+ * or the line is "ctld", set the player's eof and aborted flag and
+ * return -1.
+ * If the line is "aborted", set the player's aborted flag and return
+ * -2.
* Else return the length of the line.
* Design bug: there is no way to indicate truncation of a long line.
*/
int count;
count = -1;
- while (!player->aborted && !player->eof) {
+ while (!player->aborted) {
/* Try to get a line of input */
count = io_gets(player->iop, cmd, size);
if (count >= 0) {
/* got it */
if (strcmp(cmd, "ctld") == 0)
- player->eof = 1;
+ player->aborted = player->eof = 1;
if (strcmp(cmd, "aborted") == 0)
player->aborted = 1;
+ journal_input(cmd);
break;
}
if (player->aborted)
break;
- /* Await more input */
- io_input(player->iop, IO_WAIT);
- if (io_error(player->iop))
- player->aborted = 1;
- else if (io_eof(player->iop))
- player->eof = 1;
+ if (io_input(player->iop, IO_WAIT) <= 0) {
+ if (!io_error(player->iop) && !io_eof(player->iop)) {
+ pr_flash(player, "idle connection terminated\n");
+ player->state = PS_SHUTDOWN;
+ }
+ player->aborted = player->eof = 1;
+ }
}
- if (player->eof)
- return -1;
- if (player->aborted)
- return -2;
+ if (player->aborted) {
+ player->recvfail++;
+ if (player->recvfail > 255) {
+ /*
+ * Looks like the thread is stuck in a loop that fails to
+ * check errors; oops once, then slow it down drastically.
+ */
+ CANT_HAPPEN(player->recvfail == 256);
+ empth_sleep(time(NULL) + 60);
+ }
+ return player->eof ? -1 : -2;
+ }
- journal_input(cmd);
+ player->recvfail = 0;
return count;
}