]> granicus.if.org Git - php/commitdiff
dir modules is now resourcified & thread-safe!
authorThies C. Arntzen <thies@php.net>
Tue, 5 Oct 1999 14:36:00 +0000 (14:36 +0000)
committerThies C. Arntzen <thies@php.net>
Tue, 5 Oct 1999 14:36:00 +0000 (14:36 +0000)
ChangeLog
ext/standard/dir.c
ext/standard/php3_dir.h

index 41a0c6768fcb441481744ce19203b27e77c83d58..4641d4008b92e2522669a63fbe257d500ff86560 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@ PHP 4.0 CHANGE LOG                                                    ChangeLog
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
 ?? ?? 1999, Version 4.0 Beta 3
+- Cleaned up Directory-Module (Thies)
 - Small fix in Ora_Close (Thies)
 - Ported range() and shuffle() from PHP3 to PHP4 (Andrei)
 - Fixed header("HTTP/..."); behaviour (Sascha)
index 21880d82203a9179b16250b41ccc955129bf5f28..89b101a0dc37cc3cb7894212b0b9696634517ac4 100644 (file)
    | license@php.net so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
    | Authors:                                                             |
+   | PHP 4.0 patches by Thies C. Arntzen (thies@digicol.de)               |
    +----------------------------------------------------------------------+
  */
 
 /* $Id$ */
 
+/* {{{ includes/startup/misc */
+
 #include "php.h"
 #include "fopen-wrappers.h"
 
 #include "win32/readdir.h"
 #endif
 
-static int dirp_id = 0;
+typedef struct {
+       int default_dir;
+} php_dir_globals;
+
+#ifdef ZTS
+#define DIR(v) (dir_globals->v)
+#define DIRLS_FETCH() php_dir_globals *dir_globals = ts_resource(dir_globals_id)
+int dir_globals_id;
+#else
+#define DIR(v) (xml_globals.v)
+#define DIRLS_FETCH()
+php_dir_globals dir_globals;
+#endif
+
+typedef struct {
+       int id;
+       DIR *dir;
+} php_dir;
+
 static int le_dirp;
+
 static zend_class_entry *dir_class_entry_ptr;
 
+#define FETCH_DIRP() \
+       if (ARG_COUNT(ht) == 0) { \
+               myself = getThis(); \
+               if (myself) { \
+                       if (zend_hash_find(myself->value.obj.properties, "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { \
+                               php_error(E_WARNING, "unable to find my handle property"); \
+                               RETURN_FALSE; \
+                       } \
+                       ZEND_FETCH_RESOURCE(dirp,php_dir *,tmp,-1, "Directory", le_dirp); \
+               } else { \
+                       ZEND_FETCH_RESOURCE(dirp,php_dir *,0,DIR(default_dir), "Directory", le_dirp); \
+               } \
+       } else if ((ARG_COUNT(ht) != 1) || getParametersEx(1, &id) == FAILURE) { \
+               WRONG_PARAM_COUNT; \
+       } else { \
+               ZEND_FETCH_RESOURCE(dirp,php_dir *,id,-1, "Directory", le_dirp); \
+       } 
+
 static zend_function_entry php_dir_functions[] = {
        PHP_FE(opendir,                         NULL)
        PHP_FE(closedir,                        NULL)
@@ -65,210 +105,171 @@ php3_module_entry php3_dir_module_entry = {
        "PHP_dir", php_dir_functions, PHP_MINIT(dir), NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES
 };
 
+static void _dir_dtor(php_dir *dirp)
+{
+       closedir(dirp->dir);
+       efree(dirp);
+}
+
+#ifdef ZTS
+static void php_dir_init_globals(php_dir_globals *dir_globals)
+{
+       DIR(default_dir) = 0;
+}
+#endif
 
 PHP_MINIT_FUNCTION(dir)
 {
        zend_class_entry dir_class_entry;
 
-       le_dirp = register_list_destructors(closedir,NULL);
+       le_dirp = register_list_destructors(_dir_dtor,NULL);
 
        INIT_CLASS_ENTRY(dir_class_entry, "Directory", php_dir_class_functions);
        dir_class_entry_ptr = register_internal_class(&dir_class_entry);
+
+#ifdef ZTS
+       dir_globals_id = ts_allocate_id(sizeof(php_dir_globals), php_dir_init_globals, NULL);
+#else
+       DIR(default_dir) = 0;
+#endif
+
        return SUCCESS;
 }
 
-/* {{{ proto int opendir(string path)
-   Open a directory and return a dir_handle */
-PHP_FUNCTION(opendir)
+/* }}} */
+/* {{{ internal functions */
+
+static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
 {
-       pval *arg;
-       DIR *dirp;
-       int ret;
+       pval **arg;
+       php_dir *dirp;
+       DIRLS_FETCH();
        
-       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) {
+       if (ARG_COUNT(ht) != 1 || getParametersEx(1, &arg) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_string(arg);
+       convert_to_string_ex(arg);
 
-       /* Check open_basedir */
-       if (_php3_check_open_basedir(arg->value.str.val)) RETURN_FALSE;
+       if (_php3_check_open_basedir((*arg)->value.str.val)) {
+               RETURN_FALSE;
+       }
        
-       dirp = opendir(arg->value.str.val);
-       if (!dirp) {
-               php_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno),errno);
+       dirp = emalloc(sizeof(php_dir));
+
+       dirp->dir = opendir((*arg)->value.str.val);
+       
+       if (! dirp->dir) {
+               efree(dirp);
+               php_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno), errno);
                RETURN_FALSE;
        }
-       ret = php3_list_insert(dirp, le_dirp);
-       dirp_id = ret;
-       RETURN_LONG(ret);
+
+       dirp->id = zend_list_insert(dirp,le_dirp);
+
+       DIR(default_dir) = dirp->id;
+
+       if (createobject) {
+               object_init_ex(return_value, dir_class_entry_ptr);
+               add_property_stringl(return_value, "path", (*arg)->value.str.val, (*arg)->value.str.len, 1);
+               add_property_resource(return_value, "handle", dirp->id);
+               zend_list_addref(dirp->id);
+       } else {
+               RETURN_RESOURCE(dirp->id);
+       }
 }
+
 /* }}} */
+/* {{{ proto int opendir(string path)
+   Open a directory and return a dir_handle */
+
+PHP_FUNCTION(opendir)
+{
+       _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+
+/* }}} */
+/* {{{ proto class dir(string directory)
+Directory class with properties, handle and class and methods read, rewind and close */
+
+PHP_FUNCTION(getdir)
+{
+       _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
 
+/* }}} */
 /* {{{ proto void closedir([int dir_handle])
 Close directory connection identified by the dir_handle */
+
 PHP_FUNCTION(closedir)
 {
-       pval *id, **tmp;
-       int id_to_find;
-       DIR *dirp;
-       int dirp_type;
-       
-       if (ARG_COUNT(ht) == 0) {
-               id = getThis();
-               if (id) {
-                       if (zend_hash_find(id->value.obj.properties, "handle", sizeof("handle"), (void **)&tmp) == FAILURE) {
-                               php_error(E_WARNING, "unable to find my handle property");
-                               RETURN_FALSE;
-                       }
-                       id_to_find = (*tmp)->value.lval;
-               } else {
-                       id_to_find = dirp_id;
-               }
-       } else if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       } else {
-               convert_to_long(id);
-               id_to_find = id->value.lval;
-       }
-               
-       dirp = (DIR *)php3_list_find(id_to_find, &dirp_type);
-       if (!dirp || dirp_type != le_dirp) {
-               php_error(E_WARNING, "unable to find identifier (%d)", id_to_find);
-               RETURN_FALSE;
-       }
-       php3_list_delete(id_to_find);
+       pval **id, **tmp, *myself;
+       php_dir *dirp;
+       DIRLS_FETCH();
+
+       FETCH_DIRP();
+
+       php3_list_delete(dirp->id);
 }
 /* }}} */
-
 /* {{{ proto int chdir(string directory)
 Change the current directory */
+
 PHP_FUNCTION(chdir)
 {
-       pval *arg;
+       pval **arg;
        int ret;
        
-       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) {
+       if (ARG_COUNT(ht) != 1 || getParametersEx(1, &arg) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_string(arg);
-       ret = chdir(arg->value.str.val);
+       convert_to_string_ex(arg);
 
+       ret = chdir((*arg)->value.str.val);
+       
        if (ret < 0) {
                php_error(E_WARNING, "ChDir: %s (errno %d)", strerror(errno), errno);
                RETURN_FALSE;
        }
+
        RETURN_TRUE;
 }
 /* }}} */
-
 /* {{{ proto void rewinddir([int dir_handle])
 Rewind dir_handle back to the start */
+
 PHP_FUNCTION(rewinddir)
 {
-       pval *id, **tmp;
-       int id_to_find;
-       DIR *dirp;
-       int dirp_type;
+       pval **id, **tmp, *myself;
+       php_dir *dirp;
+       DIRLS_FETCH();
        
-       if (ARG_COUNT(ht) == 0) {
-               id = getThis();
-               if (id) {
-                       if (zend_hash_find(id->value.obj.properties, "handle", sizeof("handle"), (void **)&tmp) == FAILURE) {
-                               php_error(E_WARNING, "unable to find my handle property");
-                               RETURN_FALSE;
-                       }
-                       id_to_find = (*tmp)->value.lval;
-               } else {
-                       id_to_find = dirp_id;
-               }
-       } else if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       } else {
-               convert_to_long(id);
-               id_to_find = id->value.lval;
-       }
-               
-       dirp = (DIR *)php3_list_find(id_to_find, &dirp_type);
-       if (!dirp || dirp_type != le_dirp) {
-               php_error(E_WARNING, "unable to find identifier (%d)", id_to_find);
-               RETURN_FALSE;
-       }
-       rewinddir(dirp);
+       FETCH_DIRP();
+
+       rewinddir(dirp->dir);
 }
 /* }}} */
-
 /* {{{ proto string readdir([int dir_handle])
 Read directory entry from dir_handle */
+
 PHP_FUNCTION(readdir)
 {
-       pval *id, **tmp;
-       int id_to_find;
-       DIR *dirp;
-       int dirp_type;
+       pval **id, **tmp, *myself;
+       php_dir *dirp;
        struct dirent *direntp;
+       DIRLS_FETCH();
+
+       FETCH_DIRP();
        
-       if (ARG_COUNT(ht) == 0) {
-               id = getThis();
-               if (id) {
-                       if (zend_hash_find(id->value.obj.properties, "handle", sizeof("handle"), (void **)&tmp) == FAILURE) {
-                               php_error(E_WARNING, "unable to find my handle property");
-                               RETURN_FALSE;
-                       }
-                       id_to_find = (*tmp)->value.lval;
-               } else {
-                       id_to_find = dirp_id;
-               }
-       } else if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       } else {
-               convert_to_long(id);
-               id_to_find = id->value.lval;
-       }
-               
-       dirp = (DIR *)php3_list_find(id_to_find, &dirp_type);
-       if (!dirp || dirp_type != le_dirp) {
-               php_error(E_WARNING, "unable to find identifier (%d)", id_to_find);
-               RETURN_FALSE;
-       }
-       direntp = readdir(dirp);
+       direntp = readdir(dirp->dir);
        if (direntp) {
                RETURN_STRINGL(direntp->d_name, strlen(direntp->d_name), 1);
        }
        RETURN_FALSE;
 }
-/* }}} */
 
-/* {{{ proto class dir(string directory)
-Directory class with properties, handle and class and methods read, rewind and close */
-PHP_FUNCTION(getdir)
-{
-       pval *arg;
-       DIR *dirp;
-       int ret;
-       
-       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       }
-       convert_to_string(arg);
-
-       /* Check open_basedir */
-       if (_php3_check_open_basedir(arg->value.str.val)) RETURN_FALSE;
-       
-       dirp = opendir(arg->value.str.val);
-       if (!dirp) {
-               php_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno), errno);
-               RETURN_FALSE;
-       }
-       ret = php3_list_insert(dirp, le_dirp);
-       dirp_id = ret;
-
-       /* construct an object with some methods */
-       object_init_ex(return_value, dir_class_entry_ptr);
-       add_property_long(return_value, "handle", ret);
-       add_property_stringl(return_value, "path", arg->value.str.val, arg->value.str.len, 1);
-}
 /* }}} */
 
+
 /*
  * Local variables:
  * tab-width: 4
index 29e00716e895c21a044f425e7960a0f4cafce9ef..8b5e2af026137a4efe360eeb3ccab2e06b5c5b6e 100644 (file)
@@ -1,34 +1,22 @@
-/* 
+/*
    +----------------------------------------------------------------------+
-   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   | PHP version 4.0                                                      |
    +----------------------------------------------------------------------+
-   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   | Copyright (c) 1997, 1998, 1999 The PHP Group                         |
    +----------------------------------------------------------------------+
-   | This program is free software; you can redistribute it and/or modify |
-   | it under the terms of one of the following licenses:                 |
-   |                                                                      |
-   |  A) the GNU General Public License as published by the Free Software |
-   |     Foundation; either version 2 of the License, or (at your option) |
-   |     any later version.                                               |
-   |                                                                      |
-   |  B) the PHP License as published by the PHP Development Team and     |
-   |     included in the distribution in the file: LICENSE                |
-   |                                                                      |
-   | This program is distributed in the hope that it will be useful,      |
-   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
-   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
-   | GNU General Public License for more details.                         |
-   |                                                                      |
-   | You should have received a copy of both licenses referred to here.   |
-   | If you did not, or have any questions about PHP licensing, please    |
-   | contact core@php.net.                                                |
+   | This source file is subject to version 2.0 of the PHP license,       |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_0.txt.                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
    | Authors:                                                             |
-   |                                                                      |
+   | PHP 4.0 patches by Thies C. Arntzen (thies@digicol.de)               |
    +----------------------------------------------------------------------+
  */
 
-
 /* $Id$ */
 
 #ifndef _PHP3_DIR_H