xref: /PHP-7.4/main/reentrancy.c (revision 816b4c12)
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