1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 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_LOCALTIME_R) && defined(HAVE_LOCALTIME)
113
php_localtime_r(const time_t * const timep,struct tm * p_tm)114 PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm)
115 {
116 struct tm *tmp;
117
118 local_lock(LOCALTIME_R);
119
120 tmp = localtime(timep);
121 if (tmp) {
122 memcpy(p_tm, tmp, sizeof(struct tm));
123 tmp = p_tm;
124 }
125
126 local_unlock(LOCALTIME_R);
127
128 return tmp;
129 }
130
131 #endif
132
133 #if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME)
134
php_ctime_r(const time_t * clock,char * buf)135 PHPAPI char *php_ctime_r(const time_t *clock, char *buf)
136 {
137 char *tmp;
138
139 local_lock(CTIME_R);
140
141 tmp = ctime(clock);
142 if (tmp) {
143 strcpy(buf, tmp);
144 tmp = buf;
145 }
146
147 local_unlock(CTIME_R);
148
149 return tmp;
150 }
151
152 #endif
153
154 #if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME)
155
php_asctime_r(const struct tm * tm,char * buf)156 PHPAPI char *php_asctime_r(const struct tm *tm, char *buf)
157 {
158 char *tmp;
159
160 local_lock(ASCTIME_R);
161
162 tmp = asctime(tm);
163 if (tmp) {
164 strcpy(buf, tmp);
165 tmp = buf;
166 }
167
168 local_unlock(ASCTIME_R);
169
170 return tmp;
171 }
172
173 #endif
174
175 #if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME)
176
php_gmtime_r(const time_t * const timep,struct tm * p_tm)177 PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm)
178 {
179 struct tm *tmp;
180
181 local_lock(GMTIME_R);
182
183 tmp = gmtime(timep);
184 if (tmp) {
185 memcpy(p_tm, tmp, sizeof(struct tm));
186 tmp = p_tm;
187 }
188
189 local_unlock(GMTIME_R);
190
191 return tmp;
192 }
193
194 #endif
195
196 #if defined(PHP_NEED_REENTRANCY)
197
reentrancy_startup(void)198 void reentrancy_startup(void)
199 {
200 int i;
201
202 for (i = 0; i < NUMBER_OF_LOCKS; i++) {
203 reentrant_locks[i] = tsrm_mutex_alloc();
204 }
205 }
206
reentrancy_shutdown(void)207 void reentrancy_shutdown(void)
208 {
209 int i;
210
211 for (i = 0; i < NUMBER_OF_LOCKS; i++) {
212 tsrm_mutex_free(reentrant_locks[i]);
213 }
214 }
215
216 #endif
217
218 #ifndef HAVE_RAND_R
219
220 /*-
221 * Copyright (c) 1990, 1993
222 * The Regents of the University of California. All rights reserved.
223 *
224 * Redistribution and use in source and binary forms, with or without
225 * modification, are permitted provided that the following conditions
226 * are met:
227 * 1. Redistributions of source code must retain the above copyright
228 * notice, this list of conditions and the following disclaimer.
229 * 2. Redistributions in binary form must reproduce the above copyright
230 * notice, this list of conditions and the following disclaimer in the
231 * documentation and/or other materials provided with the distribution.
232 * 3. All advertising materials mentioning features or use of this software
233 * must display the following acknowledgement:
234 * This product includes software developed by the University of
235 * California, Berkeley and its contributors.
236 * 4. Neither the name of the University nor the names of its contributors
237 * may be used to endorse or promote products derived from this software
238 * without specific prior written permission.
239 *
240 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
241 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
242 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
243 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
244 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
245 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
246 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
247 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
248 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
249 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
250 * SUCH DAMAGE.
251 *
252 * Posix rand_r function added May 1999 by Wes Peters <wes@softweyr.com>.
253 */
254
255 #include <sys/types.h>
256 #include <stdlib.h>
257
258 static int
do_rand(unsigned long * ctx)259 do_rand(unsigned long *ctx)
260 {
261 return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)PHP_RAND_MAX + 1));
262 }
263
264
265 PHPAPI int
php_rand_r(unsigned int * ctx)266 php_rand_r(unsigned int *ctx)
267 {
268 u_long val = (u_long) *ctx;
269 *ctx = do_rand(&val);
270 return (int) *ctx;
271 }
272
273 #endif
274
275
276 #ifndef HAVE_STRTOK_R
277
278 /*
279 * Copyright (c) 1998 Softweyr LLC. All rights reserved.
280 *
281 * strtok_r, from Berkeley strtok
282 * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
283 *
284 * Copyright (c) 1988, 1993
285 * The Regents of the University of California. All rights reserved.
286 *
287 * Redistribution and use in source and binary forms, with or without
288 * modification, are permitted provided that the following conditions
289 * are met:
290 *
291 * 1. Redistributions of source code must retain the above copyright
292 * notices, this list of conditions and the following disclaimer.
293 *
294 * 2. Redistributions in binary form must reproduce the above copyright
295 * notices, this list of conditions and the following disclaimer in the
296 * documentation and/or other materials provided with the distribution.
297 *
298 * 3. All advertising materials mentioning features or use of this software
299 * must display the following acknowledgement:
300 *
301 * This product includes software developed by Softweyr LLC, the
302 * University of California, Berkeley, and its contributors.
303 *
304 * 4. Neither the name of the University nor the names of its contributors
305 * may be used to endorse or promote products derived from this software
306 * without specific prior written permission.
307 *
308 * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
309 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
310 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
311 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
312 * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
313 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
314 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
315 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
316 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
317 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
318 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
319 */
320
321 #include <stddef.h>
322
323 PHPAPI char *
php_strtok_r(char * s,const char * delim,char ** last)324 php_strtok_r(char *s, const char *delim, char **last)
325 {
326 char *spanp;
327 int c, sc;
328 char *tok;
329
330 if (s == NULL && (s = *last) == NULL)
331 {
332 return NULL;
333 }
334
335 /*
336 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
337 */
338 cont:
339 c = *s++;
340 for (spanp = (char *)delim; (sc = *spanp++) != 0; )
341 {
342 if (c == sc)
343 {
344 goto cont;
345 }
346 }
347
348 if (c == 0) /* no non-delimiter characters */
349 {
350 *last = NULL;
351 return NULL;
352 }
353 tok = s - 1;
354
355 /*
356 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
357 * Note that delim must have one NUL; we stop if we see that, too.
358 */
359 for (;;)
360 {
361 c = *s++;
362 spanp = (char *)delim;
363 do
364 {
365 if ((sc = *spanp++) == c)
366 {
367 if (c == 0)
368 {
369 s = NULL;
370 }
371 else
372 {
373 char *w = s - 1;
374 *w = '\0';
375 }
376 *last = s;
377 return tok;
378 }
379 }
380 while (sc != 0);
381 }
382 /* NOTREACHED */
383 }
384
385 #endif
386