/* }}} */
-/* {{{ 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);
+ }
}
/* }}} */
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);
#endif
}
}
+ php_stream_fix_encoding(stream, mode, NULL TSRMLS_CC);
return stream;
}
stream->position = ftell(file);
}
}
+ php_stream_fix_encoding(stream, mode, NULL TSRMLS_CC);
return stream;
}
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;
}
}
/* }}} */
+/* {{{ 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)
}
}
- /* 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);