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