From b9b0710128f4460996c98f17066da4a895b6e124 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 14 Jul 2008 22:37:02 -0400 Subject: [PATCH] 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. (cherry picked from commit b3a7a8ee11595aac2bd27f76b3adf9e4c48bb0eb) --- include/player.h | 2 +- src/lib/player/player.c | 2 +- src/lib/player/recvclient.c | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/player.h b/include/player.h index 52edb3364..f6ab9b563 100644 --- a/include/player.h +++ b/include/player.h @@ -76,7 +76,7 @@ struct player { int simulation; /* e.g. budget command */ double dolcost; 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 recvfail; /* #recvclient() failures */ int curid; /* for pr, cur. line's id, -1 none */ diff --git a/src/lib/player/player.c b/src/lib/player/player.c index 0c8a865dd..f87db4da7 100644 --- a/src/lib/player/player.c +++ b/src/lib/player/player.c @@ -111,7 +111,7 @@ player_main(struct player *p) while (status()) { command(); - player->aborted = 0; + player->aborted = player->eof; empth_yield(); } /* #*# I put the following line in to prevent server crash -KHS */ diff --git a/src/lib/player/recvclient.c b/src/lib/player/recvclient.c index d209214a9..32decde7b 100644 --- a/src/lib/player/recvclient.c +++ b/src/lib/player/recvclient.c @@ -47,7 +47,8 @@ * 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 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 * -2. * Else return the length of the line. @@ -59,13 +60,13 @@ recvclient(char *cmd, int size) 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); @@ -85,10 +86,10 @@ recvclient(char *cmd, int size) /* Await more input */ io_input(player->iop, IO_WAIT); 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++; if (player->recvfail > 255) { /* -- 2.43.0