Back to index

php5  5.3.10
reentrancy.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Sascha Schumann <sascha@schumann.cx>                         |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: reentrancy.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #include <sys/types.h>
00022 #include <string.h>
00023 #include <errno.h>
00024 #ifdef HAVE_DIRENT_H
00025 #include <dirent.h>
00026 #endif
00027 
00028 #include "php_reentrancy.h"
00029 #include "ext/standard/php_rand.h"                   /* for PHP_RAND_MAX */
00030 
00031 enum {
00032        LOCALTIME_R,
00033        CTIME_R,
00034        ASCTIME_R,
00035        GMTIME_R,
00036        READDIR_R,
00037        NUMBER_OF_LOCKS
00038 };
00039 
00040 #if defined(PHP_NEED_REENTRANCY)
00041 
00042 #include <TSRM.h>
00043 
00044 static MUTEX_T reentrant_locks[NUMBER_OF_LOCKS];
00045 
00046 #define local_lock(x) tsrm_mutex_lock(reentrant_locks[x])
00047 #define local_unlock(x) tsrm_mutex_unlock(reentrant_locks[x])
00048 
00049 #else
00050 
00051 #define local_lock(x)
00052 #define local_unlock(x)
00053 
00054 #endif
00055 
00056 #if defined(PHP_IRIX_TIME_R)
00057 
00058 #define HAVE_CTIME_R 1
00059 #define HAVE_ASCTIME_R 1
00060 
00061 PHPAPI char *php_ctime_r(const time_t *clock, char *buf)
00062 {
00063        if (ctime_r(clock, buf) == buf)
00064               return (buf);
00065        return (NULL);
00066 }
00067 
00068 PHPAPI char *php_asctime_r(const struct tm *tm, char *buf)
00069 {
00070        if (asctime_r(tm, buf) == buf)
00071               return (buf);
00072        return (NULL);
00073 }
00074 
00075 #endif
00076 
00077 #if defined(PHP_HPUX_TIME_R)
00078 
00079 #define HAVE_LOCALTIME_R 1
00080 #define HAVE_CTIME_R 1
00081 #define HAVE_ASCTIME_R 1
00082 #define HAVE_GMTIME_R 1
00083 
00084 PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm)
00085 {
00086        if (localtime_r(timep, p_tm) == 0)
00087               return (p_tm);
00088        return (NULL);
00089 }
00090 
00091 PHPAPI char *php_ctime_r(const time_t *clock, char *buf)
00092 {
00093        if (ctime_r(clock, buf, 26) != -1)
00094               return (buf);
00095        return (NULL);
00096 }
00097 
00098 PHPAPI char *php_asctime_r(const struct tm *tm, char *buf)
00099 {
00100        if (asctime_r(tm, buf, 26) != -1)
00101               return (buf);
00102        return (NULL);
00103 }
00104 
00105 PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm)
00106 {
00107        if (gmtime_r(timep, p_tm) == 0)
00108               return (p_tm);
00109        return (NULL);
00110 }
00111 
00112 #endif
00113 
00114 #if defined(__BEOS__)
00115 
00116 PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm)
00117 {
00118     /* Modified according to LibC definition */
00119         if (((struct tm*)gmtime_r(timep, p_tm)) == p_tm)
00120                 return (p_tm);
00121         return (NULL);
00122 }
00123 
00124 #endif /* BEOS */
00125 
00126 #if !defined(HAVE_POSIX_READDIR_R)
00127 
00128 PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry, 
00129               struct dirent **result)
00130 {
00131 #if defined(HAVE_OLD_READDIR_R)
00132        int ret = 0;
00133        
00134        /* We cannot rely on the return value of readdir_r
00135           as it differs between various platforms
00136           (HPUX returns 0 on success whereas Solaris returns non-zero)
00137         */
00138        entry->d_name[0] = '\0';
00139        readdir_r(dirp, entry);
00140        
00141        if (entry->d_name[0] == '\0') {
00142               *result = NULL;
00143               ret = errno;
00144        } else {
00145               *result = entry;
00146        }
00147        return ret;
00148 #else
00149        struct dirent *ptr;
00150        int ret = 0;
00151 
00152        local_lock(READDIR_R);
00153        
00154        errno = 0;
00155        
00156        ptr = readdir(dirp);
00157        
00158        if (!ptr && errno != 0)
00159               ret = errno;
00160 
00161        if (ptr)
00162               memcpy(entry, ptr, sizeof(*ptr));
00163 
00164        *result = ptr;
00165 
00166        local_unlock(READDIR_R);
00167 
00168        return ret;
00169 #endif
00170 }
00171 
00172 #endif
00173 
00174 #if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME)
00175 
00176 PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm)
00177 {
00178        struct tm *tmp;
00179        
00180        local_lock(LOCALTIME_R);
00181 
00182        tmp = localtime(timep);
00183        if (tmp) {
00184               memcpy(p_tm, tmp, sizeof(struct tm));
00185               tmp = p_tm;
00186        }
00187        
00188        local_unlock(LOCALTIME_R);
00189 
00190        return tmp;
00191 }
00192 
00193 #endif
00194 
00195 #if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME)
00196 
00197 PHPAPI char *php_ctime_r(const time_t *clock, char *buf)
00198 {
00199        char *tmp;
00200        
00201        local_lock(CTIME_R);
00202 
00203        tmp = ctime(clock);
00204        strcpy(buf, tmp);
00205 
00206        local_unlock(CTIME_R);
00207        
00208        return buf;
00209 }
00210 
00211 #endif
00212 
00213 #if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME)
00214 
00215 PHPAPI char *php_asctime_r(const struct tm *tm, char *buf)
00216 {
00217        char *tmp;
00218        
00219        local_lock(ASCTIME_R);
00220 
00221        tmp = asctime(tm);
00222        strcpy(buf, tmp);
00223 
00224        local_unlock(ASCTIME_R);
00225 
00226        return buf;
00227 }
00228 
00229 #endif
00230 
00231 #if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME)
00232 
00233 PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm)
00234 {
00235        struct tm *tmp;
00236        
00237        local_lock(GMTIME_R);
00238 
00239        tmp = gmtime(timep);
00240        if (tmp) {
00241               memcpy(p_tm, tmp, sizeof(struct tm));
00242               tmp = p_tm;
00243        }
00244        
00245        local_unlock(GMTIME_R);
00246 
00247        return tmp;
00248 }
00249 
00250 #endif
00251 
00252 #if defined(PHP_NEED_REENTRANCY)
00253 
00254 void reentrancy_startup(void)
00255 {
00256        int i;
00257 
00258        for (i = 0; i < NUMBER_OF_LOCKS; i++) {
00259               reentrant_locks[i] = tsrm_mutex_alloc();
00260        }
00261 }
00262 
00263 void reentrancy_shutdown(void)
00264 {
00265        int i;
00266 
00267        for (i = 0; i < NUMBER_OF_LOCKS; i++) {
00268               tsrm_mutex_free(reentrant_locks[i]);
00269        }
00270 }
00271 
00272 #endif
00273 
00274 #ifndef HAVE_RAND_R
00275 
00276 /*-
00277  * Copyright (c) 1990, 1993
00278  *     The Regents of the University of California.  All rights reserved.
00279  *
00280  * Redistribution and use in source and binary forms, with or without
00281  * modification, are permitted provided that the following conditions
00282  * are met:
00283  * 1. Redistributions of source code must retain the above copyright
00284  *    notice, this list of conditions and the following disclaimer.
00285  * 2. Redistributions in binary form must reproduce the above copyright
00286  *    notice, this list of conditions and the following disclaimer in the
00287  *    documentation and/or other materials provided with the distribution.
00288  * 3. All advertising materials mentioning features or use of this software
00289  *    must display the following acknowledgement:
00290  *     This product includes software developed by the University of
00291  *     California, Berkeley and its contributors.
00292  * 4. Neither the name of the University nor the names of its contributors
00293  *    may be used to endorse or promote products derived from this software
00294  *    without specific prior written permission.
00295  *
00296  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00297  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00298  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00299  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00300  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00301  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00302  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00303  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00304  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00305  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00306  * SUCH DAMAGE.
00307  *
00308  * Posix rand_r function added May 1999 by Wes Peters <wes@softweyr.com>.
00309  */
00310 
00311 #include <sys/types.h>
00312 #include <stdlib.h>
00313 
00314 static int
00315 do_rand(unsigned long *ctx)
00316 {
00317        return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)PHP_RAND_MAX + 1));
00318 }
00319 
00320 
00321 PHPAPI int
00322 php_rand_r(unsigned int *ctx)
00323 {
00324        u_long val = (u_long) *ctx;
00325        *ctx = do_rand(&val);
00326        return (int) *ctx;
00327 }
00328 
00329 #endif
00330 
00331 
00332 #ifndef HAVE_STRTOK_R
00333 
00334 /*
00335  * Copyright (c) 1998 Softweyr LLC.  All rights reserved.
00336  *
00337  * strtok_r, from Berkeley strtok
00338  * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
00339  *
00340  * Copyright (c) 1988, 1993
00341  *     The Regents of the University of California.  All rights reserved.
00342  *
00343  * Redistribution and use in source and binary forms, with or without
00344  * modification, are permitted provided that the following conditions
00345  * are met:
00346  *
00347  * 1. Redistributions of source code must retain the above copyright
00348  *    notices, this list of conditions and the following disclaimer.
00349  * 
00350  * 2. Redistributions in binary form must reproduce the above copyright
00351  *    notices, this list of conditions and the following disclaimer in the
00352  *    documentation and/or other materials provided with the distribution.
00353  * 
00354  * 3. All advertising materials mentioning features or use of this software
00355  *    must display the following acknowledgement:
00356  *
00357  *     This product includes software developed by Softweyr LLC, the
00358  *      University of California, Berkeley, and its contributors.
00359  *
00360  * 4. Neither the name of the University nor the names of its contributors
00361  *    may be used to endorse or promote products derived from this software
00362  *    without specific prior written permission.
00363  *
00364  * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
00365  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00366  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00367  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SOFTWEYR LLC, THE
00368  * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00369  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00370  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00371  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00372  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00373  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00374  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00375  */
00376 
00377 #include <stddef.h>
00378 
00379 PHPAPI char *
00380 php_strtok_r(char *s, const char *delim, char **last)
00381 {
00382     char *spanp;
00383     int c, sc;
00384     char *tok;
00385 
00386     if (s == NULL && (s = *last) == NULL)
00387     {
00388        return NULL;
00389     }
00390 
00391     /*
00392      * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
00393      */
00394 cont:
00395     c = *s++;
00396     for (spanp = (char *)delim; (sc = *spanp++) != 0; )
00397     {
00398        if (c == sc)
00399        {
00400            goto cont;
00401        }
00402     }
00403 
00404     if (c == 0)             /* no non-delimiter characters */
00405     {
00406        *last = NULL;
00407        return NULL;
00408     }
00409     tok = s - 1;
00410 
00411     /*
00412      * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
00413      * Note that delim must have one NUL; we stop if we see that, too.
00414      */
00415     for (;;)
00416     {
00417        c = *s++;
00418        spanp = (char *)delim;
00419        do
00420        {
00421            if ((sc = *spanp++) == c)
00422            {
00423               if (c == 0)
00424               {
00425                   s = NULL;
00426               }
00427               else
00428               {
00429                   char *w = s - 1;
00430                   *w = '\0';
00431               }
00432               *last = s;
00433               return tok;
00434            }
00435        }
00436        while (sc != 0);
00437     }
00438     /* NOTREACHED */
00439 }
00440 
00441 #endif
00442 
00443 /*
00444  * Local variables:
00445  * tab-width: 4
00446  * c-basic-offset: 4
00447  * End:
00448  * vim600: sw=4 ts=4 fdm=marker
00449  * vim<600: sw=4 ts=4
00450  */