ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/utils.C
Revision: 1.97
Committed: Fri Jul 2 02:00:47 2010 UTC (13 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.96: +0 -42 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.68 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 pippijn 1.39 *
4 root 1.95 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 pippijn 1.39 *
6 root 1.89 * Deliantra is free software: you can redistribute it and/or modify it under
7     * the terms of the Affero GNU General Public License as published by the
8     * Free Software Foundation, either version 3 of the License, or (at your
9     * option) any later version.
10 pippijn 1.39 *
11 root 1.60 * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15 pippijn 1.39 *
16 root 1.89 * You should have received a copy of the Affero GNU General Public License
17     * and the GNU General Public License along with this program. If not, see
18     * <http://www.gnu.org/licenses/>.
19 root 1.57 *
20 root 1.68 * The authors can be reached via e-mail to <support@deliantra.net>
21 pippijn 1.39 */
22 elmex 1.1
23     /*
24 root 1.92 * General convenience functions for deliantra.
25 elmex 1.1 */
26    
27 root 1.37 #include <cstdlib>
28     #include <sys/types.h>
29     #include <unistd.h>
30     #include <sys/time.h>
31     #include <time.h>
32     #include <signal.h>
33    
34 elmex 1.1 #include <global.h>
35     #include <material.h>
36 sf-marcmagus 1.87 #include <object.h>
37 elmex 1.1
38 root 1.79 #include <sys/time.h>
39     #include <sys/resource.h>
40    
41 root 1.4 #include <glib.h>
42    
43 root 1.63 refcnt_base::refcnt_t refcnt_dummy;
44 root 1.74 ssize_t slice_alloc;
45 root 1.40
46 root 1.94 #if !GCC_VERSION(3,4)
47     int least_significant_bit (uint32_t x)
48     {
49     x &= -x; // this isolates the lowest bit
50    
51     int r = 0;
52    
53     if (x & 0xaaaaaaaa) r += 1;
54     if (x & 0xcccccccc) r += 2;
55     if (x & 0xf0f0f0f0) r += 4;
56     if (x & 0xff00ff00) r += 8;
57     if (x & 0xffff0000) r += 16;
58    
59     return r;
60     }
61     #endif
62    
63 sf-marcmagus 1.87 /******************************************************************************/
64    
65     /* Checks a player-provided string which will become the msg property of
66     * an object for dangerous input.
67     */
68     bool
69     msg_is_safe (const char *msg)
70     {
71     bool safe = true;
72    
73     /* Trying to cheat by getting data into the object */
74 root 1.88 if (!strncmp (msg, "endmsg", sizeof ("endmsg") - 1)
75     || strstr (msg, "\nendmsg"))
76 sf-marcmagus 1.87 safe = false;
77    
78     /* Trying to make the object talk, and potentially access arbitrary code */
79     if (object::msg_has_dialogue (msg))
80     safe = false;
81    
82     return safe;
83     }
84    
85 root 1.14 /////////////////////////////////////////////////////////////////////////////
86    
87 root 1.37 void
88     fork_abort (const char *msg)
89     {
90     if (!fork ())
91     {
92 root 1.80 signal (SIGINT , SIG_IGN);
93     signal (SIGTERM, SIG_IGN);
94     signal (SIGABRT, SIG_IGN);
95 root 1.79
96 root 1.81 signal (SIGSEGV, SIG_DFL);
97     signal (SIGBUS , SIG_DFL);
98     signal (SIGILL , SIG_DFL);
99     signal (SIGTRAP, SIG_DFL);
100    
101 root 1.52 // try to put corefiles into a subdirectory, if existing, to allow
102     // an administrator to reduce the I/O load.
103     chdir ("cores");
104 root 1.79
105     // try to detach us from as many external dependencies as possible
106     // as coredumping can take time by closing all fd's.
107     {
108     struct rlimit lim;
109    
110     if (getrlimit (RLIMIT_NOFILE, &lim))
111     lim.rlim_cur = 1024;
112    
113     for (int i = 0; i < lim.rlim_cur; ++i)
114     close (i);
115     }
116    
117 root 1.81 {
118     sigset_t empty;
119     sigemptyset (&empty);
120     sigprocmask (SIG_SETMASK, &empty, 0);
121     }
122    
123     // try to coredump with SIGTRAP
124     kill (getpid (), SIGTRAP);
125 root 1.37 abort ();
126     }
127    
128 root 1.38 LOG (llevError, "fork abort: %s\n", msg);
129 root 1.37 }
130 root 1.38
131 root 1.25 void *salloc_ (int n) throw (std::bad_alloc)
132 root 1.10 {
133 root 1.25 void *ptr = g_slice_alloc (n);
134 root 1.13
135 root 1.23 if (!ptr)
136 root 1.13 throw std::bad_alloc ();
137 root 1.4
138 root 1.74 slice_alloc += n;
139 root 1.23 return ptr;
140     }
141    
142 root 1.25 void *salloc_ (int n, void *src) throw (std::bad_alloc)
143 root 1.23 {
144 root 1.25 void *ptr = salloc_ (n);
145 root 1.23
146 root 1.24 if (src)
147 root 1.25 memcpy (ptr, src, n);
148 root 1.24 else
149 root 1.25 memset (ptr, 0, n);
150 root 1.23
151     return ptr;
152 root 1.3 }
153 root 1.11
154 root 1.69 /******************************************************************************/
155    
156 root 1.72 #if DEBUG_SALLOC
157 root 1.69
158 root 1.70 #define MAGIC 0xa1b2c35543deadLL
159 root 1.69
160     void *g_slice_alloc (unsigned long size)
161     {
162     unsigned long *p = (unsigned long *) (g_slice_alloc)(size + sizeof (unsigned long));
163     *p++ = size ^ MAGIC;
164     //fprintf (stderr, "g_slice_alloc %ld %p\n", size, p);//D
165     return (void *)p;
166     }
167    
168     void *g_slice_alloc0 (unsigned long size)
169     {
170     return memset (g_slice_alloc (size), 0, size);
171     }
172    
173     void g_slice_free1 (unsigned long size, void *ptr)
174     {
175 root 1.74 //fprintf (stderr, "g_slice_free %ld %p\n", size, ptr);//D
176 root 1.69 if (expect_true (ptr))
177     {
178     unsigned long *p = (unsigned long *)ptr;
179     unsigned long s = *--p ^ MAGIC;
180    
181 root 1.71 if (size != (unsigned long)(*p ^ MAGIC))
182 root 1.74 {
183     LOG (logBacktrace | llevError, "slice free size (%lx) doesn't match alloc size (%lx)\n", size, s);
184     abort ();
185     }
186 root 1.69
187     *p = MAGIC;
188    
189     (g_slice_free1)(s + sizeof (unsigned long), p);
190     }
191     }
192    
193     #endif
194    
195     /******************************************************************************/
196    
197 root 1.86 int
198     assign (char *dst, const char *src, int maxsize)
199 root 1.11 {
200     if (!src)
201     src = "";
202    
203     int len = strlen (src);
204    
205 root 1.86 if (len >= maxsize)
206 root 1.11 {
207 root 1.86 if (maxsize <= 4)
208 root 1.11 {
209 root 1.86 memset (dst, '.', maxsize - 2);
210     dst [maxsize - 1] = 0;
211 root 1.11 }
212     else
213     {
214 root 1.86 memcpy (dst, src, maxsize - 4);
215     memcpy (dst + maxsize - 4, "...", 4);
216 root 1.11 }
217 root 1.86
218     len = maxsize;
219 root 1.11 }
220     else
221 root 1.86 memcpy (dst, src, ++len);
222    
223     return len;
224 root 1.11 }
225    
226 root 1.90 char *
227     vformat (const char *format, va_list ap)
228     {
229 root 1.96 static dynbuf_text bufs[8];
230     static int bufidx;
231    
232     dynbuf_text &buf = bufs [++bufidx & 7];
233    
234     buf.clear ();
235 root 1.90 buf.vprintf (format, ap);
236     return buf;
237     }
238    
239     char *
240 root 1.51 format (const char *format, ...)
241     {
242 root 1.65 va_list ap;
243     va_start (ap, format);
244 root 1.90 char *buf = vformat (format, ap);
245 root 1.65 va_end (ap);
246    
247     return buf;
248 root 1.51 }
249    
250 root 1.23 tstamp now ()
251     {
252     struct timeval tv;
253    
254     gettimeofday (&tv, 0);
255     return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
256     }
257 root 1.17
258 root 1.32 int
259     similar_direction (int a, int b)
260     {
261     if (!a || !b)
262     return 0;
263    
264     int diff = (b - a) & 7;
265     return diff <= 1 || diff >= 7;
266     }
267    
268 root 1.48 /* crc32 0xdebb20e3 table and supplementary functions. */
269     extern const uint32_t crc_32_tab[256] =
270     {
271     0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
272     0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
273     0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
274     0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
275     0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
276     0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
277     0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
278     0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
279     0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
280     0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
281     0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
282     0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
283     0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
284     0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
285     0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
286     0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
287     0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
288     0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
289     0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
290     0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
291     0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
292     0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
293     0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
294     0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
295     0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
296     0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
297     0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
298     0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
299     0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
300     0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
301     0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
302     0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
303     0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
304     0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
305     0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
306     0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
307     0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
308     0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
309     0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
310     0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
311     0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
312     0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
313     0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
314     0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
315     0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
316     0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
317     0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
318     0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
319     0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
320     0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
321     0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
322     0x2d02ef8dL
323     };
324    
325 root 1.73 void thread::start (void *(*start_routine)(void *), void *arg)
326     {
327 root 1.75 pthread_attr_t attr;
328    
329     pthread_attr_init (&attr);
330     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
331     pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < sizeof (long) * 4096
332     ? sizeof (long) * 4096 : PTHREAD_STACK_MIN);
333     #ifdef PTHREAD_SCOPE_PROCESS
334     pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
335     #endif
336    
337 root 1.73 sigset_t fullsigset, oldsigset;
338     sigfillset (&fullsigset);
339    
340     pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
341    
342 root 1.75 if (pthread_create (&id, &attr, start_routine, arg))
343 root 1.73 cleanup ("unable to create a new thread");
344    
345     pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
346     }
347 root 1.75