Skip to content

Commit 0f653c6

Browse files
committed
Introduce redirect_proc_descriptor helper in proc_open.c
1 parent 38b2b0f commit 0f653c6

File tree

2 files changed

+37
-32
lines changed

2 files changed

+37
-32
lines changed

ext/standard/proc_open.c

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,40 @@ static int dup_proc_descriptor(php_file_descriptor_t from, php_file_descriptor_t
674674
return SUCCESS;
675675
}
676676

677+
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)
678+
{
679+
php_file_descriptor_t redirect_to = PHP_INVALID_FD;
680+
681+
for (int i = 0; i < ndesc; i++) {
682+
if (descriptors[i].index == target) {
683+
redirect_to = descriptors[i].childend;
684+
break;
685+
}
686+
}
687+
688+
if (redirect_to == PHP_INVALID_FD) { /* didn't find the index we wanted */
689+
if (target < 0 || target > 2) {
690+
php_error_docref(NULL, E_WARNING, "Redirection target %d not found", target);
691+
return FAILURE;
692+
}
693+
694+
/* Support referring to a stdin/stdout/stderr pipe adopted from the parent,
695+
* which happens whenever an explicit override is not provided. */
696+
#ifndef PHP_WIN32
697+
redirect_to = target;
698+
#else
699+
switch (target) {
700+
case 0: redirect_to = GetStdHandle(STD_INPUT_HANDLE); break;
701+
case 1: redirect_to = GetStdHandle(STD_OUTPUT_HANDLE); break;
702+
case 2: redirect_to = GetStdHandle(STD_ERROR_HANDLE); break;
703+
EMPTY_SWITCH_DEFAULT_CASE()
704+
}
705+
#endif
706+
}
707+
708+
return dup_proc_descriptor(redirect_to, &desc->childend, nindex);
709+
}
710+
677711
static int close_parent_ends_of_pipes_in_child(struct php_proc_open_descriptor_item *descriptors, int ndesc)
678712
{
679713
/* we are running in child process
@@ -875,8 +909,6 @@ PHP_FUNCTION(proc_open)
875909
}
876910
} else if (zend_string_equals_literal(ztype, "redirect")) {
877911
zval *ztarget = zend_hash_index_find_deref(Z_ARRVAL_P(descitem), 1);
878-
php_file_descriptor_t childend = -1;
879-
880912
if (!ztarget) {
881913
zend_value_error("Missing redirection target");
882914
goto exit_fail;
@@ -885,36 +917,7 @@ PHP_FUNCTION(proc_open)
885917
zend_value_error("Redirection target must be an integer");
886918
goto exit_fail;
887919
}
888-
889-
for (i = 0; i < ndesc; i++) {
890-
if (descriptors[i].index == Z_LVAL_P(ztarget)) {
891-
childend = descriptors[i].childend;
892-
break;
893-
}
894-
}
895-
896-
if (childend == -1) {
897-
if (Z_LVAL_P(ztarget) < 0 || Z_LVAL_P(ztarget) > 2) {
898-
php_error_docref(NULL, E_WARNING,
899-
"Redirection target " ZEND_LONG_FMT " not found", Z_LVAL_P(ztarget));
900-
goto exit_fail;
901-
}
902-
903-
/* Support referring to a stdin/stdout/stderr pipe adopted from the parent,
904-
* which happens whenever an explicit override is not provided. */
905-
#ifndef PHP_WIN32
906-
childend = Z_LVAL_P(ztarget);
907-
#else
908-
switch (Z_LVAL_P(ztarget)) {
909-
case 0: childend = GetStdHandle(STD_INPUT_HANDLE); break;
910-
case 1: childend = GetStdHandle(STD_OUTPUT_HANDLE); break;
911-
case 2: childend = GetStdHandle(STD_ERROR_HANDLE); break;
912-
EMPTY_SWITCH_DEFAULT_CASE()
913-
}
914-
#endif
915-
}
916-
917-
if (dup_proc_descriptor(childend, &descriptors[ndesc].childend, nindex) == FAILURE) {
920+
if (redirect_proc_descriptor(&descriptors[ndesc], Z_LVAL_P(ztarget), descriptors, ndesc, nindex) == FAILURE) {
918921
goto exit_fail;
919922
}
920923
} else if (zend_string_equals_literal(ztype, "null")) {

ext/standard/proc_open.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
#ifdef PHP_WIN32
1818
typedef HANDLE php_file_descriptor_t;
1919
typedef DWORD php_process_id_t;
20+
# define PHP_INVALID_FD INVALID_HANDLE_VALUE
2021
#else
2122
typedef int php_file_descriptor_t;
2223
typedef pid_t php_process_id_t;
24+
# define PHP_INVALID_FD (-1)
2325
#endif
2426

2527
/* Environment block under win32 is a NUL terminated sequence of NUL terminated

0 commit comments

Comments
 (0)