Skip to content

Commit 73c15e0

Browse files
committed
Introduce close_parent_ends_of_pipes_in_child helper in proc_open.c
1 parent b2cb97b commit 73c15e0

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
@@ -623,6 +623,29 @@ static int set_proc_descriptor_to_file(struct php_proc_open_descriptor_item *des
623623
return SUCCESS;
624624
}
625625

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+
626649
static void close_all_descriptors(struct php_proc_open_descriptor_item *descriptors, int ndesc)
627650
{
628651
for (int i = 0; i < ndesc; i++) {
@@ -1046,20 +1069,12 @@ PHP_FUNCTION(proc_open)
10461069
close(slave_pty);
10471070
}
10481071
#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);
10631078
}
10641079

10651080
if (cwd) {

0 commit comments

Comments
 (0)