Browse Source

Implement persistent streams. (for pfsockopen).

Juggle some includes/definitions.
Tidy up streams use in ext/standard/file.c
migration/unlabaled-1.1.2
Wez Furlong 24 years ago
parent
commit
696e0a2301
  1. 3
      ext/standard/basic_functions.c
  2. 211
      ext/standard/file.c
  3. 2
      ext/standard/file.h
  4. 37
      ext/standard/fsock.c
  5. 4
      main/main.c
  6. 26
      main/network.c
  7. 9
      main/php.h
  8. 6
      main/php_network.h
  9. 21
      main/php_streams.h
  10. 117
      main/streams.c

3
ext/standard/basic_functions.c

@ -1136,6 +1136,7 @@ PHP_RSHUTDOWN_FUNCTION(basic)
PHP_RSHUTDOWN(syslog) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
PHP_RSHUTDOWN(assert) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
PHP_RSHUTDOWN(url_scanner_ex) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
PHP_RSHUTDOWN(streams) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
if (BG(user_tick_functions)) {
zend_llist_destroy(BG(user_tick_functions));
@ -1148,7 +1149,7 @@ PHP_RSHUTDOWN_FUNCTION(basic)
efree(BG(aggregation_table));
BG(aggregation_table) = NULL;
}
#ifdef HAVE_MMAP
if (BG(mmap_file)) {
munmap(BG(mmap_file), BG(mmap_len));

211
ext/standard/file.c

@ -119,7 +119,6 @@ php_file_globals file_globals;
/* {{{ ZTS-stuff / Globals / Prototypes */
/* sharing globals is *evil* */
static int le_stream = FAILURE;
static int le_stream_context = FAILURE;
/* }}} */
@ -130,29 +129,14 @@ static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
php_stream_context_free((php_stream_context*)rsrc->ptr);
}
static void _file_stream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
php_stream *stream = (php_stream*)rsrc->ptr;
/* the stream might be a pipe, so set the return value for pclose */
FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
}
PHPAPI int php_file_le_stream(void)
{
return le_stream;
}
static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
{
zend_hash_init(&FG(ht_persistent_socks), 0, NULL, NULL, 1);
FG(pclose_ret) = 0;
FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
}
static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC)
{
zend_hash_destroy(&FG(ht_persistent_socks));
}
@ -164,7 +148,6 @@ PHP_INI_END()
PHP_MINIT_FUNCTION(file)
{
le_stream = zend_register_list_destructors_ex(_file_stream_dtor, NULL, "stream", module_number);
le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
#ifdef ZTS
@ -219,17 +202,16 @@ static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
PHP_FUNCTION(flock)
{
zval **arg1, **arg2, **arg3;
int type, fd, act, ret, arg_count = ZEND_NUM_ARGS();
void *what;
int fd, act, ret, arg_count = ZEND_NUM_ARGS();
php_stream *stream;
if (arg_count > 3 || zend_get_parameters_ex(arg_count, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
if (php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1) == FAILURE) {
if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 1) == FAILURE) {
RETURN_FALSE;
}
@ -600,8 +582,7 @@ PHP_FUNCTION(file_get_wrapper_data)
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", NULL, 1, le_stream);
ZEND_VERIFY_RESOURCE(stream);
php_stream_from_zval(stream, arg1);
if (stream->wrapperdata) {
*return_value = *(stream->wrapperdata);
@ -707,19 +688,23 @@ static int parse_context_params(php_stream_context *context, zval *params)
/* given a zval which is either a stream or a context, return the underlying
* stream_context. If it is a stream that does not have a context assigned, it
* will create and assign a context and return that. */
static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC) {
php_stream_context *context = NULL; void *what; int type;
static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC)
{
php_stream_context *context = NULL;
context = zend_fetch_resource(&contextresource TSRMLS_CC, -1, "Stream-Context", NULL, 1, le_stream_context);
if (context == NULL) {
php_stream *stream;
what = zend_fetch_resource(&contextresource TSRMLS_CC, -1, "Stream-Context", &type, 2, le_stream_context, le_stream);
php_stream_from_zval_no_verify(stream, &contextresource);
if (what && type == le_stream) {
php_stream *stream = (php_stream*)what;
context = stream->context;
if (context == NULL)
context = stream->context = php_stream_context_alloc();
} else if (what && type == le_stream_context) {
context = (php_stream_context*)what;
if (stream) {
context = stream->context;
if (context == NULL)
context = stream->context = php_stream_context_alloc();
}
}
return context;
}
/* }}} */
@ -829,7 +814,7 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS)
RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(stream, php_stream*, &zstream, -1, "stream", le_stream);
php_stream_from_zval(stream, &zstream);
filter = php_stream_filter_create(filtername, filterparams, filterparamslen, php_stream_is_persistent(stream) TSRMLS_CC);
if (filter == NULL)
@ -897,17 +882,15 @@ PHP_NAMED_FUNCTION(php_if_fopen)
PHPAPI PHP_FUNCTION(fclose)
{
zval **arg1;
int type;
void *what;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
php_stream_close(stream);
zend_list_delete(Z_LVAL_PP(arg1));
RETURN_TRUE;
}
@ -984,18 +967,15 @@ PHP_FUNCTION(popen)
PHP_FUNCTION(pclose)
{
zval **arg1;
void *what;
int type;
php_stream *stream;
if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
zend_list_delete(Z_LVAL_PP(arg1));
RETURN_LONG(FG(pclose_ret));
RETURN_LONG(php_stream_close(stream));
}
/* }}} */
@ -1004,22 +984,19 @@ PHP_FUNCTION(pclose)
PHPAPI PHP_FUNCTION(feof)
{
zval **arg1;
int type;
void *what;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
if (type == le_stream) {
if (php_stream_eof((php_stream *) what)) {
RETURN_TRUE;
}
php_stream_from_zval(stream, arg1);
if (php_stream_eof(stream)) {
RETURN_TRUE;
} else {
RETURN_FALSE;
}
RETURN_FALSE;
}
/* }}} */
@ -1028,20 +1005,19 @@ PHPAPI PHP_FUNCTION(feof)
PHP_FUNCTION(socket_set_blocking)
{
zval **arg1, **arg2;
int block, type;
void *what;
int block;
php_stream *stream;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
block = Z_LVAL_PP(arg2);
if (php_stream_set_option((php_stream*)what, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1)
if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1)
RETURN_FALSE;
RETURN_TRUE;
}
@ -1063,17 +1039,15 @@ PHP_FUNCTION(set_socket_blocking)
PHP_FUNCTION(socket_set_timeout)
{
zval **socket, **seconds, **microseconds;
int type;
void *what;
struct timeval t;
php_stream *stream;
if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
zend_get_parameters_ex(ZEND_NUM_ARGS(), &socket, &seconds, &microseconds)==FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(socket TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, socket);
convert_to_long_ex(seconds);
t.tv_sec = Z_LVAL_PP(seconds);
@ -1086,8 +1060,8 @@ PHP_FUNCTION(socket_set_timeout)
else
t.tv_usec = 0;
if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) {
php_stream_sock_set_timeout((php_stream*)what, &t TSRMLS_CC);
if (php_stream_is(stream, PHP_STREAM_IS_SOCKET)) {
php_stream_sock_set_timeout(stream, &t TSRMLS_CC);
RETURN_TRUE;
}
@ -1136,17 +1110,16 @@ PHP_FUNCTION(socket_get_status)
PHPAPI PHP_FUNCTION(fgets)
{
zval **arg1, **arg2;
int len = 1024, type;
int len = 1024;
char *buf;
void *what;
int argc = ZEND_NUM_ARGS();
php_stream *stream;
if (argc<1 || argc>2 || zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
if (argc>1) {
convert_to_long_ex(arg2);
@ -1162,7 +1135,7 @@ PHPAPI PHP_FUNCTION(fgets)
/* needed because recv doesnt put a null at the end*/
memset(buf, 0, len+1);
if (php_stream_gets((php_stream *) what, buf, len) == NULL)
if (php_stream_gets(stream, buf, len) == NULL)
goto exit_failed;
if (PG(magic_quotes_runtime)) {
@ -1188,21 +1161,19 @@ exit_failed:
PHPAPI PHP_FUNCTION(fgetc)
{
zval **arg1;
int type;
char *buf;
void *what;
int result;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
buf = emalloc(2 * sizeof(char));
result = php_stream_getc((php_stream*)what);
result = php_stream_getc(stream);
if (result == EOF) {
efree(buf);
@ -1221,7 +1192,7 @@ PHPAPI PHP_FUNCTION(fgetc)
PHPAPI PHP_FUNCTION(fgetss)
{
zval **fd, **bytes, **allow=NULL;
int len, type;
int len;
char *buf;
php_stream *stream;
char *allowed_tags=NULL;
@ -1247,8 +1218,7 @@ PHPAPI PHP_FUNCTION(fgetss)
break;
}
stream = zend_fetch_resource(fd TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(stream);
php_stream_from_zval(stream, fd);
convert_to_long_ex(bytes);
len = Z_LVAL_PP(bytes);
@ -1299,7 +1269,8 @@ PHP_FUNCTION(fscanf)
file_handle = args[0];
format_string = args[1];
what = zend_fetch_resource(file_handle TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
what = zend_fetch_resource(file_handle TSRMLS_CC, -1, "File-Handle", &type, 2,
php_file_le_stream(), php_file_le_pstream());
/*
* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
@ -1340,10 +1311,10 @@ PHP_FUNCTION(fscanf)
PHPAPI PHP_FUNCTION(fwrite)
{
zval **arg1, **arg2, **arg3=NULL;
int ret, type;
int ret;
int num_bytes;
void *what;
char *buffer = NULL;
php_stream *stream;
switch (ZEND_NUM_ARGS()) {
case 2:
@ -1367,15 +1338,14 @@ PHPAPI PHP_FUNCTION(fwrite)
break;
}
what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
if (!arg3 && PG(magic_quotes_runtime)) {
buffer = estrndup(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2));
php_stripslashes(buffer, &num_bytes TSRMLS_CC);
}
ret = php_stream_write((php_stream *) what, buffer ? buffer : Z_STRVAL_PP(arg2), num_bytes);
ret = php_stream_write(stream, buffer ? buffer : Z_STRVAL_PP(arg2), num_bytes);
if (buffer) {
efree(buffer);
}
@ -1389,17 +1359,16 @@ PHPAPI PHP_FUNCTION(fwrite)
PHPAPI PHP_FUNCTION(fflush)
{
zval **arg1;
int ret, type;
void *what;
int ret;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
ret = php_stream_flush((php_stream *) what);
ret = php_stream_flush(stream);
if (ret) {
RETURN_FALSE;
}
@ -1412,7 +1381,7 @@ PHPAPI PHP_FUNCTION(fflush)
PHP_FUNCTION(set_file_buffer)
{
zval **arg1, **arg2;
int ret, type;
int ret;
size_t buff;
php_stream *stream;
@ -1428,8 +1397,7 @@ PHP_FUNCTION(set_file_buffer)
break;
}
stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(stream);
php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
buff = Z_LVAL_PP(arg2);
@ -1450,17 +1418,15 @@ PHP_FUNCTION(set_file_buffer)
PHPAPI PHP_FUNCTION(rewind)
{
zval **arg1;
void *what;
int type;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
if (-1 == php_stream_rewind((php_stream*)what)) {
if (-1 == php_stream_rewind(stream)) {
RETURN_FALSE;
}
RETURN_TRUE;
@ -1472,18 +1438,16 @@ PHPAPI PHP_FUNCTION(rewind)
PHPAPI PHP_FUNCTION(ftell)
{
zval **arg1;
void *what;
long ret;
int type;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
ret = php_stream_tell((php_stream*)what);
ret = php_stream_tell(stream);
if (ret == -1) {
RETURN_FALSE;
}
@ -1497,16 +1461,14 @@ PHPAPI PHP_FUNCTION(fseek)
{
zval **arg1, **arg2, **arg3;
int argcount = ZEND_NUM_ARGS(), whence = SEEK_SET;
void *what;
int type;
php_stream *stream;
if (argcount < 2 || argcount > 3 ||
zend_get_parameters_ex(argcount, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
if (argcount > 2) {
@ -1514,7 +1476,7 @@ PHPAPI PHP_FUNCTION(fseek)
whence = Z_LVAL_PP(arg3);
}
RETURN_LONG(php_stream_seek((php_stream*)what, Z_LVAL_PP(arg2), whence));
RETURN_LONG(php_stream_seek(stream, Z_LVAL_PP(arg2), whence));
}
/* }}} */
@ -1653,17 +1615,16 @@ PHP_FUNCTION(umask)
PHPAPI PHP_FUNCTION(fpassthru)
{
zval **arg1;
int size, type;
void *what;
int size;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, arg1);
size = php_stream_passthru((php_stream*)what);
size = php_stream_passthru(stream);
RETURN_LONG(size);
}
/* }}} */
@ -1742,24 +1703,22 @@ PHP_NAMED_FUNCTION(php_if_ftruncate)
{
zval **fp , **size;
short int ret;
int type;
void *what;
int fd;
php_stream *stream;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fp, &size) == FAILURE) {
WRONG_PARAM_COUNT;
}
what = zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(what);
php_stream_from_zval(stream, fp);
convert_to_long_ex(size);
if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) {
if (php_stream_is(stream, PHP_STREAM_IS_SOCKET)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate sockets!");
RETURN_FALSE;
}
if (SUCCESS == php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1)) {
if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 1)) {
ret = ftruncate(fd, Z_LVAL_PP(size));
RETURN_LONG(ret + 1);
}
@ -1774,7 +1733,6 @@ PHP_NAMED_FUNCTION(php_if_fstat)
zval **fp;
zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
*stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
int type;
php_stream *stream;
php_stream_statbuf stat_ssb;
@ -1785,8 +1743,7 @@ PHP_NAMED_FUNCTION(php_if_fstat)
WRONG_PARAM_COUNT;
}
stream = (php_stream *) zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(stream);
php_stream_from_zval(stream, fp);
if (php_stream_stat(stream, &stat_ssb)) {
RETURN_FALSE;
@ -1915,15 +1872,14 @@ PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC)
PHPAPI PHP_FUNCTION(fread)
{
zval **arg1, **arg2;
int len, type;
int len;
php_stream *stream;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(stream);
php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
len = Z_LVAL_PP(arg2);
@ -1957,7 +1913,7 @@ PHP_FUNCTION(fgetcsv)
/* first section exactly as php_fgetss */
zval **fd, **bytes, **p_delim, **p_enclosure;
int len, type;
int len;
char *buf;
php_stream *stream;
@ -2007,8 +1963,7 @@ PHP_FUNCTION(fgetcsv)
break;
}
stream = (php_stream*)zend_fetch_resource(fd TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
ZEND_VERIFY_RESOURCE(stream);
php_stream_from_zval(stream, fd);
convert_to_long_ex(bytes);
len = Z_LVAL_PP(bytes);

2
ext/standard/file.h

@ -82,7 +82,6 @@ PHP_FUNCTION(stream_filter_append);
PHP_MINIT_FUNCTION(user_streams);
PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC);
PHPAPI int php_file_le_stream(void);
PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC);
#define META_DEF_BUFSIZE 8192
@ -113,7 +112,6 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data * TSRMLS_DC);
typedef struct {
int pclose_ret;
HashTable ht_persistent_socks;
size_t def_chunk_size;
int auto_detect_line_endings;
int default_socket_timeout;

37
ext/standard/fsock.c

@ -139,7 +139,7 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
int host_len;
int port = -1;
zval *zerrno = NULL, *zerrstr = NULL;
double timeout = 60;
double timeout = FG(default_socket_timeout);
unsigned long conv;
struct timeval tv;
char *hashkey = NULL;
@ -147,20 +147,27 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
#ifdef PHP_WIN32
int err;
#endif
RETVAL_FALSE;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzd", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) {
RETURN_FALSE;
}
hashkey = emalloc(host_len + 10);
sprintf(hashkey, "%s:%d", host, port);
if (persistent && zend_hash_find(&FG(ht_persistent_socks), hashkey, strlen(hashkey) + 1,
(void *) &stream) == SUCCESS)
{
efree(hashkey);
php_stream_to_zval(stream, return_value);
return;
if (persistent) {
spprintf(&hashkey, 0, "pfsockopen__%s:%d", host, port);
switch(php_stream_from_persistent_id(hashkey, &stream TSRMLS_CC)) {
case PHP_STREAM_PERSISTENT_SUCCESS:
/* TODO: could check if the socket is still alive here */
php_stream_to_zval(stream, return_value);
/* fall through */
case PHP_STREAM_PERSISTENT_FAILURE:
efree(hashkey);
return;
}
}
/* prepare the timeout value for use */
@ -211,7 +218,7 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
}
else
#endif
stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, &tv, persistent);
stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, &tv, hashkey);
#ifdef PHP_WIN32
/* Preserve error */
@ -242,14 +249,10 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
#endif
} else
stream = php_stream_sock_open_unix(host, host_len, persistent, &tv);
stream = php_stream_sock_open_unix(host, host_len, hashkey, &tv);
if (stream && persistent) {
zend_hash_update(&FG(ht_persistent_socks), hashkey, strlen(hashkey) + 1,
&stream, sizeof(stream), NULL);
}
efree(hashkey);
if (hashkey)
efree(hashkey);
if (stream == NULL) {
if (zerrno) {

4
main/main.c

@ -1076,7 +1076,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
/* initialize stream wrappers registry
* (this uses configuration parameters from php.ini)
*/
if (php_init_stream_wrappers(TSRMLS_C) == FAILURE) {
if (php_init_stream_wrappers(module_number TSRMLS_CC) == FAILURE) {
php_printf("PHP: Unable to initialize stream url wrappers.\n");
return FAILURE;
}
@ -1192,7 +1192,7 @@ void php_module_shutdown(TSRMLS_D)
zend_shutdown(TSRMLS_C);
php_shutdown_stream_wrappers(TSRMLS_C);
php_shutdown_stream_wrappers(module_number TSRMLS_CC);
php_shutdown_info_logos();
UNREGISTER_INI_ENTRIES();

26
main/network.c

@ -529,45 +529,52 @@ int php_sockaddr_size(php_sockaddr_storage *addr)
}
/* }}} */
PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, int persistent STREAMS_DC TSRMLS_DC)
PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, const char *persistent_id STREAMS_DC TSRMLS_DC)
{
php_stream *stream;
php_netstream_data_t *sock;
sock = pemalloc(sizeof(php_netstream_data_t), persistent);
sock = pemalloc(sizeof(php_netstream_data_t), persistent_id ? 1 : 0);
memset(sock, 0, sizeof(php_netstream_data_t));
sock->is_blocked = 1;
sock->timeout.tv_sec = FG(default_socket_timeout);
sock->socket = socket;
stream = php_stream_alloc_rel(&php_stream_socket_ops, sock, persistent, "r+");
stream = php_stream_alloc_rel(&php_stream_socket_ops, sock, persistent_id, "r+");
if (stream == NULL)
pefree(sock, persistent);
pefree(sock, persistent_id ? 1 : 0);
return stream;
}
PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port,
int socktype, struct timeval *timeout, int persistent STREAMS_DC TSRMLS_DC)
int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC)
{
int socket;
php_stream *stream;
socket = php_hostconnect(host, port, socktype, timeout TSRMLS_CC);
if (socket == -1)
return NULL;
return php_stream_sock_open_from_socket_rel(socket, persistent);
stream = php_stream_sock_open_from_socket_rel(socket, persistent_id);
if (stream == NULL)
closesocket(socket);
return stream;
}
PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, int persistent,
PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, const char *persistent_id,
struct timeval *timeout STREAMS_DC TSRMLS_DC)
{
#if defined(AF_UNIX)
int socketd;
struct sockaddr_un unix_addr;
php_stream *stream;
socketd = socket(PF_UNIX, SOCK_STREAM, 0);
if (socketd == SOCK_ERR)
@ -592,7 +599,10 @@ PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, int
if (php_connect_nonb(socketd, (struct sockaddr *) &unix_addr, sizeof(unix_addr), timeout) == SOCK_CONN_ERR)
return NULL;
return php_stream_sock_open_from_socket_rel(socketd, persistent);
stream = php_stream_sock_open_from_socket_rel(socketd, persistent_id);
if (stream == NULL)
closesocket(socketd);
return stream;
#else
return NULL;
#endif

9
main/php.h

@ -230,10 +230,6 @@ char *strerror(int);
# endif
#endif
#include "php_streams.h"
#include "php_memory_streams.h"
#include "fopen_wrappers.h"
/* global variables */
extern pval *data;
@ -347,6 +343,11 @@ PHPAPI int cfg_get_string(char *varname, char **result);
#define VIRTUAL_DIR
#endif
#include "php_streams.h"
#include "php_memory_streams.h"
#include "fopen_wrappers.h"
/* Virtual current working directory support */
#include "tsrm_virtual_cwd.h"

6
main/php_network.h

@ -120,11 +120,11 @@ typedef struct _php_netstream_data_t php_netstream_data_t;
extern php_stream_ops php_stream_socket_ops;
#define PHP_STREAM_IS_SOCKET (&php_stream_socket_ops)
PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, int persistent STREAMS_DC TSRMLS_DC );
PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, const char *persistent_id STREAMS_DC TSRMLS_DC );
/* open a connection to a host using php_hostconnect and return a stream */
PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port,
int socktype, struct timeval *timeout, int persistent STREAMS_DC TSRMLS_DC);
PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, int persistent,
int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC);
PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, const char *persistent_id,
struct timeval *timeout STREAMS_DC TSRMLS_DC);
#define php_stream_sock_open_from_socket(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC TSRMLS_CC)

21
main/php_streams.h

@ -25,7 +25,8 @@
#include <sys/types.h>
#include <sys/stat.h>
/* See README.STREAMS in php4 root dir for more info about this stuff */
PHPAPI int php_file_le_stream(void);
PHPAPI int php_file_le_pstream(void);
/* {{{ Streams memory debugging stuff */
@ -269,8 +270,8 @@ struct _php_stream {
/* allocate a new stream for a particular ops */
PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract,
int persistent, const char *mode STREAMS_DC TSRMLS_DC);
#define php_stream_alloc(ops, thisptr, persistent, mode) _php_stream_alloc((ops), (thisptr), (persistent), (mode) STREAMS_CC TSRMLS_CC)
const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC);
#define php_stream_alloc(ops, thisptr, persistent_id, mode) _php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC TSRMLS_CC)
/* stack filter onto a stream */
PHPAPI void php_stream_filter_prepend(php_stream *stream, php_stream_filter *filter);
@ -306,7 +307,13 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, const
# define php_stream_to_zval(stream, zval) { ZVAL_RESOURCE(zval, (stream)->rsrc_id); }
#endif
#define php_stream_from_zval(stream, ppzval) ZEND_FETCH_RESOURCE((stream), php_stream *, (ppzval), -1, "stream", php_file_le_stream())
#define php_stream_from_zval(stream, ppzval) ZEND_FETCH_RESOURCE2((stream), php_stream *, (ppzval), -1, "stream", php_file_le_stream(), php_file_le_pstream())
#define php_stream_from_zval_no_verify(stream, ppzval) (stream) = (php_stream*)zend_fetch_resource((ppzval) TSRMLS_CC, -1, "stream", NULL, 2, php_file_le_stream(), php_file_le_pstream())
PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC);
#define PHP_STREAM_PERSISTENT_SUCCESS 0 /* id exists */
#define PHP_STREAM_PERSISTENT_FAILURE 1 /* id exists but is not a stream! */
#define PHP_STREAM_PERSISTENT_NOT_EXIST 2 /* id does not exist */
#define PHP_STREAM_FREE_CALL_DTOR 1 /* call ops->close */
#define PHP_STREAM_FREE_RELEASE_STREAM 2 /* pefree(stream) */
@ -472,8 +479,10 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show
# define IGNORE_URL_WIN 0
#endif
int php_init_stream_wrappers(TSRMLS_D);
int php_shutdown_stream_wrappers(TSRMLS_D);
int php_init_stream_wrappers(int module_number TSRMLS_DC);
int php_shutdown_stream_wrappers(int module_number TSRMLS_DC);
PHP_RSHUTDOWN_FUNCTION(streams);
PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC);
PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC);
PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);

117
main/streams.c

@ -50,7 +50,6 @@
#endif
#define STREAM_DEBUG 0
#define SANITY_CHECK_SEEK 1
#define STREAM_WRAPPER_PLAIN_FILES ((php_stream_wrapper*)-1)
@ -77,31 +76,102 @@
/* }}} */
static HashTable url_stream_wrappers_hash;
static int le_stream = FAILURE; /* true global */
static int le_pstream = FAILURE; /* true global */
PHPAPI int php_file_le_stream(void)
{
return le_stream;
}
PHPAPI int php_file_le_pstream(void)
{
return le_pstream;
}
static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
php_stream *stream;
if (Z_TYPE_P(rsrc) != le_pstream)
return 0;
stream = (php_stream*)rsrc->ptr;
#if STREAM_DEBUG
fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream);
#endif
stream->rsrc_id = FAILURE;
return 0;
}
PHP_RSHUTDOWN_FUNCTION(streams)
{
zend_hash_apply(&EG(persistent_list), (apply_func_t)forget_persistent_resource_id_numbers TSRMLS_CC);
return SUCCESS;
}
PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC)
{
list_entry *le;
if (zend_hash_find(&EG(persistent_list), (char*)persistent_id, strlen(persistent_id)+1, (void*) &le) == SUCCESS) {
if (Z_TYPE_P(le) == le_pstream) {
if (stream) {
*stream = (php_stream*)le->ptr;
if ((*stream)->rsrc_id == FAILURE) {
/* first access this request; give it a valid id */
(*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream);
}
}
return PHP_STREAM_PERSISTENT_SUCCESS;
}
return PHP_STREAM_PERSISTENT_FAILURE;
}
return PHP_STREAM_PERSISTENT_NOT_EXIST;
}
/* allocate a new stream for a particular ops */
PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, int persistent, const char *mode STREAMS_DC TSRMLS_DC) /* {{{ */
PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC) /* {{{ */
{
php_stream *ret;
ret = (php_stream*) pemalloc_rel_orig(sizeof(php_stream), persistent);
ret = (php_stream*) pemalloc_rel_orig(sizeof(php_stream), persistent_id ? 1 : 0);
memset(ret, 0, sizeof(php_stream));
#if STREAM_DEBUG
fprintf(stderr, "stream_alloc: %s:%p\n", ops->label, ret);
fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persistent_id);
#endif
ret->ops = ops;
ret->abstract = abstract;
ret->is_persistent = persistent;
ret->is_persistent = persistent_id ? 1 : 0;
ret->chunk_size = FG(def_chunk_size);
if (FG(auto_detect_line_endings))
ret->flags |= PHP_STREAM_FLAG_DETECT_EOL;
if (persistent_id) {
list_entry le;
Z_TYPE(le) = le_pstream;
le.ptr = ret;
if (FAILURE == zend_hash_update(&EG(persistent_list), (char *)persistent_id,
strlen(persistent_id) + 1,
(void *)&le, sizeof(list_entry), NULL)) {
pefree(ret, 1);
return NULL;
}
}
ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, php_file_le_stream());
ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, persistent_id ? le_pstream : le_stream);
strlcpy(ret->mode, mode, sizeof(ret->mode));
return ret;
}
/* }}} */
@ -111,7 +181,7 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /*
int ret = 1;
#if STREAM_DEBUG
fprintf(stderr, "stream_free: %s:%p in_free=%d opts=%08x\n", stream->ops->label, stream, stream->in_free, close_options);
fprintf(stderr, "stream_free: %s:%p[%s] in_free=%d opts=%08x\n", stream->ops->label, stream, stream->__orig_path, stream->in_free, close_options);
#endif
if (stream->in_free)
@ -545,7 +615,7 @@ PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRML
/* terminate the buffer */
*buf = '\0';
stream->position += didread;
return buf;
}
@ -766,7 +836,7 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen
void *srcfile;
#if STREAM_DEBUG
fprintf(stderr, "mmap attempt: maxlen=%d filesize=%d\n", maxlen, sbuf.st_size);
fprintf(stderr, "mmap attempt: maxlen=%d filesize=%ld\n", maxlen, sbuf.st_size);
#endif
if (maxlen > sbuf.st_size || maxlen == 0)
@ -1542,12 +1612,33 @@ exit_success:
/* }}} */
/* {{{ wrapper init and registration */
int php_init_stream_wrappers(TSRMLS_D)
static void stream_resource_regular_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
php_stream *stream = (php_stream*)rsrc->ptr;
/* set the return value for pclose */
FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
}
static void stream_resource_persistent_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
php_stream *stream = (php_stream*)rsrc->ptr;
FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
}
int php_init_stream_wrappers(int module_number TSRMLS_DC)
{
return zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS && zend_hash_init(&stream_filters_hash, 0, NULL, NULL, 1) == SUCCESS ? SUCCESS : FAILURE;
le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number);
le_pstream = zend_register_list_destructors_ex(NULL, stream_resource_persistent_dtor, "persistent stream", module_number);
return (
zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS
&&
zend_hash_init(&stream_filters_hash, 0, NULL, NULL, 1) == SUCCESS
) ? SUCCESS : FAILURE;
}
int php_shutdown_stream_wrappers(TSRMLS_D)
int php_shutdown_stream_wrappers(int module_number TSRMLS_DC)
{
zend_hash_destroy(&url_stream_wrappers_hash);
zend_hash_destroy(&stream_filters_hash);

Loading…
Cancel
Save