summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/basic_functions.c7
-rw-r--r--ext/standard/file.c625
-rw-r--r--ext/standard/file.h4
-rw-r--r--ext/standard/fsock.c168
-rw-r--r--ext/standard/fsock.h4
-rw-r--r--ext/standard/info.c5
6 files changed, 542 insertions, 271 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 83e8a60fbb..3e538ba5f8 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -430,6 +430,9 @@ function_entry basic_functions[] = {
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 @@ PHP_FUNCTION(move_uploaded_file)
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;
diff --git a/ext/standard/file.c b/ext/standard/file.c
index 98928c45d8..8513feb895 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -101,7 +101,10 @@ php_file_globals file_globals;
/* {{{ 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_popen_dtor(zend_rsrc_list_entry *rsrc)
}
-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 @@ static void _file_socket_dtor(zend_rsrc_list_entry *rsrc)
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 @@ PHP_MINIT_FUNCTION(file)
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 @@ PHP_FUNCTION(flock)
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 @@ PHP_FUNCTION(get_meta_tags)
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 @@ PHP_FUNCTION(get_meta_tags)
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 @@ PHP_FUNCTION(get_meta_tags)
}
RETURN_FALSE;
}
-
+
if (array_init(return_value)==FAILURE) {
if (issock) {
SOCK_FCLOSE(socketd);
@@ -426,7 +447,7 @@ PHP_FUNCTION(file)
int target_len, len;
zend_bool reached_eof=0;
PLS_FETCH();
-
+
/* check args */
switch (ARG_COUNT(ht)) {
case 1:
@@ -445,7 +466,7 @@ PHP_FUNCTION(file)
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 @@ PHP_FUNCTION(file)
/* 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 @@ PHP_FUNCTION(tempnam)
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_NAMED_FUNCTION(php_if_tmpfile)
}
/* }}} */
+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 @@ PHP_NAMED_FUNCTION(php_if_fopen)
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 @@ PHP_NAMED_FUNCTION(php_if_fopen)
}
}
-/* }}} */
+/* }}} */
/* {{{ proto int fclose(int fp)
Close an open file pointer */
@@ -625,14 +671,14 @@ PHP_FUNCTION(fclose)
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 @@ PHP_FUNCTION(popen)
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 @@ PHP_FUNCTION(pclose)
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 @@ PHP_FUNCTION(feof)
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 @@ PHPAPI int php_set_sock_blocking(int socketd, int block)
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 @@ PHPAPI int php_set_sock_blocking(int socketd, int block)
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 @@ PHP_FUNCTION(socket_set_timeout)
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 @@ PHP_FUNCTION(socket_get_status)
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 @@ PHP_FUNCTION(fgets)
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 @@ PHP_FUNCTION(fgets)
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 @@ PHP_FUNCTION(fgetc) {
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 @@ PHP_FUNCTION(fgetc) {
}
#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 @@ PHP_FUNCTION(fgetss)
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 @@ PHP_FUNCTION(fgetss)
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 @@ PHP_FUNCTION(fgetss)
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 @@ PHP_FUNCTION(fwrite)
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_FUNCTION(fwrite)
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 @@ PHP_FUNCTION(fwrite)
RETURN_LONG(ret);
}
-/* }}} */
+/* }}} */
/* {{{ proto int fflush(int fp)
Flushes output */
@@ -1197,9 +1320,19 @@ PHP_FUNCTION(fflush)
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 @@ PHP_FUNCTION(fflush)
}
}
-/* }}} */
+/* }}} */
/* {{{ proto int set_file_buffer(int fp, int buffer)
Set file write buffer */
@@ -1227,24 +1360,26 @@ PHP_FUNCTION(set_file_buffer)
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 @@ PHP_FUNCTION(set_file_buffer)
RETURN_LONG(ret);
}
-/* }}} */
+/* }}} */
/* {{{ proto int rewind(int fp)
Rewind the position of a file pointer */
@@ -1264,14 +1399,15 @@ PHP_FUNCTION(rewind)
{
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 @@ PHP_FUNCTION(ftell)
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 @@ PHP_FUNCTION(fseek)
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 @@ PHP_FUNCTION(fseek)
convert_to_long_ex(arg3);
whence = (*arg3)->value.lval;
}
-
+
RETURN_LONG(fseek((FILE*)what, (*arg2)->value.lval, whence));
}
@@ -1338,7 +1476,7 @@ PHP_FUNCTION(mkdir)
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 @@ PHP_FUNCTION(mkdir)
RETURN_TRUE;
}
-/* }}} */
+/* }}} */
/* {{{ proto int rmdir(string dirname)
Remove a directory */
@@ -1365,7 +1503,7 @@ PHP_FUNCTION(rmdir)
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 @@ PHP_FUNCTION(rmdir)
RETURN_TRUE;
}
-/* }}} */
+/* }}} */
/* {{{ php_passthru_fd */
static size_t php_passthru_fd(int socketd, FILE *fp, int issock)
@@ -1389,8 +1527,9 @@ static size_t php_passthru_fd(int socketd, FILE *fp, int issock)
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 @@ static size_t php_passthru_fd(int socketd, FILE *fp, int issock)
fd = fileno(fp);
fstat(fd, &sbuf);
-
+
if (sbuf.st_size > sizeof(buf)) {
off = ftell(fp);
len = sbuf.st_size - off;
@@ -1423,7 +1562,7 @@ static size_t php_passthru_fd(int socketd, FILE *fp, int issock)
bcount += b;
}
}
-
+
return bcount;
}
@@ -1439,7 +1578,7 @@ PHP_FUNCTION(readfile)
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 @@ PHP_FUNCTION(umask)
pval **arg1;
int oldumask;
int arg_count = ARG_COUNT(ht);
-
+
oldumask = umask(077);
if (arg_count == 0) {
@@ -1527,11 +1666,12 @@ PHP_FUNCTION(fpassthru)
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 @@ PHP_FUNCTION(rename)
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 @@ PHP_FUNCTION(unlink)
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 @@ PHP_NAMED_FUNCTION(php_if_ftruncate)
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 @@ PHP_NAMED_FUNCTION(php_if_fstat)
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 @@ PHP_NAMED_FUNCTION(php_if_fstat)
#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 @@ PHPAPI int php_copy_file(char *src, char *dest)
}
}
ret = SUCCESS;
-
+
cleanup:
close(fd_s);
close(fd_t);
return ret;
-}
+}
@@ -1791,10 +1933,11 @@ PHP_FUNCTION(fread)
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 @@ PHP_FUNCTION(fread)
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 @@ PHP_FUNCTION(fread)
/* }}} */
/* {{{ 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 @@ PHP_FUNCTION(fgetcsv) {
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 @@ PHP_FUNCTION(fgetcsv) {
/* 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 @@ PHP_FUNCTION(fgetcsv) {
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 @@ PHP_FUNCTION(fgetcsv) {
/* 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 @@ PHP_FUNCTION(fgetcsv) {
/* 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 @@ PHP_FUNCTION(fgetcsv) {
/* 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 @@ PHP_FUNCTION(fgetcsv) {
add_next_index_string(return_value, temp, 1);
tptr=temp;
} while (*bptr);
-
+
efree(lineEnd);
efree(temp);
efree(buf);
@@ -2010,7 +2154,7 @@ PHP_FUNCTION(realpath)
}
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 @@ static int max_fd;
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 @@ PHP_FUNCTION(select)
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 @@ PHP_FUNCTION(fd_isset)
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 @@ PHP_FUNCTION(fd_isset)
if(FD_ISSET(fd,&readfd)) {
RETURN_TRUE;
- }
+ }
RETURN_FALSE;
-}
+}
#endif
@@ -2127,9 +2275,10 @@ size_t php_fread_all(char **buf, int socket, FILE *fp, int issock) {
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 @@ php_meta_tags_token php_next_meta_token(FILE *fp, int socketd, int issock, int *
if (*datalen == META_DEF_BUFSIZE)
break;
}
-
+
*data = (char *) emalloc( *datalen + 1 );
memcpy(*data,buff,*datalen+1);
diff --git a/ext/standard/file.h b/ext/standard/file.h
index 8af3bc79cd..2c54abf04b 100644
--- a/ext/standard/file.h
+++ b/ext/standard/file.h
@@ -67,6 +67,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);
PHPAPI int php_file_le_popen(void);
diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c
index 00ecbc0003..a3a8bf4ee1 100644
--- a/ext/standard/fsock.c
+++ b/ext/standard/fsock.c
@@ -204,7 +204,7 @@ PHPAPI int connect_nonb(int sockfd,
/* }}} */
/* {{{ 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 @@ static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
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 @@ static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
ZEND_REGISTER_RESOURCE(return_value,sock,php_file_le_socket());
return;
}
-
+
if (portno) {
struct sockaddr_in server;
@@ -264,23 +264,23 @@ static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
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 @@ static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
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 @@ static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
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 @@ static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
*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 @@ static void php_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
/* {{{ 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 @@ static php_sockbuf *php_sockfind(int socket FLS_DC)
{
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 @@ static php_sockbuf *php_sockcreate(int socket FLS_DC)
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 @@ PHPAPI size_t php_sock_set_def_chunk_size(size_t size)
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 @@ static void php_sockwait_for_data(php_sockbuf *sock)
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 @@ static void php_sockwait_for_data(php_sockbuf *sock)
timeout = sock->timeout;
retval = select(sock->socket + 1, &tfdr, NULL, NULL, ptimeout);
-
+
if (retval == 0)
sock->timeout_event = 1;
@@ -524,15 +524,15 @@ static size_t php_sockread_internal(php_sockbuf *sock)
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 @@ static size_t php_sockread(php_sockbuf *sock)
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 @@ PHPAPI int php_sockset_blocking(int socket, int mode)
SOCK_FIND(sock, socket);
old = sock->is_blocked;
-
+
sock->is_blocked = mode;
-
+
return old;
}
@@ -632,13 +632,13 @@ PHPAPI char *php_sock_fgets(char *buf, size_t maxlen, int socket)
}
}
-
+
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 @@ PHPAPI char *php_sock_fgets(char *buf, size_t maxlen, int socket)
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 @@ PHPAPI int php_sock_feof(int socket)
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 @@ PHPAPI size_t php_sock_fread(char *ptr, size_t size, int socket)
size_t ret = 0;
SOCK_FIND_AND_READ_MAX(size);
- if(size < 0)
+ if(size < 0)
return ret;
ret = MIN(TOREAD(sock), size);
@@ -722,6 +722,112 @@ PHPAPI void php_msock_destroy(int *data)
/* }}} */
+/* {{{ 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)
{
FLS_FETCH();
diff --git a/ext/standard/fsock.h b/ext/standard/fsock.h
index 1418eb0908..f285306836 100644
--- a/ext/standard/fsock.h
+++ b/ext/standard/fsock.h
@@ -49,6 +49,10 @@
#define PHP_FSOCK_CHUNK_SIZE 8192
+#if HAVE_PHP_STREAM
+extern php_stream_ops php_stream_socket_ops;
+#endif
+
struct php_sockbuf {
int socket;
unsigned char *readbuf;
diff --git a/ext/standard/info.c b/ext/standard/info.c
index 055ff9aedb..e0233012c8 100644
--- a/ext/standard/info.c
+++ b/ext/standard/info.c
@@ -203,6 +203,11 @@ PHPAPI void php_print_info(int flag)
#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 */