Skip to content

Commit a532a50

Browse files
committed
Introduce redirect_proc_descriptor helper in proc_open.c
1 parent 9b75507 commit a532a50

File tree

1 file changed

+38
-32
lines changed

1 file changed

+38
-32
lines changed

ext/standard/proc_open.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,43 @@ static int dup_proc_descriptor(php_file_descriptor_t from, php_file_descriptor_t
680680
return SUCCESS;
681681
}
682682

683+
static int redirect_proc_descriptor(struct php_proc_open_descriptor_item *desc, int target, struct php_proc_open_descriptor_item *descriptors, int ndesc, int nindex)
684+
{
685+
php_file_descriptor_t redirect_to = -1;
686+
687+
for (int i = 0; i < ndesc; i++) {
688+
if (descriptors[i].index == target) {
689+
redirect_to = descriptors[i].childend;
690+
break;
691+
}
692+
}
693+
694+
if (redirect_to == -1) { /* didn't find the index we wanted */
695+
if (target < 0 || target > 2) {
696+
php_error_docref(NULL, E_WARNING, "Redirection target %d not found", target);
697+
return FAILURE;
698+
}
699+
700+
/* Support referring to a stdin/stdout/stderr pipe adopted from the parent,
701+
* which happens whenever an explicit override is not provided. */
702+
#ifndef PHP_WIN32
703+
redirect_to = target;
704+
#else
705+
switch (target) {
706+
case 0: redirect_to = GetStdHandle(STD_INPUT_HANDLE); break;
707+
case 1: redirect_to = GetStdHandle(STD_OUTPUT_HANDLE); break;
708+
case 2: redirect_to = GetStdHandle(STD_ERROR_HANDLE); break;
709+
EMPTY_SWITCH_DEFAULT_CASE()
710+
}
711+
#endif
712+
}
713+
714+
if (dup_proc_descriptor(redirect_to, &desc->childend, nindex) == FAILURE) {
715+
return FAILURE;
716+
}
717+
return SUCCESS;
718+
}
719+
683720
static int close_parent_ends_of_pipes_in_child(struct php_proc_open_descriptor_item *descriptors, int ndesc)
684721
{
685722
/* we are running in child process
@@ -882,8 +919,6 @@ PHP_FUNCTION(proc_open)
882919
}
883920
} else if (strcmp(ZSTR_VAL(ztype), "redirect") == 0) {
884921
zval *ztarget = zend_hash_index_find_deref(Z_ARRVAL_P(descitem), 1);
885-
php_file_descriptor_t childend = -1;
886-
887922
if (!ztarget) {
888923
zend_value_error("Missing redirection target");
889924
goto exit_fail;
@@ -892,36 +927,7 @@ PHP_FUNCTION(proc_open)
892927
zend_value_error("Redirection target must be an integer");
893928
goto exit_fail;
894929
}
895-
896-
for (i = 0; i < ndesc; i++) {
897-
if (descriptors[i].index == Z_LVAL_P(ztarget)) {
898-
childend = descriptors[i].childend;
899-
break;
900-
}
901-
}
902-
903-
if (childend == -1) {
904-
if (Z_LVAL_P(ztarget) < 0 || Z_LVAL_P(ztarget) > 2) {
905-
php_error_docref(NULL, E_WARNING,
906-
"Redirection target " ZEND_LONG_FMT " not found", Z_LVAL_P(ztarget));
907-
goto exit_fail;
908-
}
909-
910-
/* Support referring to a stdin/stdout/stderr pipe adopted from the parent,
911-
* which happens whenever an explicit override is not provided. */
912-
#ifndef PHP_WIN32
913-
childend = Z_LVAL_P(ztarget);
914-
#else
915-
switch (Z_LVAL_P(ztarget)) {
916-
case 0: childend = GetStdHandle(STD_INPUT_HANDLE); break;
917-
case 1: childend = GetStdHandle(STD_OUTPUT_HANDLE); break;
918-
case 2: childend = GetStdHandle(STD_ERROR_HANDLE); break;
919-
EMPTY_SWITCH_DEFAULT_CASE()
920-
}
921-
#endif
922-
}
923-
924-
if (dup_proc_descriptor(childend, &descriptors[ndesc].childend, nindex) == FAILURE) {
930+
if (redirect_proc_descriptor(&descriptors[ndesc], Z_LVAL_P(ztarget), descriptors, ndesc, nindex) == FAILURE) {
925931
goto exit_fail;
926932
}
927933
} else if (strcmp(ZSTR_VAL(ztype), "null") == 0) {

0 commit comments

Comments
 (0)