Add question to reset execution in run/exec/clean

This commit is contained in:
Bob Weinand 2014-10-26 03:50:28 +01:00
parent 25e3560546
commit cc70ec1e67
7 changed files with 173 additions and 141 deletions

View file

@ -45,6 +45,8 @@
#endif /* }}} */ #endif /* }}} */
ZEND_DECLARE_MODULE_GLOBALS(phpdbg); ZEND_DECLARE_MODULE_GLOBALS(phpdbg);
int phpdbg_startup_run = 0;
char *phpdbg_exec = NULL;
static PHP_INI_MH(OnUpdateEol) static PHP_INI_MH(OnUpdateEol)
{ {
@ -487,7 +489,7 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */
case PHPDBG_NEXT: case PHPDBG_NEXT:
return; return;
} }
} while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING));
} }
} else fprintf(stdout, "%s\n", message); } else fprintf(stdout, "%s\n", message);
@ -752,7 +754,7 @@ static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */
phpdbg_writeln("intro", "help=\"help\"", "To get help using phpdbg type \"help\" and press enter"); phpdbg_writeln("intro", "help=\"help\"", "To get help using phpdbg type \"help\" and press enter");
phpdbg_notice("intro", "report=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES); phpdbg_notice("intro", "report=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES);
phpdbg_xml("</intros>"); phpdbg_xml("</intros>");
} else { } else if (phpdbg_startup_run == 0) {
if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) {
phpdbg_notice(NULL, NULL, "Clean Execution Environment"); phpdbg_notice(NULL, NULL, "Clean Execution Environment");
} }
@ -776,7 +778,7 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */
if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) { if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) {
/* we quit remote consoles on recv SIGINT */ /* we quit remote consoles on recv SIGINT */
if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; PHPDBG_G(flags) |= PHPDBG_IS_STOPPING;
zend_bailout(); zend_bailout();
} }
} else { } else {
@ -961,8 +963,6 @@ int main(int argc, char **argv) /* {{{ */
zend_ulong zend_extensions_len = 0L; zend_ulong zend_extensions_len = 0L;
zend_bool ini_ignore; zend_bool ini_ignore;
char *ini_override; char *ini_override;
char *exec;
size_t exec_len;
char *init_file; char *init_file;
size_t init_file_len; size_t init_file_len;
zend_bool init_file_default; zend_bool init_file_default;
@ -973,7 +973,6 @@ int main(int argc, char **argv) /* {{{ */
int php_optind, opt, show_banner = 1; int php_optind, opt, show_banner = 1;
long cleaning = 0; long cleaning = 0;
zend_bool remote = 0; zend_bool remote = 0;
int run = 0;
int step = 0; int step = 0;
#ifdef _WIN32 #ifdef _WIN32
@ -1046,8 +1045,6 @@ phpdbg_main:
ini_override = NULL; ini_override = NULL;
zend_extensions = NULL; zend_extensions = NULL;
zend_extensions_len = 0L; zend_extensions_len = 0L;
exec = NULL;
exec_len = 0;
init_file = NULL; init_file = NULL;
init_file_len = 0; init_file_len = 0;
init_file_default = 1; init_file_default = 1;
@ -1057,14 +1054,13 @@ phpdbg_main:
php_optarg = NULL; php_optarg = NULL;
php_optind = 1; php_optind = 1;
opt = 0; opt = 0;
run = 0;
step = 0; step = 0;
sapi_name = NULL; sapi_name = NULL;
while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
switch (opt) { switch (opt) {
case 'r': case 'r':
run++; phpdbg_startup_run++;
break; break;
case 'n': case 'n':
ini_ignore = 1; ini_ignore = 1;
@ -1201,14 +1197,12 @@ phpdbg_main:
} }
/* set exec if present on command line */ /* set exec if present on command line */
if ((argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS)) if (!phpdbg_exec && (argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS)) {
{ if (strlen(argv[php_optind])) {
exec_len = strlen(argv[php_optind]); if (phpdbg_exec) {
if (exec_len) { free(phpdbg_exec);
if (exec) {
free(exec);
} }
exec = strdup(argv[php_optind]); phpdbg_exec = strdup(argv[php_optind]);
} }
php_optind++; php_optind++;
} }
@ -1331,7 +1325,7 @@ phpdbg_main:
for (i = SG(request_info).argc; --i;) { for (i = SG(request_info).argc; --i;) {
SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]);
} }
SG(request_info).argv[i] = exec ? estrndup(exec, exec_len) : estrdup(""); SG(request_info).argv[i] = phpdbg_exec ? estrdup(phpdbg_exec) : estrdup("");
php_hash_environment(TSRMLS_C); php_hash_environment(TSRMLS_C);
} }
@ -1394,11 +1388,12 @@ phpdbg_main:
php_stream_stdio_ops.write = phpdbg_stdiop_write; php_stream_stdio_ops.write = phpdbg_stdiop_write;
#endif #endif
if (exec) { /* set execution context */ if (phpdbg_exec) { /* set execution context */
PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC); PHPDBG_G(exec) = phpdbg_resolve_path(phpdbg_exec TSRMLS_CC);
PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec));
free(exec); free(phpdbg_exec);
phpdbg_exec = NULL;
} }
if (oplog_file) { /* open oplog */ if (oplog_file) { /* open oplog */
@ -1448,13 +1443,14 @@ phpdbg_main:
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
} }
if (run) { if (phpdbg_startup_run) {
/* no need to try{}, run does it ... */ /* no need to try{}, run does it ... */
PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC); PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC);
if (run > 1) { if (phpdbg_startup_run > 1) {
/* if -r is on the command line more than once just quit */ /* if -r is on the command line more than once just quit */
goto phpdbg_out; goto phpdbg_out;
} }
phpdbg_startup_run = 0;
} }
phpdbg_interact: phpdbg_interact:
@ -1494,7 +1490,7 @@ phpdbg_interact:
} }
} }
} zend_end_try(); } zend_end_try();
} while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING));
/* this must be forced */ /* this must be forced */
CG(unclean_shutdown) = 0; CG(unclean_shutdown) = 0;

View file

@ -190,6 +190,7 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
#define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL | PHPDBG_IN_FINISH | PHPDBG_IN_LEAVE) #define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL | PHPDBG_IN_FINISH | PHPDBG_IN_LEAVE)
#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP) #define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP)
#define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP | PHPDBG_HAS_SYM_BP | PHPDBG_HAS_METHOD_BP | PHPDBG_HAS_OPLINE_BP | PHPDBG_HAS_COND_BP | PHPDBG_HAS_OPCODE_BP | PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP) #define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP | PHPDBG_HAS_SYM_BP | PHPDBG_HAS_METHOD_BP | PHPDBG_HAS_OPLINE_BP | PHPDBG_HAS_COND_BP | PHPDBG_HAS_OPCODE_BP | PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP)
#define PHPDBG_IS_STOPPING (PHPDBG_IS_QUITTING | PHPDBG_IS_CLEANING)
#ifndef _WIN32 #ifndef _WIN32
# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED|PHPDBG_IS_BP_ENABLED) # define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED|PHPDBG_IS_BP_ENABLED)

View file

@ -796,80 +796,30 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, zend_bool allow_async
PHPDBG_API char *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ PHPDBG_API char *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */
{ {
char buf[PHPDBG_MAX_CMD];
char *cmd = NULL; char *cmd = NULL;
char *buffer = NULL; char *buffer = NULL;
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && (buffered == NULL) && !phpdbg_active_sigsafe_mem(TSRMLS_C)) { if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && (buffered == NULL) && !phpdbg_active_sigsafe_mem(TSRMLS_C)) {
fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr); fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr);
} }
if (buffered == NULL) { if (buffered == NULL) {
if (0) {
disconnect:
PHPDBG_G(flags) |= (PHPDBG_IS_QUITTING|PHPDBG_IS_DISCONNECTED);
zend_bailout();
return NULL;
}
#define USE_LIB_STAR (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)) #define USE_LIB_STAR (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT))
/* note: EOF makes readline write prompt again in local console mode - and ignored if compiled without readline */ /* note: EOF makes readline write prompt again in local console mode - and ignored if compiled without readline */
/* strongly assuming to be in blocking mode... */
#if USE_LIB_STAR #if USE_LIB_STAR
readline: readline:
if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE)
#endif #endif
{ {
char buf[PHPDBG_MAX_CMD];
int bytes = PHPDBG_G(input_buflen), len = 0;
if (PHPDBG_G(input_buflen)) {
memcpy(buf, PHPDBG_G(input_buffer), bytes);
}
phpdbg_write("prompt", "", "%s", phpdbg_get_prompt(TSRMLS_C)); phpdbg_write("prompt", "", "%s", phpdbg_get_prompt(TSRMLS_C));
PHPDBG_G(last_was_newline) = 1; phpdbg_consume_stdin_line(cmd = buf TSRMLS_CC);
do {
int i;
if (bytes <= 0) {
continue;
}
for (i = len; i < len + bytes; i++) {
if (buf[i] == '\x03') {
if (i != len + bytes - 1) {
memmove(buf + i, buf + i + 1, len + bytes - i - 1);
}
len--;
i--;
continue;
}
if (buf[i] == '\n') {
PHPDBG_G(input_buflen) = len + bytes - 1 - i;
if (PHPDBG_G(input_buflen)) {
memcpy(PHPDBG_G(input_buffer), buf + i + 1, PHPDBG_G(input_buflen));
}
if (i != PHPDBG_MAX_CMD - 1) {
buf[i + 1] = 0;
}
cmd = buf;
goto end;
}
}
len += bytes;
/* XXX export the timeout through INI??*/
} while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0);
if (bytes <= 0) {
goto disconnect;
}
cmd = buf;
} }
#if USE_LIB_STAR #if USE_LIB_STAR
else { else {
cmd = readline(phpdbg_get_prompt(TSRMLS_C)); cmd = readline(phpdbg_get_prompt(TSRMLS_C));
PHPDBG_G(last_was_newline) = 1;
} }
if (!cmd) { if (!cmd) {
@ -883,8 +833,7 @@ readline:
} else { } else {
cmd = buffered; cmd = buffered;
} }
end:
PHPDBG_G(last_was_newline) = 1;
buffer = estrdup(cmd); buffer = estrdup(cmd);
#if USE_LIB_STAR #if USE_LIB_STAR
@ -922,3 +871,24 @@ PHPDBG_API void phpdbg_destroy_input(char **input TSRMLS_DC) /*{{{ */
{ {
efree(*input); efree(*input);
} /* }}} */ } /* }}} */
PHPDBG_API int phpdbg_ask_user_permission(const char *question TSRMLS_DC) {
if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) {
char buf[PHPDBG_MAX_CMD];
phpdbg_out("%s", question);
phpdbg_out(" (type y or n): ");
while (1) {
phpdbg_consume_stdin_line(buf TSRMLS_CC);
if (buf[1] == '\n' && (buf[0] == 'y' || buf[0] == 'n')) {
if (buf[0] == 'y') {
return SUCCESS;
}
return FAILURE;
}
phpdbg_out("Please enter either y (yes) or n (no): ");
}
}
return SUCCESS;
}

View file

@ -131,6 +131,7 @@ typedef struct {
*/ */
PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC); PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC);
PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC);
PHPDBG_API int phpdbg_ask_user_permission(const char *question TSRMLS_DC);
/** /**
* Stack Management * Stack Management

View file

@ -47,6 +47,55 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg); ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
/* is easy to generalize ... but not needed for now */
PHPDBG_API int phpdbg_consume_stdin_line(char *buf TSRMLS_DC) {
int bytes = PHPDBG_G(input_buflen), len = 0;
if (PHPDBG_G(input_buflen)) {
memcpy(buf, PHPDBG_G(input_buffer), bytes);
}
PHPDBG_G(last_was_newline) = 1;
do {
int i;
if (bytes <= 0) {
continue;
}
for (i = len; i < len + bytes; i++) {
if (buf[i] == '\x03') {
if (i != len + bytes - 1) {
memmove(buf + i, buf + i + 1, len + bytes - i - 1);
}
len--;
i--;
continue;
}
if (buf[i] == '\n') {
PHPDBG_G(input_buflen) = len + bytes - 1 - i;
if (PHPDBG_G(input_buflen)) {
memcpy(PHPDBG_G(input_buffer), buf + i + 1, PHPDBG_G(input_buflen));
}
if (i != PHPDBG_MAX_CMD - 1) {
buf[i + 1] = 0;
}
return i;
}
}
len += bytes;
} while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0);
if (bytes <= 0) {
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING | PHPDBG_IS_DISCONNECTED;
zend_bailout();
return 0;
}
return bytes;
}
PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC) { PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC) {
int got_now, i = len, j; int got_now, i = len, j;
char *p = ptr; char *p = ptr;

View file

@ -21,6 +21,8 @@
#include "phpdbg.h" #include "phpdbg.h"
PHPDBG_API int phpdbg_consume_stdin_line(char *buf TSRMLS_DC);
PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC); PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC);
PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len); PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len);
PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC); PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC);

View file

@ -43,6 +43,8 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg); ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
ZEND_EXTERN_MODULE_GLOBALS(output); ZEND_EXTERN_MODULE_GLOBALS(output);
extern int phpdbg_startup_run;
extern char *phpdbg_exec;
#ifdef HAVE_LIBDL #ifdef HAVE_LIBDL
#ifdef PHP_WIN32 #ifdef PHP_WIN32
@ -355,6 +357,11 @@ PHPDBG_COMMAND(exec) /* {{{ */
size_t res_len = strlen(res); size_t res_len = strlen(res);
if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) {
if (EG(in_execution)) {
if (phpdbg_ask_user_permission("Do you really want to stop execution to set a new execution context?" TSRMLS_CC) == FAILURE) {
return FAILURE;
}
}
if (PHPDBG_G(exec)) { if (PHPDBG_G(exec)) {
phpdbg_notice("exec", "type=\"unset\" context=\"%s\"", "Unsetting old execution context: %s", PHPDBG_G(exec)); phpdbg_notice("exec", "type=\"unset\" context=\"%s\"", "Unsetting old execution context: %s", PHPDBG_G(exec));
@ -378,9 +385,11 @@ PHPDBG_COMMAND(exec) /* {{{ */
phpdbg_notice("exec", "type=\"set\" context=\"%s\"", "Set execution context: %s", PHPDBG_G(exec)); phpdbg_notice("exec", "type=\"set\" context=\"%s\"", "Set execution context: %s", PHPDBG_G(exec));
if (phpdbg_compile(TSRMLS_C) == FAILURE) { if (EG(in_execution)) {
phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s", PHPDBG_G(exec)); phpdbg_clean(1 TSRMLS_CC);
} }
phpdbg_compile(TSRMLS_C);
} else { } else {
phpdbg_notice("exec", "type=\"unchanged\"", "Execution context not changed"); phpdbg_notice("exec", "type=\"unchanged\"", "Execution context not changed");
} }
@ -399,20 +408,15 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */
if (!PHPDBG_G(exec)) { if (!PHPDBG_G(exec)) {
phpdbg_error("inactive", "type=\"nocontext\"", "No execution context"); phpdbg_error("inactive", "type=\"nocontext\"", "No execution context");
return SUCCESS;
}
if (EG(in_execution)) {
phpdbg_error("inactive", "type=\"isrunning\"", "Cannot compile while in execution");
return FAILURE; return FAILURE;
} }
if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) { if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) {
PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE TSRMLS_CC); PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE TSRMLS_CC);
zend_destroy_file_handle(&fh TSRMLS_CC); zend_destroy_file_handle(&fh TSRMLS_CC);
phpdbg_notice("compile", "context=\"%s\"", "Successful compilation of %s", PHPDBG_G(exec)); phpdbg_notice("compile", "context=\"%s\"", "Successful compilation of %s", PHPDBG_G(exec));
return SUCCESS; return SUCCESS;
} else { } else {
phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec)); phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec));
@ -570,11 +574,6 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */
PHPDBG_COMMAND(run) /* {{{ */ PHPDBG_COMMAND(run) /* {{{ */
{ {
if (EG(in_execution)) {
phpdbg_error("inactive", "type=\"isrunning\"", "Cannot start another execution while one is in progress");
return SUCCESS;
}
if (PHPDBG_G(ops) || PHPDBG_G(exec)) { if (PHPDBG_G(ops) || PHPDBG_G(exec)) {
zend_op **orig_opline = EG(opline_ptr); zend_op **orig_opline = EG(opline_ptr);
zend_op_array *orig_op_array = EG(active_op_array); zend_op_array *orig_op_array = EG(active_op_array);
@ -582,6 +581,14 @@ PHPDBG_COMMAND(run) /* {{{ */
zend_bool restore = 1; zend_bool restore = 1;
zend_execute_data *ex = EG(current_execute_data); zend_execute_data *ex = EG(current_execute_data);
if (EG(in_execution)) {
if (phpdbg_ask_user_permission("Do you really want to restart execution?" TSRMLS_CC) == SUCCESS) {
phpdbg_startup_run++;
phpdbg_clean(1 TSRMLS_CC);
}
return SUCCESS;
}
if (!PHPDBG_G(ops)) { if (!PHPDBG_G(ops)) {
if (phpdbg_compile(TSRMLS_C) == FAILURE) { if (phpdbg_compile(TSRMLS_C) == FAILURE) {
phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec)); phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec));
@ -643,7 +650,7 @@ PHPDBG_COMMAND(run) /* {{{ */
EG(opline_ptr) = orig_opline; EG(opline_ptr) = orig_opline;
EG(return_value_ptr_ptr) = orig_retval_ptr; EG(return_value_ptr_ptr) = orig_retval_ptr;
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM"); phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
restore = 0; restore = 0;
} }
@ -1127,7 +1134,7 @@ PHPDBG_COMMAND(register) /* {{{ */
PHPDBG_COMMAND(quit) /* {{{ */ PHPDBG_COMMAND(quit) /* {{{ */
{ {
/* don't allow this to loop, ever ... */ /* don't allow this to loop, ever ... */
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
zend_bailout(); zend_bailout();
} }
@ -1138,9 +1145,10 @@ PHPDBG_COMMAND(quit) /* {{{ */
PHPDBG_COMMAND(clean) /* {{{ */ PHPDBG_COMMAND(clean) /* {{{ */
{ {
if (EG(in_execution)) { if (EG(in_execution)) {
phpdbg_error("inactive", "type=\"isrunning\"", "Cannot clean environment while executing"); if (phpdbg_ask_user_permission("Do you really want to clean your current environment?" TSRMLS_CC) == FAILURE) {
return SUCCESS; return SUCCESS;
} }
}
phpdbg_out("Cleaning Execution Environment\n"); phpdbg_out("Cleaning Execution Environment\n");
phpdbg_xml("<cleaninfo %r>"); phpdbg_xml("<cleaninfo %r>");
@ -1227,10 +1235,16 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */
PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE; PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE;
input = phpdbg_read_input(NULL TSRMLS_CC); while (1) {
if (PHPDBG_G(flags) & PHPDBG_IS_STOPPING) {
zend_bailout();
}
if (!(input = phpdbg_read_input(NULL TSRMLS_CC))) {
break;
}
if (input) {
do {
phpdbg_init_param(&stack, STACK_PARAM); phpdbg_init_param(&stack, STACK_PARAM);
if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
@ -1244,7 +1258,7 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */
#endif #endif
switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) { switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) {
case FAILURE: case FAILURE:
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC); phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC);
} }
@ -1257,10 +1271,10 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */
case PHPDBG_NEXT: { case PHPDBG_NEXT: {
phpdbg_activate_err_buf(0 TSRMLS_CC); phpdbg_activate_err_buf(0 TSRMLS_CC);
phpdbg_free_err_buf(TSRMLS_C); phpdbg_free_err_buf(TSRMLS_C);
if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
phpdbg_error("command", "type=\"noexec\"", "Not running"); phpdbg_error("command", "type=\"noexec\"", "Not running");
} }
goto out; break;
} }
} }
@ -1277,10 +1291,8 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */
phpdbg_stack_free(&stack); phpdbg_stack_free(&stack);
phpdbg_destroy_input(&input TSRMLS_CC); phpdbg_destroy_input(&input TSRMLS_CC);
PHPDBG_G(req_id) = 0; PHPDBG_G(req_id) = 0;
} while ((input = phpdbg_read_input(NULL TSRMLS_CC)));
} }
out:
if (input) { if (input) {
phpdbg_stack_free(&stack); phpdbg_stack_free(&stack);
phpdbg_destroy_input(&input TSRMLS_CC); phpdbg_destroy_input(&input TSRMLS_CC);
@ -1308,6 +1320,7 @@ void phpdbg_clean(zend_bool full TSRMLS_DC) /* {{{ */
} }
if (full) { if (full) {
phpdbg_exec = strdup(PHPDBG_G(exec)); /* preserve exec, don't reparse that from cmd */
PHPDBG_G(flags) |= PHPDBG_IS_CLEANING; PHPDBG_G(flags) |= PHPDBG_IS_CLEANING;
zend_bailout(); zend_bailout();
@ -1593,7 +1606,7 @@ void phpdbg_force_interruption(TSRMLS_D) {
next: next:
PHPDBG_G(flags) &= ~PHPDBG_IN_SIGNAL_HANDLER; PHPDBG_G(flags) &= ~PHPDBG_IN_SIGNAL_HANDLER;
if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { if (PHPDBG_G(flags) & PHPDBG_IS_STOPPING) {
zend_bailout(); zend_bailout();
} }
} }