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
31enum {
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
44static 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
61PHPAPI 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
68PHPAPI 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
84PHPAPI 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
91PHPAPI 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
98PHPAPI 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
105PHPAPI 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
116PHPAPI 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
128PHPAPI 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
176PHPAPI 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
197PHPAPI 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
215PHPAPI 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
233PHPAPI 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
254void 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
263void 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
314static int
315do_rand(unsigned long *ctx)
316{
317 return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)PHP_RAND_MAX + 1));
318}
319
320
321PHPAPI int
322php_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
379PHPAPI char *
380php_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 */
394cont:
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