--- deliantra/server/common/utils.C 2008/05/04 14:12:37 1.77 +++ deliantra/server/common/utils.C 2008/09/10 21:29:39 1.81 @@ -35,6 +35,9 @@ #include #include +#include +#include + #include refcnt_base::refcnt_t refcnt_dummy; @@ -95,13 +98,9 @@ int random_roll (int r_min, int r_max, const object *op, int goodbad) { - int base = r_max - r_min > 1 ? 20 : 50; /* d2 and d3 are corner cases */ + r_max = max (r_min, r_max); - if (r_max < r_min) - { - LOG (llevError | logBacktrace, "Calling random_roll with min=%d max=%d\n", r_min, r_max); - return r_min; - } + int base = r_max - r_min > 1 ? 20 : 50; /* d2 and d3 are corner cases */ if (op->type == PLAYER) { @@ -121,17 +120,11 @@ * for exp loss calculations for players changing religions. */ sint64 -random_roll64 (sint64 min, sint64 max, const object *op, int goodbad) +random_roll64 (sint64 r_min, sint64 r_max, const object *op, int goodbad) { - sint64 omin = min; - sint64 diff = max - min + 1; - int base = diff > 2 ? 20 : 50; /* d2 and d3 are corner cases */ - - if (diff < 0) - { - LOG (llevError | logBacktrace, "Calling random_roll64 with min=%" PRId64 " max=%" PRId64 "\n", min, max); - return (min); /* avoids a float exception */ - } + sint64 omin = r_min; + sint64 range = max (0, r_max - r_min + 1); + int base = range > 2 ? 20 : 50; /* d2 and d3 are corner cases */ /* * Make a call to get two 32 bit unsigned random numbers, and just to @@ -140,24 +133,24 @@ sint64 ran = (sint64) rndm.next () ^ ((sint64) rndm.next () << 31); if (op->type != PLAYER) - return ((ran % diff) + min); + return ((ran % range) + r_min); int luck = op->stats.luck; - if (rndm (base) < MIN (10, abs (luck))) + if (rndm (base) < min (10, abs (luck))) { /* we have a winner */ ((luck > 0) ? (luck = 1) : (luck = -1)); - diff -= luck; - if (diff < 1) + range -= luck; + if (range < 1) return (omin); /*check again */ - ((goodbad) ? (min += luck) : (diff)); + ((goodbad) ? (r_min += luck) : (range)); - return (MAX (omin, MIN (max, (ran % diff) + min))); + return (max (omin, min (r_max, (ran % range) + r_min))); } - return ran % diff + min; + return ran % range + r_min; } /* @@ -458,10 +451,41 @@ { if (!fork ()) { - signal (SIGABRT, SIG_DFL); + fprintf (stderr, "background fork_abort in progress, remove me when debugged.\n");//D + + signal (SIGINT , SIG_IGN); + signal (SIGTERM, SIG_IGN); + signal (SIGABRT, SIG_IGN); + + signal (SIGSEGV, SIG_DFL); + signal (SIGBUS , SIG_DFL); + signal (SIGILL , SIG_DFL); + signal (SIGTRAP, SIG_DFL); + // try to put corefiles into a subdirectory, if existing, to allow // an administrator to reduce the I/O load. chdir ("cores"); + + // try to detach us from as many external dependencies as possible + // as coredumping can take time by closing all fd's. + { + struct rlimit lim; + + if (getrlimit (RLIMIT_NOFILE, &lim)) + lim.rlim_cur = 1024; + + for (int i = 0; i < lim.rlim_cur; ++i) + close (i); + } + + { + sigset_t empty; + sigemptyset (&empty); + sigprocmask (SIG_SETMASK, &empty, 0); + } + + // try to coredump with SIGTRAP + kill (getpid (), SIGTRAP); abort (); }