1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | PHP Version 5 | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1997-2015 The PHP Group | |
6 | +----------------------------------------------------------------------+ |
7 | | This source file is subject to version 3.01 of the PHP license, | |
8 | | that is bundled with this package in the file LICENSE, and is | |
9 | | available through the world-wide-web at the following url: | |
10 | | http://www.php.net/license/3_01.txt | |
11 | | If you did not receive a copy of the PHP license and are unable to | |
12 | | obtain it through the world-wide-web, please send a note to | |
13 | | license@php.net so we can mail you a copy immediately. | |
14 | +----------------------------------------------------------------------+ |
15 | | Author: Sascha Schumann <sascha@schumann.cx> | |
16 | +----------------------------------------------------------------------+ |
17 | */ |
18 | |
19 | /* $Id$ */ |
20 | |
21 | #include <sys/types.h> |
22 | #include <string.h> |
23 | #include <errno.h> |
24 | #ifdef HAVE_DIRENT_H |
25 | #include <dirent.h> |
26 | #endif |
27 | |
28 | #include "php_reentrancy.h" |
29 | #include "ext/standard/php_rand.h" /* for PHP_RAND_MAX */ |
30 | |
31 | enum { |
32 | LOCALTIME_R, |
33 | CTIME_R, |
34 | ASCTIME_R, |
35 | GMTIME_R, |
36 | READDIR_R, |
37 | NUMBER_OF_LOCKS |
38 | }; |
39 | |
40 | #if defined(PHP_NEED_REENTRANCY) |
41 | |
42 | #include <TSRM.h> |
43 | |
44 | static MUTEX_T reentrant_locks[NUMBER_OF_LOCKS]; |
45 | |
46 | #define local_lock(x) tsrm_mutex_lock(reentrant_locks[x]) |
47 | #define local_unlock(x) tsrm_mutex_unlock(reentrant_locks[x]) |
48 | |
49 | #else |
50 | |
51 | #define local_lock(x) |
52 | #define local_unlock(x) |
53 | |
54 | #endif |
55 | |
56 | #if defined(PHP_IRIX_TIME_R) |
57 | |
58 | #define HAVE_CTIME_R 1 |
59 | #define HAVE_ASCTIME_R 1 |
60 | |
61 | PHPAPI char *php_ctime_r(const time_t *clock, char *buf) |
62 | { |
63 | if (ctime_r(clock, buf) == buf) |
64 | return (buf); |
65 | return (NULL); |
66 | } |
67 | |
68 | PHPAPI char *php_asctime_r(const struct tm *tm, char *buf) |
69 | { |
70 | if (asctime_r(tm, buf) == buf) |
71 | return (buf); |
72 | return (NULL); |
73 | } |
74 | |
75 | #endif |
76 | |
77 | #if defined(PHP_HPUX_TIME_R) |
78 | |
79 | #define HAVE_LOCALTIME_R 1 |
80 | #define HAVE_CTIME_R 1 |
81 | #define HAVE_ASCTIME_R 1 |
82 | #define HAVE_GMTIME_R 1 |
83 | |
84 | PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm) |
85 | { |
86 | if (localtime_r(timep, p_tm) == 0) |
87 | return (p_tm); |
88 | return (NULL); |
89 | } |
90 | |
91 | PHPAPI char *php_ctime_r(const time_t *clock, char *buf) |
92 | { |
93 | if (ctime_r(clock, buf, 26) != -1) |
94 | return (buf); |
95 | return (NULL); |
96 | } |
97 | |
98 | PHPAPI char *php_asctime_r(const struct tm *tm, char *buf) |
99 | { |
100 | if (asctime_r(tm, buf, 26) != -1) |
101 | return (buf); |
102 | return (NULL); |
103 | } |
104 | |
105 | PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm) |
106 | { |
107 | if (gmtime_r(timep, p_tm) == 0) |
108 | return (p_tm); |
109 | return (NULL); |
110 | } |
111 | |
112 | #endif |
113 | |
114 | #if defined(__BEOS__) |
115 | |
116 | PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm) |
117 | { |
118 | /* Modified according to LibC definition */ |
119 | if (((struct tm*)gmtime_r(timep, p_tm)) == p_tm) |
120 | return (p_tm); |
121 | return (NULL); |
122 | } |
123 | |
124 | #endif /* BEOS */ |
125 | |
126 | #if !defined(HAVE_POSIX_READDIR_R) |
127 | |
128 | PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry, |
129 | struct dirent **result) |
130 | { |
131 | #if defined(HAVE_OLD_READDIR_R) |
132 | int ret = 0; |
133 | |
134 | /* We cannot rely on the return value of readdir_r |
135 | as it differs between various platforms |
136 | (HPUX returns 0 on success whereas Solaris returns non-zero) |
137 | */ |
138 | entry->d_name[0] = '\0'; |
139 | readdir_r(dirp, entry); |
140 | |
141 | if (entry->d_name[0] == '\0') { |
142 | *result = NULL; |
143 | ret = errno; |
144 | } else { |
145 | *result = entry; |
146 | } |
147 | return ret; |
148 | #else |
149 | struct dirent *ptr; |
150 | int ret = 0; |
151 | |
152 | local_lock(READDIR_R); |
153 | |
154 | errno = 0; |
155 | |
156 | ptr = readdir(dirp); |
157 | |
158 | if (!ptr && errno != 0) |
159 | ret = errno; |
160 | |
161 | if (ptr) |
162 | memcpy(entry, ptr, sizeof(*ptr)); |
163 | |
164 | *result = ptr; |
165 | |
166 | local_unlock(READDIR_R); |
167 | |
168 | return ret; |
169 | #endif |
170 | } |
171 | |
172 | #endif |
173 | |
174 | #if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME) |
175 | |
176 | PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm) |
177 | { |
178 | struct tm *tmp; |
179 | |
180 | local_lock(LOCALTIME_R); |
181 | |
182 | tmp = localtime(timep); |
183 | if (tmp) { |
184 | memcpy(p_tm, tmp, sizeof(struct tm)); |
185 | tmp = p_tm; |
186 | } |
187 | |
188 | local_unlock(LOCALTIME_R); |
189 | |
190 | return tmp; |
191 | } |
192 | |
193 | #endif |
194 | |
195 | #if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME) |
196 | |
197 | PHPAPI char *php_ctime_r(const time_t *clock, char *buf) |
198 | { |
199 | char *tmp; |
200 | |
201 | local_lock(CTIME_R); |
202 | |
203 | tmp = ctime(clock); |
204 | strcpy(buf, tmp); |
205 | |
206 | local_unlock(CTIME_R); |
207 | |
208 | return buf; |
209 | } |
210 | |
211 | #endif |
212 | |
213 | #if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME) |
214 | |
215 | PHPAPI char *php_asctime_r(const struct tm *tm, char *buf) |
216 | { |
217 | char *tmp; |
218 | |
219 | local_lock(ASCTIME_R); |
220 | |
221 | tmp = asctime(tm); |
222 | strcpy(buf, tmp); |
223 | |
224 | local_unlock(ASCTIME_R); |
225 | |
226 | return buf; |
227 | } |
228 | |
229 | #endif |
230 | |
231 | #if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME) |
232 | |
233 | PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm) |
234 | { |
235 | struct tm *tmp; |
236 | |
237 | local_lock(GMTIME_R); |
238 | |
239 | tmp = gmtime(timep); |
240 | if (tmp) { |
241 | memcpy(p_tm, tmp, sizeof(struct tm)); |
242 | tmp = p_tm; |
243 | } |
244 | |
245 | local_unlock(GMTIME_R); |
246 | |
247 | return tmp; |
248 | } |
249 | |
250 | #endif |
251 | |
252 | #if defined(PHP_NEED_REENTRANCY) |
253 | |
254 | void reentrancy_startup(void) |
255 | { |
256 | int i; |
257 | |
258 | for (i = 0; i < NUMBER_OF_LOCKS; i++) { |
259 | reentrant_locks[i] = tsrm_mutex_alloc(); |
260 | } |
261 | } |
262 | |
263 | void reentrancy_shutdown(void) |
264 | { |
265 | int i; |
266 | |
267 | for (i = 0; i < NUMBER_OF_LOCKS; i++) { |
268 | tsrm_mutex_free(reentrant_locks[i]); |
269 | } |
270 | } |
271 | |
272 | #endif |
273 | |
274 | #ifndef HAVE_RAND_R |
275 | |
276 | /*- |
277 | * Copyright (c) 1990, 1993 |
278 | * The Regents of the University of California. All rights reserved. |
279 | * |
280 | * Redistribution and use in source and binary forms, with or without |
281 | * modification, are permitted provided that the following conditions |
282 | * are met: |
283 | * 1. Redistributions of source code must retain the above copyright |
284 | * notice, this list of conditions and the following disclaimer. |
285 | * 2. Redistributions in binary form must reproduce the above copyright |
286 | * notice, this list of conditions and the following disclaimer in the |
287 | * documentation and/or other materials provided with the distribution. |
288 | * 3. All advertising materials mentioning features or use of this software |
289 | * must display the following acknowledgement: |
290 | * This product includes software developed by the University of |
291 | * California, Berkeley and its contributors. |
292 | * 4. Neither the name of the University nor the names of its contributors |
293 | * may be used to endorse or promote products derived from this software |
294 | * without specific prior written permission. |
295 | * |
296 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
297 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
298 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
299 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
300 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
301 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
302 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
303 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
304 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
305 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
306 | * SUCH DAMAGE. |
307 | * |
308 | * Posix rand_r function added May 1999 by Wes Peters <wes@softweyr.com>. |
309 | */ |
310 | |
311 | #include <sys/types.h> |
312 | #include <stdlib.h> |
313 | |
314 | static int |
315 | do_rand(unsigned long *ctx) |
316 | { |
317 | return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)PHP_RAND_MAX + 1)); |
318 | } |
319 | |
320 | |
321 | PHPAPI int |
322 | php_rand_r(unsigned int *ctx) |
323 | { |
324 | u_long val = (u_long) *ctx; |
325 | *ctx = do_rand(&val); |
326 | return (int) *ctx; |
327 | } |
328 | |
329 | #endif |
330 | |
331 | |
332 | #ifndef HAVE_STRTOK_R |
333 | |
334 | /* |
335 | * Copyright (c) 1998 Softweyr LLC. All rights reserved. |
336 | * |
337 | * strtok_r, from Berkeley strtok |
338 | * Oct 13, 1998 by Wes Peters <wes@softweyr.com> |
339 | * |
340 | * Copyright (c) 1988, 1993 |
341 | * The Regents of the University of California. All rights reserved. |
342 | * |
343 | * Redistribution and use in source and binary forms, with or without |
344 | * modification, are permitted provided that the following conditions |
345 | * are met: |
346 | * |
347 | * 1. Redistributions of source code must retain the above copyright |
348 | * notices, this list of conditions and the following disclaimer. |
349 | * |
350 | * 2. Redistributions in binary form must reproduce the above copyright |
351 | * notices, this list of conditions and the following disclaimer in the |
352 | * documentation and/or other materials provided with the distribution. |
353 | * |
354 | * 3. All advertising materials mentioning features or use of this software |
355 | * must display the following acknowledgement: |
356 | * |
357 | * This product includes software developed by Softweyr LLC, the |
358 | * University of California, Berkeley, and its contributors. |
359 | * |
360 | * 4. Neither the name of the University nor the names of its contributors |
361 | * may be used to endorse or promote products derived from this software |
362 | * without specific prior written permission. |
363 | * |
364 | * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS |
365 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
366 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
367 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE |
368 | * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
369 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
370 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
371 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
372 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
373 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
374 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
375 | */ |
376 | |
377 | #include <stddef.h> |
378 | |
379 | PHPAPI char * |
380 | php_strtok_r(char *s, const char *delim, char **last) |
381 | { |
382 | char *spanp; |
383 | int c, sc; |
384 | char *tok; |
385 | |
386 | if (s == NULL && (s = *last) == NULL) |
387 | { |
388 | return NULL; |
389 | } |
390 | |
391 | /* |
392 | * Skip (span) leading delimiters (s += strspn(s, delim), sort of). |
393 | */ |
394 | cont: |
395 | c = *s++; |
396 | for (spanp = (char *)delim; (sc = *spanp++) != 0; ) |
397 | { |
398 | if (c == sc) |
399 | { |
400 | goto cont; |
401 | } |
402 | } |
403 | |
404 | if (c == 0) /* no non-delimiter characters */ |
405 | { |
406 | *last = NULL; |
407 | return NULL; |
408 | } |
409 | tok = s - 1; |
410 | |
411 | /* |
412 | * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). |
413 | * Note that delim must have one NUL; we stop if we see that, too. |
414 | */ |
415 | for (;;) |
416 | { |
417 | c = *s++; |
418 | spanp = (char *)delim; |
419 | do |
420 | { |
421 | if ((sc = *spanp++) == c) |
422 | { |
423 | if (c == 0) |
424 | { |
425 | s = NULL; |
426 | } |
427 | else |
428 | { |
429 | char *w = s - 1; |
430 | *w = '\0'; |
431 | } |
432 | *last = s; |
433 | return tok; |
434 | } |
435 | } |
436 | while (sc != 0); |
437 | } |
438 | /* NOTREACHED */ |
439 | } |
440 | |
441 | #endif |
442 | |
443 | /* |
444 | * Local variables: |
445 | * tab-width: 4 |
446 | * c-basic-offset: 4 |
447 | * End: |
448 | * vim600: sw=4 ts=4 fdm=marker |
449 | * vim<600: sw=4 ts=4 |
450 | */ |
451 | |