Skip to content

Commit 492d79d

Browse files
committed
Introduce close_parent_ends_of_pipes_in_child helper in proc_open.c
1 parent 38c5596 commit 492d79d

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

ext/standard/proc_open.c

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,29 @@ static int set_proc_descriptor_to_file(struct php_proc_open_descriptor_item *des
621621
#endif
622622
}
623623

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+
624647
static void close_all_descriptors(struct php_proc_open_descriptor_item *descriptors, int ndesc)
625648
{
626649
for (int i = 0; i < ndesc; i++) {
@@ -1047,20 +1070,12 @@ PHP_FUNCTION(proc_open)
10471070
close(slave_pty);
10481071
}
10491072
#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);
10641079
}
10651080

10661081
if (cwd) {

0 commit comments

Comments
 (0)