diff --git a/doc/fixes35.0 b/doc/fixes35.0 index aeb5014c9..582ff5513 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -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 ----------------------------------------- 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 off the window win32gui: set correct checkmark on "Lock Windows" menu item on startup diff --git a/include/decl.h b/include/decl.h index c4b4db3ed..3c8b85bb7 100644 --- a/include/decl.h +++ b/include/decl.h @@ -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. */ /* NetHack may be freely redistributed. See license for details. */ @@ -145,9 +145,10 @@ E struct linfo level_info[MAXLINFO]; E NEARDATA struct sinfo { int gameover; /* self explanatory? */ 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 * -- no more screen output */ + int preserve_locks; /* don't remove level files prior to exit */ #endif int something_worth_saving; /* in case of panic */ int panicking; /* `panic' is in progress */ diff --git a/include/extern.h b/include/extern.h index 6ceeba1d7..8e5ccc499 100644 --- a/include/extern.h +++ b/include/extern.h @@ -197,6 +197,10 @@ E void NDECL(confdir); E int FDECL(isok, (int,int)); 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)); +#ifdef HANGUPHANDLING +E void FDECL(hangup, (int)); +E void NDECL(end_of_input); +#endif E char NDECL(readchar); #ifdef WIZARD E void NDECL(sanity_check); @@ -1937,9 +1941,6 @@ E void NDECL(rumor_check); /* ### save.c ### */ E int NDECL(dosave); -#if defined(UNIX) || defined(VMS) || defined(__EMX__) || defined(WIN32) -E void FDECL(hangup, (int)); -#endif E int NDECL(dosave0); #ifdef INSURANCE E void NDECL(savestateinlock); diff --git a/include/global.h b/include/global.h index 3c5b55242..f98c53936 100644 --- a/include/global.h +++ b/include/global.h @@ -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. */ /* NetHack may be freely redistributed. See license for details. */ @@ -269,6 +269,13 @@ typedef char nhptext; # 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 Strcat (void) strcat diff --git a/src/allmain.c b/src/allmain.c index 899ab7fb3..de890cac6 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -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. */ /* NetHack may be freely redistributed. See license for details. */ @@ -72,6 +72,9 @@ boolean resuming; context.move = 0; for(;;) { +#ifdef SAFERHANGUP + if (program_state.done_hup) end_of_input(); +#endif get_nh_event(); #ifdef POSITIONBAR do_positionbar(); diff --git a/src/files.c b/src/files.c index 4ab5aeeb6..6466b0087 100644 --- a/src/files.c +++ b/src/files.c @@ -556,20 +556,28 @@ int lev; void clearlocks() { +#ifdef HANGUPHANDLING + if (program_state.preserve_locks) return; +#endif #if !defined(PC_LOCKING) && defined(MFLOPPY) && !defined(AMIGA) eraseall(levels, alllevels); if (ramdisk) eraseall(permbones, alllevels); #else + { register int x; +# ifndef NO_SIGNAL + (void) signal(SIGINT, SIG_IGN); +# endif # if defined(UNIX) || defined(VMS) sethanguphandler((void FDECL((*),(int)))SIG_IGN); # endif /* can't access maxledgerno() before dungeons are created -dlc */ for (x = (n_dgns ? maxledgerno() : 0); x >= 0; x--) delete_levelfile(x); /* not all levels need be present */ -#endif + } +#endif /* ?PC_LOCKING,&c */ } #if defined(SELECTSAVED) diff --git a/src/mon.c b/src/mon.c index f9ad7902a..d5103a162 100644 --- a/src/mon.c +++ b/src/mon.c @@ -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. */ /* NetHack may be freely redistributed. See license for details. */ @@ -581,6 +581,12 @@ movemon() */ for(mtmp = fmon; mtmp; mtmp = nmtmp) { +#ifdef SAFERHANGUP + if (program_state.done_hup) { + somebody_can_move = FALSE; + break; + } +#endif nmtmp = mtmp->nmon; if (DEADMONSTER(mtmp)) continue; diff --git a/src/save.c b/src/save.c index 4db45bf26..3316db5ec 100644 --- a/src/save.c +++ b/src/save.c @@ -119,7 +119,6 @@ dosave() program_state.done_hup = 0; #endif if(dosave0()) { - program_state.something_worth_saving = 0; u.uhp = -1; /* universal game's over indicator */ /* make sure they see the Saving message */ display_nhwindow(WIN_MESSAGE, TRUE); @@ -130,35 +129,6 @@ dosave() 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 */ int dosave0() @@ -169,7 +139,7 @@ dosave0() d_level uz_save; char whynot[BUFSZ]; - if (!SAVEF[0]) + if (!program_state.something_worth_saving || !SAVEF[0]) return 0; fq_save = fqname(SAVEF, SAVEPREFIX, 1); /* level files take 0 */ @@ -316,6 +286,8 @@ dosave0() delete_levelfile(ledger_no(&u.uz)); delete_levelfile(0); nh_compress(fq_save); + /* this should probably come sooner... */ + program_state.something_worth_saving = 0; return(1); } diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 11c340ef7..18f1fea18 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -157,6 +157,7 @@ char *argv[]; * It seems you really want to play. */ u.uhp = 1; /* prevent RIP on early quits */ + program_state.preserve_locks = 1; sethanguphandler((SIG_RET_TYPE)hangup); process_options(argc, argv); /* command line options */ @@ -212,6 +213,7 @@ char *argv[]; getlock(); } #endif /* WIZARD */ + program_state.preserve_locks = 0; /* after getlock() */ dlb_init(); /* must be before newgame() */ diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 9f04b540b..e333e4ae1 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -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. */ /* NetHack may be freely redistributed. See license for details. */ @@ -71,6 +71,7 @@ eraseoldlocks() { 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 * before starting everything (including the dungeon initialization * that sets astral_level, needed for maxledgerno()) up diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index 5a3796693..379464535 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -379,11 +379,7 @@ whoami() static void byebye() { - /* Different versions of both VAX C and GNU C use different return types - for signal functions. Return type 'int' along with the explicit casts - below satisfy the most combinations of compiler vs . - */ - int (*hup)(); + void FDECL((*hup), (int)); #ifdef SHELL extern unsigned long dosh_pid, mail_pid; extern unsigned long FDECL(sys$delprc,(unsigned long *,const genericptr_t)); @@ -394,10 +390,15 @@ byebye() #endif /* 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++ && - hup != (int(*)()) SIG_DFL && hup != (int(*)()) SIG_IGN) - (void) (*hup)(); + hup != (void FDECL((*),(int))) SIG_DFL && + hup != (void FDECL((*),(int))) SIG_IGN) { + (*hup)(SIGHUP); +#ifdef SAFERHANGUP + end_of_input(); +#endif + } #ifdef CHDIR (void) chdir(getenv("PATH"));