summaryrefslogtreecommitdiff
path: root/ext/pcntl
diff options
context:
space:
mode:
authorJason Greene <jason@php.net>2001-09-30 06:59:12 +0000
committerJason Greene <jason@php.net>2001-09-30 06:59:12 +0000
commit8a705b8cd91a6fc5df86540da9b574a6428d1a47 (patch)
tree99295d8b5ce64ebe3b6a335a13a1a0198d2199cd /ext/pcntl
parent94d789e5d7016ba84da9897eec7388c9ea6f0df8 (diff)
downloadphp-git-8a705b8cd91a6fc5df86540da9b574a6428d1a47.tar.gz
@Added new function pcntl_exec, which behaves similar to execve.
Diffstat (limited to 'ext/pcntl')
-rwxr-xr-xext/pcntl/pcntl.c87
-rw-r--r--ext/pcntl/php_pcntl.h1
2 files changed, 88 insertions, 0 deletions
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index f2ae7f4ca2..8f7998c478 100755
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -50,6 +50,7 @@ function_entry pcntl_functions[] = {
PHP_FE(pcntl_wexitstatus, NULL)
PHP_FE(pcntl_wtermsig, NULL)
PHP_FE(pcntl_wstopsig, NULL)
+ PHP_FE(pcntl_exec, NULL)
{NULL, NULL, NULL}
};
@@ -363,6 +364,92 @@ PHP_FUNCTION(pcntl_wstopsig)
}
/* }}} */
+/* {{{ proto bool pcntl_exec(string path, [array args], [array envs])
+ Executes specified program in current process space as defined by exec(2) */
+PHP_FUNCTION(pcntl_exec)
+{
+ zval *args, *envs;
+ zval **element;
+ HashTable *args_hash, *envs_hash;
+ int argc=0, argi=0;
+ int envc=0, envi=0;
+ int return_val=0;
+ char **argv=NULL, **envp=NULL;
+ char **current_arg, **pair;
+ int pair_length;
+ char *key;
+ int key_length;
+ char *path;
+ int path_len;
+ long key_num;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|aa", &path, &path_len, &args, &envs) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 1) {
+ /* Build argumnent list */
+ args_hash=HASH_OF(args);
+ argc=zend_hash_num_elements(args_hash);
+
+ argv=alloca((argc+2) * sizeof(char *));
+ *argv=path;
+ for ( zend_hash_internal_pointer_reset(args_hash), current_arg=argv+1;
+ (argi < argc && (zend_hash_get_current_data(args_hash, (void **) &element) == SUCCESS));
+ (argi++, current_arg++, zend_hash_move_forward(args_hash)) ) {
+ *current_arg=Z_STRVAL_PP(element);
+ }
+ *(current_arg)=NULL;
+ /* while(*argv != NULL) printf("Arg: %s\n",*argv++); */
+ } else {
+ argv=alloca(2 * sizeof(char *));
+ *argv=path;
+ *(argv+1)=NULL;
+ }
+
+ if ( ZEND_NUM_ARGS() == 3 ) {
+ /* Build environment pair list */
+ envs_hash=HASH_OF(envs);
+ envc=zend_hash_num_elements(envs_hash);
+
+ envp=alloca((envc+1) * sizeof(char *));
+ for ( zend_hash_internal_pointer_reset(envs_hash), pair=envp;
+ (envi < envc && (zend_hash_get_current_data(envs_hash, (void **) &element) == SUCCESS));
+ (envi++, pair++, zend_hash_move_forward(envs_hash)) ) {
+ switch (return_val=zend_hash_get_current_key_ex(envs_hash, &key, &key_length, &key_num, 0, NULL)) {
+ case HASH_KEY_IS_LONG:
+ key=alloca(101);
+ snprintf(key, 100, "%ld", key_num);
+ key_length=strlen(key);
+ break;
+ case HASH_KEY_NON_EXISTANT:
+ pair--;
+ continue;
+ }
+ /* Length of element + equal sign + length of key + null */
+ pair_length=Z_STRLEN_PP(element) + key_length + 2;
+ *pair=emalloc(pair_length);
+ strlcpy(*pair, key, key_length);
+ strlcat(*pair, "=", pair_length);
+ strlcat(*pair, Z_STRVAL_PP(element), pair_length);
+
+ /* Cleanup */
+ if (return_val == HASH_KEY_IS_LONG) free_alloca(101);
+ }
+ *(pair)=NULL;
+ /* while(*envp != NULL) printf("Env: %s\n",*envp++); */
+ }
+
+ if (execve(path, argv, envp) == -1) {
+ php_error(E_ERROR, "Error has occured in %s: (errno %d) %s", get_active_function_name(TSRMLS_CC),
+ errno, strerror(errno));
+
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
/* {{{ proto bool pcntl_signal(long signo, mixed handle)
Assigns a system signal handler to a php function */
PHP_FUNCTION(pcntl_signal)
diff --git a/ext/pcntl/php_pcntl.h b/ext/pcntl/php_pcntl.h
index d80aadd138..3fff8f976a 100644
--- a/ext/pcntl/php_pcntl.h
+++ b/ext/pcntl/php_pcntl.h
@@ -48,6 +48,7 @@ PHP_FUNCTION(pcntl_wexitstatus);
PHP_FUNCTION(pcntl_wtermsig);
PHP_FUNCTION(pcntl_wstopsig);
PHP_FUNCTION(pcntl_signal);
+PHP_FUNCTION(pcntl_exec);
static void pcntl_signal_handler(int);