Fix treatment of EOF from player

Commit 79407e68 (v4.3.11) changed recvclient() to keep failing after
receiving EOF from player.  This was bad, because some places getting
input check player->aborted instead of recvclient() failure, and
player->aborted wasn't set on EOF.  Bugs caused by this:

* comm_bomb(), ship_bomb(), plane_bomb(), land_bomb() went into an
  infinite loop that eventually ate all memory.

* deli(), desi(), dist(), fly(), morale(), zdon(), att_prompt(),
  ask_move_in() interpreted EOF as empty input instead of no more
  input.

* cmd_sail_ship() dereferenced a null pointer.

Fix by setting player->aborted on EOF, too.
This commit is contained in:
Markus Armbruster 2008-07-14 22:37:02 -04:00
parent 9c5854c8c9
commit b3a7a8ee11
3 changed files with 8 additions and 7 deletions

View file

@ -76,7 +76,7 @@ struct player {
int simulation; /* e.g. budget command */ int simulation; /* e.g. budget command */
double dolcost; double dolcost;
time_t curup; /* when last input was received */ time_t curup; /* when last input was received */
int aborted; /* interrupt cookie received? */ int aborted; /* interrupt cookie or EOF received? */
int eof; /* EOF (cookie or real) received? */ int eof; /* EOF (cookie or real) received? */
int recvfail; /* #recvclient() failures */ int recvfail; /* #recvclient() failures */
int curid; /* for pr, cur. line's id, -1 none */ int curid; /* for pr, cur. line's id, -1 none */

View file

@ -111,7 +111,7 @@ player_main(struct player *p)
while (status()) { while (status()) {
command(); command();
player->aborted = 0; player->aborted = player->eof;
empth_yield(); empth_yield();
} }
/* #*# I put the following line in to prevent server crash -KHS */ /* #*# I put the following line in to prevent server crash -KHS */

View file

@ -48,7 +48,8 @@
* This may block for input, yielding the processor. Flush buffered * This may block for input, yielding the processor. Flush buffered
* output when blocking, to make sure player sees the prompt. * output when blocking, to make sure player sees the prompt.
* If the player's connection has the I/O error or EOF indicator set, * If the player's connection has the I/O error or EOF indicator set,
* or the line is "ctld", set the player's eof flag and return -1. * 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 * If the line is "aborted", set the player's aborted flag and return
* -2. * -2.
* Else return the length of the line. * Else return the length of the line.
@ -60,13 +61,13 @@ recvclient(char *cmd, int size)
int count; int count;
count = -1; count = -1;
while (!player->aborted && !player->eof) { while (!player->aborted) {
/* Try to get a line of input */ /* Try to get a line of input */
count = io_gets(player->iop, cmd, size); count = io_gets(player->iop, cmd, size);
if (count >= 0) { if (count >= 0) {
/* got it */ /* got it */
if (strcmp(cmd, "ctld") == 0) if (strcmp(cmd, "ctld") == 0)
player->eof = 1; player->aborted = player->eof = 1;
if (strcmp(cmd, "aborted") == 0) if (strcmp(cmd, "aborted") == 0)
player->aborted = 1; player->aborted = 1;
journal_input(cmd); journal_input(cmd);
@ -86,10 +87,10 @@ recvclient(char *cmd, int size)
/* Await more input */ /* Await more input */
io_input(player->iop, IO_WAIT); io_input(player->iop, IO_WAIT);
if (io_error(player->iop) || io_eof(player->iop)) if (io_error(player->iop) || io_eof(player->iop))
player->eof = 1; player->aborted = player->eof = 1;
} }
if (player->aborted || player->eof) { if (player->aborted) {
player->recvfail++; player->recvfail++;
if (player->recvfail > 255) { if (player->recvfail > 255) {
/* /*