hangup revamp (trunk only)

[See cvs log for src/cmd.c for more complete description.]

     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:54:38 +00:00
parent b01f1f804f
commit 151dcad8fa
11 changed files with 53 additions and 49 deletions

View File

@@ -189,6 +189,8 @@ can't drop part of a stack of N weapons welded to hero's hand
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
----------------------------------------- -----------------------------------------
unix: new -wwindowtype option unix: new -wwindowtype option
unix: don't clobber old level files if 2nd hangup/disconnect occurs while
reconnected user is responding to the "destroy old game?" prompt
win32gui: better handling of "more" prompt for messages that would have scrolled win32gui: better handling of "more" prompt for messages that would have scrolled
off the window off the window
win32gui: set correct checkmark on "Lock Windows" menu item on startup win32gui: set correct checkmark on "Lock Windows" menu item on startup

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)decl.h 3.5 2005/11/19 */ /* SCCS Id: @(#)decl.h 3.5 2007/01/12 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -145,9 +145,10 @@ E struct linfo level_info[MAXLINFO];
E NEARDATA struct sinfo { E NEARDATA struct sinfo {
int gameover; /* self explanatory? */ int gameover; /* self explanatory? */
int stopprint; /* inhibit further end of game disclosure */ int stopprint; /* inhibit further end of game disclosure */
#if defined(UNIX) || defined(VMS) || defined (__EMX__) || defined(WIN32) #ifdef HANGUPHANDLING
volatile int done_hup; /* SIGHUP or moral equivalent received volatile int done_hup; /* SIGHUP or moral equivalent received
* -- no more screen output */ * -- no more screen output */
int preserve_locks; /* don't remove level files prior to exit */
#endif #endif
int something_worth_saving; /* in case of panic */ int something_worth_saving; /* in case of panic */
int panicking; /* `panic' is in progress */ int panicking; /* `panic' is in progress */

View File

@@ -197,6 +197,10 @@ E void NDECL(confdir);
E int FDECL(isok, (int,int)); E int FDECL(isok, (int,int));
E int FDECL(get_adjacent_loc, (const char *, const char *, XCHAR_P, XCHAR_P, coord *)); E int FDECL(get_adjacent_loc, (const char *, const char *, XCHAR_P, XCHAR_P, coord *));
E const char *FDECL(click_to_cmd, (int,int,int)); E const char *FDECL(click_to_cmd, (int,int,int));
#ifdef HANGUPHANDLING
E void FDECL(hangup, (int));
E void NDECL(end_of_input);
#endif
E char NDECL(readchar); E char NDECL(readchar);
#ifdef WIZARD #ifdef WIZARD
E void NDECL(sanity_check); E void NDECL(sanity_check);
@@ -1937,9 +1941,6 @@ E void NDECL(rumor_check);
/* ### save.c ### */ /* ### save.c ### */
E int NDECL(dosave); E int NDECL(dosave);
#if defined(UNIX) || defined(VMS) || defined(__EMX__) || defined(WIN32)
E void FDECL(hangup, (int));
#endif
E int NDECL(dosave0); E int NDECL(dosave0);
#ifdef INSURANCE #ifdef INSURANCE
E void NDECL(savestateinlock); E void NDECL(savestateinlock);

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)global.h 3.5 2006/10/17 */ /* SCCS Id: @(#)global.h 3.5 2007/01/12 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -269,6 +269,13 @@ typedef char nhptext;
# endif # endif
#endif #endif
#if defined(UNIX) || defined(VMS) || defined(__EMX__) || defined(WIN32)
# define HANGUPHANDLING
#endif
#if defined(SAFERHANGUP) && !defined(HANGUPHANDLING)
# undef SAFERHANGUP
#endif
#define Sprintf (void) sprintf #define Sprintf (void) sprintf
#define Strcat (void) strcat #define Strcat (void) strcat

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)allmain.c 3.5 2006/11/27 */ /* SCCS Id: @(#)allmain.c 3.5 2007/01/12 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -72,6 +72,9 @@ boolean resuming;
context.move = 0; context.move = 0;
for(;;) { for(;;) {
#ifdef SAFERHANGUP
if (program_state.done_hup) end_of_input();
#endif
get_nh_event(); get_nh_event();
#ifdef POSITIONBAR #ifdef POSITIONBAR
do_positionbar(); do_positionbar();

View File

@@ -556,20 +556,28 @@ int lev;
void void
clearlocks() clearlocks()
{ {
#ifdef HANGUPHANDLING
if (program_state.preserve_locks) return;
#endif
#if !defined(PC_LOCKING) && defined(MFLOPPY) && !defined(AMIGA) #if !defined(PC_LOCKING) && defined(MFLOPPY) && !defined(AMIGA)
eraseall(levels, alllevels); eraseall(levels, alllevels);
if (ramdisk) if (ramdisk)
eraseall(permbones, alllevels); eraseall(permbones, alllevels);
#else #else
{
register int x; register int x;
# ifndef NO_SIGNAL
(void) signal(SIGINT, SIG_IGN);
# endif
# if defined(UNIX) || defined(VMS) # if defined(UNIX) || defined(VMS)
sethanguphandler((void FDECL((*),(int)))SIG_IGN); sethanguphandler((void FDECL((*),(int)))SIG_IGN);
# endif # endif
/* can't access maxledgerno() before dungeons are created -dlc */ /* can't access maxledgerno() before dungeons are created -dlc */
for (x = (n_dgns ? maxledgerno() : 0); x >= 0; x--) for (x = (n_dgns ? maxledgerno() : 0); x >= 0; x--)
delete_levelfile(x); /* not all levels need be present */ delete_levelfile(x); /* not all levels need be present */
#endif }
#endif /* ?PC_LOCKING,&c */
} }
#if defined(SELECTSAVED) #if defined(SELECTSAVED)

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mon.c 3.5 2006/10/20 */ /* SCCS Id: @(#)mon.c 3.5 2007/01/12 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -581,6 +581,12 @@ movemon()
*/ */
for(mtmp = fmon; mtmp; mtmp = nmtmp) { for(mtmp = fmon; mtmp; mtmp = nmtmp) {
#ifdef SAFERHANGUP
if (program_state.done_hup) {
somebody_can_move = FALSE;
break;
}
#endif
nmtmp = mtmp->nmon; nmtmp = mtmp->nmon;
if (DEADMONSTER(mtmp)) continue; if (DEADMONSTER(mtmp)) continue;

View File

@@ -119,7 +119,6 @@ dosave()
program_state.done_hup = 0; program_state.done_hup = 0;
#endif #endif
if(dosave0()) { if(dosave0()) {
program_state.something_worth_saving = 0;
u.uhp = -1; /* universal game's over indicator */ u.uhp = -1; /* universal game's over indicator */
/* make sure they see the Saving message */ /* make sure they see the Saving message */
display_nhwindow(WIN_MESSAGE, TRUE); display_nhwindow(WIN_MESSAGE, TRUE);
@@ -130,35 +129,6 @@ dosave()
return 0; return 0;
} }
#if defined(UNIX) || defined(VMS) || defined (__EMX__) || defined(WIN32)
/*ARGSUSED*/
void
hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
int sig_unused;
{
# ifdef NOSAVEONHANGUP
(void) signal(SIGINT, SIG_IGN);
clearlocks();
terminate(EXIT_FAILURE);
# else /* SAVEONHANGUP */
if (!program_state.done_hup++) {
# ifndef SAFERHANGUP
/* When using SAFERHANGUP, the done_hup flag it tested in rhack
* and actual hangup behavior occurs then. This is 'safer'
* because it disallows certain cheats and also protects
* against losing objects in the process of being thrown. */
if (program_state.something_worth_saving)
(void) dosave0();
clearlocks();
terminate(EXIT_FAILURE);
# endif /* !SAFERHANGUP */
}
# endif /* !NOSAVEONHANGUP */
}
#endif
/* returns 1 if save successful */ /* returns 1 if save successful */
int int
dosave0() dosave0()
@@ -169,7 +139,7 @@ dosave0()
d_level uz_save; d_level uz_save;
char whynot[BUFSZ]; char whynot[BUFSZ];
if (!SAVEF[0]) if (!program_state.something_worth_saving || !SAVEF[0])
return 0; return 0;
fq_save = fqname(SAVEF, SAVEPREFIX, 1); /* level files take 0 */ fq_save = fqname(SAVEF, SAVEPREFIX, 1); /* level files take 0 */
@@ -316,6 +286,8 @@ dosave0()
delete_levelfile(ledger_no(&u.uz)); delete_levelfile(ledger_no(&u.uz));
delete_levelfile(0); delete_levelfile(0);
nh_compress(fq_save); nh_compress(fq_save);
/* this should probably come sooner... */
program_state.something_worth_saving = 0;
return(1); return(1);
} }

View File

@@ -157,6 +157,7 @@ char *argv[];
* It seems you really want to play. * It seems you really want to play.
*/ */
u.uhp = 1; /* prevent RIP on early quits */ u.uhp = 1; /* prevent RIP on early quits */
program_state.preserve_locks = 1;
sethanguphandler((SIG_RET_TYPE)hangup); sethanguphandler((SIG_RET_TYPE)hangup);
process_options(argc, argv); /* command line options */ process_options(argc, argv); /* command line options */
@@ -212,6 +213,7 @@ char *argv[];
getlock(); getlock();
} }
#endif /* WIZARD */ #endif /* WIZARD */
program_state.preserve_locks = 0; /* after getlock() */
dlb_init(); /* must be before newgame() */ dlb_init(); /* must be before newgame() */

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)unixunix.c 3.5 1994/11/07 */ /* SCCS Id: @(#)unixunix.c 3.5 2007/01/12 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -71,6 +71,7 @@ eraseoldlocks()
{ {
register int i; register int i;
program_state.preserve_locks = 0; /* not required but shows intent */
/* cannot use maxledgerno() here, because we need to find a lock name /* cannot use maxledgerno() here, because we need to find a lock name
* before starting everything (including the dungeon initialization * before starting everything (including the dungeon initialization
* that sets astral_level, needed for maxledgerno()) up * that sets astral_level, needed for maxledgerno()) up

View File

@@ -379,11 +379,7 @@ whoami()
static void static void
byebye() byebye()
{ {
/* Different versions of both VAX C and GNU C use different return types void FDECL((*hup), (int));
for signal functions. Return type 'int' along with the explicit casts
below satisfy the most combinations of compiler vs <signal.h>.
*/
int (*hup)();
#ifdef SHELL #ifdef SHELL
extern unsigned long dosh_pid, mail_pid; extern unsigned long dosh_pid, mail_pid;
extern unsigned long FDECL(sys$delprc,(unsigned long *,const genericptr_t)); extern unsigned long FDECL(sys$delprc,(unsigned long *,const genericptr_t));
@@ -394,10 +390,15 @@ byebye()
#endif #endif
/* SIGHUP doesn't seem to do anything on VMS, so we fudge it here... */ /* SIGHUP doesn't seem to do anything on VMS, so we fudge it here... */
hup = (int(*)()) signal(SIGHUP, SIG_IGN); hup = (void FDECL((*),(int))) signal(SIGHUP, SIG_IGN);
if (!program_state.exiting++ && if (!program_state.exiting++ &&
hup != (int(*)()) SIG_DFL && hup != (int(*)()) SIG_IGN) hup != (void FDECL((*),(int))) SIG_DFL &&
(void) (*hup)(); hup != (void FDECL((*),(int))) SIG_IGN) {
(*hup)(SIGHUP);
#ifdef SAFERHANGUP
end_of_input();
#endif
}
#ifdef CHDIR #ifdef CHDIR
(void) chdir(getenv("PATH")); (void) chdir(getenv("PATH"));