Diff for /embedaddon/php/main/streams/userspace.c between versions 1.1 and 1.1.1.3

version 1.1, 2012/02/21 23:48:05 version 1.1.1.3, 2013/07/22 01:32:11
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2013 The PHP Group                                |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | This source file is subject to version 3.01 of the PHP license,      |     | This source file is subject to version 3.01 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |     | that is bundled with this package in the file LICENSE, and is        |
Line 26 Line 26
 #ifdef HAVE_SYS_FILE_H  #ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>  #include <sys/file.h>
 #endif  #endif
   #include <stddef.h>
   
   #if HAVE_UTIME
   # ifdef PHP_WIN32
   #  include <sys/utime.h>
   # else
   #  include <utime.h>
   # endif
   #endif
   
 static int le_protocols;  static int le_protocols;
   
 struct php_user_stream_wrapper {  struct php_user_stream_wrapper {
Line 42  static int user_wrapper_unlink(php_stream_wrapper *wra Line 51  static int user_wrapper_unlink(php_stream_wrapper *wra
 static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC);  static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC);
 static int user_wrapper_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int options, php_stream_context *context TSRMLS_DC);  static int user_wrapper_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int options, php_stream_context *context TSRMLS_DC);
 static int user_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC);  static int user_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC);
   static int user_wrapper_metadata(php_stream_wrapper *wrapper, char *url, int option, void *value, php_stream_context *context TSRMLS_DC);
 static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, char *filename, char *mode,  static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, char *filename, char *mode,
                 int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);                  int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
   
Line 55  static php_stream_wrapper_ops user_stream_wops = { Line 65  static php_stream_wrapper_ops user_stream_wops = {
         user_wrapper_unlink,          user_wrapper_unlink,
         user_wrapper_rename,          user_wrapper_rename,
         user_wrapper_mkdir,          user_wrapper_mkdir,
        user_wrapper_rmdir        user_wrapper_rmdir,
         user_wrapper_metadata
 };  };
   
   
Line 77  PHP_MINIT_FUNCTION(user_streams) Line 88  PHP_MINIT_FUNCTION(user_streams)
   
         REGISTER_LONG_CONSTANT("STREAM_USE_PATH",                       USE_PATH, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("STREAM_USE_PATH",                       USE_PATH, CONST_CS|CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("STREAM_IGNORE_URL",             IGNORE_URL, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("STREAM_IGNORE_URL",             IGNORE_URL, CONST_CS|CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("STREAM_ENFORCE_SAFE_MODE",      ENFORCE_SAFE_MODE, CONST_CS|CONST_PERSISTENT);  
         REGISTER_LONG_CONSTANT("STREAM_REPORT_ERRORS",          REPORT_ERRORS, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("STREAM_REPORT_ERRORS",          REPORT_ERRORS, CONST_CS|CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("STREAM_MUST_SEEK",                      STREAM_MUST_SEEK, CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("STREAM_MUST_SEEK",                      STREAM_MUST_SEEK, CONST_CS|CONST_PERSISTENT);
   
Line 99  PHP_MINIT_FUNCTION(user_streams) Line 109  PHP_MINIT_FUNCTION(user_streams)
         REGISTER_LONG_CONSTANT("STREAM_CAST_AS_STREAM",         PHP_STREAM_AS_STDIO,                    CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("STREAM_CAST_AS_STREAM",         PHP_STREAM_AS_STDIO,                    CONST_CS|CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("STREAM_CAST_FOR_SELECT",        PHP_STREAM_AS_FD_FOR_SELECT,            CONST_CS|CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("STREAM_CAST_FOR_SELECT",        PHP_STREAM_AS_FD_FOR_SELECT,            CONST_CS|CONST_PERSISTENT);
   
           REGISTER_LONG_CONSTANT("STREAM_META_TOUCH",                     PHP_STREAM_META_TOUCH,                  CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("STREAM_META_OWNER",                     PHP_STREAM_META_OWNER,                  CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("STREAM_META_OWNER_NAME",        PHP_STREAM_META_OWNER_NAME,             CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("STREAM_META_GROUP",                     PHP_STREAM_META_GROUP,                  CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("STREAM_META_GROUP_NAME",        PHP_STREAM_META_GROUP_NAME,             CONST_CS|CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("STREAM_META_ACCESS",            PHP_STREAM_META_ACCESS,                 CONST_CS|CONST_PERSISTENT);
         return SUCCESS;          return SUCCESS;
 }  }
   
Line 130  typedef struct _php_userstream_data php_userstream_dat Line 146  typedef struct _php_userstream_data php_userstream_dat
 #define USERSTREAM_LOCK     "stream_lock"  #define USERSTREAM_LOCK     "stream_lock"
 #define USERSTREAM_CAST         "stream_cast"  #define USERSTREAM_CAST         "stream_cast"
 #define USERSTREAM_SET_OPTION   "stream_set_option"  #define USERSTREAM_SET_OPTION   "stream_set_option"
   #define USERSTREAM_TRUNCATE     "stream_truncate"
   #define USERSTREAM_METADATA     "stream_metadata"
   
 /* {{{ class should have methods like these:  /* {{{ class should have methods like these:
 
         function stream_open($path, $mode, $options, &$opened_path)          function stream_open($path, $mode, $options, &$opened_path)
         {          {
                 return true/false;                  return true/false;
         }          }
        
         function stream_read($count)          function stream_read($count)
         {          {
                 return false on error;                  return false on error;
                 else return string;                  else return string;
         }          }
        
         function stream_write($data)          function stream_write($data)
         {          {
                 return false on error;                  return false on error;
                 else return count written;                  else return count written;
         }          }
        
         function stream_close()          function stream_close()
         {          {
         }          }
        
         function stream_flush()          function stream_flush()
         {          {
                 return true/false;                  return true/false;
         }          }
        
         function stream_seek($offset, $whence)          function stream_seek($offset, $whence)
         {          {
                 return true/false;                  return true/false;
Line 255  typedef struct _php_userstream_data php_userstream_dat Line 273  typedef struct _php_userstream_data php_userstream_dat
         {          {
                 return true / false;                  return true / false;
         }          }
  
         function stream_truncate($new_size)
         {
                 return true / false;
         }
 
         }}} **/          }}} **/
   
static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)static zval *user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context TSRMLS_DC)
 {  {
        struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;        zval *object;
        php_userstream_data_t *us;        /* create an instance of our class */
        zval *zfilename, *zmode, *zopened, *zoptions, *zretval = NULL, *zfuncname;        ALLOC_ZVAL(object);
        zval **args[4];         object_init_ex(object, uwrap->ce);
        int call_result;        Z_SET_REFCOUNT_P(object, 1);
        php_stream *stream = NULL;        Z_SET_ISREF_P(object);
        zend_bool old_in_user_include; 
   
        /* Try to catch bad usage without preventing flexibility */        if (context) {
        if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) {                add_property_resource(object, "context", context->rsrc_id);
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented");                zend_list_addref(context->rsrc_id);
                return NULL;        } else {
                 add_property_null(object, "context");
         }          }
         FG(user_stream_current_filename) = filename;  
           
         /* if the user stream was registered as local and we are in include context,  
                 we add allow_url_include restrictions to allow_url_fopen ones */  
         /* we need only is_url == 0 here since if is_url == 1 and remote wrappers  
                 were restricted we wouldn't get here */  
         old_in_user_include = PG(in_user_include);  
         if(uwrap->wrapper.is_url == 0 &&   
                 (options & STREAM_OPEN_FOR_INCLUDE) &&  
                 !PG(allow_url_include)) {  
                 PG(in_user_include) = 1;  
         }  
   
         us = emalloc(sizeof(*us));  
         us->wrapper = uwrap;      
   
         /* create an instance of our class */  
         ALLOC_ZVAL(us->object);  
         object_init_ex(us->object, uwrap->ce);  
         Z_SET_REFCOUNT_P(us->object, 1);  
         Z_SET_ISREF_P(us->object);  
           
         if (uwrap->ce->constructor) {          if (uwrap->ce->constructor) {
                 zend_fcall_info fci;                  zend_fcall_info fci;
                 zend_fcall_info_cache fcc;                  zend_fcall_info_cache fcc;
                 zval *retval_ptr;                  zval *retval_ptr;
                
                 fci.size = sizeof(fci);                  fci.size = sizeof(fci);
                 fci.function_table = &uwrap->ce->function_table;                  fci.function_table = &uwrap->ce->function_table;
                 fci.function_name = NULL;                  fci.function_name = NULL;
                 fci.symbol_table = NULL;                  fci.symbol_table = NULL;
                fci.object_ptr = us->object;                fci.object_ptr = object;
                 fci.retval_ptr_ptr = &retval_ptr;                  fci.retval_ptr_ptr = &retval_ptr;
                 fci.param_count = 0;                  fci.param_count = 0;
                 fci.params = NULL;                  fci.params = NULL;
                 fci.no_separation = 1;                  fci.no_separation = 1;
                
                 fcc.initialized = 1;                  fcc.initialized = 1;
                 fcc.function_handler = uwrap->ce->constructor;                  fcc.function_handler = uwrap->ce->constructor;
                 fcc.calling_scope = EG(scope);                  fcc.calling_scope = EG(scope);
                fcc.called_scope = Z_OBJCE_P(us->object);                fcc.called_scope = Z_OBJCE_P(object);
                fcc.object_ptr = us->object;                fcc.object_ptr = object;
   
                 if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {                  if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute %s::%s()", uwrap->ce->name, uwrap->ce->constructor->common.function_name);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute %s::%s()", uwrap->ce->name, uwrap->ce->constructor->common.function_name);
                        zval_dtor(us->object);                        zval_dtor(object);
                        FREE_ZVAL(us->object);                        FREE_ZVAL(object);
                        efree(us); 
                        FG(user_stream_current_filename) = NULL; 
                        PG(in_user_include) = old_in_user_include; 
                         return NULL;                          return NULL;
                 } else {                  } else {
                         if (retval_ptr) {                          if (retval_ptr) {
Line 330  static php_stream *user_wrapper_opener(php_stream_wrap Line 329  static php_stream *user_wrapper_opener(php_stream_wrap
                         }                          }
                 }                  }
         }          }
           return object;
   }
   
        if (context) {static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
                add_property_resource(us->object, "context", context->rsrc_id);{
                zend_list_addref(context->rsrc_id);        struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;
        } else {        php_userstream_data_t *us;
                add_property_null(us->object, "context");        zval *zfilename, *zmode, *zopened, *zoptions, *zretval = NULL, *zfuncname;
         zval **args[4];
         int call_result;
         php_stream *stream = NULL;
         zend_bool old_in_user_include;
 
         /* Try to catch bad usage without preventing flexibility */
         if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) {
                 php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented");
                 return NULL;
         }          }
                FG(user_stream_current_filename) = filename;
 
         /* if the user stream was registered as local and we are in include context,
                 we add allow_url_include restrictions to allow_url_fopen ones */
         /* we need only is_url == 0 here since if is_url == 1 and remote wrappers
                 were restricted we wouldn't get here */
         old_in_user_include = PG(in_user_include);
         if(uwrap->wrapper.is_url == 0 &&
                 (options & STREAM_OPEN_FOR_INCLUDE) &&
                 !PG(allow_url_include)) {
                 PG(in_user_include) = 1;
         }
 
         us = emalloc(sizeof(*us));
         us->wrapper = uwrap;
 
         us->object = user_stream_create_object(uwrap, context TSRMLS_CC);
         if(us->object == NULL) {
                 FG(user_stream_current_filename) = NULL;
                 PG(in_user_include) = old_in_user_include;
                 efree(us);
                 return NULL;
         }
 
         /* call it's stream_open method - set up params first */          /* call it's stream_open method - set up params first */
         MAKE_STD_ZVAL(zfilename);          MAKE_STD_ZVAL(zfilename);
         ZVAL_STRING(zfilename, filename, 1);          ZVAL_STRING(zfilename, filename, 1);
Line 359  static php_stream *user_wrapper_opener(php_stream_wrap Line 392  static php_stream *user_wrapper_opener(php_stream_wrap
   
         MAKE_STD_ZVAL(zfuncname);          MAKE_STD_ZVAL(zfuncname);
         ZVAL_STRING(zfuncname, USERSTREAM_OPEN, 1);          ZVAL_STRING(zfuncname, USERSTREAM_OPEN, 1);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &us->object,                          &us->object,
                         zfuncname,                          zfuncname,
                         &zretval,                          &zretval,
                         4, args,                          4, args,
                         0, NULL TSRMLS_CC);                          0, NULL TSRMLS_CC);
        
         if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) {          if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) {
                 /* the stream is now open! */                  /* the stream is now open! */
                 stream = php_stream_alloc_rel(&php_stream_userspace_ops, us, 0, mode);                  stream = php_stream_alloc_rel(&php_stream_userspace_ops, us, 0, mode);
Line 383  static php_stream *user_wrapper_opener(php_stream_wrap Line 416  static php_stream *user_wrapper_opener(php_stream_wrap
                 php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_OPEN "\" call failed",                  php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_OPEN "\" call failed",
                         us->wrapper->classname);                          us->wrapper->classname);
         }          }
        
         /* destroy everything else */          /* destroy everything else */
         if (stream == NULL) {          if (stream == NULL) {
                 zval_ptr_dtor(&us->object);                  zval_ptr_dtor(&us->object);
Line 391  static php_stream *user_wrapper_opener(php_stream_wrap Line 424  static php_stream *user_wrapper_opener(php_stream_wrap
         }          }
         if (zretval)          if (zretval)
                 zval_ptr_dtor(&zretval);                  zval_ptr_dtor(&zretval);
        
         zval_ptr_dtor(&zfuncname);          zval_ptr_dtor(&zfuncname);
         zval_ptr_dtor(&zopened);          zval_ptr_dtor(&zopened);
         zval_ptr_dtor(&zoptions);          zval_ptr_dtor(&zoptions);
Line 399  static php_stream *user_wrapper_opener(php_stream_wrap Line 432  static php_stream *user_wrapper_opener(php_stream_wrap
         zval_ptr_dtor(&zfilename);          zval_ptr_dtor(&zfilename);
   
         FG(user_stream_current_filename) = NULL;          FG(user_stream_current_filename) = NULL;
                
         PG(in_user_include) = old_in_user_include;          PG(in_user_include) = old_in_user_include;
         return stream;          return stream;
 }  }
Line 410  static php_stream *user_wrapper_opendir(php_stream_wra Line 443  static php_stream *user_wrapper_opendir(php_stream_wra
         struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;          struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;
         php_userstream_data_t *us;          php_userstream_data_t *us;
         zval *zfilename, *zoptions, *zretval = NULL, *zfuncname;          zval *zfilename, *zoptions, *zretval = NULL, *zfuncname;
        zval **args[2];         zval **args[2];
         int call_result;          int call_result;
         php_stream *stream = NULL;          php_stream *stream = NULL;
   
Line 420  static php_stream *user_wrapper_opendir(php_stream_wra Line 453  static php_stream *user_wrapper_opendir(php_stream_wra
                 return NULL;                  return NULL;
         }          }
         FG(user_stream_current_filename) = filename;          FG(user_stream_current_filename) = filename;
        
         us = emalloc(sizeof(*us));          us = emalloc(sizeof(*us));
        us->wrapper = uwrap;            us->wrapper = uwrap;
   
        /* create an instance of our class */        us->object = user_stream_create_object(uwrap, context TSRMLS_CC);
        ALLOC_ZVAL(us->object);        if(us->object == NULL) {
        object_init_ex(us->object, uwrap->ce);                FG(user_stream_current_filename) = NULL;
        Z_SET_REFCOUNT_P(us->object, 1);                efree(us);
        Z_SET_ISREF_P(us->object);                return NULL;
 
        if (context) { 
                add_property_resource(us->object, "context", context->rsrc_id); 
                zend_list_addref(context->rsrc_id); 
        } else { 
                add_property_null(us->object, "context"); 
         }          }
        
         /* call it's dir_open method - set up params first */          /* call it's dir_open method - set up params first */
         MAKE_STD_ZVAL(zfilename);          MAKE_STD_ZVAL(zfilename);
         ZVAL_STRING(zfilename, filename, 1);          ZVAL_STRING(zfilename, filename, 1);
Line 448  static php_stream *user_wrapper_opendir(php_stream_wra Line 475  static php_stream *user_wrapper_opendir(php_stream_wra
   
         MAKE_STD_ZVAL(zfuncname);          MAKE_STD_ZVAL(zfuncname);
         ZVAL_STRING(zfuncname, USERSTREAM_DIR_OPEN, 1);          ZVAL_STRING(zfuncname, USERSTREAM_DIR_OPEN, 1);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &us->object,                          &us->object,
                         zfuncname,                          zfuncname,
                         &zretval,                          &zretval,
                         2, args,                          2, args,
                         0, NULL TSRMLS_CC);                          0, NULL TSRMLS_CC);
        
         if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) {          if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) {
                 /* the stream is now open! */                  /* the stream is now open! */
                 stream = php_stream_alloc_rel(&php_stream_userspace_dir_ops, us, 0, mode);                  stream = php_stream_alloc_rel(&php_stream_userspace_dir_ops, us, 0, mode);
Line 467  static php_stream *user_wrapper_opendir(php_stream_wra Line 494  static php_stream *user_wrapper_opendir(php_stream_wra
                 php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed",                  php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed",
                         us->wrapper->classname);                          us->wrapper->classname);
         }          }
        
         /* destroy everything else */          /* destroy everything else */
         if (stream == NULL) {          if (stream == NULL) {
                 zval_ptr_dtor(&us->object);                  zval_ptr_dtor(&us->object);
Line 475  static php_stream *user_wrapper_opendir(php_stream_wra Line 502  static php_stream *user_wrapper_opendir(php_stream_wra
         }          }
         if (zretval)          if (zretval)
                 zval_ptr_dtor(&zretval);                  zval_ptr_dtor(&zretval);
        
         zval_ptr_dtor(&zfuncname);          zval_ptr_dtor(&zfuncname);
         zval_ptr_dtor(&zoptions);          zval_ptr_dtor(&zoptions);
         zval_ptr_dtor(&zfilename);          zval_ptr_dtor(&zfilename);
   
         FG(user_stream_current_filename) = NULL;          FG(user_stream_current_filename) = NULL;
                
         return stream;          return stream;
 }  }
   
Line 495  PHP_FUNCTION(stream_wrapper_register) Line 522  PHP_FUNCTION(stream_wrapper_register)
         struct php_user_stream_wrapper * uwrap;          struct php_user_stream_wrapper * uwrap;
         int rsrc_id;          int rsrc_id;
         long flags = 0;          long flags = 0;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &protocol, &protocol_len, &classname, &classname_len, &flags) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &protocol, &protocol_len, &classname, &classname_len, &flags) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
         uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));          uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));
         uwrap->protoname = estrndup(protocol, protocol_len);          uwrap->protoname = estrndup(protocol, protocol_len);
         uwrap->classname = estrndup(classname, classname_len);          uwrap->classname = estrndup(classname, classname_len);
Line 585  PHP_FUNCTION(stream_wrapper_restore) Line 612  PHP_FUNCTION(stream_wrapper_restore)
         if (php_register_url_stream_wrapper_volatile(protocol, wrapper TSRMLS_CC) == FAILURE) {          if (php_register_url_stream_wrapper_volatile(protocol, wrapper TSRMLS_CC) == FAILURE) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to restore original %s:// wrapper", protocol);                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to restore original %s:// wrapper", protocol);
                 RETURN_FALSE;                  RETURN_FALSE;
        }               }
   
         RETURN_TRUE;          RETURN_TRUE;
 }  }
Line 633  static size_t php_userstreamop_write(php_stream *strea Line 660  static size_t php_userstreamop_write(php_stream *strea
                                 (long)(didwrite - count), (long)didwrite, (long)count);                                  (long)(didwrite - count), (long)didwrite, (long)count);
                 didwrite = count;                  didwrite = count;
         }          }
        
         if (retval)          if (retval)
                 zval_ptr_dtor(&retval);                  zval_ptr_dtor(&retval);
        
         return didwrite;          return didwrite;
 }  }
   
Line 721  static int php_userstreamop_close(php_stream *stream,  Line 748  static int php_userstreamop_close(php_stream *stream, 
         php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;          php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;
   
         assert(us != NULL);          assert(us != NULL);
        
         ZVAL_STRINGL(&func_name, USERSTREAM_CLOSE, sizeof(USERSTREAM_CLOSE)-1, 0);          ZVAL_STRINGL(&func_name, USERSTREAM_CLOSE, sizeof(USERSTREAM_CLOSE)-1, 0);
        
         call_user_function_ex(NULL,          call_user_function_ex(NULL,
                         &us->object,                          &us->object,
                         &func_name,                          &func_name,
Line 732  static int php_userstreamop_close(php_stream *stream,  Line 759  static int php_userstreamop_close(php_stream *stream, 
   
         if (retval)          if (retval)
                 zval_ptr_dtor(&retval);                  zval_ptr_dtor(&retval);
        
         zval_ptr_dtor(&us->object);          zval_ptr_dtor(&us->object);
   
         efree(us);          efree(us);
        
         return 0;          return 0;
 }  }
   
Line 750  static int php_userstreamop_flush(php_stream *stream T Line 777  static int php_userstreamop_flush(php_stream *stream T
         assert(us != NULL);          assert(us != NULL);
   
         ZVAL_STRINGL(&func_name, USERSTREAM_FLUSH, sizeof(USERSTREAM_FLUSH)-1, 0);          ZVAL_STRINGL(&func_name, USERSTREAM_FLUSH, sizeof(USERSTREAM_FLUSH)-1, 0);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &us->object,                          &us->object,
                         &func_name,                          &func_name,
Line 761  static int php_userstreamop_flush(php_stream *stream T Line 788  static int php_userstreamop_flush(php_stream *stream T
                 call_result = 0;                  call_result = 0;
         else          else
                 call_result = -1;                  call_result = -1;
        
         if (retval)          if (retval)
                 zval_ptr_dtor(&retval);                  zval_ptr_dtor(&retval);
        
         return call_result;          return call_result;
 }  }
   
Line 803  static int php_userstreamop_seek(php_stream *stream, o Line 830  static int php_userstreamop_seek(php_stream *stream, o
                 /* stream_seek is not implemented, so disable seeks for this stream */                  /* stream_seek is not implemented, so disable seeks for this stream */
                 stream->flags |= PHP_STREAM_FLAG_NO_SEEK;                  stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
                 /* there should be no retval to clean up */                  /* there should be no retval to clean up */
                
                if (retval)                 if (retval)
                         zval_ptr_dtor(&retval);                          zval_ptr_dtor(&retval);
                
                 return -1;                  return -1;
         } else if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) {          } else if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) {
                 ret = 0;                  ret = 0;
Line 890  static int statbuf_from_array(zval *array, php_stream_ Line 917  static int statbuf_from_array(zval *array, php_stream_
         STAT_PROP_ENTRY(blocks);          STAT_PROP_ENTRY(blocks);
 #endif  #endif
   
#undef STAT_PROP_ENTRY  #undef STAT_PROP_ENTRY
#undef STAT_PROP_ENTRY_EX       #undef STAT_PROP_ENTRY_EX
         return SUCCESS;          return SUCCESS;
 }  }
   
Line 921  static int php_userstreamop_stat(php_stream *stream, p Line 948  static int php_userstreamop_stat(php_stream *stream, p
                 }                  }
         }          }
   
        if (retval)         if (retval)
                 zval_ptr_dtor(&retval);                  zval_ptr_dtor(&retval);
        
         return ret;          return ret;
 }  }
   
Line 933  static int php_userstreamop_set_option(php_stream *str Line 960  static int php_userstreamop_set_option(php_stream *str
         zval *retval = NULL;          zval *retval = NULL;
         int call_result;          int call_result;
         php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;          php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;
        int ret = -1;        int ret = PHP_STREAM_OPTION_RETURN_NOTIMPL;
         zval *zvalue = NULL;          zval *zvalue = NULL;
         zval **args[3];          zval **args[3];
   
Line 971  static int php_userstreamop_set_option(php_stream *str Line 998  static int php_userstreamop_set_option(php_stream *str
                 }                  }
   
                 args[0] = &zvalue;                  args[0] = &zvalue;
                
                 /* TODO wouldblock */                  /* TODO wouldblock */
                 ZVAL_STRINGL(&func_name, USERSTREAM_LOCK, sizeof(USERSTREAM_LOCK)-1, 0);                  ZVAL_STRINGL(&func_name, USERSTREAM_LOCK, sizeof(USERSTREAM_LOCK)-1, 0);
                
                 call_result = call_user_function_ex(NULL,                  call_result = call_user_function_ex(NULL,
                                                                                         &us->object,                                                                                          &us->object,
                                                                                         &func_name,                                                                                          &func_name,
                                                                                         &retval,                                                                                          &retval,
                                                                                         1, args, 0, NULL TSRMLS_CC);                                                                                          1, args, 0, NULL TSRMLS_CC);
                
                 if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_BOOL) {                  if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_BOOL) {
                         ret = !Z_LVAL_P(retval);                          ret = !Z_LVAL_P(retval);
                 } else if (call_result == FAILURE) {                  } else if (call_result == FAILURE) {
                        if (value == 0) {                         if (value == 0) {
                                 /* lock support test (TODO: more check) */                                  /* lock support test (TODO: more check) */
                                ret = 0;                                ret = PHP_STREAM_OPTION_RETURN_OK;
                         } else {                          } else {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!",                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!",
                                                                  us->wrapper->classname);                                                                   us->wrapper->classname);
                                   ret = PHP_STREAM_OPTION_RETURN_ERR;
                         }                          }
                 }                  }
   
                 break;                  break;
        
         case PHP_STREAM_OPTION_TRUNCATE_API:
                 ZVAL_STRINGL(&func_name, USERSTREAM_TRUNCATE, sizeof(USERSTREAM_TRUNCATE)-1, 0);
 
                 switch (value) {
                 case PHP_STREAM_TRUNCATE_SUPPORTED:
                         if (zend_is_callable_ex(&func_name, us->object, IS_CALLABLE_CHECK_SILENT,
                                         NULL, NULL, NULL, NULL TSRMLS_CC))
                                 ret = PHP_STREAM_OPTION_RETURN_OK;
                         else
                                 ret = PHP_STREAM_OPTION_RETURN_ERR;
                         break;
 
                 case PHP_STREAM_TRUNCATE_SET_SIZE: {
                         ptrdiff_t new_size = *(ptrdiff_t*) ptrparam;
                         if (new_size >= 0 && new_size <= (ptrdiff_t)LONG_MAX) {
                                 MAKE_STD_ZVAL(zvalue);
                                 ZVAL_LONG(zvalue, (long)new_size);
                                 args[0] = &zvalue;
                                 call_result = call_user_function_ex(NULL,
                                                                                                         &us->object,
                                                                                                         &func_name,
                                                                                                         &retval,
                                                                                                         1, args, 0, NULL TSRMLS_CC);
                                 if (call_result == SUCCESS && retval != NULL) {
                                         if (Z_TYPE_P(retval) == IS_BOOL) {
                                                 ret = Z_LVAL_P(retval) ? PHP_STREAM_OPTION_RETURN_OK :
                                                                                                  PHP_STREAM_OPTION_RETURN_ERR;
                                         } else {
                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING,
                                                                 "%s::" USERSTREAM_TRUNCATE " did not return a boolean!",
                                                                 us->wrapper->classname);
                                         }
                                 } else {
                                         php_error_docref(NULL TSRMLS_CC, E_WARNING,
                                                         "%s::" USERSTREAM_TRUNCATE " is not implemented!",
                                                         us->wrapper->classname);
                                 }
                         } else { /* bad new size */
                                 ret = PHP_STREAM_OPTION_RETURN_ERR;
                         }
                         break;
                 }
                 }
                 break;
 
         case PHP_STREAM_OPTION_READ_BUFFER:          case PHP_STREAM_OPTION_READ_BUFFER:
         case PHP_STREAM_OPTION_WRITE_BUFFER:          case PHP_STREAM_OPTION_WRITE_BUFFER:
         case PHP_STREAM_OPTION_READ_TIMEOUT:          case PHP_STREAM_OPTION_READ_TIMEOUT:
         case PHP_STREAM_OPTION_BLOCKING: {          case PHP_STREAM_OPTION_BLOCKING: {
                 zval *zoption = NULL;                  zval *zoption = NULL;
                 zval *zptrparam = NULL;                  zval *zptrparam = NULL;
                
                 ZVAL_STRINGL(&func_name, USERSTREAM_SET_OPTION, sizeof(USERSTREAM_SET_OPTION)-1, 0);                  ZVAL_STRINGL(&func_name, USERSTREAM_SET_OPTION, sizeof(USERSTREAM_SET_OPTION)-1, 0);
   
                 ALLOC_INIT_ZVAL(zoption);                  ALLOC_INIT_ZVAL(zoption);
Line 1042  static int php_userstreamop_set_option(php_stream *str Line 1115  static int php_userstreamop_set_option(php_stream *str
                         &func_name,                          &func_name,
                         &retval,                          &retval,
                         3, args, 0, NULL TSRMLS_CC);                          3, args, 0, NULL TSRMLS_CC);
           
                 do {  
                         if (call_result == FAILURE) {  
                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!",  
                                                 us->wrapper->classname);  
                                 break;  
                         }  
                         if (retval && zend_is_true(retval)) {  
                                 ret = PHP_STREAM_OPTION_RETURN_OK;  
                         }  
                 } while (0);  
   
                   if (call_result == FAILURE) {
                           php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!",
                                           us->wrapper->classname);
                           ret = PHP_STREAM_OPTION_RETURN_ERR;
                   } else if (retval && zend_is_true(retval)) {
                           ret = PHP_STREAM_OPTION_RETURN_OK;
                   } else {
                           ret = PHP_STREAM_OPTION_RETURN_ERR;
                   }
   
                 if (zoption) {                  if (zoption) {
                         zval_ptr_dtor(&zoption);                          zval_ptr_dtor(&zoption);
                 }                  }
Line 1069  static int php_userstreamop_set_option(php_stream *str Line 1141  static int php_userstreamop_set_option(php_stream *str
         if (retval) {          if (retval) {
                 zval_ptr_dtor(&retval);                  zval_ptr_dtor(&retval);
         }          }
     
   
   
         if (zvalue) {          if (zvalue) {
                 zval_ptr_dtor(&zvalue);                  zval_ptr_dtor(&zvalue);
         }          }
Line 1089  static int user_wrapper_unlink(php_stream_wrapper *wra Line 1161  static int user_wrapper_unlink(php_stream_wrapper *wra
         int ret = 0;          int ret = 0;
   
         /* create an instance of our class */          /* create an instance of our class */
        ALLOC_ZVAL(object);        object = user_stream_create_object(uwrap, context TSRMLS_CC);
        object_init_ex(object, uwrap->ce);        if(object == NULL) {
        Z_SET_REFCOUNT_P(object, 1);                return ret;
        Z_SET_ISREF_P(object); 
 
        if (context) { 
                add_property_resource(object, "context", context->rsrc_id); 
                zend_list_addref(context->rsrc_id); 
        } else { 
                add_property_null(object, "context"); 
         }          }
   
         /* call the unlink method */          /* call the unlink method */
Line 1108  static int user_wrapper_unlink(php_stream_wrapper *wra Line 1173  static int user_wrapper_unlink(php_stream_wrapper *wra
   
         MAKE_STD_ZVAL(zfuncname);          MAKE_STD_ZVAL(zfuncname);
         ZVAL_STRING(zfuncname, USERSTREAM_UNLINK, 1);          ZVAL_STRING(zfuncname, USERSTREAM_UNLINK, 1);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &object,                          &object,
                         zfuncname,                          zfuncname,
Line 1126  static int user_wrapper_unlink(php_stream_wrapper *wra Line 1191  static int user_wrapper_unlink(php_stream_wrapper *wra
         zval_ptr_dtor(&object);          zval_ptr_dtor(&object);
         if (zretval)          if (zretval)
                 zval_ptr_dtor(&zretval);                  zval_ptr_dtor(&zretval);
        
         zval_ptr_dtor(&zfuncname);          zval_ptr_dtor(&zfuncname);
         zval_ptr_dtor(&zfilename);          zval_ptr_dtor(&zfilename);
   
Line 1143  static int user_wrapper_rename(php_stream_wrapper *wra Line 1208  static int user_wrapper_rename(php_stream_wrapper *wra
         int ret = 0;          int ret = 0;
   
         /* create an instance of our class */          /* create an instance of our class */
        ALLOC_ZVAL(object);        object = user_stream_create_object(uwrap, context TSRMLS_CC);     
        object_init_ex(object, uwrap->ce);        if(object == NULL) {
        Z_SET_REFCOUNT_P(object, 1);                return ret;
        Z_SET_ISREF_P(object); 
 
        if (context) { 
                add_property_resource(object, "context", context->rsrc_id); 
                zend_list_addref(context->rsrc_id); 
        } else { 
                add_property_null(object, "context"); 
         }          }
   
         /* call the rename method */          /* call the rename method */
Line 1166  static int user_wrapper_rename(php_stream_wrapper *wra Line 1224  static int user_wrapper_rename(php_stream_wrapper *wra
   
         MAKE_STD_ZVAL(zfuncname);          MAKE_STD_ZVAL(zfuncname);
         ZVAL_STRING(zfuncname, USERSTREAM_RENAME, 1);          ZVAL_STRING(zfuncname, USERSTREAM_RENAME, 1);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &object,                          &object,
                         zfuncname,                          zfuncname,
Line 1184  static int user_wrapper_rename(php_stream_wrapper *wra Line 1242  static int user_wrapper_rename(php_stream_wrapper *wra
         zval_ptr_dtor(&object);          zval_ptr_dtor(&object);
         if (zretval)          if (zretval)
                 zval_ptr_dtor(&zretval);                  zval_ptr_dtor(&zretval);
        
         zval_ptr_dtor(&zfuncname);          zval_ptr_dtor(&zfuncname);
         zval_ptr_dtor(&zold_name);          zval_ptr_dtor(&zold_name);
         zval_ptr_dtor(&znew_name);          zval_ptr_dtor(&znew_name);
Line 1202  static int user_wrapper_mkdir(php_stream_wrapper *wrap Line 1260  static int user_wrapper_mkdir(php_stream_wrapper *wrap
         int ret = 0;          int ret = 0;
   
         /* create an instance of our class */          /* create an instance of our class */
        ALLOC_ZVAL(object);        object = user_stream_create_object(uwrap, context TSRMLS_CC);     
        object_init_ex(object, uwrap->ce);        if(object == NULL) {
        Z_SET_REFCOUNT_P(object, 1);                return ret;
        Z_SET_ISREF_P(object); 
 
        if (context) { 
                add_property_resource(object, "context", context->rsrc_id); 
                zend_list_addref(context->rsrc_id); 
        } else { 
                add_property_null(object, "context"); 
         }          }
   
         /* call the mkdir method */          /* call the mkdir method */
Line 1229  static int user_wrapper_mkdir(php_stream_wrapper *wrap Line 1280  static int user_wrapper_mkdir(php_stream_wrapper *wrap
   
         MAKE_STD_ZVAL(zfuncname);          MAKE_STD_ZVAL(zfuncname);
         ZVAL_STRING(zfuncname, USERSTREAM_MKDIR, 1);          ZVAL_STRING(zfuncname, USERSTREAM_MKDIR, 1);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &object,                          &object,
                         zfuncname,                          zfuncname,
Line 1248  static int user_wrapper_mkdir(php_stream_wrapper *wrap Line 1299  static int user_wrapper_mkdir(php_stream_wrapper *wrap
         if (zretval) {          if (zretval) {
                 zval_ptr_dtor(&zretval);                  zval_ptr_dtor(&zretval);
         }          }
        
         zval_ptr_dtor(&zfuncname);          zval_ptr_dtor(&zfuncname);
         zval_ptr_dtor(&zfilename);          zval_ptr_dtor(&zfilename);
         zval_ptr_dtor(&zmode);          zval_ptr_dtor(&zmode);
Line 1267  static int user_wrapper_rmdir(php_stream_wrapper *wrap Line 1318  static int user_wrapper_rmdir(php_stream_wrapper *wrap
         int ret = 0;          int ret = 0;
   
         /* create an instance of our class */          /* create an instance of our class */
        ALLOC_ZVAL(object);        object = user_stream_create_object(uwrap, context TSRMLS_CC);     
        object_init_ex(object, uwrap->ce);        if(object == NULL) {
        Z_SET_REFCOUNT_P(object, 1);                return ret;
        Z_SET_ISREF_P(object); 
 
        if (context) { 
                add_property_resource(object, "context", context->rsrc_id); 
                zend_list_addref(context->rsrc_id); 
        } else { 
                add_property_null(object, "context"); 
         }          }
   
         /* call the rmdir method */          /* call the rmdir method */
Line 1290  static int user_wrapper_rmdir(php_stream_wrapper *wrap Line 1334  static int user_wrapper_rmdir(php_stream_wrapper *wrap
   
         MAKE_STD_ZVAL(zfuncname);          MAKE_STD_ZVAL(zfuncname);
         ZVAL_STRING(zfuncname, USERSTREAM_RMDIR, 1);          ZVAL_STRING(zfuncname, USERSTREAM_RMDIR, 1);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &object,                          &object,
                         zfuncname,                          zfuncname,
Line 1309  static int user_wrapper_rmdir(php_stream_wrapper *wrap Line 1353  static int user_wrapper_rmdir(php_stream_wrapper *wrap
         if (zretval) {          if (zretval) {
                 zval_ptr_dtor(&zretval);                  zval_ptr_dtor(&zretval);
         }          }
        
         zval_ptr_dtor(&zfuncname);          zval_ptr_dtor(&zfuncname);
         zval_ptr_dtor(&zfilename);          zval_ptr_dtor(&zfilename);
         zval_ptr_dtor(&zoptions);          zval_ptr_dtor(&zoptions);
Line 1317  static int user_wrapper_rmdir(php_stream_wrapper *wrap Line 1361  static int user_wrapper_rmdir(php_stream_wrapper *wrap
         return ret;          return ret;
 }  }
   
   static int user_wrapper_metadata(php_stream_wrapper *wrapper, char *url, int option, void *value, php_stream_context *context TSRMLS_DC)
   {
           struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;
           zval *zfilename, *zoption, *zvalue, *zfuncname, *zretval;
           zval **args[3];
           int call_result;
           zval *object;
           int ret = 0;
   
           MAKE_STD_ZVAL(zvalue);
           switch(option) {
                   case PHP_STREAM_META_TOUCH:
                           array_init(zvalue);
                           if(value) {
                                   struct utimbuf *newtime = (struct utimbuf *)value;
                                   add_index_long(zvalue, 0, newtime->modtime);
                                   add_index_long(zvalue, 1, newtime->actime);
                           }
                           break;
                   case PHP_STREAM_META_GROUP:
                   case PHP_STREAM_META_OWNER:
                   case PHP_STREAM_META_ACCESS:
                           ZVAL_LONG(zvalue, *(long *)value);
                           break;
                   case PHP_STREAM_META_GROUP_NAME:
                   case PHP_STREAM_META_OWNER_NAME:
                           ZVAL_STRING(zvalue, value, 1);
                           break;
                   default:
                           php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option %d for " USERSTREAM_METADATA, option);
                           zval_ptr_dtor(&zvalue);
                           return ret;
           }
   
           /* create an instance of our class */
           object = user_stream_create_object(uwrap, context TSRMLS_CC);   
           if(object == NULL) {
                   zval_ptr_dtor(&zvalue);
                   return ret;
           }
   
           /* call the mkdir method */
           MAKE_STD_ZVAL(zfilename);
           ZVAL_STRING(zfilename, url, 1);
           args[0] = &zfilename;
   
           MAKE_STD_ZVAL(zoption);
           ZVAL_LONG(zoption, option);
           args[1] = &zoption;
   
           args[2] = &zvalue;
   
           MAKE_STD_ZVAL(zfuncname);
           ZVAL_STRING(zfuncname, USERSTREAM_METADATA, 1);
   
           call_result = call_user_function_ex(NULL,
                           &object,
                           zfuncname,
                           &zretval,
                           3, args,
                           0, NULL TSRMLS_CC);
   
           if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) {
                   ret = Z_LVAL_P(zretval);
           } else if (call_result == FAILURE) {
                   php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", uwrap->classname);
           }
   
           /* clean up */
           zval_ptr_dtor(&object);
           if (zretval) {
                   zval_ptr_dtor(&zretval);
           }
   
           zval_ptr_dtor(&zfuncname);
           zval_ptr_dtor(&zfilename);
           zval_ptr_dtor(&zoption);
           zval_ptr_dtor(&zvalue);
   
           return ret;
   }
   
   
 static int user_wrapper_stat_url(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC)  static int user_wrapper_stat_url(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC)
 {  {
         struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;          struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;
         zval *zfilename, *zfuncname, *zretval, *zflags;          zval *zfilename, *zfuncname, *zretval, *zflags;
        zval **args[2];         zval **args[2];
         int call_result;          int call_result;
         zval *object;          zval *object;
         int ret = -1;          int ret = -1;
   
         /* create an instance of our class */          /* create an instance of our class */
        ALLOC_ZVAL(object);        object = user_stream_create_object(uwrap, context TSRMLS_CC);     
        object_init_ex(object, uwrap->ce);        if(object == NULL) {
        Z_SET_REFCOUNT_P(object, 1);                return ret;
        Z_SET_ISREF_P(object); 
 
        if (context) { 
                add_property_resource(object, "context", context->rsrc_id); 
                zend_list_addref(context->rsrc_id); 
        } else { 
                add_property_null(object, "context"); 
         }          }
   
         /* call it's stat_url method - set up params first */          /* call it's stat_url method - set up params first */
Line 1350  static int user_wrapper_stat_url(php_stream_wrapper *w Line 1470  static int user_wrapper_stat_url(php_stream_wrapper *w
   
         MAKE_STD_ZVAL(zfuncname);          MAKE_STD_ZVAL(zfuncname);
         ZVAL_STRING(zfuncname, USERSTREAM_STATURL, 1);          ZVAL_STRING(zfuncname, USERSTREAM_STATURL, 1);
        
         call_result = call_user_function_ex(NULL,          call_result = call_user_function_ex(NULL,
                         &object,                          &object,
                         zfuncname,                          zfuncname,
                         &zretval,                          &zretval,
                         2, args,                          2, args,
                         0, NULL TSRMLS_CC);                          0, NULL TSRMLS_CC);
        
         if (call_result == SUCCESS && zretval != NULL && Z_TYPE_P(zretval) == IS_ARRAY) {          if (call_result == SUCCESS && zretval != NULL && Z_TYPE_P(zretval) == IS_ARRAY) {
                 /* We got the info we needed */                  /* We got the info we needed */
                 if (SUCCESS == statbuf_from_array(zretval, ssb TSRMLS_CC))                  if (SUCCESS == statbuf_from_array(zretval, ssb TSRMLS_CC))
Line 1368  static int user_wrapper_stat_url(php_stream_wrapper *w Line 1488  static int user_wrapper_stat_url(php_stream_wrapper *w
                                         uwrap->classname);                                          uwrap->classname);
                 }                  }
         }          }
        
         /* clean up */          /* clean up */
         zval_ptr_dtor(&object);          zval_ptr_dtor(&object);
         if (zretval)          if (zretval)
                 zval_ptr_dtor(&zretval);                  zval_ptr_dtor(&zretval);
        
         zval_ptr_dtor(&zfuncname);          zval_ptr_dtor(&zfuncname);
         zval_ptr_dtor(&zfilename);          zval_ptr_dtor(&zfilename);
         zval_ptr_dtor(&zflags);          zval_ptr_dtor(&zflags);
                
         return ret;          return ret;
   
 }  }
Line 1427  static int php_userstreamop_closedir(php_stream *strea Line 1547  static int php_userstreamop_closedir(php_stream *strea
         php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;          php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;
   
         assert(us != NULL);          assert(us != NULL);
        
         ZVAL_STRINGL(&func_name, USERSTREAM_DIR_CLOSE, sizeof(USERSTREAM_DIR_CLOSE)-1, 0);          ZVAL_STRINGL(&func_name, USERSTREAM_DIR_CLOSE, sizeof(USERSTREAM_DIR_CLOSE)-1, 0);
        
         call_user_function_ex(NULL,          call_user_function_ex(NULL,
                         &us->object,                          &us->object,
                         &func_name,                          &func_name,
Line 1438  static int php_userstreamop_closedir(php_stream *strea Line 1558  static int php_userstreamop_closedir(php_stream *strea
   
         if (retval)          if (retval)
                 zval_ptr_dtor(&retval);                  zval_ptr_dtor(&retval);
        
         zval_ptr_dtor(&us->object);          zval_ptr_dtor(&us->object);
   
         efree(us);          efree(us);
        
         return 0;          return 0;
 }  }
   
Line 1453  static int php_userstreamop_rewinddir(php_stream *stre Line 1573  static int php_userstreamop_rewinddir(php_stream *stre
         php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;          php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;
   
         ZVAL_STRINGL(&func_name, USERSTREAM_DIR_REWIND, sizeof(USERSTREAM_DIR_REWIND)-1, 0);          ZVAL_STRINGL(&func_name, USERSTREAM_DIR_REWIND, sizeof(USERSTREAM_DIR_REWIND)-1, 0);
        
         call_user_function_ex(NULL,          call_user_function_ex(NULL,
                         &us->object,                          &us->object,
                         &func_name,                          &func_name,
Line 1462  static int php_userstreamop_rewinddir(php_stream *stre Line 1582  static int php_userstreamop_rewinddir(php_stream *stre
   
         if (retval)          if (retval)
                 zval_ptr_dtor(&retval);                  zval_ptr_dtor(&retval);
        
         return 0;          return 0;
   
 }  }
Line 1537  php_stream_ops php_stream_userspace_ops = { Line 1657  php_stream_ops php_stream_userspace_ops = {
         "user-space",          "user-space",
         php_userstreamop_seek,          php_userstreamop_seek,
         php_userstreamop_cast,          php_userstreamop_cast,
        php_userstreamop_stat,         php_userstreamop_stat,
         php_userstreamop_set_option,          php_userstreamop_set_option,
 };  };
   

Removed from v.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>