1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 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
php_ctime_r(const time_t * clock,char * buf)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
php_asctime_r(const struct tm * tm,char * buf)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
php_localtime_r(const time_t * const timep,struct tm * p_tm)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
php_ctime_r(const time_t * clock,char * buf)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
php_asctime_r(const struct tm * tm,char * buf)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
php_gmtime_r(const time_t * const timep,struct tm * p_tm)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
php_gmtime_r(const time_t * const timep,struct tm * p_tm)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
php_readdir_r(DIR * dirp,struct dirent * entry,struct dirent ** result)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
php_localtime_r(const time_t * const timep,struct tm * p_tm)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
php_ctime_r(const time_t * clock,char * buf)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
php_asctime_r(const struct tm * tm,char * buf)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
php_gmtime_r(const time_t * const timep,struct tm * p_tm)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
reentrancy_startup(void)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
reentrancy_shutdown(void)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
do_rand(unsigned long * ctx)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
php_rand_r(unsigned int * ctx)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 *
php_strtok_r(char * s,const char * delim,char ** last)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