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
-/* 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. */
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 */
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);
/* ### 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);
-/* 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. */
# 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
-/* 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. */
context.move = 0;
for(;;) {
+#ifdef SAFERHANGUP
+ if (program_state.done_hup) end_of_input();
+#endif
get_nh_event();
#ifdef POSITIONBAR
do_positionbar();
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)
-/* 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. */
*/
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;
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);
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()
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 */
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);
}
* 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 */
getlock();
}
#endif /* WIZARD */
+ program_state.preserve_locks = 0; /* after getlock() */
dlb_init(); /* must be before newgame() */
-/* 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. */
{
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
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 <signal.h>.
- */
- 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));
#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"));