summaryrefslogtreecommitdiff
path: root/sapi/cli/php_cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/cli/php_cli.c')
-rw-r--r--sapi/cli/php_cli.c78
1 files changed, 57 insertions, 21 deletions
diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c
index 330c91d58b..835582df88 100644
--- a/sapi/cli/php_cli.c
+++ b/sapi/cli/php_cli.c
@@ -172,6 +172,9 @@ const opt_struct OPTIONS[] = {
{14, 1, "ri"},
{14, 1, "rextinfo"},
{15, 0, "ini"},
+ /* Internal testing option -- may be changed or removed without notice,
+ * including in patch releases. */
+ {16, 1, "repeat"},
{'-', 0, NULL} /* end of args */
};
@@ -529,7 +532,7 @@ static void php_cli_usage(char *argv0)
static php_stream *s_in_process = NULL;
-static void cli_register_file_handles(void) /* {{{ */
+static void cli_register_file_handles(bool no_close) /* {{{ */
{
php_stream *s_in, *s_out, *s_err;
php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
@@ -546,11 +549,11 @@ static void cli_register_file_handles(void) /* {{{ */
return;
}
-#if PHP_DEBUG
- /* do not close stdout and stderr */
- s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
- s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
-#endif
+ if (no_close) {
+ s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
+ s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
+ s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
+ }
s_in_process = s_in;
@@ -584,6 +587,7 @@ static int cli_seek_file_begin(zend_file_handle *file_handle, char *script_file)
}
zend_stream_init_fp(file_handle, fp, script_file);
+ file_handle->primary_script = 1;
return SUCCESS;
}
/* }}} */
@@ -614,6 +618,10 @@ static int do_cli(int argc, char **argv) /* {{{ */
int interactive=0;
const char *param_error=NULL;
int hide_argv = 0;
+ int num_repeats = 1;
+ pid_t pid = getpid();
+
+ file_handle.filename = NULL;
zend_try {
@@ -640,12 +648,12 @@ static int do_cli(int argc, char **argv) /* {{{ */
#else
"NTS "
#endif
-#ifdef COMPILER
- COMPILER
+#ifdef PHP_BUILD_COMPILER
+ PHP_BUILD_COMPILER
" "
#endif
-#ifdef ARCHITECTURE
- ARCHITECTURE
+#ifdef PHP_BUILD_ARCH
+ PHP_BUILD_ARCH
" "
#endif
#if ZEND_DEBUG
@@ -839,6 +847,9 @@ static int do_cli(int argc, char **argv) /* {{{ */
case 15:
behavior = PHP_MODE_SHOW_INI_CONFIG;
break;
+ case 16:
+ num_repeats = atoi(php_optarg);
+ break;
default:
break;
}
@@ -873,6 +884,12 @@ static int do_cli(int argc, char **argv) /* {{{ */
fflush(stdout);
}
+ if (num_repeats > 1) {
+ fprintf(stdout, "Executing for the first time...\n");
+ fflush(stdout);
+ }
+
+do_repeat:
/* only set script_file if not set already and not in direct mode and not at end of parameter list */
if (argc > php_optind
&& !script_file
@@ -884,6 +901,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
php_optind++;
}
if (script_file) {
+ virtual_cwd_activate();
if (cli_seek_file_begin(&file_handle, script_file) != SUCCESS) {
goto err;
} else {
@@ -892,28 +910,32 @@ static int do_cli(int argc, char **argv) /* {{{ */
translated_path = strdup(real_path);
}
script_filename = script_file;
+ php_self = script_file;
}
} else {
/* We could handle PHP_MODE_PROCESS_STDIN in a different manner */
/* here but this would make things only more complicated. And it */
/* is consistent with the way -R works where the stdin file handle*/
/* is also accessible. */
- zend_stream_init_fp(&file_handle, stdin, "Standard input code");
+ php_self = "Standard input code";
+ if (behavior < PHP_MODE_CLI_DIRECT
+ && (!interactive || PHP_MODE_STANDARD != PHP_MODE_STANDARD)) {
+ zend_stream_init_fp(&file_handle, stdin, php_self);
+ file_handle.primary_script = 1;
+ }
}
- php_self = (char*)file_handle.filename;
/* before registering argv to module exchange the *new* argv[0] */
/* we can achieve this without allocating more memory */
SG(request_info).argc=argc-php_optind+1;
arg_excp = argv+php_optind-1;
arg_free = argv[php_optind-1];
- SG(request_info).path_translated = translated_path? translated_path: (char*)file_handle.filename;
- argv[php_optind-1] = (char*)file_handle.filename;
+ SG(request_info).path_translated = translated_path ? translated_path : php_self;
+ argv[php_optind-1] = php_self;
SG(request_info).argv=argv+php_optind-1;
if (php_request_startup()==FAILURE) {
*arg_excp = arg_free;
- fclose(file_handle.handle.fp);
PUTS("Could not startup.\n");
goto err;
}
@@ -939,8 +961,8 @@ static int do_cli(int argc, char **argv) /* {{{ */
PG(during_request_startup) = 0;
switch (behavior) {
case PHP_MODE_STANDARD:
- if (strcmp(file_handle.filename, "Standard input code")) {
- cli_register_file_handles();
+ if (script_file) {
+ cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
}
if (interactive && cli_shell_callbacks.cli_shell_run) {
@@ -952,9 +974,9 @@ static int do_cli(int argc, char **argv) /* {{{ */
case PHP_MODE_LINT:
EG(exit_status) = php_lint_script(&file_handle);
if (EG(exit_status) == SUCCESS) {
- zend_printf("No syntax errors detected in %s\n", file_handle.filename);
+ zend_printf("No syntax errors detected in %s\n", php_self);
} else {
- zend_printf("Errors parsing %s\n", file_handle.filename);
+ zend_printf("Errors parsing %s\n", php_self);
}
break;
case PHP_MODE_STRIP:
@@ -975,7 +997,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
}
break;
case PHP_MODE_CLI_DIRECT:
- cli_register_file_handles();
+ cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
break;
@@ -985,7 +1007,12 @@ static int do_cli(int argc, char **argv) /* {{{ */
size_t len, index = 0;
zval argn, argi;
- cli_register_file_handles();
+ if (!exec_run && script_file) {
+ zend_string_release_ex(file_handle.filename, 0);
+ file_handle.filename = NULL;
+ }
+
+ cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
if (exec_begin) {
zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1);
@@ -1106,12 +1133,21 @@ static int do_cli(int argc, char **argv) /* {{{ */
} zend_end_try();
out:
+ if (file_handle.filename) {
+ zend_destroy_file_handle(&file_handle);
+ }
if (request_started) {
php_request_shutdown((void *) 0);
}
if (translated_path) {
free(translated_path);
}
+ /* Don't repeat fork()ed processes. */
+ if (--num_repeats && pid == getpid()) {
+ fprintf(stdout, "Finished execution, repeating...\n");
+ fflush(stdout);
+ goto do_repeat;
+ }
return EG(exit_status);
err:
sapi_deactivate();