From 5aae01104f88f98f42fd997d360757651f7cc919 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 12 Oct 2016 20:11:51 +0200 Subject: Add stdin command and -s command line parameter to phpdbg This allows reading the initial script file from stdin instead of being forced to put the script into a file in order to run it with phpdbg. Especially important for programmatic execution of phpdbg. Also adding tests/include_once.phpt and tests/set_exception_handler.phpt as I seem to have forgotten to git add them sometime long ago... --- sapi/phpdbg/phpdbg.c | 79 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 12 deletions(-) (limited to 'sapi/phpdbg/phpdbg.c') diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 8b1dde5768..45eb068e32 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -341,7 +341,7 @@ static PHP_FUNCTION(phpdbg_break_file) return; } - phpdbg_set_breakpoint_file(file, line); + phpdbg_set_breakpoint_file(file, 0, line); } /* }}} */ /* {{{ proto void phpdbg_break_method(string class, string method) */ @@ -1042,6 +1042,7 @@ const opt_struct OPTIONS[] = { /* {{{ */ {'r', 0, "run"}, {'e', 0, "generate ext_stmt opcodes"}, {'E', 0, "step-through-eval"}, + {'s', 1, "script from stdin"}, {'S', 1, "sapi-name"}, #ifndef _WIN32 {'l', 1, "listen"}, @@ -1345,6 +1346,8 @@ int main(int argc, char **argv) /* {{{ */ zend_bool use_mm_wrappers = 0; zend_bool is_exit; int exit_status; + char *read_from_stdin = NULL; + zend_string *backup_phpdbg_compile = NULL; #ifndef _WIN32 struct sigaction sigio_struct; @@ -1455,6 +1458,12 @@ phpdbg_main: /* begin phpdbg options */ + case 's': { /* read script from stdin */ + if (settings == NULL) { + read_from_stdin = strdup(php_optarg); + } + } break; + case 'S': { /* set SAPI name */ if (sapi_name) { free(sapi_name); @@ -1567,8 +1576,10 @@ phpdbg_main: php_optarg = NULL; } + quit_immediately = phpdbg_startup_run > 1; + /* set exec if present on command line */ - if (argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) { + if (!read_from_stdin && argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) { if (!exec && strlen(argv[php_optind])) { exec = strdup(argv[php_optind]); } @@ -1832,13 +1843,6 @@ phpdbg_main: if (init_file) { phpdbg_init(init_file, init_file_len, init_file_default); } - if (bp_tmp) { - PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; - phpdbg_string_init(bp_tmp); - free(bp_tmp); - bp_tmp = NULL; - PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; - } } zend_end_try(); PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING; @@ -1848,18 +1852,55 @@ phpdbg_main: } /* auto compile */ - if (PHPDBG_G(exec)) { + if (read_from_stdin) { + if (!read_from_stdin[0]) { + if (!quit_immediately) { + phpdbg_error("error", "", "Impossible to not specify a stdin delimiter without -rr"); + PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; + goto phpdbg_out; + } + } + if (show_banner || read_from_stdin[0]) { + phpdbg_notice("stdin", "delimiter=\"%s\"", "Reading input from stdin; put '%s' followed by a newline on an own line after code to end input", read_from_stdin); + } + + if (phpdbg_startup_run > 0) { + PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; + } + + zend_try { + phpdbg_param_t cmd; + cmd.str = read_from_stdin; + cmd.len = strlen(read_from_stdin); + PHPDBG_COMMAND_HANDLER(stdin)(&cmd); + } zend_end_try(); + + PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; + } else if (PHPDBG_G(exec)) { if (settings || phpdbg_startup_run > 0) { PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; } zend_try { - phpdbg_compile(); + if (backup_phpdbg_compile) { + phpdbg_compile_stdin(backup_phpdbg_compile); + } else { + phpdbg_compile(); + } } zend_end_try(); + backup_phpdbg_compile = NULL; PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; } + if (bp_tmp) { + PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT | PHPDBG_IS_INITIALIZING; + phpdbg_string_init(bp_tmp); + free(bp_tmp); + bp_tmp = NULL; + PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT & ~PHPDBG_IS_INITIALIZING; + } + if (settings == (void *) 0x1) { if (PHPDBG_G(ops)) { phpdbg_print_opcodes(print_opline_func); @@ -1881,7 +1922,6 @@ phpdbg_interact: do { zend_try { if (phpdbg_startup_run) { - quit_immediately = phpdbg_startup_run > 1; phpdbg_startup_run = 0; if (quit_immediately) { PHPDBG_G(flags) = (PHPDBG_G(flags) & ~PHPDBG_HAS_PAGINATION) | PHPDBG_IS_INTERACTIVE | PHPDBG_PREVENT_INTERACTIVE; @@ -2059,6 +2099,12 @@ phpdbg_out: wrapper->wops->stream_opener = PHPDBG_G(orig_url_wrap_php); } + if (PHPDBG_G(exec) && !memcmp("-", PHPDBG_G(exec), 2)) { /* i.e. execution context has been read from stdin - back it up */ + phpdbg_file_source *data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), PHPDBG_G(exec), PHPDBG_G(exec_len)); + backup_phpdbg_compile = zend_string_alloc(data->len + 2, 1); + sprintf(ZSTR_VAL(backup_phpdbg_compile), "?>%.*s", (int) data->len, data->buf); + } + zend_try { php_module_shutdown(); } zend_end_try(); @@ -2071,6 +2117,11 @@ phpdbg_out: sapi_shutdown(); } + if (read_from_stdin) { + free(read_from_stdin); + read_from_stdin = NULL; + } + if ((cleaning > 0 || remote) && !quit_immediately) { /* reset internal php_getopt state */ php_getopt(-1, argv, OPTIONS, NULL, &php_optind, 0, 0); @@ -2083,6 +2134,10 @@ phpdbg_out: /* tsrm_shutdown(); */ #endif + if (backup_phpdbg_compile) { + zend_string_free(backup_phpdbg_compile); + } + #ifndef _WIN32 if (address) { free(address); -- cgit v1.2.1