ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/utils.C
Revision: 1.107
Committed: Sat Nov 17 23:33:17 2018 UTC (5 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.106: +0 -17 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 root 1.101 *
4 root 1.104 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 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 sf-marcmagus 1.87 /******************************************************************************/
47    
48     /* Checks a player-provided string which will become the msg property of
49     * an object for dangerous input.
50     */
51 root 1.105 bool
52 sf-marcmagus 1.87 msg_is_safe (const char *msg)
53     {
54     bool safe = true;
55    
56     /* Trying to cheat by getting data into the object */
57 root 1.88 if (!strncmp (msg, "endmsg", sizeof ("endmsg") - 1)
58     || strstr (msg, "\nendmsg"))
59 sf-marcmagus 1.87 safe = false;
60    
61     /* Trying to make the object talk, and potentially access arbitrary code */
62     if (object::msg_has_dialogue (msg))
63     safe = false;
64    
65     return safe;
66     }
67    
68 root 1.14 /////////////////////////////////////////////////////////////////////////////
69    
70 root 1.37 void
71     fork_abort (const char *msg)
72     {
73     if (!fork ())
74     {
75 root 1.80 signal (SIGINT , SIG_IGN);
76     signal (SIGTERM, SIG_IGN);
77     signal (SIGABRT, SIG_IGN);
78 root 1.79
79 root 1.81 signal (SIGSEGV, SIG_DFL);
80 root 1.103 signal (SIGFPE , SIG_DFL);
81     #ifdef SIGBUS
82 root 1.81 signal (SIGBUS , SIG_DFL);
83 root 1.103 #endif
84 root 1.81 signal (SIGILL , SIG_DFL);
85     signal (SIGTRAP, SIG_DFL);
86    
87 root 1.52 // try to put corefiles into a subdirectory, if existing, to allow
88     // an administrator to reduce the I/O load.
89     chdir ("cores");
90 root 1.79
91     // try to detach us from as many external dependencies as possible
92     // as coredumping can take time by closing all fd's.
93     {
94     struct rlimit lim;
95    
96     if (getrlimit (RLIMIT_NOFILE, &lim))
97     lim.rlim_cur = 1024;
98    
99     for (int i = 0; i < lim.rlim_cur; ++i)
100     close (i);
101     }
102    
103 root 1.81 {
104     sigset_t empty;
105     sigemptyset (&empty);
106     sigprocmask (SIG_SETMASK, &empty, 0);
107     }
108    
109     // try to coredump with SIGTRAP
110     kill (getpid (), SIGTRAP);
111 root 1.37 abort ();
112     }
113    
114 root 1.38 LOG (llevError, "fork abort: %s\n", msg);
115 root 1.37 }
116 root 1.38
117 root 1.99 void *
118 root 1.106 salloc_ (int n)
119 root 1.10 {
120 root 1.25 void *ptr = g_slice_alloc (n);
121 root 1.13
122 root 1.23 if (!ptr)
123 root 1.13 throw std::bad_alloc ();
124 root 1.4
125 root 1.74 slice_alloc += n;
126 root 1.23 return ptr;
127     }
128    
129 root 1.99 void *
130 root 1.106 salloc_ (int n, void *src)
131 root 1.23 {
132 root 1.25 void *ptr = salloc_ (n);
133 root 1.23
134 root 1.24 if (src)
135 root 1.25 memcpy (ptr, src, n);
136 root 1.24 else
137 root 1.25 memset (ptr, 0, n);
138 root 1.23
139     return ptr;
140 root 1.3 }
141 root 1.11
142 root 1.69 /******************************************************************************/
143    
144 root 1.72 #if DEBUG_SALLOC
145 root 1.69
146 root 1.70 #define MAGIC 0xa1b2c35543deadLL
147 root 1.69
148 root 1.99 void *
149     g_slice_alloc (unsigned long size)
150 root 1.69 {
151     unsigned long *p = (unsigned long *) (g_slice_alloc)(size + sizeof (unsigned long));
152     *p++ = size ^ MAGIC;
153     //fprintf (stderr, "g_slice_alloc %ld %p\n", size, p);//D
154     return (void *)p;
155     }
156    
157 root 1.99 void *
158     g_slice_alloc0 (unsigned long size)
159 root 1.69 {
160     return memset (g_slice_alloc (size), 0, size);
161     }
162    
163 root 1.99 void
164     g_slice_free1 (unsigned long size, void *ptr)
165 root 1.69 {
166 root 1.74 //fprintf (stderr, "g_slice_free %ld %p\n", size, ptr);//D
167 root 1.69 if (expect_true (ptr))
168     {
169     unsigned long *p = (unsigned long *)ptr;
170     unsigned long s = *--p ^ MAGIC;
171    
172 root 1.71 if (size != (unsigned long)(*p ^ MAGIC))
173 root 1.74 {
174     LOG (logBacktrace | llevError, "slice free size (%lx) doesn't match alloc size (%lx)\n", size, s);
175     abort ();
176     }
177 root 1.69
178     *p = MAGIC;
179    
180     (g_slice_free1)(s + sizeof (unsigned long), p);
181     }
182     }
183    
184     #endif
185    
186     /******************************************************************************/
187    
188 root 1.99 refcnt_buf::refcnt_buf (size_t size)
189     {
190 root 1.102 static uint32_t empty_buf [2] = { 0, 1 }; // 2 == never deallocated
191     data = (char *)empty_buf + overhead;
192     assert (overhead == sizeof (empty_buf));
193     inc ();
194 root 1.99 }
195    
196     refcnt_buf::refcnt_buf (void *data, size_t size)
197     {
198     _alloc (size);
199     memcpy (this->data, data, size);
200     }
201    
202     refcnt_buf::~refcnt_buf ()
203     {
204     dec ();
205     }
206    
207 root 1.102 void
208     refcnt_buf::_dealloc ()
209     {
210     sfree<char> (data - overhead, size () + overhead);
211     }
212    
213 root 1.99 refcnt_buf &
214     refcnt_buf::operator =(const refcnt_buf &src)
215     {
216     dec ();
217     data = src.data;
218 root 1.102 inc ();
219 root 1.99 return *this;
220     }
221    
222     /******************************************************************************/
223    
224 root 1.86 int
225     assign (char *dst, const char *src, int maxsize)
226 root 1.11 {
227     if (!src)
228     src = "";
229    
230     int len = strlen (src);
231    
232 root 1.86 if (len >= maxsize)
233 root 1.11 {
234 root 1.86 if (maxsize <= 4)
235 root 1.11 {
236 root 1.86 memset (dst, '.', maxsize - 2);
237     dst [maxsize - 1] = 0;
238 root 1.11 }
239     else
240     {
241 root 1.86 memcpy (dst, src, maxsize - 4);
242     memcpy (dst + maxsize - 4, "...", 4);
243 root 1.11 }
244 root 1.86
245     len = maxsize;
246 root 1.11 }
247     else
248 root 1.86 memcpy (dst, src, ++len);
249    
250     return len;
251 root 1.11 }
252    
253 root 1.90 char *
254     vformat (const char *format, va_list ap)
255     {
256 root 1.96 static dynbuf_text bufs[8];
257     static int bufidx;
258    
259     dynbuf_text &buf = bufs [++bufidx & 7];
260    
261     buf.clear ();
262 root 1.90 buf.vprintf (format, ap);
263     return buf;
264     }
265    
266     char *
267 root 1.51 format (const char *format, ...)
268     {
269 root 1.65 va_list ap;
270     va_start (ap, format);
271 root 1.90 char *buf = vformat (format, ap);
272 root 1.65 va_end (ap);
273    
274     return buf;
275 root 1.51 }
276    
277 root 1.99 tstamp
278     now ()
279 root 1.23 {
280     struct timeval tv;
281    
282     gettimeofday (&tv, 0);
283     return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
284     }
285 root 1.17
286 root 1.32 int
287     similar_direction (int a, int b)
288     {
289     if (!a || !b)
290     return 0;
291    
292     int diff = (b - a) & 7;
293     return diff <= 1 || diff >= 7;
294     }
295    
296 root 1.48 /* crc32 0xdebb20e3 table and supplementary functions. */
297     extern const uint32_t crc_32_tab[256] =
298     {
299     0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
300     0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
301     0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
302     0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
303     0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
304     0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
305     0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
306     0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
307     0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
308     0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
309     0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
310     0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
311     0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
312     0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
313     0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
314     0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
315     0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
316     0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
317     0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
318     0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
319     0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
320     0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
321     0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
322     0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
323     0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
324     0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
325     0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
326     0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
327     0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
328     0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
329     0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
330     0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
331     0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
332     0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
333     0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
334     0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
335     0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
336     0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
337     0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
338     0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
339     0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
340     0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
341     0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
342     0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
343     0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
344     0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
345     0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
346     0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
347     0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
348     0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
349     0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
350     0x2d02ef8dL
351     };
352    
353 root 1.99 void
354     thread::start (void *(*start_routine)(void *), void *arg)
355 root 1.73 {
356 root 1.75 pthread_attr_t attr;
357    
358     pthread_attr_init (&attr);
359     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
360     pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < sizeof (long) * 4096
361     ? sizeof (long) * 4096 : PTHREAD_STACK_MIN);
362     #ifdef PTHREAD_SCOPE_PROCESS
363     pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
364     #endif
365    
366 root 1.73 sigset_t fullsigset, oldsigset;
367     sigfillset (&fullsigset);
368    
369     pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
370    
371 root 1.75 if (pthread_create (&id, &attr, start_routine, arg))
372 root 1.73 cleanup ("unable to create a new thread");
373    
374     pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
375     }
376 root 1.75