reentrancy.c 10 KB

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