diff options
Diffstat (limited to 'ext/standard/proc_open.c')
| -rw-r--r-- | ext/standard/proc_open.c | 171 |
1 files changed, 77 insertions, 94 deletions
diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 50ceb605ed..0ab8ffa7e7 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -75,17 +75,17 @@ static int le_proc_open; /* {{{ _php_array_to_envp */ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent TSRMLS_DC) { - zval **element; + zval *element; php_process_env_t env; - char *string_key, *data; + zend_string *string_key; + char *data; #ifndef PHP_WIN32 char **ep; #endif char *p; - uint string_length, cnt, l, sizeenv=0, el_len; + uint cnt, l, sizeenv=0, el_len; ulong num_key; HashTable *target_hash; - HashPosition pos; memset(&env, 0, sizeof(env)); @@ -109,20 +109,16 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent } /* first, we have to get the size of all the elements in the hash */ - for (zend_hash_internal_pointer_reset_ex(target_hash, &pos); - zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos) == SUCCESS; - zend_hash_move_forward_ex(target_hash, &pos)) { - - if (Z_TYPE_PP(element) != IS_STRING) { - zval tmp; + ZEND_HASH_FOREACH_KEY_VAL(target_hash, num_key, string_key, element) { + zval tmp; - MAKE_COPY_ZVAL(element, &tmp); + if (Z_TYPE_P(element) != IS_STRING) { + ZVAL_DUP(&tmp, element); convert_to_string(&tmp); el_len = Z_STRLEN(tmp); - zval_dtor(&tmp); } else { - el_len = Z_STRLEN_PP(element); + el_len = Z_STRLEN_P(element); } if (el_len == 0) { continue; @@ -130,31 +126,27 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent sizeenv += el_len+1; - switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_length, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (string_length == 0) { - continue; - } - sizeenv += string_length; - break; + if (string_key) { + if (string_key->len == 0) { + continue; + } + sizeenv += string_key->len + 1; } - } + } ZEND_HASH_FOREACH_END(); #ifndef PHP_WIN32 ep = env.envarray = (char **) pecalloc(cnt + 1, sizeof(char *), is_persistent); #endif p = env.envp = (char *) pecalloc(sizeenv + 4, 1, is_persistent); - for (zend_hash_internal_pointer_reset_ex(target_hash, &pos); - zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos) == SUCCESS; - zend_hash_move_forward_ex(target_hash, &pos)) { + ZEND_HASH_FOREACH_KEY_VAL(target_hash, num_key, string_key, element) { zval tmp; - if (Z_TYPE_PP(element) != IS_STRING) { - MAKE_COPY_ZVAL(element, &tmp); + if (Z_TYPE_P(element) != IS_STRING) { + ZVAL_DUP(&tmp, element); convert_to_string(&tmp); } else { - tmp = **element; + ZVAL_COPY_VALUE(&tmp, element); } el_len = Z_STRLEN(tmp); @@ -164,45 +156,38 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent } data = Z_STRVAL(tmp); - switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_length, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (string_length == 0) { - goto next_element; - } - l = string_length + el_len + 1; - memcpy(p, string_key, string_length); - strncat(p, "=", 1); - strncat(p, data, el_len); + if (string_key) { + if (string_key->len == 0) { + goto next_element; + } + + l = string_key->len + el_len + 2; + memcpy(p, string_key->val, string_key->len); + strncat(p, "=", 1); + strncat(p, data, el_len); #ifndef PHP_WIN32 - *ep = p; - ++ep; + *ep = p; + ++ep; #endif - p += l; - break; - case HASH_KEY_IS_LONG: - memcpy(p,data,el_len); + p += l; + } else { + memcpy(p,data,el_len); #ifndef PHP_WIN32 - *ep = p; - ++ep; + *ep = p; + ++ep; #endif - p += el_len + 1; - break; - case HASH_KEY_NON_EXISTENT: - break; + p += el_len + 1; } - next_element: - if (Z_TYPE_PP(element) != IS_STRING) { + if (Z_TYPE_P(element) != IS_STRING) { zval_dtor(&tmp); } - } + } ZEND_HASH_FOREACH_END(); assert((uint)(p - env.envp) <= sizeenv); - zend_hash_internal_pointer_reset_ex(target_hash, &pos); - return env; } /* }}} */ @@ -222,7 +207,7 @@ static void _php_free_envp(php_process_env_t env, int is_persistent) /* }}} */ /* {{{ proc_open_rsrc_dtor */ -static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void proc_open_rsrc_dtor(zend_resource *rsrc TSRMLS_DC) { struct php_process_handle *proc = (struct php_process_handle*)rsrc->ptr; int i; @@ -237,7 +222,9 @@ static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* Close all handles to avoid a deadlock */ for (i = 0; i < proc->npipes; i++) { if (proc->pipes[i] != 0) { - zend_list_delete(proc->pipes[i]); + if (--GC_REFCOUNT(proc->pipes[i]) <= 0) { + zend_list_delete(proc->pipes[i]); + } proc->pipes[i] = 0; } } @@ -301,7 +288,7 @@ PHP_FUNCTION(proc_terminate) RETURN_FALSE; } - ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, &zproc, -1, "process", le_proc_open); + ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, zproc, -1, "process", le_proc_open); #ifdef PHP_WIN32 if (TerminateProcess(proc->childHandle, 255)) { @@ -330,10 +317,10 @@ PHP_FUNCTION(proc_close) RETURN_FALSE; } - ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, &zproc, -1, "process", le_proc_open); + ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, zproc, -1, "process", le_proc_open); FG(pclose_wait) = 1; - zend_list_delete(Z_LVAL_P(zproc)); + zend_list_delete(Z_RES_P(zproc)); FG(pclose_wait) = 0; RETURN_LONG(FG(pclose_ret)); } @@ -358,11 +345,11 @@ PHP_FUNCTION(proc_get_status) RETURN_FALSE; } - ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, &zproc, -1, "process", le_proc_open); + ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, zproc, -1, "process", le_proc_open); array_init(return_value); - add_assoc_string(return_value, "command", proc->command, 1); + add_assoc_string(return_value, "command", proc->command); add_assoc_long(return_value, "pid", (long) proc->child); #ifdef PHP_WIN32 @@ -460,8 +447,9 @@ PHP_FUNCTION(proc_open) php_process_env_t env; int ndesc = 0; int i; - zval **descitem = NULL; - HashPosition pos; + zval *descitem = NULL; + zend_string *str_index; + ulong nindex; struct php_proc_open_descriptor_item descriptors[PHP_PROC_OPEN_MAX_DESCRIPTORS]; #ifdef PHP_WIN32 PROCESS_INFORMATION pi; @@ -538,14 +526,8 @@ PHP_FUNCTION(proc_open) #endif /* walk the descriptor spec and set up files/pipes */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(descriptorspec), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(descriptorspec), (void **)&descitem, &pos) == SUCCESS) { - char *str_index; - ulong nindex; - zval **ztype; - - str_index = NULL; - zend_hash_get_current_key_ex(Z_ARRVAL_P(descriptorspec), &str_index, NULL, &nindex, 0, &pos); + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(descriptorspec), nindex, str_index, descitem) { + zval *ztype; if (str_index) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "descriptor spec must be an integer indexed array"); @@ -554,7 +536,7 @@ PHP_FUNCTION(proc_open) descriptors[ndesc].index = nindex; - if (Z_TYPE_PP(descitem) == IS_RESOURCE) { + if (Z_TYPE_P(descitem) == IS_RESOURCE) { /* should be a stream - try and dup the descriptor */ php_stream *stream; php_socket_t fd; @@ -580,23 +562,23 @@ PHP_FUNCTION(proc_open) #endif descriptors[ndesc].mode = DESC_FILE; - } else if (Z_TYPE_PP(descitem) != IS_ARRAY) { + } else if (Z_TYPE_P(descitem) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Descriptor item must be either an array or a File-Handle"); goto exit_fail; } else { - if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 0, (void **)&ztype) == SUCCESS) { + if ((ztype = zend_hash_index_find(Z_ARRVAL_P(descitem), 0)) != NULL) { convert_to_string_ex(ztype); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing handle qualifier in array"); goto exit_fail; } - if (strcmp(Z_STRVAL_PP(ztype), "pipe") == 0) { + if (strcmp(Z_STRVAL_P(ztype), "pipe") == 0) { php_file_descriptor_t newpipe[2]; - zval **zmode; + zval *zmode; - if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zmode) == SUCCESS) { + if ((zmode = zend_hash_index_find(Z_ARRVAL_P(descitem), 1)) != NULL) { convert_to_string_ex(zmode); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing mode parameter for 'pipe'"); @@ -610,7 +592,7 @@ PHP_FUNCTION(proc_open) goto exit_fail; } - if (strncmp(Z_STRVAL_PP(zmode), "w", 1) != 0) { + if (strncmp(Z_STRVAL_P(zmode), "w", 1) != 0) { descriptors[ndesc].parentend = newpipe[1]; descriptors[ndesc].childend = newpipe[0]; descriptors[ndesc].mode |= DESC_PARENT_MODE_WRITE; @@ -624,25 +606,25 @@ PHP_FUNCTION(proc_open) #endif descriptors[ndesc].mode_flags = descriptors[ndesc].mode & DESC_PARENT_MODE_WRITE ? O_WRONLY : O_RDONLY; #ifdef PHP_WIN32 - if (Z_STRLEN_PP(zmode) >= 2 && Z_STRVAL_PP(zmode)[1] == 'b') + if (Z_STRLEN_P(zmode) >= 2 && Z_STRVAL_P(zmode)[1] == 'b') descriptors[ndesc].mode_flags |= O_BINARY; #endif - } else if (strcmp(Z_STRVAL_PP(ztype), "file") == 0) { - zval **zfile, **zmode; + } else if (strcmp(Z_STRVAL_P(ztype), "file") == 0) { + zval *zfile, *zmode; php_socket_t fd; php_stream *stream; descriptors[ndesc].mode = DESC_FILE; - if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zfile) == SUCCESS) { + if ((zfile = zend_hash_index_find(Z_ARRVAL_P(descitem), 1)) != NULL) { convert_to_string_ex(zfile); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing file name parameter for 'file'"); goto exit_fail; } - if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 2, (void **)&zmode) == SUCCESS) { + if ((zmode = zend_hash_index_find(Z_ARRVAL_P(descitem), 2)) != NULL) { convert_to_string_ex(zmode); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing mode parameter for 'file'"); @@ -650,7 +632,7 @@ PHP_FUNCTION(proc_open) } /* try a wrapper */ - stream = php_stream_open_wrapper(Z_STRVAL_PP(zfile), Z_STRVAL_PP(zmode), + stream = php_stream_open_wrapper(Z_STRVAL_P(zfile), Z_STRVAL_P(zmode), REPORT_ERRORS|STREAM_WILL_CAST, NULL); /* force into an fd */ @@ -672,7 +654,7 @@ PHP_FUNCTION(proc_open) #else descriptors[ndesc].childend = fd; #endif - } else if (strcmp(Z_STRVAL_PP(ztype), "pty") == 0) { + } else if (strcmp(Z_STRVAL_P(ztype), "pty") == 0) { #if PHP_CAN_DO_PTS if (dev_ptmx == -1) { /* open things up */ @@ -699,15 +681,14 @@ PHP_FUNCTION(proc_open) goto exit_fail; #endif } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a valid descriptor spec/mode", Z_STRVAL_PP(ztype)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a valid descriptor spec/mode", Z_STRVAL_P(ztype)); goto exit_fail; } } - zend_hash_move_forward_ex(Z_ARRVAL_P(descriptorspec), &pos); if (++ndesc == PHP_PROC_OPEN_MAX_DESCRIPTORS) break; - } + } ZEND_HASH_FOREACH_END(); #ifdef PHP_WIN32 if (cwd == NULL) { @@ -918,8 +899,10 @@ PHP_FUNCTION(proc_open) proc->env = env; if (pipes != NULL) { + ZVAL_DEREF(pipes); zval_dtor(pipes); - } + } + array_init(pipes); #if PHP_CAN_DO_PTS @@ -969,20 +952,20 @@ PHP_FUNCTION(proc_open) # endif #endif if (stream) { - zval *retfp; + zval retfp; /* nasty hack; don't copy it */ stream->flags |= PHP_STREAM_FLAG_NO_SEEK; - MAKE_STD_ZVAL(retfp); - php_stream_to_zval(stream, retfp); - add_index_zval(pipes, descriptors[i].index, retfp); + php_stream_to_zval(stream, &retfp); + add_index_zval(pipes, descriptors[i].index, &retfp); - proc->pipes[i] = Z_LVAL_P(retfp); + proc->pipes[i] = Z_RES(retfp); + Z_ADDREF(retfp); } break; default: - proc->pipes[i] = 0; + proc->pipes[i] = NULL; } } |
