From f8fdb67056720d5a867b7a6e8d4d26cc755881c6 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Sun, 24 Sep 2006 20:33:14 +0000 Subject: [PATCH] PHP6 Updates for popen() and related functionality --- ext/standard/file.c | 55 +++++++++++++++++++++--------------- main/php_streams.h | 1 + main/streams/plain_wrapper.c | 4 +++ main/streams/streams.c | 45 +++++++++++++++++------------ 4 files changed, 64 insertions(+), 41 deletions(-) diff --git a/ext/standard/file.c b/ext/standard/file.c index 91580ea64b..a0a565873b 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1075,46 +1075,55 @@ PHPAPI PHP_FUNCTION(fclose) /* }}} */ -/* {{{ proto resource popen(string command, string mode) +/* {{{ proto resource popen(string command, string mode) U Execute a command and open either a read or a write pipe to it */ - PHP_FUNCTION(popen) { - zval **arg1, **arg2; + char *command, *mode; + int command_len, mode_len; + zend_uchar command_type; FILE *fp; - char *p; - php_stream *stream; + char *posix_mode; - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ts", &command, &command_len, &command_type, &mode, &mode_len) == FAILURE) { + return; } - convert_to_string_ex(arg1); - convert_to_string_ex(arg2); - p = estrndup(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2)); + + if (command_type == IS_UNICODE) { + if (FAILURE == php_stream_path_encode(NULL, &command, &command_len, (UChar*)command, command_len, REPORT_ERRORS, FG(default_context))) { + RETURN_FALSE; + } + } + + posix_mode = estrndup(mode, mode_len); #ifndef PHP_WIN32 { - char *z = memchr(p, 'b', Z_STRLEN_PP(arg2)); + char *z = memchr(posix_mode, 'b', mode_len); if (z) { - memmove(p + (z - p), z + 1, Z_STRLEN_PP(arg2) - (z - p)); + memmove(z, z + 1, mode_len - (z - posix_mode)); } } #endif - fp = VCWD_POPEN(Z_STRVAL_PP(arg1), p); + fp = VCWD_POPEN(command, posix_mode); if (!fp) { - php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(arg1), p, E_WARNING, "%s", strerror(errno)); - efree(p); - RETURN_FALSE; - } - stream = php_stream_fopen_from_pipe(fp, p); - - if (stream == NULL) { - php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(arg1), p, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL TSRMLS_CC, command, mode, E_WARNING, "%s", strerror(errno)); + efree(posix_mode); RETVAL_FALSE; } else { - php_stream_to_zval(stream, return_value); + php_stream *stream = php_stream_fopen_from_pipe(fp, mode); + + if (stream == NULL) { + php_error_docref2(NULL TSRMLS_CC, command, mode, E_WARNING, "%s", strerror(errno)); + RETVAL_FALSE; + } else { + php_stream_to_zval(stream, return_value); + } } - efree(p); + efree(posix_mode); + if (command_type == IS_UNICODE) { + efree(command); + } } /* }}} */ diff --git a/main/php_streams.h b/main/php_streams.h index 8219081d9e..88e673e556 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -561,6 +561,7 @@ PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *w PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC); PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC); +PHPAPI void php_stream_fix_encoding(php_stream *stream, const char *mode, php_stream_context *context 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); PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC); PHPAPI void *php_stream_locate_eol(php_stream *stream, zstr zbuf, int buf_len TSRMLS_DC); diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index a8611973cb..4c86bae3c8 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -216,6 +216,7 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const cha #endif } } + php_stream_fix_encoding(stream, mode, NULL TSRMLS_CC); return stream; } @@ -259,6 +260,7 @@ PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STRE stream->position = ftell(file); } } + php_stream_fix_encoding(stream, mode, NULL TSRMLS_CC); return stream; } @@ -279,6 +281,8 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); stream->flags |= PHP_STREAM_FLAG_NO_SEEK; + php_stream_fix_encoding(stream, mode, NULL TSRMLS_CC); + return stream; } diff --git a/main/streams/streams.c b/main/streams/streams.c index 75b8a6f63d..6fcff4a217 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -2285,6 +2285,32 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_ } /* }}} */ +/* {{{ php_stream_fix_encoding + * Sets read/write encoding on a stream based on the fopen mode, context options, and INI setting */ +PHPAPI void php_stream_fix_encoding(php_stream *stream, const char *mode, php_stream_context *context TSRMLS_DC) +{ + /* Output encoding on text mode streams defaults to utf8 unless specified in context parameter */ + if (stream && strchr(mode, 't') && UG(unicode)) { + /* Only apply implicit unicode.to. filter if the wrapper didn't do it for us */ + if ((php_stream_filter_product(&stream->writefilters, IS_UNICODE) == IS_UNICODE) && + (strchr(mode, 'w') || strchr(mode, 'a') || strchr(mode, '+'))) { + char *encoding = (context && context->output_encoding) ? context->output_encoding : UG(stream_encoding); + + /* UTODO: (Maybe?) Allow overriding the default error handlers on a per-stream basis via context params */ + php_stream_encoding_apply(stream, 1, encoding, UG(from_error_mode), UG(from_subst_char)); + } + + /* Only apply implicit unicode.from. filter if the wrapper didn't do it for us */ + if ((stream->readbuf_type == IS_STRING) && (strchr(mode, 'r') || strchr(mode, '+'))) { + char *encoding = (context && context->input_encoding) ? context->input_encoding : UG(stream_encoding); + + /* UTODO: (Maybe?) Allow overriding the default error handlers on a per-stream basis via context params */ + php_stream_encoding_apply(stream, 0, encoding, UG(to_error_mode), NULL); + } + } +} +/* }}} */ + /* {{{ php_stream_open_wrapper_ex */ 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) @@ -2387,25 +2413,8 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio } } - /* Output encoding on text mode streams defaults to utf8 unless specified in context parameter */ - if (stream && strchr(implicit_mode, 't') && UG(unicode)) { - /* Only apply implicit unicode.to. filter if the wrapper didn't do it for us */ - if ((php_stream_filter_product(&stream->writefilters, IS_UNICODE) == IS_UNICODE) && - (strchr(implicit_mode, 'w') || strchr(implicit_mode, 'a') || strchr(implicit_mode, '+'))) { - char *encoding = (context && context->output_encoding) ? context->output_encoding : UG(stream_encoding); - /* UTODO: (Maybe?) Allow overriding the default error handlers on a per-stream basis via context params */ - php_stream_encoding_apply(stream, 1, encoding, UG(from_error_mode), UG(from_subst_char)); - } - - /* Only apply implicit unicode.from. filter if the wrapper didn't do it for us */ - if ((stream->readbuf_type == IS_STRING) && (strchr(implicit_mode, 'r') || strchr(implicit_mode, '+'))) { - char *encoding = (context && context->input_encoding) ? context->input_encoding : UG(stream_encoding); - - /* UTODO: (Maybe?) Allow overriding the default error handlers on a per-stream basis via context params */ - php_stream_encoding_apply(stream, 0, encoding, UG(to_error_mode), NULL); - } - } + php_stream_fix_encoding(stream, implicit_mode, context TSRMLS_CC); if (stream == NULL && (options & REPORT_ERRORS)) { php_stream_display_wrapper_errors(wrapper, path, "failed to open stream" TSRMLS_CC); -- 2.40.0