@@ -621,6 +621,29 @@ static int set_proc_descriptor_to_file(struct php_proc_open_descriptor_item *des
621
621
#endif
622
622
}
623
623
624
+ static int close_parent_ends_of_pipes_in_child (struct php_proc_open_descriptor_item * descriptors , int ndesc )
625
+ {
626
+ /* we are running in child process
627
+ * close the 'parent end' of all pipes which were opened before forking/spawning
628
+ * also, dup() the child end of all pipes as necessary so they will use the FD number
629
+ * which the user requested */
630
+ for (int i = 0 ; i < ndesc ; i ++ ) {
631
+ if (descriptors [i ].is_pipe ) {
632
+ close (descriptors [i ].parentend );
633
+ if (descriptors [i ].childend != descriptors [i ].index ) {
634
+ if (dup2 (descriptors [i ].childend , descriptors [i ].index ) < 0 ) {
635
+ php_error_docref (NULL , E_WARNING , "Unable to copy file descriptor %d (for pipe) into file descriptor %d - %s" ,
636
+ descriptors [i ].childend , descriptors [i ].index , strerror (errno ));
637
+ return FAILURE ;
638
+ }
639
+ close (descriptors [i ].childend );
640
+ }
641
+ }
642
+ }
643
+
644
+ return SUCCESS ;
645
+ }
646
+
624
647
static void close_all_descriptors (struct php_proc_open_descriptor_item * descriptors , int ndesc )
625
648
{
626
649
for (int i = 0 ; i < ndesc ; i ++ ) {
@@ -1047,20 +1070,12 @@ PHP_FUNCTION(proc_open)
1047
1070
close (slave_pty );
1048
1071
}
1049
1072
#endif
1050
- /* close those descriptors that we just opened for the parent stuff,
1051
- * dup new descriptors into required descriptors and close the original
1052
- * cruft */
1053
- for (i = 0 ; i < ndesc ; i ++ ) {
1054
- if (descriptors [i ].is_pipe ) {
1055
- close (descriptors [i ].parentend );
1056
- }
1057
- if (dup2 (descriptors [i ].childend , descriptors [i ].index ) < 0 ) {
1058
- /* better way to report any problems? */
1059
- perror ("dup2" );
1060
- }
1061
- if (descriptors [i ].childend != descriptors [i ].index ) {
1062
- close (descriptors [i ].childend );
1063
- }
1073
+
1074
+ if (close_parent_ends_of_pipes_in_child (descriptors , ndesc ) == FAILURE ) {
1075
+ /* We are already in child process and can't do anything to make
1076
+ * proc_open() return an error in the parent
1077
+ * All we can do is exit with a non-zero (error) exit code */
1078
+ _exit (127 );
1064
1079
}
1065
1080
1066
1081
if (cwd ) {
0 commit comments