]> granicus.if.org Git - php/commitdiff
PHP6 Updates for popen() and related functionality
authorSara Golemon <pollita@php.net>
Sun, 24 Sep 2006 20:33:14 +0000 (20:33 +0000)
committerSara Golemon <pollita@php.net>
Sun, 24 Sep 2006 20:33:14 +0000 (20:33 +0000)
ext/standard/file.c
main/php_streams.h
main/streams/plain_wrapper.c
main/streams/streams.c

index 91580ea64bcd7187d5a0d7c86e3c4e218ed4756c..a0a565873b528025a8b0c15364ecf0c8bf518ac5 100644 (file)
@@ -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);
+       }
 }
 /* }}} */
 
index 8219081d9e611713ed0d79c28c905425f6569add..88e673e5569a03719e9e9b23b97878061c856c65 100755 (executable)
@@ -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);
index a8611973cb5fc17c6e1b9f8c107c8a1087387adb..4c86bae3c87d29332cbe94ce35e443fbd0284cfc 100644 (file)
@@ -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;
 }
 
index 75b8a6f63dec02f030586bbb45f32c5c693c8eee..6fcff4a217cb7495f970690b50a92a6e35ac2857 100755 (executable)
@@ -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);