]> granicus.if.org Git - php/commitdiff
Add question to reset execution in run/exec/clean
authorBob Weinand <bobwei9@hotmail.com>
Sun, 26 Oct 2014 02:50:28 +0000 (03:50 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Sun, 26 Oct 2014 02:50:28 +0000 (03:50 +0100)
phpdbg.c
phpdbg.h
phpdbg_cmd.c
phpdbg_cmd.h
phpdbg_io.c
phpdbg_io.h
phpdbg_prompt.c

index aaf1e5f4060b4dff0be9971b4285c0494f2ea86e..ff03c670d0622bee5a866ea35d4aadd1f131a075 100644 (file)
--- a/phpdbg.c
+++ b/phpdbg.c
@@ -45,6 +45,8 @@
 #endif /* }}} */
 
 ZEND_DECLARE_MODULE_GLOBALS(phpdbg);
+int phpdbg_startup_run = 0;
+char *phpdbg_exec = NULL;
 
 static PHP_INI_MH(OnUpdateEol)
 {
@@ -487,7 +489,7 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */
                                                case PHPDBG_NEXT:
                                                        return;
                                        }
-                               } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING));
+                               } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING));
 
                }
        } 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_notice("intro", "report=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES);
                phpdbg_xml("</intros>");
-       } else {
+       } else if (phpdbg_startup_run == 0) {
                if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) {
                        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) {
                /* we quit remote consoles on recv SIGINT */
                if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
-                       PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
+                       PHPDBG_G(flags) |= PHPDBG_IS_STOPPING;
                        zend_bailout();
                }
        } else {
@@ -961,8 +963,6 @@ int main(int argc, char **argv) /* {{{ */
        zend_ulong zend_extensions_len = 0L;
        zend_bool ini_ignore;
        char *ini_override;
-       char *exec;
-       size_t exec_len;
        char *init_file;
        size_t init_file_len;
        zend_bool init_file_default;
@@ -973,7 +973,6 @@ int main(int argc, char **argv) /* {{{ */
        int php_optind, opt, show_banner = 1;
        long cleaning = 0;
        zend_bool remote = 0;
-       int run = 0;
        int step = 0;
 
 #ifdef _WIN32
@@ -1046,8 +1045,6 @@ phpdbg_main:
        ini_override = NULL;
        zend_extensions = NULL;
        zend_extensions_len = 0L;
-       exec = NULL;
-       exec_len = 0;
        init_file = NULL;
        init_file_len = 0;
        init_file_default = 1;
@@ -1057,14 +1054,13 @@ phpdbg_main:
        php_optarg = NULL;
        php_optind = 1;
        opt = 0;
-       run = 0;
        step = 0;
        sapi_name = NULL;
 
        while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
                switch (opt) {
                        case 'r':
-                               run++;
+                               phpdbg_startup_run++;
                                break;
                        case 'n':
                                ini_ignore = 1;
@@ -1201,14 +1197,12 @@ phpdbg_main:
        }
        
        /* set exec if present on command line */
-       if ((argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS))
-       {
-               exec_len = strlen(argv[php_optind]);
-               if (exec_len) {
-                       if (exec) {
-                               free(exec);
+       if (!phpdbg_exec && (argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS)) {
+               if (strlen(argv[php_optind])) {
+                       if (phpdbg_exec) {
+                               free(phpdbg_exec);
                        }
-                       exec = strdup(argv[php_optind]);
+                       phpdbg_exec = strdup(argv[php_optind]);
                }
                php_optind++;
        }
@@ -1331,7 +1325,7 @@ phpdbg_main:
                        for (i = SG(request_info).argc; --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);
                }
@@ -1394,11 +1388,12 @@ phpdbg_main:
                php_stream_stdio_ops.write = phpdbg_stdiop_write;
 #endif
 
-               if (exec) { /* set execution context */
-                       PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC);
+               if (phpdbg_exec) { /* set execution context */
+                       PHPDBG_G(exec) = phpdbg_resolve_path(phpdbg_exec TSRMLS_CC);
                        PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec));
 
-                       free(exec);
+                       free(phpdbg_exec);
+                       phpdbg_exec = NULL;
                }
 
                if (oplog_file) { /* open oplog */
@@ -1448,13 +1443,14 @@ phpdbg_main:
                        PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
                }
 
-               if (run) {
+               if (phpdbg_startup_run) {
                        /* no need to try{}, run does it ... */
                        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 */
                                goto phpdbg_out;
                        }
+                       phpdbg_startup_run = 0;
                }
 
 phpdbg_interact:
@@ -1494,7 +1490,7 @@ phpdbg_interact:
                                        }
                                }
                        } zend_end_try();
-               } while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING));
+               } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING));
                
                /* this must be forced */
                CG(unclean_shutdown) = 0;
index 8c0dbb4afa0a57f77337f48e39b4af9f0cb68fca..688ba7cdfcbc6ec143d1177fedbaf63df04717af 100644 (file)
--- a/phpdbg.h
+++ b/phpdbg.h
@@ -187,9 +187,10 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
 
 #define PHPDBG_IN_SIGNAL_HANDLER      (1<<30)
 
-#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_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_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_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
 #      define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED|PHPDBG_IS_BP_ENABLED)
index 30ea48cfbe47420daa55b21bbf5d97aef94d2e0a..ab0755454ecfb713f0ca7577e1f190ae125a4e54 100644 (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) /* {{{ */
 {
+       char buf[PHPDBG_MAX_CMD];
        char *cmd = 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)) {
                        fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr);
                }
 
                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))
-
                        /* 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
 readline:
                        if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE)
 #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_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;
-                                                       }
-                                                       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;
+                               phpdbg_consume_stdin_line(cmd = buf TSRMLS_CC);
                        }
 #if USE_LIB_STAR
                        else {
                                cmd = readline(phpdbg_get_prompt(TSRMLS_C));
+                               PHPDBG_G(last_was_newline) = 1;
                        }
 
                        if (!cmd) {
@@ -883,8 +833,7 @@ readline:
                } else {
                        cmd = buffered;
                }
-end:
-               PHPDBG_G(last_was_newline) = 1;
+
                buffer = estrdup(cmd);
 
 #if USE_LIB_STAR
@@ -922,3 +871,24 @@ PHPDBG_API void phpdbg_destroy_input(char **input TSRMLS_DC) /*{{{ */
 {
        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;
+}
index 3896551c9a23b82d3efe606b9dea9c685c4488d7..4c9e5383d82292a54f4692ab2692f46e53d52f07 100644 (file)
@@ -131,6 +131,7 @@ typedef struct {
 */
 PHPDBG_API char* phpdbg_read_input(char *buffered 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
index 97f0356285c5fb81df56a4e99d02072e3196baf3..a2a5c5969f491520c2ed9ba35e21ee3bfe70bdba 100644 (file)
 
 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) {
        int got_now, i = len, j;
        char *p = ptr;
index 3ac8f4112d0dbbed8ce591802740c86387167a64..a5659e88c653878e2ae3198f407af53b9264de03 100644 (file)
@@ -21,6 +21,8 @@
 
 #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_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);
index 2e0c698f0505b4ae598584c2b34007ce435dbf10..29c75c583c06099898470b1b9e877badf0e7478e 100644 (file)
@@ -43,6 +43,8 @@
 
 ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
 ZEND_EXTERN_MODULE_GLOBALS(output);
+extern int phpdbg_startup_run;
+extern char *phpdbg_exec;
 
 #ifdef HAVE_LIBDL
 #ifdef PHP_WIN32
@@ -355,6 +357,11 @@ PHPDBG_COMMAND(exec) /* {{{ */
                        size_t res_len = strlen(res);
 
                        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)) {
                                        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));
 
-                               if (phpdbg_compile(TSRMLS_C) == FAILURE) {
-                                       phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s", PHPDBG_G(exec));
+                               if (EG(in_execution)) {
+                                       phpdbg_clean(1 TSRMLS_CC);
                                }
+
+                               phpdbg_compile(TSRMLS_C);
                        } else {
                                phpdbg_notice("exec", "type=\"unchanged\"", "Execution context not changed");
                        }
@@ -399,20 +408,15 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */
 
        if (!PHPDBG_G(exec)) {
                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;
        }
 
        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);
                zend_destroy_file_handle(&fh TSRMLS_CC);
 
                phpdbg_notice("compile", "context=\"%s\"", "Successful compilation of %s", PHPDBG_G(exec));
+
                return SUCCESS;
        } else {
                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) /* {{{ */
 {
-       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)) {
                zend_op **orig_opline = EG(opline_ptr);
                zend_op_array *orig_op_array = EG(active_op_array);
@@ -582,6 +581,14 @@ PHPDBG_COMMAND(run) /* {{{ */
                zend_bool restore = 1;
                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_compile(TSRMLS_C) == FAILURE) {
                                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(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");
                                restore = 0;
                        }
@@ -1127,7 +1134,7 @@ PHPDBG_COMMAND(register) /* {{{ */
 PHPDBG_COMMAND(quit) /* {{{ */
 {
        /* 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;
                zend_bailout();
        }
@@ -1138,8 +1145,9 @@ PHPDBG_COMMAND(quit) /* {{{ */
 PHPDBG_COMMAND(clean) /* {{{ */
 {
        if (EG(in_execution)) {
-               phpdbg_error("inactive", "type=\"isrunning\"", "Cannot clean environment while executing");
-               return SUCCESS;
+               if (phpdbg_ask_user_permission("Do you really want to clean your current environment?" TSRMLS_CC) == FAILURE) {
+                       return SUCCESS;
+               }
        }
 
        phpdbg_out("Cleaning Execution Environment\n");
@@ -1227,60 +1235,64 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */
 
        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) {
-               do {
-                       phpdbg_init_param(&stack, STACK_PARAM);
+               if (!(input = phpdbg_read_input(NULL TSRMLS_CC))) {
+                       break;
+               }
 
-                       if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
-                               phpdbg_activate_err_buf(1 TSRMLS_CC);
+
+               phpdbg_init_param(&stack, STACK_PARAM);
+
+               if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
+                       phpdbg_activate_err_buf(1 TSRMLS_CC);
 
 #ifdef PHP_WIN32
 #define PARA ((phpdbg_param_t *)stack.next)->type
-                               if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) {
-                                       sigio_watcher_start();
-                               }
+                       if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) {
+                               sigio_watcher_start();
+                       }
 #endif
-                               switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) {
-                                       case FAILURE:
-                                               if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
-                                                       if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
-                                                               phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC);
-                                                       }
+                       switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) {
+                               case FAILURE:
+                                       if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
+                                               if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
+                                                       phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC);
                                                }
-                                       break;
+                                       }
+                               break;
 
-                                       case PHPDBG_LEAVE:
-                                       case PHPDBG_FINISH:
-                                       case PHPDBG_UNTIL:
-                                       case PHPDBG_NEXT: {
-                                               phpdbg_activate_err_buf(0 TSRMLS_CC);
-                                               phpdbg_free_err_buf(TSRMLS_C);
-                                               if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
-                                                       phpdbg_error("command", "type=\"noexec\"", "Not running");
-                                               }
-                                               goto out;
+                               case PHPDBG_LEAVE:
+                               case PHPDBG_FINISH:
+                               case PHPDBG_UNTIL:
+                               case PHPDBG_NEXT: {
+                                       phpdbg_activate_err_buf(0 TSRMLS_CC);
+                                       phpdbg_free_err_buf(TSRMLS_C);
+                                       if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
+                                               phpdbg_error("command", "type=\"noexec\"", "Not running");
                                        }
+                                       break;
                                }
+                       }
 
-                               phpdbg_activate_err_buf(0 TSRMLS_CC);
-                               phpdbg_free_err_buf(TSRMLS_C);
+                       phpdbg_activate_err_buf(0 TSRMLS_CC);
+                       phpdbg_free_err_buf(TSRMLS_C);
 #ifdef PHP_WIN32
-                               if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) {
-                                       sigio_watcher_stop();
-                               }
+                       if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) {
+                               sigio_watcher_stop();
+                       }
 #undef PARA
 #endif
-                       }
+               }
 
-                       phpdbg_stack_free(&stack);
-                       phpdbg_destroy_input(&input TSRMLS_CC);
-                       PHPDBG_G(req_id) = 0;
-               } while ((input = phpdbg_read_input(NULL TSRMLS_CC)));
+               phpdbg_stack_free(&stack);
+               phpdbg_destroy_input(&input TSRMLS_CC);
+               PHPDBG_G(req_id) = 0;
        }
 
-out:
        if (input) {
                phpdbg_stack_free(&stack);
                phpdbg_destroy_input(&input TSRMLS_CC);
@@ -1308,6 +1320,7 @@ void phpdbg_clean(zend_bool full TSRMLS_DC) /* {{{ */
        }
 
        if (full) {
+               phpdbg_exec = strdup(PHPDBG_G(exec)); /* preserve exec, don't reparse that from cmd */
                PHPDBG_G(flags) |= PHPDBG_IS_CLEANING;
 
                zend_bailout();
@@ -1593,7 +1606,7 @@ void phpdbg_force_interruption(TSRMLS_D) {
 next:
        PHPDBG_G(flags) &= ~PHPDBG_IN_SIGNAL_HANDLER;
 
-       if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
+       if (PHPDBG_G(flags) & PHPDBG_IS_STOPPING) {
                zend_bailout();
        }
 }