]> granicus.if.org Git - nethack/commitdiff
hangup revamp (trunk only)
authornethack.rankin <nethack.rankin>
Tue, 16 Jan 2007 04:54:38 +0000 (04:54 +0000)
committernethack.rankin <nethack.rankin>
Tue, 16 Jan 2007 04:54:38 +0000 (04:54 +0000)
[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.

doc/fixes35.0
include/decl.h
include/extern.h
include/global.h
src/allmain.c
src/files.c
src/mon.c
src/save.c
sys/unix/unixmain.c
sys/unix/unixunix.c
sys/vms/vmsmain.c

index aeb5014c9b86eefd2774e2dbfc6cbde4692b05e6..582ff5513ddac74b42d64ed30a160e704d29884e 100644 (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
 -----------------------------------------
 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
index c4b4db3ed3e4217534ee86384619a1f209578869..3c8b85bb73c82f21596cec4f9d334db3e8d1a38d 100644 (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. */
 /* 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 */
index 6ceeba1d7a760c2dddd9d72b6f7d9d676b6453d4..8e5ccc499b0972658c170b2c6640dd5383803903 100644 (file)
@@ -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);
index 3c5b552424df7ff990226d731106dbdcc29eabb7..f98c53936948b9b68caa810fe9a2acfe8958f0e4 100644 (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. */
 /* 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
index 899ab7fb3784c5ea0e33401d4740cc73b728359b..de890cac6c2b32016abdfcdec6882e8fe65e6295 100644 (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. */
 /* 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();
index 4ab5aeeb61acbcf52986623bd6d38e6a99ccd2b6..6466b00876c5ab23797c5684e89ffaf56fa6fbe0 100644 (file)
@@ -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)
index f9ad7902a6ea9e48411251bb43864bf789205e48..d5103a16215928f407dbf5291d35c1ca3700494b 100644 (file)
--- 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;
 
index 4db45bf26e9877e8e44e23bbbf8ca4f745126685..3316db5ec594f11f4586ac2b1c9260fa7c302355 100644 (file)
@@ -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);
 }
 
index 11c340ef75dd21ff40094de3b7d264fb50185080..18f1fea18aa3921ead28b0a8d174f091e99d5bfd 100644 (file)
@@ -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() */
 
index 9f04b540b6b0bb8ce1ae3d2b6e90624ac3d47efa..e333e4ae16a40d654c68d7c408ceda6ca606594b 100644 (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. */
 /* 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
index 5a37966936bd9fe9f0654813a6ee2522c14c30ed..379464535914be95c0d1d8158fc69e2503caca99 100644 (file)
@@ -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 <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));
@@ -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"));