hangup revamp (trunk only)

The previous "hangup cleanup" didn't accomplish much (other than to
give everyone a good view of extern.h).  This one achieves more, and also
tries to fix the bug From a bug report:
> Buglet: Destroy old game -prompt can make game unrecoverable
>
> I haven't confirmed this myself, but few people playing on NAO
> have had the following happen:
> 1) play nethack
> 2) your network connection gets cut
> 3) reconnect, and get "Destroy old game" -prompt
> 4) your network connection gets cut, again, before you get to answer 'n'
> 5) game is not recoverable, because the level 0 file is gone.

     The reason for #5 is simple to explain; it's the expected behavior of
current hangup() routine (although that hasn't always called clearlocks();
I don't know why it was added).  The puzzle is why #2 left any lock files
around in the first place.  I suspect it was because SAFERHANGUP defers
until rhack(), and rhack() doesn't get called if the hero is immobilized or
in the midst of a counted operation.  I don't know how long a disconnected
process is allowed to run, but I don't think it's forever.  (Alternatively,
nethack might be attempting further terminal I/O and getting stuck on the
hung connection; this won't help much if that's the case.)

     This turns clearlocks() into a no-op during the period when the UNIX
port is asking the user to confirm whether to overwrite an existing game.
Also, this removes the duplication of code and function between hangup()
and end_of_input(), and it simplifies the check for whether hangups are
supported by adding new macro HANGUPHANDLING.  (I don't think global.h is
the best place to be defining that but I couldn't figure out where else
it would fit, other than repeating for individual xxxconf.h files.)  And
adds a couple more done_hup checks to try to cope with situations where
rhack() is being bypassed.  Lastly, having readchar() return EOF was
ignored for non-UNIX configs; now everybody gets ESC instead of letting
EOF be seen further inside the core.
This commit is contained in:
nethack.rankin
2007-01-16 04:53:20 +00:00
parent b6778e36cf
commit b01f1f804f

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)cmd.c 3.5 2006/07/08 */
/* SCCS Id: @(#)cmd.c 3.5 2007/01/12 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -8,6 +8,7 @@
struct cmd Cmd = { 0 }; /* flag.h */
#ifdef UNIX
/*
* Some systems may have getchar() return EOF for various reasons, and
* we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
@@ -15,6 +16,7 @@ struct cmd Cmd = { 0 }; /* flag.h */
#if defined(SYSV) || defined(DGUX) || defined(HPUX)
#define NR_OF_EOFS 20
#endif
#endif
#define CMD_TRAVEL (char)0x90
#define CMD_CLICKLOOK (char)0x8F
@@ -159,9 +161,6 @@ STATIC_PTR boolean NDECL(minimal_enlightenment);
STATIC_DCL void FDECL(enlght_line, (const char *,const char *,const char *,char *));
STATIC_DCL char *FDECL(enlght_combatinc, (const char *,int,int,char *));
#if defined(UNIX) || defined(SAFERHANGUP)
static void NDECL(end_of_input);
#endif
static const char* readchar_queue="";
static coord clicklook_cc;
@@ -2798,22 +2797,42 @@ parse()
return(in_line);
}
#if defined(UNIX) || defined(SAFERHANGUP)
static
#ifdef HANGUPHANDLING
/*ARGUSED*/
void
hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
int sig_unused;
{
# ifdef SAFERHANGUP
/* When using SAFERHANGUP, the done_hup flag it tested in rhack
and a couple of other places; actual hangup handling occurs then.
This is 'safer' because it disallows certain cheats and also
protects against losing objects in the process of being thrown,
but also potentially riskier because the disconnected program
must continue running longer before attempting a hangup save. */
program_state.done_hup++;
# else
end_of_input();
# endif /* ?SAFERHANGUP */
}
void
end_of_input()
{
#ifndef NOSAVEONHANGUP
# ifdef NOSAVEONHANGUP
program_state_something_worth_saving = 0;
# endif
# ifndef SAFERHANGUP
if (!program_state.done_hup++)
#endif
# endif
if (program_state.something_worth_saving) (void) dosave0();
#endif
exit_nhwindows((char *)0);
clearlocks();
terminate(EXIT_SUCCESS);
/*NOTREACHED*/ /* not necessarily true for vms... */
return;
}
#endif
#endif /* HANGUPHANDLING */
char
readchar()
@@ -2830,8 +2849,7 @@ readchar()
sym = Getchar();
#endif
#ifdef UNIX
# ifdef NR_OF_EOFS
#ifdef NR_OF_EOFS
if (sym == EOF) {
register int cnt = NR_OF_EOFS;
/*
@@ -2844,18 +2862,14 @@ readchar()
sym = Getchar();
} while (--cnt && sym == EOF);
}
# endif /* NR_OF_EOFS */
if (sym == EOF) {
# ifndef SAFERHANGUP
end_of_input();
# else
program_state.done_hup++;
sym = '\033';
# endif
}
#endif /* UNIX */
#endif /* NR_OF_EOFS */
if(sym == 0) {
if (sym == EOF) {
#ifdef HANGUPHANDLING
hangup(0); /* call end_of_input() or set program_state.done_hup */
#endif
sym = '\033';
} else if (sym == 0) {
/* click event */
readchar_queue = click_to_cmd(x, y, mod);
sym = *readchar_queue++;