ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/utils.C
Revision: 1.101
Committed: Mon Oct 29 23:55:52 2012 UTC (11 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.100: +5 -5 lines
Log Message:
trailing space removal

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.68 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 root 1.101 *
4 root 1.100 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 root 1.101 *
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 root 1.101 *
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 root 1.101 *
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.101 *
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.99 void *
132     salloc_ (int n) throw (std::bad_alloc)
133 root 1.10 {
134 root 1.25 void *ptr = g_slice_alloc (n);
135 root 1.13
136 root 1.23 if (!ptr)
137 root 1.13 throw std::bad_alloc ();
138 root 1.4
139 root 1.74 slice_alloc += n;
140 root 1.23 return ptr;
141     }
142    
143 root 1.99 void *
144     salloc_ (int n, void *src) throw (std::bad_alloc)
145 root 1.23 {
146 root 1.25 void *ptr = salloc_ (n);
147 root 1.23
148 root 1.24 if (src)
149 root 1.25 memcpy (ptr, src, n);
150 root 1.24 else
151 root 1.25 memset (ptr, 0, n);
152 root 1.23
153     return ptr;
154 root 1.3 }
155 root 1.11
156 root 1.69 /******************************************************************************/
157    
158 root 1.72 #if DEBUG_SALLOC
159 root 1.69
160 root 1.70 #define MAGIC 0xa1b2c35543deadLL
161 root 1.69
162 root 1.99 void *
163     g_slice_alloc (unsigned long size)
164 root 1.69 {
165     unsigned long *p = (unsigned long *) (g_slice_alloc)(size + sizeof (unsigned long));
166     *p++ = size ^ MAGIC;
167     //fprintf (stderr, "g_slice_alloc %ld %p\n", size, p);//D
168     return (void *)p;
169     }
170    
171 root 1.99 void *
172     g_slice_alloc0 (unsigned long size)
173 root 1.69 {
174     return memset (g_slice_alloc (size), 0, size);
175     }
176    
177 root 1.99 void
178     g_slice_free1 (unsigned long size, void *ptr)
179 root 1.69 {
180 root 1.74 //fprintf (stderr, "g_slice_free %ld %p\n", size, ptr);//D
181 root 1.69 if (expect_true (ptr))
182     {
183     unsigned long *p = (unsigned long *)ptr;
184     unsigned long s = *--p ^ MAGIC;
185    
186 root 1.71 if (size != (unsigned long)(*p ^ MAGIC))
187 root 1.74 {
188     LOG (logBacktrace | llevError, "slice free size (%lx) doesn't match alloc size (%lx)\n", size, s);
189     abort ();
190     }
191 root 1.69
192     *p = MAGIC;
193    
194     (g_slice_free1)(s + sizeof (unsigned long), p);
195     }
196     }
197    
198     #endif
199    
200     /******************************************************************************/
201    
202 root 1.99 refcnt_buf::refcnt_buf (size_t size)
203     {
204     _alloc (size);
205     }
206    
207     refcnt_buf::refcnt_buf (void *data, size_t size)
208     {
209     _alloc (size);
210     memcpy (this->data, data, size);
211     }
212    
213     refcnt_buf::~refcnt_buf ()
214     {
215     dec ();
216     }
217    
218     refcnt_buf &
219     refcnt_buf::operator =(const refcnt_buf &src)
220     {
221     dec ();
222     data = src.data;
223     ++_refcnt ();
224     return *this;
225     }
226    
227     /******************************************************************************/
228    
229 root 1.86 int
230     assign (char *dst, const char *src, int maxsize)
231 root 1.11 {
232     if (!src)
233     src = "";
234    
235     int len = strlen (src);
236    
237 root 1.86 if (len >= maxsize)
238 root 1.11 {
239 root 1.86 if (maxsize <= 4)
240 root 1.11 {
241 root 1.86 memset (dst, '.', maxsize - 2);
242     dst [maxsize - 1] = 0;
243 root 1.11 }
244     else
245     {
246 root 1.86 memcpy (dst, src, maxsize - 4);
247     memcpy (dst + maxsize - 4, "...", 4);
248 root 1.11 }
249 root 1.86
250     len = maxsize;
251 root 1.11 }
252     else
253 root 1.86 memcpy (dst, src, ++len);
254    
255     return len;
256 root 1.11 }
257    
258 root 1.90 char *
259     vformat (const char *format, va_list ap)
260     {
261 root 1.96 static dynbuf_text bufs[8];
262     static int bufidx;
263    
264     dynbuf_text &buf = bufs [++bufidx & 7];
265    
266     buf.clear ();
267 root 1.90 buf.vprintf (format, ap);
268     return buf;
269     }
270    
271     char *
272 root 1.51 format (const char *format, ...)
273     {
274 root 1.65 va_list ap;
275     va_start (ap, format);
276 root 1.90 char *buf = vformat (format, ap);
277 root 1.65 va_end (ap);
278    
279     return buf;
280 root 1.51 }
281    
282 root 1.99 tstamp
283     now ()
284 root 1.23 {
285     struct timeval tv;
286    
287     gettimeofday (&tv, 0);
288     return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
289     }
290 root 1.17
291 root 1.32 int
292     similar_direction (int a, int b)
293     {
294     if (!a || !b)
295     return 0;
296    
297     int diff = (b - a) & 7;
298     return diff <= 1 || diff >= 7;
299     }
300    
301 root 1.48 /* crc32 0xdebb20e3 table and supplementary functions. */
302     extern const uint32_t crc_32_tab[256] =
303     {
304     0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
305     0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
306     0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
307     0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
308     0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
309     0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
310     0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
311     0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
312     0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
313     0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
314     0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
315     0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
316     0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
317     0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
318     0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
319     0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
320     0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
321     0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
322     0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
323     0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
324     0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
325     0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
326     0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
327     0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
328     0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
329     0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
330     0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
331     0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
332     0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
333     0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
334     0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
335     0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
336     0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
337     0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
338     0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
339     0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
340     0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
341     0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
342     0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
343     0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
344     0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
345     0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
346     0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
347     0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
348     0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
349     0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
350     0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
351     0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
352     0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
353     0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
354     0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
355     0x2d02ef8dL
356     };
357    
358 root 1.99 void
359     thread::start (void *(*start_routine)(void *), void *arg)
360 root 1.73 {
361 root 1.75 pthread_attr_t attr;
362    
363     pthread_attr_init (&attr);
364     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
365     pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < sizeof (long) * 4096
366     ? sizeof (long) * 4096 : PTHREAD_STACK_MIN);
367     #ifdef PTHREAD_SCOPE_PROCESS
368     pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
369     #endif
370    
371 root 1.73 sigset_t fullsigset, oldsigset;
372     sigfillset (&fullsigset);
373    
374     pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
375    
376 root 1.75 if (pthread_create (&id, &attr, start_routine, arg))
377 root 1.73 cleanup ("unable to create a new thread");
378    
379     pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
380     }
381 root 1.75