Shane
Index: ext/standard/proc_open.c
===================================================================
RCS file: /repository/php4/ext/standard/proc_open.c,v
retrieving revision 1.3
diff -u -d -u -r1.3 proc_open.c
--- ext/standard/proc_open.c 24 Jan 2003 16:45:34 -0000 1.3
+++ ext/standard/proc_open.c 10 Feb 2003 07:31:43 -0000
@@ -56,6 +56,111 @@
static int le_proc_open;
+/* {{{ _php_array_to_envp */
+static char *_php_array_to_envp(zval *environment, int is_persistent TSRMLS_DC)
+{
+ zval **element;
+ char *envp, *p;
+#ifndef PHP_WIN32
+ char **myenvp, **ep;
+#endif
+ char *string_key, *data;
+ uint string_length, cnt, l, sizeenv=0, el_len;
+ ulong num_key;
+ HashTable *target_hash;
+ HashPosition pos;
+
+ if (!environment) return NULL;
+ cnt = zend_hash_num_elements(Z_ARRVAL_P(environment));
+ if (cnt < 1) return NULL;
+
+ target_hash = HASH_OF(environment);
+ if (!target_hash) return NULL;
+
+ /* first, we have to get the size of all the elements in the hash */
+ for (zend_hash_internal_pointer_reset_ex(target_hash, &pos);
+ zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos)
+== SUCCESS;
+ zend_hash_move_forward_ex(target_hash, &pos)) {
+
+ convert_to_string_ex(element);
+ el_len = Z_STRLEN_PP(element);
+ if (el_len == 0) continue;
+ sizeenv += el_len+1;
+ switch (zend_hash_get_current_key_ex(target_hash, &string_key,
+&string_length, &num_key, 0, &pos)) {
+ case HASH_KEY_IS_STRING:
+ if (string_length == 0) continue;
+ sizeenv += string_length+1;
+ }
+ }
+
+#ifndef PHP_WIN32
+ ep = myenvp = (char **) calloc(cnt+1,sizeof(char *));
+#endif
+ p = envp = (char *) calloc(sizeenv+4,1);
+
+ for (zend_hash_internal_pointer_reset_ex(target_hash, &pos);
+ zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos)
+== SUCCESS;
+ zend_hash_move_forward_ex(target_hash, &pos)) {
+
+ convert_to_string_ex(element);
+ el_len = Z_STRLEN_PP(element);
+ if (el_len == 0) continue;
+ data = Z_STRVAL_PP(element);
+ switch (zend_hash_get_current_key_ex(target_hash, &string_key,
+&string_length, &num_key, 0, &pos)) {
+ case HASH_KEY_IS_STRING:
+ if (string_length == 0) continue;
+ l = string_length + el_len + 1;
+ memcpy(p, string_key, string_length);
+ strcat(p, "=");
+ strcat(p, data);
+ if (PG(magic_quotes_gpc)) {
+ php_stripslashes(p,&l TSRMLS_CC);
+ }
+#ifndef PHP_WIN32
+ *ep = p;
+ ++ep;
+#endif
+ p += l;
+ break;
+ case HASH_KEY_IS_LONG:
+ memcpy(p,data,el_len);
+ if (PG(magic_quotes_gpc)) {
+ php_stripslashes(p,&el_len TSRMLS_CC);
+ }
+#ifndef PHP_WIN32
+ *ep = p;
+ ++ep;
+#endif
+ p += el_len + 1;
+ break;
+ case HASH_KEY_NON_EXISTANT:
+ break;
+ }
+ }
+
+ assert(p-envp <= sizeenv);
+ zend_hash_internal_pointer_reset_ex(target_hash, &pos);
+#ifdef PHP_WIN32
+ return envp;
+#else
+ return (char *)myenvp;
+#endif
+}
+/* }}} */
+
+/* {{{ _php_free_envp */
+static void _php_free_envp(char *envp)
+{
+ if (envp) {
+#ifndef PHP_WIN32
+ free(*envp);
+#endif
+ free(envp);
+ }
+}
+/* }}} */
+
+
static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
struct php_process_handle *proc = (struct php_process_handle*)rsrc->ptr;
@@ -98,7 +203,7 @@
#else
FG(pclose_ret) = -1;
#endif
-
+ _php_free_envp(proc->envp);
pefree(proc->command, proc->is_persistent);
pefree(proc, proc->is_persistent);
@@ -166,8 +271,6 @@
}
/* }}} */
-
-
PHP_MINIT_FUNCTION(proc_open)
{
le_proc_open = zend_register_list_destructors_ex(proc_open_rsrc_dtor, NULL,
"process", module_number);
@@ -294,15 +397,17 @@
};
/* }}} */
-/* {{{ proto resource proc_open(string command, array descriptorspec, array &pipes)
+/* {{{ proto resource proc_open(string command, array descriptorspec, array &pipes [,
+string cwd [, array env]])
Run a process with more control over it's file descriptors */
PHP_FUNCTION(proc_open)
{
- char *command;
- long command_len;
+ char *command, *cwd=NULL;
+ long command_len, cwd_len;
zval *descriptorspec;
zval *pipes;
+ zval *environment = NULL;
+ char *envp = NULL;
int ndesc = 0;
int i;
zval **descitem = NULL;
@@ -319,8 +424,8 @@
struct php_process_handle *proc;
int is_persistent = 0; /* TODO: ensure that persistent procs will work */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "saz/", &command,
- &command_len, &descriptorspec, &pipes) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "saz/|sa", &command,
+ &command_len, &descriptorspec, &pipes, &cwd, &cwd_len,
+&environment) == FAILURE) {
RETURN_FALSE;
}
@@ -330,6 +435,11 @@
command_len = strlen(command);
+ if (environment) {
+ envp = _php_array_to_envp(environment, is_persistent TSRMLS_CC);
+ }
+ if (cwd_len == 0) cwd = NULL;
+
memset(descriptors, 0, sizeof(descriptors));
#ifdef PHP_WIN32
@@ -511,7 +621,7 @@
command_with_cmd = emalloc(command_len + sizeof(COMSPEC_9X) + 1 + sizeof(" /c
"));
sprintf(command_with_cmd, "%s /c %s", GetVersion() < 0x80000000 ? COMSPEC_NT :
COMSPEC_9X, command);
- newprocok = CreateProcess(NULL, command_with_cmd, &security, &security, TRUE,
NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
+ newprocok = CreateProcess(NULL, command_with_cmd, &security, &security, TRUE,
+NORMAL_PRIORITY_CLASS, envp, cwd, &si, &pi);
efree(command_with_cmd);
if (FALSE == newprocok) {
@@ -544,8 +654,14 @@
if (descriptors[i].childend != descriptors[i].index)
close(descriptors[i].childend);
}
-
- execl("/bin/sh", "sh", "-c", command, NULL);
+ if (cwd) {
+ chdir(cwd);
+ }
+ if (envp) {
+ execle("/bin/sh", "sh", "-c", command, NULL, (char **)envp);
+ } else {
+ execl("/bin/sh", "sh", "-c", command, NULL);
+ }
_exit(127);
} else if (child < 0) {
@@ -572,6 +688,7 @@
proc->command = command;
proc->npipes = ndesc;
proc->child = child;
+ proc->envp = envp;
array_init(pipes);
@@ -630,6 +747,7 @@
return;
exit_fail:
+ _php_free_envp(envp);
pefree(command, is_persistent);
RETURN_FALSE;
Index: ext/standard/proc_open.h
===================================================================
RCS file: /repository/php4/ext/standard/proc_open.h,v
retrieving revision 1.1
diff -u -d -u -r1.1 proc_open.h
--- ext/standard/proc_open.h 15 Jan 2003 18:54:03 -0000 1.1
+++ ext/standard/proc_open.h 10 Feb 2003 07:31:43 -0000
@@ -33,5 +33,6 @@
long pipes[PHP_PROC_OPEN_MAX_DESCRIPTORS];
char *command;
int is_persistent;
+ char *envp;
};
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php
