wez             Tue Apr 17 10:06:07 2001 EDT

  Modified files:              
    /php4/ext/standard  basic_functions.c file.c file.h fsock.c fsock.h 
                        info.c 
  Log:
  Changes for streams.  Added temporary fopenstream function to PHP so that
  the streams can be tested.
  
  
Index: php4/ext/standard/basic_functions.c
diff -u php4/ext/standard/basic_functions.c:1.323 
php4/ext/standard/basic_functions.c:1.324
--- php4/ext/standard/basic_functions.c:1.323   Sat Apr  7 08:43:06 2001
+++ php4/ext/standard/basic_functions.c Tue Apr 17 10:06:06 2001
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: basic_functions.c,v 1.323 2001/04/07 15:43:06 andre Exp $ */
+/* $Id: basic_functions.c,v 1.324 2001/04/17 17:06:06 wez Exp $ */
 
 #include "php.h"
 #include "php_main.h"
@@ -430,6 +430,9 @@
           use socket_set_blocking() instead */
        PHP_FE(set_socket_blocking,     NULL)
        PHP_FE(socket_set_blocking,     NULL)
+#if HAVE_PHP_STREAM
+       PHP_FE(fopenstream,                     NULL)
+#endif
 #if HAVE_SYS_TIME_H
        PHP_FE(socket_set_timeout,      NULL)
 #else
@@ -2491,11 +2494,11 @@
        if (!zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), 
Z_STRLEN_PP(path)+1)) {
                RETURN_FALSE;
        }
-       
+
        if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(new_path), NULL, 
CHECKUID_CHECK_FILE_AND_DIR))) {
                RETURN_FALSE;
        }
-       
+
        V_UNLINK(Z_STRVAL_PP(new_path));
        if (rename(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path))==0) {
                successful=1;
Index: php4/ext/standard/file.c
diff -u php4/ext/standard/file.c:1.152 php4/ext/standard/file.c:1.153
--- php4/ext/standard/file.c:1.152      Sun Apr 15 12:03:12 2001
+++ php4/ext/standard/file.c    Tue Apr 17 10:06:06 2001
@@ -20,7 +20,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: file.c,v 1.152 2001/04/15 19:03:12 sasha Exp $ */
+/* $Id: file.c,v 1.153 2001/04/17 17:06:06 wez Exp $ */
 
 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
 
@@ -101,7 +101,10 @@
 /* {{{ ZTS-stuff / Globals / Prototypes */
 
 /* sharing globals is *evil* */
-static int le_fopen, le_popen, le_socket; 
+static int le_fopen, le_popen, le_socket;
+/* sorry folks; including this even if you haven't enabled streams
+       saves a zillion ifdefs */
+static int le_stream = FAILURE;
 
 
 /* }}} */
@@ -116,7 +119,7 @@
 }
 
 
-static void _file_socket_dtor(zend_rsrc_list_entry *rsrc) 
+static void _file_socket_dtor(zend_rsrc_list_entry *rsrc)
 {
        int *sock = (int *)rsrc->ptr;
        SOCK_FCLOSE(*sock);
@@ -126,8 +129,15 @@
        efree(sock);
 }
 
+#if HAVE_PHP_STREAM
+static void _file_stream_dtor(zend_rsrc_list_entry * rsrc)
+{
+       php_stream * stream = (php_stream*)rsrc->ptr;
+       php_stream_close(stream);
+}
+#endif
 
-static void _file_fopen_dtor(zend_rsrc_list_entry *rsrc) 
+static void _file_fopen_dtor(zend_rsrc_list_entry *rsrc)
 {
        FILE *fp = (FILE *)rsrc->ptr;
        fclose(fp);
@@ -176,6 +186,10 @@
        le_popen = zend_register_list_destructors_ex(_file_popen_dtor, NULL, "pipe", 
module_number);
        le_socket = zend_register_list_destructors_ex(_file_socket_dtor, NULL, 
"socket", module_number);
 
+#if HAVE_PHP_STREAM
+       le_stream = zend_register_list_destructors_ex(_file_stream_dtor, NULL, 
+"stream", module_number);
+#endif
+
 #ifdef ZTS
        file_globals_id = ts_allocate_id(sizeof(php_file_globals), (ts_allocate_ctor) 
file_globals_ctor, (ts_allocate_dtor) file_globals_dtor);
 #else
@@ -217,20 +231,27 @@
     pval **arg1, **arg2, **arg3;
     int type, fd, act, ret, arg_count = ARG_COUNT(ht);
        void *what;
-       
+
     if (arg_count > 3 || zend_get_parameters_ex(arg_count, &arg1, &arg2, &arg3) == 
FAILURE) {
         WRONG_PARAM_COUNT;
     }
-       
-       what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
+
+       what = zend_fetch_resource(arg1, -1, "File-Handle", &type, 4, le_fopen, 
+le_popen, le_socket, le_stream);
        ZEND_VERIFY_RESOURCE(what);
-       
+
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               if (php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 
+1) == FAILURE)     {
+                       RETURN_FALSE;
+               }
+       } else 
+#endif
        if (type == le_socket) {
                fd = *(int *) what;
        } else {
                fd = fileno((FILE*) what);
        }
-       
+
     convert_to_long_ex(arg2);
 
     act = (*arg2)->value.lval & 3;
@@ -271,7 +292,7 @@
        char *token_data=NULL, *name=NULL, *value=NULL, *temp=NULL;
        php_meta_tags_token tok, tok_last;
        PLS_FETCH();
-       
+
        /* check args */
        switch (ARG_COUNT(ht)) {
        case 1:
@@ -290,7 +311,7 @@
                WRONG_PARAM_COUNT;
        }
        convert_to_string_ex(filename);
-       
+
        fp = php_fopen_wrapper((*filename)->value.str.val,"rb", 
use_include_path|ENFORCE_SAFE_MODE, &issock, &socketd, NULL);
        if (!fp && !socketd) {
                if (issock != BAD_URL) {
@@ -301,7 +322,7 @@
                }
                RETURN_FALSE;
        }
-       
+
        if (array_init(return_value)==FAILURE) {
                if (issock) {
                        SOCK_FCLOSE(socketd);
@@ -426,7 +447,7 @@
        int target_len, len;
        zend_bool reached_eof=0;
        PLS_FETCH();
-       
+
        /* check args */
        switch (ARG_COUNT(ht)) {
        case 1:
@@ -445,7 +466,7 @@
                WRONG_PARAM_COUNT;
        }
        convert_to_string_ex(filename);
-       
+
        fp = php_fopen_wrapper((*filename)->value.str.val,"rb", 
use_include_path|ENFORCE_SAFE_MODE, &issock, &socketd, NULL);
        if (!fp && !socketd) {
                if (issock != BAD_URL) {
@@ -460,8 +481,8 @@
        /* Initialize return array */
        if (array_init(return_value) == FAILURE) {
                RETURN_FALSE;
-       }       
-       
+       }
+
        /* Now loop through the file and do the magic quotes thing if needed */
        target_len = 0;
        target_buf = NULL;
@@ -519,7 +540,7 @@
        char *opened_path;
        char p[64];
        FILE *fp;
-       
+
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
@@ -555,6 +576,31 @@
 }
 /* }}} */
 
+PHP_FUNCTION(fopenstream)
+{
+#if HAVE_PHP_STREAM
+       zval ** zfilename, ** zmode;
+       php_stream * stream;
+
+       if (ZEND_NUM_ARGS() != 2  || zend_get_parameters_ex(2, &zfilename, &zmode) == 
+FAILURE)  {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string_ex(zfilename);
+       convert_to_string_ex(zmode);
+
+       stream = php_stream_fopen(Z_STRVAL_PP(zfilename), Z_STRVAL_PP(zmode));
+
+       if (stream == NULL)     {
+               zend_error(E_WARNING, "%s(): unable to open %s: %s", 
+get_active_function_name(), Z_STRVAL_PP(zfilename), strerror(errno));
+               RETURN_FALSE;
+       }
+       ZEND_REGISTER_RESOURCE(return_value, stream, le_stream);
+#else
+       zend_error(E_ERROR, "%s(): no stream support in this PHP build", 
+get_active_function_name());
+       RETURN_FALSE;
+#endif
+}
+
 /* {{{ proto int fopen(string filename, string mode [, int use_include_path])
    Open a file or a URL and return a file pointer */
 
@@ -567,7 +613,7 @@
        int use_include_path = 0;
        int issock=0, socketd=0;
        FLS_FETCH();
-       
+
        switch(ARG_COUNT(ht)) {
        case 2:
                if (zend_get_parameters_ex(2,&arg1,&arg2) == FAILURE) {
@@ -616,7 +662,7 @@
        }
 }
 
-/* }}} */      
+/* }}} */
 /* {{{ proto int fclose(int fp)
    Close an open file pointer */
 
@@ -625,14 +671,14 @@
        pval **arg1;
        int type;
        void *what;
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
-       what = zend_fetch_resource(arg1,-1,"File-Handle",&type,2,le_fopen,le_socket);
+       what = zend_fetch_resource(arg1, -1, "File-Handle", &type, 3, le_fopen, 
+le_socket, le_stream);
        ZEND_VERIFY_RESOURCE(what);
-       
+
        zend_list_delete((*arg1)->value.lval);
        RETURN_TRUE;
 }
@@ -648,7 +694,7 @@
        char *p,*tmp = NULL;
        char *b, buf[1024];
        PLS_FETCH();
-       
+
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
@@ -705,14 +751,14 @@
        pval **arg1;
        void *what;
        FLS_FETCH();
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
        what = zend_fetch_resource(arg1,-1,"File-Handle",NULL,1,le_popen);
        ZEND_VERIFY_RESOURCE(what);
-       
+
        zend_list_delete((*arg1)->value.lval);
        RETURN_LONG(FG(pclose_ret));
 }
@@ -728,23 +774,35 @@
        int issock=0;
        int socketd=0;
        void *what;
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
+       what = zend_fetch_resource(arg1, -1, "File-Handle", &type, 4, le_fopen, 
+le_popen, le_socket, le_stream);
        ZEND_VERIFY_RESOURCE(what);
 
        if (type == le_socket) {
                issock=1;
                socketd=*(int *) what;
-       } 
+       }
 
-       if (FP_FEOF(socketd, (FILE*)what, issock)) {
-               RETURN_TRUE;
-       } else {
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               if (php_stream_eof((php_stream*)what))
+               {
+                       RETURN_TRUE;
+               }
                RETURN_FALSE;
        }
+       else
+#endif
+       {
+               if (FP_FEOF(socketd, (FILE*)what, issock)) {
+                       RETURN_TRUE;
+               } else {
+                       RETURN_FALSE;
+               }
+       }
 }
 /* }}} */
 
@@ -756,7 +814,7 @@
       int ret = SUCCESS;
       int flags;
       int myflag = 0;
-      
+
 #ifdef PHP_WIN32
       /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */
          flags = !block;
@@ -784,27 +842,35 @@
 PHP_FUNCTION(socket_set_blocking)
 {
        pval **arg1, **arg2;
-       int block;
+       int block, type;
        int socketd = 0;
        void *what;
-       
+
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
-       what = zend_fetch_resource(arg1,-1,"File-Handle",NULL,1,le_socket);
+       what = zend_fetch_resource(arg1, -1, "File-Handle", &type, 2, le_socket, 
+le_stream);
        ZEND_VERIFY_RESOURCE(what);
 
        convert_to_long_ex(arg2);
        block = (*arg2)->value.lval;
-       
-       socketd = *(int*)what;
 
+       if (type == le_socket)  {
+               socketd = *(int*)what;
+       }
+#if HAVE_PHP_STREAM
+       else if (type == le_stream)     {
+               if (php_stream_cast((php_stream*)what, PHP_STREAM_AS_SOCKETD, 
+(void*)&socketd, 1) == FAILURE)   {
+                       RETURN_FALSE;
+               }
+       }
+#endif
        if (php_set_sock_blocking(socketd, block) == FAILURE)
                RETURN_FALSE;
 
        php_sockset_blocking(socketd, block == 0 ? 0 : 1);
-       
+
        RETURN_TRUE;
 }
 
@@ -831,11 +897,11 @@
                zend_get_parameters_ex(ZEND_NUM_ARGS(), &socket, &seconds, 
&microseconds)==FAILURE) {
                WRONG_PARAM_COUNT;
        }
-
+       /* XXX: add stream support --Wez. */
        what = zend_fetch_resource(socket, -1, "File-Handle", &type, 1, le_socket);
        ZEND_VERIFY_RESOURCE(what);
        socketd = *(int *)what;
-       
+
        convert_to_long_ex(seconds);
        t.tv_sec = (*seconds)->value.lval;
 
@@ -868,6 +934,7 @@
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &socket) 
== FAILURE) {
                WRONG_PARAM_COUNT;
        }
+       /* XXX: add stream support --Wez. */
 
        what = zend_fetch_resource(socket, -1, "File-Handle", &type, 1, le_socket);
        ZEND_VERIFY_RESOURCE(what);
@@ -896,12 +963,12 @@
        int socketd=0;
        void *what;
        PLS_FETCH();
-       
+
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
-       what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
+       what = zend_fetch_resource(arg1, -1, "File-Handle", &type, 4, le_fopen, 
+le_popen, le_socket, le_stream);
        ZEND_VERIFY_RESOURCE(what);
 
        convert_to_long_ex(arg2);
@@ -920,27 +987,44 @@
        buf = emalloc(sizeof(char) * (len + 1));
        /* needed because recv doesnt put a null at the end*/
        memset(buf,0,len+1);
-#ifdef HAVE_FLUSHIO
-       if (type == le_fopen) {
-               fseek((FILE*)what, 0, SEEK_CUR);
+
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               if (php_stream_gets((php_stream*)what, buf, len) == NULL)
+                       goto exit_failed;
        }
+       else
 #endif
-       if (FP_FGETS(buf, len, socketd, (FILE*)what, issock) == NULL) {
-               efree(buf);
-               RETVAL_FALSE;
+       {
+               if (type == le_socket) {
+                       issock=1;
+                       socketd=*(int*)what;
+               }
+#ifdef HAVE_FLUSHIO
+               if (type == le_fopen) {
+                       fseek((FILE*)what, 0, SEEK_CUR);
+               }
+#endif
+               if (FP_FGETS(buf, len, socketd, (FILE*)what, issock) == NULL)
+                       goto exit_failed;
+       }
+
+       if (PG(magic_quotes_runtime)) {
+               return_value->value.str.val = 
+php_addslashes(buf,0,&return_value->value.str.len,1);
        } else {
-               if (PG(magic_quotes_runtime)) {
-                       return_value->value.str.val = 
php_addslashes(buf,0,&return_value->value.str.len,1);
-               } else {
-                       return_value->value.str.val = buf;
-                       return_value->value.str.len = 
strlen(return_value->value.str.val);
-                       /* resize buffer if it's much larger than the result */
-                       if(return_value->value.str.len < len/2) {
-                               return_value->value.str.val = 
erealloc(buf,return_value->value.str.len+1);
-                       }
+               return_value->value.str.val = buf;
+               return_value->value.str.len = strlen(return_value->value.str.val);
+               /* resize buffer if it's much larger than the result */
+               if(return_value->value.str.len < len/2) {
+                       return_value->value.str.val = 
+erealloc(buf,return_value->value.str.len+1);
                }
-               return_value->type = IS_STRING;
        }
+       return_value->type = IS_STRING;
+       return;
+
+exit_failed:
+       RETVAL_FALSE;
+       efree(buf);
 }
 
 /* }}} */
@@ -955,12 +1039,12 @@
        int socketd=0;
        void *what;
        int result;
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
-       what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
+       what = zend_fetch_resource(arg1, -1, "File-Handle", &type, 4, le_fopen, 
+le_popen, le_socket, le_stream);
        ZEND_VERIFY_RESOURCE(what);
 
        if (type == le_socket) {
@@ -974,14 +1058,24 @@
        }
 #endif
        buf = emalloc(sizeof(int));
-       if ((result = FP_FGETC(socketd, (FILE*)what, issock)) == EOF) {
+
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               result = php_stream_getc((php_stream*)what);
+       }
+       else
+#endif
+       result = FP_FGETC(socketd, (FILE*)what, issock);
+
+
+       if (result == EOF) {
                efree(buf);
                RETVAL_FALSE;
        } else {
                buf[0]=result;
                buf[1]='\0';
-               return_value->value.str.val = buf; 
-               return_value->value.str.len = 1; 
+               return_value->value.str.val = buf;
+               return_value->value.str.len = 1;
                return_value->type = IS_STRING;
        }
 }
@@ -1023,7 +1117,7 @@
                break;
        }
 
-       what = 
zend_fetch_resource(fd,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
+       what = zend_fetch_resource(fd, -1, "File-Handle", &type, 4, le_fopen, 
+le_popen, le_socket, le_stream);
        ZEND_VERIFY_RESOURCE(what);
 
        if (type == le_socket) {
@@ -1041,6 +1135,16 @@
        buf = emalloc(sizeof(char) * (len + 1));
        /*needed because recv doesnt set null char at end*/
        memset(buf, 0, len + 1);
+
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               if (php_stream_gets((php_stream*)what, buf, len) == NULL)       {
+                       efree(buf);
+                       RETURN_FALSE;
+               }
+       }
+       else
+#endif
        if (FP_FGETS(buf, len, socketd, (FILE*)what, issock) == NULL) {
                efree(buf);
                RETURN_FALSE;
@@ -1057,64 +1161,75 @@
    Implements a mostly ANSI compatible fscanf() */
 PHP_FUNCTION(fscanf)
 {
-    int  result;
-    pval **file_handle, **format_string;
-    int len, type;
-    char *buf;
-    int issock=0;
-    int socketd=0;
-    void *what;
-    
-    zval ***args;
-    int argCount;   
-    
-    argCount = ZEND_NUM_ARGS();
-    if (argCount < 2) {
-        WRONG_PARAM_COUNT;
-    }
-    args = (zval ***)emalloc(argCount * sizeof(zval **));
-    if (!args || (zend_get_parameters_array_ex(argCount,args) == FAILURE)) {
-        efree( args );
-        WRONG_PARAM_COUNT;
-    }
-    
-    file_handle    = args[0];
-    format_string  = args[1];
-
-    what = 
zend_fetch_resource(file_handle,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
-
-    /*
-     * we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
-     * with a leak if we have an invalid filehandle. This needs changing
-     * if the code behind ZEND_VERIFY_RESOURCE changed. - cc
-     */
-    if (!what) {
-        efree(args);
-        RETURN_FALSE;
-    }
+       int  result;
+       pval **file_handle, **format_string;
+       int len, type;
+       char *buf;
+       int issock=0;
+       int socketd=0;
+       void *what;
 
-    len = SCAN_MAX_FSCANF_BUFSIZE;
+       zval ***args;
+       int argCount;
 
-    if (type == le_socket) {
-        issock=1;
-        socketd=*(int*)what;
-    }
-    buf = emalloc(sizeof(char) * (len + 1));
-    /* needed because recv doesnt put a null at the end*/
-    memset(buf,0,len+1);
-    if (FP_FGETS(buf, len, socketd, (FILE*)what, issock) == NULL) {
-        efree(buf);
-        RETVAL_FALSE;
-    } else {
-        convert_to_string_ex( format_string );  
-        result = php_sscanf_internal( buf,(*format_string)->value.str.val,
-                        argCount,args, 2,&return_value);
-        efree(args);
-        efree(buf);
-        if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
-            WRONG_PARAM_COUNT
-        }
-    }
+       argCount = ZEND_NUM_ARGS();
+       if (argCount < 2) {
+               WRONG_PARAM_COUNT;
+       }
+       args = (zval ***)emalloc(argCount * sizeof(zval **));
+       if (!args || (zend_get_parameters_array_ex(argCount,args) == FAILURE)) {
+               efree( args );
+               WRONG_PARAM_COUNT;
+       }
+
+       file_handle    = args[0];
+       format_string  = args[1];
+
+       what = zend_fetch_resource(file_handle, -1, "File-Handle", &type, 4, le_fopen, 
+le_popen, le_socket, le_stream);
+
+       /*
+        * we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
+        * with a leak if we have an invalid filehandle. This needs changing
+        * if the code behind ZEND_VERIFY_RESOURCE changed. - cc
+        */
+       if (!what) {
+               efree(args);
+               RETURN_FALSE;
+       }
+
+       len = SCAN_MAX_FSCANF_BUFSIZE;
+
+       if (type == le_socket) {
+               issock=1;
+               socketd=*(int*)what;
+       }
+       buf = emalloc(sizeof(char) * (len + 1));
+       /* needed because recv doesnt put a null at the end*/
+       memset(buf,0,len+1);
+
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               if (php_stream_gets((php_stream*)what, buf, len) == NULL)       {
+                       efree(buf);
+                       RETURN_FALSE;
+               }
+       }
+       else
+#endif
+
+       if (FP_FGETS(buf, len, socketd, (FILE*)what, issock) == NULL) {
+               efree(buf);
+               RETURN_FALSE;
+       } 
+
+       convert_to_string_ex( format_string );
+       result = php_sscanf_internal( buf,(*format_string)->value.str.val,
+                       argCount,args, 2,&return_value);
+       efree(args);
+       efree(buf);
+       if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
+               WRONG_PARAM_COUNT
+       }
 
 
 }
@@ -1153,9 +1268,10 @@
                WRONG_PARAM_COUNT;
                /* NOTREACHED */
                break;
-       }                               
+       }
 
-       what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
+       what = zend_fetch_resource(arg1, -1, "File-Handle", &type, 4, le_fopen,
+                       le_popen, le_socket, le_stream);
        ZEND_VERIFY_RESOURCE(what);
 
        if (type == le_socket) {
@@ -1168,6 +1284,13 @@
                php_stripslashes((*arg2)->value.str.val,&num_bytes);
        }
 
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               ret = php_stream_write((php_stream*)what, Z_STRVAL_PP(arg2), 
+num_bytes);
+       }
+       else
+#endif
+       
        if (issock){
                ret = SOCK_WRITEL((*arg2)->value.str.val,num_bytes,socketd);
        } else {
@@ -1181,7 +1304,7 @@
        RETURN_LONG(ret);
 }
 
-/* }}} */      
+/* }}} */
 /* {{{ proto int fflush(int fp)
    Flushes output */
 
@@ -1197,9 +1320,19 @@
                WRONG_PARAM_COUNT;
        }
 
-       what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
+       what = 
+zend_fetch_resource(arg1,-1,"File-Handle",&type,4,le_fopen,le_popen,le_socket, 
+le_stream);
        ZEND_VERIFY_RESOURCE(what);
 
+#if HAVE_PHP_STREAM
+       if (type == le_stream)  {
+               ret = php_stream_flush((php_stream*)what);
+               if (ret)        {
+                       RETURN_FALSE;
+               }
+               RETURN_TRUE;
+       }
+#endif
+       
        if (type == le_socket) {
                issock=1;
                socketd=*(int*)what;
@@ -1218,7 +1351,7 @@
        }
 }
 
-/* }}} */      
+/* }}} */
 /* {{{ proto int set_file_buffer(int fp, int buffer)
    Set file write buffer */
 
@@ -1227,24 +1360,26 @@
        pval **arg1, **arg2;
        int ret,type,buff;
        void *what;
-      
+
        switch (ARG_COUNT(ht)) {
        case 2:
                if (zend_get_parameters_ex(2, &arg1, &arg2)==FAILURE) {
                        RETURN_FALSE;
-               } 
+               }
                break;
        default:
                WRONG_PARAM_COUNT;
                /* NOTREACHED */
                break;
-       }                               
+       }
 
+       /* XXX: add stream support --Wez. */
+
        what = zend_fetch_resource(arg1,-1,"File-Handle",&type,2,le_fopen,le_popen);
        ZEND_VERIFY_RESOURCE(what);
 
        convert_to_long_ex(arg2);
-       buff = (*arg2)->value.lval;    
+       buff = (*arg2)->value.lval;
 
        /* if buff is 0 then set to non-buffered */
        if (buff == 0){
@@ -1256,7 +1391,7 @@
        RETURN_LONG(ret);
 }
 
-/* }}} */     
+/* }}} */
 /* {{{ proto int rewind(int fp)
    Rewind the position of a file pointer */
 
@@ -1264,14 +1399,15 @@
 {
        pval **arg1;
        void *what;
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       
+       /* XXX: add stream support --Wez. */
+
        what = zend_fetch_resource(arg1,-1,"File-Handle",NULL,2,le_fopen,le_popen);
        ZEND_VERIFY_RESOURCE(what);
-       
+
        rewind((FILE*) what);
        RETURN_TRUE;
 }
@@ -1285,19 +1421,20 @@
        pval **arg1;
        void *what;
        long ret;
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       
+       /* XXX: add stream support --Wez. */
+
        what = zend_fetch_resource(arg1,-1,"File-Handle",NULL,2,le_fopen,le_popen);
        ZEND_VERIFY_RESOURCE(what);
 
        ret = ftell((FILE*) what);
        if(ret == -1) {
                RETURN_FALSE;
-       } 
-       
+       }
+
        RETURN_LONG(ret);
 }
 
@@ -1310,12 +1447,13 @@
        zval **arg1, **arg2, **arg3;
        int argcount = ARG_COUNT(ht), whence = SEEK_SET;
        void *what;
-       
+
        if (argcount < 2 || argcount > 3 ||
            zend_get_parameters_ex(argcount, &arg1, &arg2, &arg3) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       
+       /* XXX: add stream support --Wez. */
+
        what = zend_fetch_resource(arg1,-1,"File-Handle",NULL,2,le_fopen,le_popen);
        ZEND_VERIFY_RESOURCE(what);
 
@@ -1324,7 +1462,7 @@
                convert_to_long_ex(arg3);
                whence = (*arg3)->value.lval;
        }
-       
+
        RETURN_LONG(fseek((FILE*)what, (*arg2)->value.lval, whence));
 }
 
@@ -1338,7 +1476,7 @@
        int ret;
        mode_t mode;
        PLS_FETCH();
-       
+
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
@@ -1356,7 +1494,7 @@
        RETURN_TRUE;
 }
 
-/* }}} */      
+/* }}} */
 /* {{{ proto int rmdir(string dirname)
    Remove a directory */
 
@@ -1365,7 +1503,7 @@
        pval **arg1;
        int ret;
        PLS_FETCH();
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
@@ -1381,7 +1519,7 @@
        RETURN_TRUE;
 }
 
-/* }}} */      
+/* }}} */
 /* {{{ php_passthru_fd */
 
 static size_t php_passthru_fd(int socketd, FILE *fp, int issock)
@@ -1389,8 +1527,9 @@
        size_t bcount = 0;
        int ready = 0;
        char buf[8192];
-       
-#ifdef HAVE_MMAP 
+       /* XXX: add stream support --Wez. */
+
+#ifdef HAVE_MMAP
        if(!issock) {
                int fd;
                struct stat sbuf;
@@ -1400,7 +1539,7 @@
 
                fd = fileno(fp);
                fstat(fd, &sbuf);
-       
+
                if (sbuf.st_size > sizeof(buf)) {
                        off = ftell(fp);
                        len = sbuf.st_size - off;
@@ -1423,7 +1562,7 @@
                        bcount += b;
                }
        }
-               
+
        return bcount;
 }
 
@@ -1439,7 +1578,7 @@
        int use_include_path=0;
        int issock=0, socketd=0;
        int rsrc_id;
-       
+
        /* check args */
        switch (ARG_COUNT(ht)) {
        case 1:
@@ -1498,7 +1637,7 @@
        pval **arg1;
        int oldumask;
        int arg_count = ARG_COUNT(ht);
-       
+
        oldumask = umask(077);
 
        if (arg_count == 0) {
@@ -1527,11 +1666,12 @@
        int issock=0;
        int socketd=0;
        void *what;
-       
+
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
+       /* XXX: add stream support --Wez. */
        what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
        ZEND_VERIFY_RESOURCE(what);
 
@@ -1556,7 +1696,7 @@
        char *old_name, *new_name;
        int ret;
        PLS_FETCH();
-       
+
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &old_arg, &new_arg) == 
FAILURE) {
                WRONG_PARAM_COUNT;
        }
@@ -1589,7 +1729,7 @@
        pval **filename;
        int ret;
        PLS_FETCH();
-       
+
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
@@ -1623,7 +1763,8 @@
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &fp, &size) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       
+       /* XXX: add stream support --Wez. */
+
        what = 
zend_fetch_resource(fp,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
        ZEND_VERIFY_RESOURCE(what);
 
@@ -1652,6 +1793,7 @@
        if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &fp) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
+       /* XXX: add stream support --Wez. */
 
        what = 
zend_fetch_resource(fp,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
        ZEND_VERIFY_RESOURCE(what);
@@ -1675,7 +1817,7 @@
 #ifdef HAVE_ST_BLKSIZE
        add_assoc_long ( return_value , "blksize" , stat_sb.st_blksize );
 #endif
-       
+
        add_assoc_long ( return_value , "size" , stat_sb.st_size );
        add_assoc_long ( return_value , "atime" , stat_sb.st_atime );
        add_assoc_long ( return_value , "mtime" , stat_sb.st_mtime );
@@ -1770,12 +1912,12 @@
                }
        }
        ret = SUCCESS;
-       
+
 cleanup:
        close(fd_s);
        close(fd_t);
        return ret;
-}      
+}
 
 
 
@@ -1791,10 +1933,11 @@
        int socketd=0;
        void *what;
        PLS_FETCH();
-       
+
        if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
+       /* XXX: add stream support --Wez. */
 
        what = 
zend_fetch_resource(arg1,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
        ZEND_VERIFY_RESOURCE(what);
@@ -1813,7 +1956,7 @@
 
        return_value->value.str.val = emalloc(sizeof(char) * (len + 1));
        /* needed because recv doesnt put a null at the end*/
-       
+
        if (!issock) {
 #ifdef HAVE_FLUSHIO
                if (type == le_fopen) {
@@ -1834,7 +1977,7 @@
 /* }}} */
 /* {{{ proto array fgetcsv(int fp, int length [, string delimiter])
    Get line from file pointer and parse for CSV fields */
- 
+
 PHP_FUNCTION(fgetcsv) {
        char *temp, *tptr, *bptr, *lineEnd;
        char delimiter = ',';   /* allow this to be set as parameter */
@@ -1847,14 +1990,14 @@
        int issock=0;
        int socketd=0;
        void *what;
-       
+
        switch(ARG_COUNT(ht)) {
        case 2:
                if (zend_get_parameters_ex(2, &fd, &bytes) == FAILURE) {
                        WRONG_PARAM_COUNT;
                }
                break;
-               
+
        case 3:
                if (zend_get_parameters_ex(3, &fd, &bytes, &p_delim) == FAILURE) {
                        WRONG_PARAM_COUNT;
@@ -1867,12 +2010,13 @@
                        /* use first character from string */
                delimiter = (*p_delim)->value.str.val[0];
                break;
-               
+
        default:
                WRONG_PARAM_COUNT;
                /* NOTREACHED */
                break;
        }
+       /* XXX: add stream support --Wez. */
 
        what = 
zend_fetch_resource(fd,-1,"File-Handle",&type,3,le_fopen,le_popen,le_socket);
        ZEND_VERIFY_RESOURCE(what);
@@ -1884,10 +2028,10 @@
 
        convert_to_long_ex(bytes);
        len = (*bytes)->value.lval;
-    if (len < 0) {
+       if (len < 0) {
                php_error(E_WARNING, "length parameter to fgetcsv() may not be 
negative");
                RETURN_FALSE;
-    }
+       }
 
        buf = emalloc(sizeof(char) * (len + 1));
        /*needed because recv doesnt set null char at end*/
@@ -1902,11 +2046,11 @@
        /* Strip trailing space from buf, saving end of line in case required for 
quoted field */
 
        lineEnd = emalloc(sizeof(char) * (len + 1));
-        bptr = buf;
-        tptr = buf + strlen(buf) -1;
-        while ( isspace((int)*tptr) && (*tptr!=delimiter) && (tptr > bptr) ) tptr--;
-        tptr++;
-        strcpy(lineEnd, tptr);
+       bptr = buf;
+       tptr = buf + strlen(buf) -1;
+       while ( isspace((int)*tptr) && (*tptr!=delimiter) && (tptr > bptr) ) tptr--;
+       tptr++;
+       strcpy(lineEnd, tptr);
 
        /* add single space - makes it easier to parse trailing null field */
        *tptr++ = ' ';
@@ -1929,8 +2073,8 @@
        /* NB this routine will return a single null entry for a blank line */
 
        do      {
-               /* 1. Strip any leading space */                
-               while(isspace((int)*bptr) && (*bptr!=delimiter)) bptr++;        
+               /* 1. Strip any leading space */
+               while(isspace((int)*bptr) && (*bptr!=delimiter)) bptr++;
                /* 2. Read field, leaving bptr pointing at start of next field */
                if (*bptr == '"') {
                        /* 2A. handle quote delimited field */
@@ -1952,26 +2096,26 @@
                                /* normal character */
                                        *tptr++ = *bptr++;
 
-                                        if (*bptr == 0) {       /* embedded line end? 
*/
-                                                *(tptr-1)=0;            /* remove 
space character added on reading line */
-                                                strcat(temp,lineEnd);   /* add the 
embedded line end to the field */
+                                       if (*bptr == 0) {       /* embedded line end? 
+*/
+                                               *(tptr-1)=0;            /* remove 
+space character added on reading line */
+                                               strcat(temp,lineEnd);   /* add the 
+embedded line end to the field */
 
-                                                        /* read a new line from 
input, as at start of routine */
-                                                memset(buf,0,len+1);
+                                               /* read a new line from input, as at 
+start of routine */
+                                               memset(buf,0,len+1);
                                                if (FP_FGETS(buf, len, socketd, 
(FILE*)what, issock) == NULL) {
-                                                        efree(lineEnd); efree(temp); 
efree(buf);
-                                                                                      
                         zval_dtor(return_value);
-                                                        RETURN_FALSE;
-                                                        }
-                                                bptr = buf;
-                                                tptr = buf + strlen(buf) -1;
-                                                while ( isspace((int)*tptr) && 
(*tptr!=delimiter) && (tptr > bptr) ) tptr--;
-                                                tptr++; strcpy(lineEnd, tptr);
-                                                *tptr++ = ' ';  *tptr = 0;
-
-                                                tptr=temp;      /* reset temp pointer 
to end of field as read so far */
-                                                while (*tptr) tptr++;
-                                        }
+                                                       efree(lineEnd); efree(temp); 
+efree(buf);
+                                                       zval_dtor(return_value);
+                                                       RETURN_FALSE;
+                                               }
+                                               bptr = buf;
+                                               tptr = buf + strlen(buf) -1;
+                                               while ( isspace((int)*tptr) && 
+(*tptr!=delimiter) && (tptr > bptr) ) tptr--;
+                                               tptr++; strcpy(lineEnd, tptr);
+                                               *tptr++ = ' ';  *tptr = 0;
+
+                                               tptr=temp;      /* reset temp pointer 
+to end of field as read so far */
+                                               while (*tptr) tptr++;
+                                       }
                                }
                        }
                } else {
@@ -1988,7 +2132,7 @@
                add_next_index_string(return_value, temp, 1);
                tptr=temp;
        } while (*bptr);
-       
+
        efree(lineEnd);
        efree(temp);
        efree(buf);
@@ -2010,7 +2154,7 @@
        }
 
        convert_to_string_ex(path);
-       
+
        if (V_REALPATH((*path)->value.str.val, resolved_path_buff)) {
                RETURN_STRING(resolved_path_buff, 1);
        } else {
@@ -2028,50 +2172,52 @@
 
 PHP_FUNCTION(fd_set)
 {
-        pval **arg;
-        void *what;
-        int type, fd;
-
-        if(ARG_COUNT(ht) <= 0) {
-                php_error(E_WARNING, "fd_set: Must be passed at least one value" );
-                var_uninit(return_value);
-                return;
-        }
-        else if(ARG_COUNT(ht) == 1) {
-                if(zend_get_parameters_ex(1, &arg) == FAILURE) {
-                        WRONG_PARAM_COUNT;
-                }
-        what = 
zend_fetch_resource(arg,-1,"select",&type,3,le_fopen,le_socket,le_popen);
-        ZEND_VERIFY_RESOURCE(what);
-        if(type == le_socket) {
-                fd = *(int *)what;
-        } else {
-                fd = fileno((FILE *)what);
-        }
-        max_fd = fd;
-        FD_ZERO(&readfd);
-        FD_SET(max_fd, &readfd);
-        }
-        else {
-                pval ***args = (pval ***) emalloc(sizeof(pval **) * ARG_COUNT(ht));
-                int i;
-                if(zend_get_parameters_array_ex(ARG_COUNT(ht), args) == FAILURE) {
-                        efree(args);
-                        WRONG_PARAM_COUNT;
-                }
-                FD_ZERO(&readfd);
-                for(i = 0; i < ARG_COUNT(ht); i++) {
-                        what = 
zend_fetch_resource(*args,-1,"select",&type,3,le_fopen,le_socket,le_popen);
-                        ZEND_VERIFY_RESOURCE(what);
-                        if(type == le_socket) {
-                                fd = *(int *)what;
-                        } else {
-                                fd = fileno((FILE *)what);
-                        }
-                FD_SET(fd, &readfd);
-                if(fd > max_fd) max_fd = fd;
+       pval **arg;
+       void *what;
+       int type, fd;
+
+       if(ARG_COUNT(ht) <= 0) {
+                       php_error(E_WARNING, "fd_set: Must be passed at least one 
+value" );
+                       var_uninit(return_value);
+                       return;
+       }
+       else if(ARG_COUNT(ht) == 1) {
+               if(zend_get_parameters_ex(1, &arg) == FAILURE) {
+                               WRONG_PARAM_COUNT;
                }
-       efree(args);
+       /* XXX: add stream support --Wez. */
+               what = 
+zend_fetch_resource(arg,-1,"select",&type,3,le_fopen,le_socket,le_popen);
+               ZEND_VERIFY_RESOURCE(what);
+               if(type == le_socket) {
+                               fd = *(int *)what;
+               } else {
+                               fd = fileno((FILE *)what);
+               }
+               max_fd = fd;
+               FD_ZERO(&readfd);
+               FD_SET(max_fd, &readfd);
+       }
+       else {
+               pval ***args = (pval ***) emalloc(sizeof(pval **) * ARG_COUNT(ht));
+               int i;
+               if(zend_get_parameters_array_ex(ARG_COUNT(ht), args) == FAILURE) {
+                               efree(args);
+                               WRONG_PARAM_COUNT;
+               }
+               FD_ZERO(&readfd);
+               for(i = 0; i < ARG_COUNT(ht); i++) {
+       /* XXX: add stream support --Wez. */
+                               what = 
+zend_fetch_resource(*args,-1,"select",&type,3,le_fopen,le_socket,le_popen);
+                               ZEND_VERIFY_RESOURCE(what);
+                               if(type == le_socket) {
+                                               fd = *(int *)what;
+                               } else {
+                                               fd = fileno((FILE *)what);
+                               }
+                       FD_SET(fd, &readfd);
+                       if(fd > max_fd) max_fd = fd;
+               }
+               efree(args);
        }
        RETURN_LONG(1);
 }
@@ -2089,6 +2235,7 @@
 
        tv.tv_sec = (*timeout)->value.lval / 1000000;
        tv.tv_usec = (*timeout)->value.lval % 1000000;
+       /* XXX: add stream support --Wez. */
 
        RETURN_LONG(select(max_fd + 1,&readfd,NULL,NULL,((*timeout)->value.lval <= 0) 
? NULL : &tv));
 }
@@ -2102,6 +2249,7 @@
        if(ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &fdarg) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
+       /* XXX: add stream support --Wez. */
 
        what = 
zend_fetch_resource(fdarg,-1,"select",&type,3,le_fopen,le_socket,le_popen);
        ZEND_VERIFY_RESOURCE(what);
@@ -2114,9 +2262,9 @@
 
        if(FD_ISSET(fd,&readfd)) {
                RETURN_TRUE;
-       }       
+       }
        RETURN_FALSE;
-}      
+}
 
 #endif
 
@@ -2127,9 +2275,10 @@
        size_t len = 0, max_len;
        int step = PHP_FSOCK_CHUNK_SIZE;
        int min_room = PHP_FSOCK_CHUNK_SIZE/4;
-       
+
        ptr = *buf = emalloc(step);
        max_len = step;
+       /* XXX: add stream support --Wez. */
 
        while((ret = FP_FREAD(ptr, max_len - len, socket, fp, issock))) {
                len += ret;
@@ -2193,7 +2342,7 @@
                                if (*datalen == META_DEF_BUFSIZE)
                                        break;
                        }
-                       
+
             *data = (char *) emalloc( *datalen + 1 );
                        memcpy(*data,buff,*datalen+1);
 
Index: php4/ext/standard/file.h
diff -u php4/ext/standard/file.h:1.34 php4/ext/standard/file.h:1.35
--- php4/ext/standard/file.h:1.34       Sun Feb 25 22:07:17 2001
+++ php4/ext/standard/file.h    Tue Apr 17 10:06:06 2001
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: file.h,v 1.34 2001/02/26 06:07:17 andi Exp $ */
+/* $Id: file.h,v 1.35 2001/04/17 17:06:06 wez Exp $ */
 
 /* Synced with php 3.0 revision 1.30 1999-06-16 [ssb] */
 
@@ -66,6 +66,10 @@
 PHP_FUNCTION(realpath);
 PHP_NAMED_FUNCTION(php_if_ftruncate);
 PHP_NAMED_FUNCTION(php_if_fstat);
+
+/* temporary function for testing streams */
+PHP_FUNCTION(fopenstream);
+
 
 PHPAPI int php_set_sock_blocking(int socketd, int block);
 PHPAPI int php_file_le_fopen(void);
Index: php4/ext/standard/fsock.c
diff -u php4/ext/standard/fsock.c:1.65 php4/ext/standard/fsock.c:1.66
--- php4/ext/standard/fsock.c:1.65      Sun Feb 25 22:07:17 2001
+++ php4/ext/standard/fsock.c   Tue Apr 17 10:06:06 2001
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: fsock.c,v 1.65 2001/02/26 06:07:17 andi Exp $ */
+/* $Id: fsock.c,v 1.66 2001/04/17 17:06:06 wez Exp $ */
 
 /* Synced with php 3.0 revision 1.121 1999-06-18 [ssb] */
 /* Synced with php 3.0 revision 1.133 1999-07-21 [sas] */
@@ -204,7 +204,7 @@
 /* }}} */
 /* {{{ php_fsockopen() */
 
-/* 
+/*
    This function takes an optional third argument which should be
    passed by reference.  The error code from the connect call is written
    to this variable.
@@ -221,7 +221,7 @@
        unsigned long conv;
        char *key = NULL;
        FLS_FETCH();
-       
+
        if (arg_count > 5 || arg_count < 2 || 
zend_get_parameters_array_ex(arg_count,args)==FAILURE) {
                CLOSE_SOCK(1);
                WRONG_PARAM_COUNT;
@@ -256,7 +256,7 @@
                ZEND_REGISTER_RESOURCE(return_value,sock,php_file_le_socket());
                return;
        }
-       
+
        if (portno) {
                struct sockaddr_in server;
 
@@ -264,23 +264,23 @@
                if(Z_STRLEN_PP(args[0]) >= 6 && !memcmp(Z_STRVAL_PP(args[0]), 
"udp://", sizeof("udp://")-1)) {
                        udp = 1;
                }
-               
+
                socketd = socket(AF_INET,udp ? SOCK_DGRAM : SOCK_STREAM,0);
 
                if (socketd == SOCK_ERR) {
                        CLOSE_SOCK(1);
                        RETURN_FALSE;
                }
-         
+
                server.sin_family = AF_INET;
-               
+
                if(php_lookup_hostname(udp ? &(*args[0])->value.str.val[6] : 
(*args[0])->value.str.val,&server.sin_addr)) {
                        CLOSE_SOCK(1);
                        RETURN_FALSE;
                }
-  
+
                server.sin_port = htons(portno);
-  
+
                if (connect_nonb(socketd, (struct sockaddr *)&server, sizeof(server), 
&timeout) == SOCK_CONN_ERR) {
                        CLOSE_SOCK(1);
 
@@ -303,7 +303,7 @@
                        CLOSE_SOCK(1);
                        RETURN_FALSE;
                }
-         
+
                memset(&unix_addr, (char)0, sizeof(unix_addr));
                unix_addr.sun_family = AF_UNIX;
                strlcpy(unix_addr.sun_path, (*args[0])->value.str.val, 
sizeof(unix_addr.sun_path));
@@ -328,7 +328,7 @@
                RETURN_LONG(-6);  /* FIXME */
        }
 
-#ifdef HAVE_SETVBUF  
+#ifdef HAVE_SETVBUF
        if ((setvbuf(fp, NULL, _IONBF, 0)) != 0){
                RETURN_LONG(-7);  /* FIXME */
        }
@@ -337,7 +337,7 @@
 
        *sock=socketd;
        if (persistent) {
-               zend_hash_update(&FG(ht_fsock_keys), key, strlen(key) + 1, 
+               zend_hash_update(&FG(ht_fsock_keys), key, strlen(key) + 1,
                                sock, sizeof(*sock), NULL);
                zend_hash_update(&FG(ht_fsock_socks), (char *) sock, sizeof(*sock),
                                key, strlen(key) + 1, NULL);
@@ -350,14 +350,14 @@
 
 /* {{{ proto int fsockopen(string hostname, int port [, int errno [, string errstr [, 
double timeout]]])
    Open Internet or Unix domain socket connection */
-PHP_FUNCTION(fsockopen) 
+PHP_FUNCTION(fsockopen)
 {
        php_fsockopen(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
 }
 /* }}} */
 /* {{{ proto int pfsockopen(string hostname, int port [, int errno [, string errstr 
[, double timeout]]])
    Open persistent Internet or Unix domain socket connection */
-PHP_FUNCTION(pfsockopen) 
+PHP_FUNCTION(pfsockopen)
 {
        php_fsockopen(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
 }
@@ -396,7 +396,7 @@
 {
        php_sockbuf *buf = NULL, *tmp;
 
-       for(tmp = FG(phpsockbuf); tmp; tmp = tmp->next) 
+       for(tmp = FG(phpsockbuf); tmp; tmp = tmp->next)
                if(tmp->socket == socket) {
                        buf = tmp;
                        break;
@@ -412,7 +412,7 @@
 
        sock = pecalloc(sizeof(*sock), 1, persistent);
        sock->socket = socket;
-       if((sock->next = FG(phpsockbuf))) 
+       if((sock->next = FG(phpsockbuf)))
                FG(phpsockbuf)->prev = sock;
        sock->persistent = persistent;
        sock->is_blocked = 1;
@@ -436,7 +436,7 @@
 
        old = FG(def_chunk_size);
 
-       if(size <= PHP_FSOCK_CHUNK_SIZE || size > 0) 
+       if(size <= PHP_FSOCK_CHUNK_SIZE || size > 0)
                FG(def_chunk_size) = size;
 
        return old;
@@ -500,7 +500,7 @@
        FD_SET(sock->socket, &fdr);
        sock->timeout_event = 0;
 
-       if (sock->timeout.tv_sec == -1) 
+       if (sock->timeout.tv_sec == -1)
                ptimeout = NULL;
        else
                ptimeout = &timeout;
@@ -510,7 +510,7 @@
                timeout = sock->timeout;
 
                retval = select(sock->socket + 1, &tfdr, NULL, NULL, ptimeout);
-               
+
                if (retval == 0)
                        sock->timeout_event = 1;
 
@@ -524,15 +524,15 @@
        char buf[PHP_FSOCK_CHUNK_SIZE];
        int nr_bytes;
        size_t nr_read = 0;
-       
+
        /* For blocking sockets, we wait until there is some
           data to read (real data or EOF)
-          
+
           Otherwise, recv() may time out and return 0 and
           therefore sock->eof would be set errornously.
         */
+
 
-       
        if(sock->is_blocked) {
                php_sockwait_for_data(sock);
                if (sock->timeout_event)
@@ -569,7 +569,7 @@
        size_t nr_bytes;
        size_t nr_read = 0;
        int i;
-       
+
        for(i = 0; !sock->eof && i < MAX_CHUNKS_PER_READ; i++) {
                nr_bytes = php_sockread_internal(sock);
                if(nr_bytes == 0) break;
@@ -585,9 +585,9 @@
        SOCK_FIND(sock, socket);
 
        old = sock->is_blocked;
-       
+
        sock->is_blocked = mode;
-       
+
        return old;
 }
 
@@ -631,14 +631,14 @@
                        SEARCHCR();
                }
        }
+
 
-       
        if(p) {
                amount = (ptrdiff_t) p - (ptrdiff_t) READPTR(sock) + 1;
        } else {
                amount = TOREAD(sock);
        }
-       
+
        amount = MIN(amount, maxlen);
 
        if(amount > 0) {
@@ -646,8 +646,8 @@
                sock->readpos += amount;
        }
        buf[amount] = '\0';
-       
-       /* signal error only, if we don't return data from this call and 
+
+       /* signal error only, if we don't return data from this call and
           if there is no data to read and if the eof flag is set */
        if(amount || TOREAD(sock) || !sock->eof) {
                ret = buf;
@@ -685,8 +685,8 @@
 
        if(!sock->is_blocked)
                php_sockread(sock);
-       
-       if(!TOREAD(sock) && sock->eof) 
+
+       if(!TOREAD(sock) && sock->eof)
                ret = 1;
 
        return ret;
@@ -699,7 +699,7 @@
        size_t ret = 0;
        SOCK_FIND_AND_READ_MAX(size);
 
-       if(size < 0) 
+       if(size < 0)
                return ret;
 
        ret = MIN(TOREAD(sock), size);
@@ -721,6 +721,112 @@
 }
 /* }}} */
 
+
+/* {{{ stream abstraction */
+#if HAVE_PHP_STREAM
+static size_t php_sockop_write(php_stream * stream, const char * buf, size_t count)
+{
+       int socket = (int)stream->abstract;
+       return send(socket, buf, count, 0);
+}
+
+static void php_stream_sockwait_for_data(php_stream * stream)
+{
+       fd_set fdr, tfdr;
+       int retval, socket;
+       struct timeval timeout, *ptimeout;
+
+       socket = (int)stream->abstract;
+
+       FD_ZERO(&fdr);
+       FD_SET(socket, &fdr);
+       stream->timeout_event = 0;
+
+       if (stream->timeout.tv_sec == -1)
+               ptimeout = NULL;
+       else
+               ptimeout = &timeout;
+
+       while(1) {
+               tfdr = fdr;
+               timeout = stream->timeout;
+
+               retval = select(socket + 1, &tfdr, NULL, NULL, ptimeout);
+
+               if (retval == 0)
+                       stream->timeout_event = 1;
+
+               if (retval >= 0)
+                       break;
+       }
+}
+
+static size_t php_sockop_read(php_stream * stream, char * buf, size_t count)
+{
+       int socket = (int)stream->abstract;
+
+       /* For blocking sockets, we wait until there is some
+          data to read (real data or EOF)
+
+          Otherwise, recv() may time out and return 0 and
+          therefore sock->eof would be set errornously.
+        */
+
+       if (stream->is_blocked) {
+               php_stream_sockwait_for_data(stream);
+               if (stream->timeout_event)
+                       return 0;
+       }
+       return recv(socket, buf, count, 0);
+}
+
+static int php_sockop_close(php_stream * stream)
+{
+       int socket = (int)stream->abstract;
+       SOCK_CLOSE(socket);
+       return 0;
+}
+
+static int php_sockop_flush(php_stream * stream)
+{
+       int socket = (int)stream->abstract;
+       return fsync(socket);
+}
+
+static int php_sockop_cast(php_stream * stream, int castas, void ** ret)
+{
+       int socket = (int)stream->abstract;
+
+       switch(castas)  {
+               case PHP_STREAM_AS_STDIO:
+                       if (ret)        {
+                               /* DANGER!: data buffered in stream->readbuf will be 
+forgotten! */
+                               *ret = fdopen(socket, stream->mode);
+                               if (*ret)
+                                       return SUCCESS;
+                               return FAILURE;
+                       }
+                       return SUCCESS;
+               case PHP_STREAM_AS_FD:
+               case PHP_STREAM_AS_SOCKETD:
+                       if (ret)
+                               *ret = (void*)socket;
+                       return SUCCESS;
+               default:
+                       return FAILURE;
+       }
+}
+
+php_stream_ops php_stream_socket_ops = {
+       php_sockop_write, php_sockop_read,
+       php_sockop_close, php_sockop_flush,
+       NULL, NULL,
+       php_sockop_cast,
+       "socket"
+};
+#endif
+
+/* }}} */
 
 PHP_RSHUTDOWN_FUNCTION(fsock)
 {
Index: php4/ext/standard/fsock.h
diff -u php4/ext/standard/fsock.h:1.34 php4/ext/standard/fsock.h:1.35
--- php4/ext/standard/fsock.h:1.34      Sun Feb 25 22:07:17 2001
+++ php4/ext/standard/fsock.h   Tue Apr 17 10:06:06 2001
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: fsock.h,v 1.34 2001/02/26 06:07:17 andi Exp $ */
+/* $Id: fsock.h,v 1.35 2001/04/17 17:06:06 wez Exp $ */
 
 /* Synced with php 3.0 revision 1.24 1999-06-18 [ssb] */
 
@@ -48,6 +48,10 @@
 #endif
 
 #define PHP_FSOCK_CHUNK_SIZE 8192
+
+#if HAVE_PHP_STREAM
+extern php_stream_ops php_stream_socket_ops;
+#endif
 
 struct php_sockbuf {
        int socket;
Index: php4/ext/standard/info.c
diff -u php4/ext/standard/info.c:1.132 php4/ext/standard/info.c:1.133
--- php4/ext/standard/info.c:1.132      Sun Mar  4 14:03:23 2001
+++ php4/ext/standard/info.c    Tue Apr 17 10:06:06 2001
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: info.c,v 1.132 2001/03/04 22:03:23 zeev Exp $ */
+/* $Id: info.c,v 1.133 2001/04/17 17:06:06 wez Exp $ */
 
 #include "php.h"
 #include "php_ini.h"
@@ -203,6 +203,11 @@
 #else
                php_info_print_table_row(2, "Thread Safety", "disabled" );
 #endif
+
+#if HAVE_PHP_STREAM
+               php_info_print_table_row(2, "Experimental PHP Streams", "enabled");
+#endif
+               
                php_info_print_table_end();
 
                /* Zend Engine */

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to