Skip to content

Commit 2dc4481

Browse files
committed
Extract one more function from proc_open() implementation
1 parent 51b0494 commit 2dc4481

File tree

1 file changed

+84
-77
lines changed

1 file changed

+84
-77
lines changed

ext/standard/proc_open.c

Lines changed: 84 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,85 @@ static int redirect_proc_descriptor(struct php_proc_open_descriptor_item *desc,
708708
return dup_proc_descriptor(redirect_to, &desc->childend, nindex);
709709
}
710710

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+
711790
static int close_parent_ends_of_pipes_in_child(struct php_proc_open_descriptor_item *descriptors, int ndesc)
712791
{
713792
/* we are running in child process
@@ -791,12 +870,6 @@ PHP_FUNCTION(proc_open)
791870
php_process_id_t child;
792871
struct php_process_handle *proc;
793872

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-
800873
#if PHP_CAN_DO_PTS
801874
php_file_descriptor_t dev_ptmx = -1; /* master */
802875
php_file_descriptor_t slave_pty = -1;
@@ -883,78 +956,13 @@ PHP_FUNCTION(proc_open)
883956
if (dup_proc_descriptor(desc, &descriptors[ndesc].childend, nindex) == FAILURE) {
884957
goto exit_fail;
885958
}
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) {
955961
goto exit_fail;
956962
}
957-
cleanup_zend_strings();
963+
} else {
964+
zend_argument_value_error(2, "must only contain arrays and File-Handles");
965+
goto exit_fail;
958966
}
959967
ndesc++;
960968
} ZEND_HASH_FOREACH_END();
@@ -1203,7 +1211,6 @@ PHP_FUNCTION(proc_open)
12031211
#else
12041212
efree_argv(argv);
12051213
#endif
1206-
cleanup_zend_strings();
12071214
#if PHP_CAN_DO_PTS
12081215
if (dev_ptmx >= 0) {
12091216
close(dev_ptmx);

0 commit comments

Comments
 (0)