diff options
Diffstat (limited to 'ext/standard/proc_open.c')
| -rw-r--r-- | ext/standard/proc_open.c | 216 |
1 files changed, 88 insertions, 128 deletions
diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 50ceb605ed..903b3a7be1 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -75,17 +75,15 @@ 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; #ifndef PHP_WIN32 char **ep; #endif char *p; - uint string_length, cnt, l, sizeenv=0, el_len; - ulong num_key; + uint cnt, l, sizeenv=0; HashTable *target_hash; - HashPosition pos; memset(&env, 0, sizeof(env)); @@ -109,100 +107,66 @@ 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)) { + ZEND_HASH_FOREACH_STR_KEY_VAL(target_hash, string_key, element) { + zend_string *str = zval_get_string(element); + uint el_len = str->len; + STR_RELEASE(str); - if (Z_TYPE_PP(element) != IS_STRING) { - zval tmp; - - MAKE_COPY_ZVAL(element, &tmp); - convert_to_string(&tmp); - el_len = Z_STRLEN(tmp); - - zval_dtor(&tmp); - } else { - el_len = Z_STRLEN_PP(element); - } if (el_len == 0) { continue; } - sizeenv += el_len+1; + 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)) { - zval tmp; - - if (Z_TYPE_PP(element) != IS_STRING) { - MAKE_COPY_ZVAL(element, &tmp); - convert_to_string(&tmp); - } else { - tmp = **element; - } + ZEND_HASH_FOREACH_STR_KEY_VAL(target_hash, string_key, element) { + zend_string *str = zval_get_string(element); - el_len = Z_STRLEN(tmp); - - if (el_len == 0) { + if (str->len == 0) { goto next_element; } - 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; - } + if (string_key) { + if (string_key->len == 0) { + goto next_element; + } - l = string_length + el_len + 1; - memcpy(p, string_key, string_length); - strncat(p, "=", 1); - strncat(p, data, el_len); + l = string_key->len + str->len + 2; + memcpy(p, string_key->val, string_key->len); + strncat(p, "=", 1); + strncat(p, str->val, str->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, str->val, str->len); #ifndef PHP_WIN32 - *ep = p; - ++ep; + *ep = p; + ++ep; #endif - p += el_len + 1; - break; - case HASH_KEY_NON_EXISTENT: - break; + p += str->len + 1; } - next_element: - if (Z_TYPE_PP(element) != IS_STRING) { - zval_dtor(&tmp); - } - } + STR_RELEASE(str); + } ZEND_HASH_FOREACH_END(); assert((uint)(p - env.envp) <= sizeenv); - zend_hash_internal_pointer_reset_ex(target_hash, &pos); - return env; } /* }}} */ @@ -222,7 +186,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 +201,8 @@ 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]); + GC_REFCOUNT(proc->pipes[i])--; + zend_list_close(proc->pipes[i]); proc->pipes[i] = 0; } } @@ -295,13 +260,13 @@ PHP_FUNCTION(proc_terminate) { zval *zproc; struct php_process_handle *proc; - long sig_no = SIGTERM; + php_int_t sig_no = SIGTERM; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zproc, &sig_no) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|i", &zproc, &sig_no) == FAILURE) { 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,12 +295,12 @@ 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_close(Z_RES_P(zproc)); FG(pclose_wait) = 0; - RETURN_LONG(FG(pclose_ret)); + RETURN_INT(FG(pclose_ret)); } /* }}} */ @@ -358,12 +323,12 @@ 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_long(return_value, "pid", (long) proc->child); + add_assoc_string(return_value, "command", proc->command); + add_assoc_int(return_value, "pid", (php_int_t) proc->child); #ifdef PHP_WIN32 @@ -403,9 +368,9 @@ PHP_FUNCTION(proc_get_status) add_assoc_bool(return_value, "running", running); add_assoc_bool(return_value, "signaled", signaled); add_assoc_bool(return_value, "stopped", stopped); - add_assoc_long(return_value, "exitcode", exitcode); - add_assoc_long(return_value, "termsig", termsig); - add_assoc_long(return_value, "stopsig", stopsig); + add_assoc_int(return_value, "exitcode", exitcode); + add_assoc_int(return_value, "termsig", termsig); + add_assoc_int(return_value, "stopsig", stopsig); } /* }}} */ @@ -460,8 +425,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; + php_uint_t nindex; struct php_proc_open_descriptor_item descriptors[PHP_PROC_OPEN_MAX_DESCRIPTORS]; #ifdef PHP_WIN32 PROCESS_INFORMATION pi; @@ -493,7 +459,7 @@ PHP_FUNCTION(proc_open) php_file_descriptor_t slave_pty = -1; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "saz|s!a!a!", &command, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "saz/|s!a!a!", &command, &command_len, &descriptorspec, &pipes, &cwd, &cwd_len, &environment, &other_options) == FAILURE) { RETURN_FALSE; @@ -503,16 +469,16 @@ PHP_FUNCTION(proc_open) #ifdef PHP_WIN32 if (other_options) { - zval **item; - if (SUCCESS == zend_hash_find(Z_ARRVAL_P(other_options), "suppress_errors", sizeof("suppress_errors"), (void**)&item)) { - if ((Z_TYPE_PP(item) == IS_BOOL || Z_TYPE_PP(item) == IS_LONG) && - Z_LVAL_PP(item)) { + zval *item = zend_hash_str_find(Z_ARRVAL_P(other_options), "suppress_errors", sizeof("suppress_errors") - 1); + if (item != NULL) { + if (Z_TYPE_P(item) == IS_TRUE || ((Z_TYPE_P(item) == IS_INT) && Z_IVAL_P(item))) { suppress_errors = 1; } } - if (SUCCESS == zend_hash_find(Z_ARRVAL_P(other_options), "bypass_shell", sizeof("bypass_shell"), (void**)&item)) { - if ((Z_TYPE_PP(item) == IS_BOOL || Z_TYPE_PP(item) == IS_LONG) && - Z_LVAL_PP(item)) { + + item = zend_hash_str_find(Z_ARRVAL_P(other_options), "bypass_shell", sizeof("bypass_shell") - 1); + if (item != NULL) { + if (Z_TYPE_P(item) == IS_TRUE || ((Z_TYPE_P(item) == IS_INT) && Z_IVAL_P(item))) { bypass_shell = 1; } } @@ -538,14 +504,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 +514,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 +540,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 +570,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 +584,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_STRSIZE_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 +610,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 */ @@ -666,13 +626,13 @@ PHP_FUNCTION(proc_open) /* simulate the append mode by fseeking to the end of the file this introduces a potential race-condition, but it is the best we can do, though */ - if (strchr(Z_STRVAL_PP(zmode), 'a')) { + if (strchr(Z_STRVAL_P(zmode), 'a')) { SetFilePointer(descriptors[ndesc].childend, 0, NULL, FILE_END); } #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 +659,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) { @@ -919,7 +878,8 @@ PHP_FUNCTION(proc_open) if (pipes != NULL) { zval_dtor(pipes); - } + } + array_init(pipes); #if PHP_CAN_DO_PTS @@ -969,20 +929,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; } } |
