]> granicus.if.org Git - php/commitdiff
initial stuff to make allow blocking pipes on windows
authorAnatol Belski <ab@php.net>
Tue, 30 Jun 2015 13:47:25 +0000 (15:47 +0200)
committerAnatol Belski <ab@php.net>
Thu, 2 Jul 2015 12:22:55 +0000 (14:22 +0200)
ext/standard/php_fopen_wrapper.c
ext/standard/proc_open.c
main/streams/plain_wrapper.c

index f004c943b5e1a523540de1b828ce1b2550e0d41d..c3bd4b0048ec25a7799fca1e5413b272e9da0a71 100644 (file)
@@ -400,6 +400,15 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa
                if (stream == NULL) {
                        close(fd);
                }
+#ifdef PHP_WIN32
+               {
+                       zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking");
+                       if (blocking_pipes) {
+                               convert_to_long(blocking_pipes);
+                               php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, Z_LVAL_P(blocking_pipes), NULL);
+                       }
+               }
+#endif
        }
 
        return stream;
index 27584ea1f2a4f2724369a96ec049c2e2d911503d..cee4728a545bb99b905ffcf7ddf712d7a4b9874a 100644 (file)
@@ -461,6 +461,7 @@ PHP_FUNCTION(proc_open)
 #ifdef PHP_WIN32
        int suppress_errors = 0;
        int bypass_shell = 0;
+       int blocking_pipes = 0;
 #endif
 #if PHP_CAN_DO_PTS
        php_file_descriptor_t dev_ptmx = -1;    /* master */
@@ -490,6 +491,13 @@ PHP_FUNCTION(proc_open)
                                bypass_shell = 1;
                        }
                }
+
+               item = zend_hash_str_find(Z_ARRVAL_P(other_options), "blocking_pipes", sizeof("blocking_pipes") - 1);
+               if (item != NULL) {
+                       if (Z_TYPE_P(item) == IS_TRUE || ((Z_TYPE_P(item) == IS_LONG) && Z_LVAL_P(item))) {
+                               blocking_pipes = 1;
+                       }
+               }
        }
 #endif
 
@@ -538,6 +546,7 @@ PHP_FUNCTION(proc_open)
                        }
 
 #ifdef PHP_WIN32
+                       php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, blocking_pipes, NULL);
                        descriptors[ndesc].childend = dup_fd_as_handle((int)fd);
                        if (descriptors[ndesc].childend == NULL) {
                                php_error_docref(NULL, E_WARNING, "unable to dup File-Handle for descriptor %d", nindex);
index e44e1ea348a0c2a508840cae0d41c8d3bc33ff9f..2fcaa9c645eccd3fa1bf8eab0e31ce4822967862 100644 (file)
@@ -121,7 +121,7 @@ typedef struct {
        unsigned is_process_pipe:1;     /* use pclose instead of fclose */
        unsigned is_pipe:1;                     /* don't try and seek */
        unsigned cached_fstat:1;        /* sb is valid */
-       unsigned _reserved:29;
+       unsigned is_pipe_blocking;
 
        int lock_flag;                  /* stores the lock state */
        zend_string *temp_name; /* if non-null, this is the path to a temporary file that
@@ -170,6 +170,9 @@ static php_stream *_php_stream_fopen_from_fd_int(int fd, const char *mode, const
        self->is_process_pipe = 0;
        self->temp_name = NULL;
        self->fd = fd;
+#ifndef PHP_WIN32
+       is_pipe_blocking = 0;
+#endif
 
        return php_stream_alloc_rel(&php_stream_stdio_ops, self, persistent_id, mode);
 }
@@ -186,6 +189,9 @@ static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode
        self->is_process_pipe = 0;
        self->temp_name = NULL;
        self->fd = fileno(file);
+#ifndef PHP_WIN32
+       is_pipe_blocking = 0;
+#endif
 
        return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
 }
@@ -312,6 +318,9 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE
        self->is_process_pipe = 1;
        self->fd = fileno(file);
        self->temp_name = NULL;
+#ifndef PHP_WIN32
+       is_pipe_blocking = 0;
+#endif
 
        stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
        stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
@@ -356,7 +365,7 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count)
 #ifdef PHP_WIN32
                php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
 
-               if (self->is_pipe || self->is_process_pipe) {
+               if ((self->is_pipe || self->is_process_pipe) && !self->is_pipe_blocking) {
                        HANDLE ph = (HANDLE)_get_osfhandle(data->fd);
                        int retry = 0;
                        DWORD avail_read = 0;
@@ -832,6 +841,12 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
                                }
                        }
 
+#ifdef PHP_WIN32
+               case PHP_STREAM_OPTION_PIPE_BLOCKING:
+                       data->is_pipe_blocking = value;
+                       return PHP_STREAM_OPTION_RETURN_OK;
+#endif
+
                default:
                        return PHP_STREAM_OPTION_RETURN_NOTIMPL;
        }
@@ -1005,6 +1020,11 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zen
                                        return NULL;
                                }
                        }
+
+                       if (options & STREAM_USE_BLOCKING_PIPE) {
+                               php_stdio_stream_data *self = (php_stdio_stream_data*)ret->abstract;
+                               self->is_pipe_blocking = 1;
+                       }
 #endif
 
                        return ret;