@@ -708,6 +708,85 @@ static int redirect_proc_descriptor(struct php_proc_open_descriptor_item *desc,
708
708
return dup_proc_descriptor (redirect_to , & desc -> childend , nindex );
709
709
}
710
710
711
+
712
+ int set_proc_descriptor_from_array (
713
+ zval * descitem , struct php_proc_open_descriptor_item * descriptors , int ndesc , int nindex ) {
714
+ zend_string * ztype = get_string_parameter (descitem , 0 , "handle qualifier" );
715
+ if (!ztype ) {
716
+ return FAILURE ;
717
+ }
718
+
719
+ zend_string * zmode = NULL , * zfile = NULL ;
720
+ int retval = FAILURE ;
721
+ if (zend_string_equals_literal (ztype , "pipe" )) {
722
+ if ((zmode = get_string_parameter (descitem , 1 , "mode parameter for 'pipe'" )) == NULL ) {
723
+ goto finish ;
724
+ }
725
+
726
+ retval = set_proc_descriptor_to_pipe (& descriptors [ndesc ], zmode );
727
+ } else if (zend_string_equals_literal (ztype , "file" )) {
728
+ if ((zfile = get_string_parameter (descitem , 1 , "file name parameter for 'file'" )) == NULL ) {
729
+ goto finish ;
730
+ }
731
+ if ((zmode = get_string_parameter (descitem , 2 , "mode parameter for 'file'" )) == NULL ) {
732
+ goto finish ;
733
+ }
734
+
735
+ retval = set_proc_descriptor_to_file (& descriptors [ndesc ], zfile , zmode );
736
+ } else if (zend_string_equals_literal (ztype , "redirect" )) {
737
+ zval * ztarget = zend_hash_index_find_deref (Z_ARRVAL_P (descitem ), 1 );
738
+ if (!ztarget ) {
739
+ zend_value_error ("Missing redirection target" );
740
+ goto finish ;
741
+ }
742
+ if (Z_TYPE_P (ztarget ) != IS_LONG ) {
743
+ zend_value_error ("Redirection target must be of type int, %s given" , zend_get_type_by_const (Z_TYPE_P (ztarget )));
744
+ goto finish ;
745
+ }
746
+
747
+ retval = redirect_proc_descriptor (
748
+ & descriptors [ndesc ], Z_LVAL_P (ztarget ), descriptors , ndesc , nindex );
749
+ } else if (zend_string_equals_literal (ztype , "null" )) {
750
+ retval = set_proc_descriptor_to_blackhole (& descriptors [ndesc ]);
751
+ } else if (zend_string_equals_literal (ztype , "pty" )) {
752
+ #if PHP_CAN_DO_PTS
753
+ if (dev_ptmx == -1 ) {
754
+ /* open things up */
755
+ dev_ptmx = open ("/dev/ptmx" , O_RDWR );
756
+ if (dev_ptmx == -1 ) {
757
+ php_error_docref (NULL , E_WARNING , "Failed to open /dev/ptmx, errno %d" , errno );
758
+ goto finish ;
759
+ }
760
+ grantpt (dev_ptmx );
761
+ unlockpt (dev_ptmx );
762
+ slave_pty = open (ptsname (dev_ptmx ), O_RDWR );
763
+
764
+ if (slave_pty == -1 ) {
765
+ php_error_docref (NULL , E_WARNING , "Failed to open slave pty, errno %d" , errno );
766
+ goto finish ;
767
+ }
768
+ }
769
+ descriptors [ndesc ].is_pipe = 1 ;
770
+ descriptors [ndesc ].childend = dup (slave_pty );
771
+ descriptors [ndesc ].parentend = dup (dev_ptmx );
772
+ descriptors [ndesc ].mode_flags = O_RDWR ;
773
+ retval = SUCCESS ;
774
+ #else
775
+ php_error_docref (NULL , E_WARNING , "PTY pseudo terminal not supported on this system" );
776
+ goto finish ;
777
+ #endif
778
+ } else {
779
+ php_error_docref (NULL , E_WARNING , "%s is not a valid descriptor spec/mode" , ZSTR_VAL (ztype ));
780
+ goto finish ;
781
+ }
782
+
783
+ finish :
784
+ if (zmode ) zend_string_release (zmode );
785
+ if (zfile ) zend_string_release (zfile );
786
+ zend_string_release (ztype );
787
+ return retval ;
788
+ }
789
+
711
790
static int close_parent_ends_of_pipes_in_child (struct php_proc_open_descriptor_item * descriptors , int ndesc )
712
791
{
713
792
/* we are running in child process
@@ -791,12 +870,6 @@ PHP_FUNCTION(proc_open)
791
870
php_process_id_t child ;
792
871
struct php_process_handle * proc ;
793
872
794
- /* zend_strings which may be allocated while processing the descriptorspec
795
- * we need to make sure that each one allocated is released once and only once */
796
- zend_string * ztype = NULL , * zmode = NULL , * zfile = NULL ;
797
- #define cleanup_zend_string (ptr ) do { zend_tmp_string_release(ptr); ptr = NULL; } while(0)
798
- #define cleanup_zend_strings () cleanup_zend_string(ztype); cleanup_zend_string(zmode); cleanup_zend_string(zfile)
799
-
800
873
#if PHP_CAN_DO_PTS
801
874
php_file_descriptor_t dev_ptmx = -1 ; /* master */
802
875
php_file_descriptor_t slave_pty = -1 ;
@@ -883,78 +956,13 @@ PHP_FUNCTION(proc_open)
883
956
if (dup_proc_descriptor (desc , & descriptors [ndesc ].childend , nindex ) == FAILURE ) {
884
957
goto exit_fail ;
885
958
}
886
- } else if (Z_TYPE_P (descitem ) != IS_ARRAY ) {
887
- zend_argument_value_error (2 , "must only contain arrays and File-Handles" );
888
- goto exit_fail ;
889
- } else if ((ztype = get_string_parameter (descitem , 0 , "handle qualifier" )) == NULL ) {
890
- goto exit_fail ;
891
- } else {
892
- if (zend_string_equals_literal (ztype , "pipe" )) {
893
- if ((zmode = get_string_parameter (descitem , 1 , "mode parameter for 'pipe'" )) == NULL ) {
894
- goto exit_fail ;
895
- }
896
- if (set_proc_descriptor_to_pipe (& descriptors [ndesc ], zmode ) == FAILURE ) {
897
- goto exit_fail ;
898
- }
899
- } else if (zend_string_equals_literal (ztype , "file" )) {
900
- if ((zfile = get_string_parameter (descitem , 1 , "file name parameter for 'file'" )) == NULL ) {
901
- goto exit_fail ;
902
- }
903
- if ((zmode = get_string_parameter (descitem , 2 , "mode parameter for 'file'" )) == NULL ) {
904
- goto exit_fail ;
905
- }
906
-
907
- if (set_proc_descriptor_to_file (& descriptors [ndesc ], zfile , zmode ) == FAILURE ) {
908
- goto exit_fail ;
909
- }
910
- } else if (zend_string_equals_literal (ztype , "redirect" )) {
911
- zval * ztarget = zend_hash_index_find_deref (Z_ARRVAL_P (descitem ), 1 );
912
- if (!ztarget ) {
913
- zend_value_error ("Missing redirection target" );
914
- goto exit_fail ;
915
- }
916
- if (Z_TYPE_P (ztarget ) != IS_LONG ) {
917
- zend_value_error ("Redirection target must be of type int, %s given" , zend_get_type_by_const (Z_TYPE_P (ztarget )));
918
- goto exit_fail ;
919
- }
920
- if (redirect_proc_descriptor (& descriptors [ndesc ], Z_LVAL_P (ztarget ), descriptors , ndesc , nindex ) == FAILURE ) {
921
- goto exit_fail ;
922
- }
923
- } else if (zend_string_equals_literal (ztype , "null" )) {
924
- if (set_proc_descriptor_to_blackhole (& descriptors [ndesc ]) == FAILURE ) {
925
- goto exit_fail ;
926
- }
927
- } else if (zend_string_equals_literal (ztype , "pty" )) {
928
- #if PHP_CAN_DO_PTS
929
- if (dev_ptmx == -1 ) {
930
- /* open things up */
931
- dev_ptmx = open ("/dev/ptmx" , O_RDWR );
932
- if (dev_ptmx == -1 ) {
933
- php_error_docref (NULL , E_WARNING , "Failed to open /dev/ptmx, errno %d" , errno );
934
- goto exit_fail ;
935
- }
936
- grantpt (dev_ptmx );
937
- unlockpt (dev_ptmx );
938
- slave_pty = open (ptsname (dev_ptmx ), O_RDWR );
939
-
940
- if (slave_pty == -1 ) {
941
- php_error_docref (NULL , E_WARNING , "Failed to open slave pty, errno %d" , errno );
942
- goto exit_fail ;
943
- }
944
- }
945
- descriptors [ndesc ].is_pipe = 1 ;
946
- descriptors [ndesc ].childend = dup (slave_pty );
947
- descriptors [ndesc ].parentend = dup (dev_ptmx );
948
- descriptors [ndesc ].mode_flags = O_RDWR ;
949
- #else
950
- php_error_docref (NULL , E_WARNING , "PTY pseudo terminal not supported on this system" );
951
- goto exit_fail ;
952
- #endif
953
- } else {
954
- php_error_docref (NULL , E_WARNING , "%s is not a valid descriptor spec/mode" , ZSTR_VAL (ztype ));
959
+ } else if (Z_TYPE_P (descitem ) == IS_ARRAY ) {
960
+ if (set_proc_descriptor_from_array (descitem , descriptors , ndesc , nindex ) == FAILURE ) {
955
961
goto exit_fail ;
956
962
}
957
- cleanup_zend_strings ();
963
+ } else {
964
+ zend_argument_value_error (2 , "must only contain arrays and File-Handles" );
965
+ goto exit_fail ;
958
966
}
959
967
ndesc ++ ;
960
968
} ZEND_HASH_FOREACH_END ();
@@ -1203,7 +1211,6 @@ PHP_FUNCTION(proc_open)
1203
1211
#else
1204
1212
efree_argv (argv );
1205
1213
#endif
1206
- cleanup_zend_strings ();
1207
1214
#if PHP_CAN_DO_PTS
1208
1215
if (dev_ptmx >= 0 ) {
1209
1216
close (dev_ptmx );
0 commit comments