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