@@ -680,6 +680,43 @@ static int dup_proc_descriptor(php_file_descriptor_t from, php_file_descriptor_t
680
680
return SUCCESS ;
681
681
}
682
682
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
+
683
720
static int close_parent_ends_of_pipes_in_child (struct php_proc_open_descriptor_item * descriptors , int ndesc )
684
721
{
685
722
/* we are running in child process
@@ -882,8 +919,6 @@ PHP_FUNCTION(proc_open)
882
919
}
883
920
} else if (strcmp (ZSTR_VAL (ztype ), "redirect" ) == 0 ) {
884
921
zval * ztarget = zend_hash_index_find_deref (Z_ARRVAL_P (descitem ), 1 );
885
- php_file_descriptor_t childend = -1 ;
886
-
887
922
if (!ztarget ) {
888
923
zend_value_error ("Missing redirection target" );
889
924
goto exit_fail ;
@@ -892,36 +927,7 @@ PHP_FUNCTION(proc_open)
892
927
zend_value_error ("Redirection target must be an integer" );
893
928
goto exit_fail ;
894
929
}
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 ) {
925
931
goto exit_fail ;
926
932
}
927
933
} else if (strcmp (ZSTR_VAL (ztype ), "null" ) == 0 ) {
0 commit comments