]> granicus.if.org Git - php/commitdiff
Remove the ugly hack via a temp file to store breakpoints
authorBob Weinand <bobwei9@hotmail.com>
Tue, 28 Oct 2014 16:20:21 +0000 (17:20 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Tue, 28 Oct 2014 16:25:48 +0000 (17:25 +0100)
sapi/phpdbg/phpdbg.c
sapi/phpdbg/phpdbg_bp.c
sapi/phpdbg/phpdbg_bp.h
sapi/phpdbg/phpdbg_prompt.c
sapi/phpdbg/phpdbg_prompt.h

index 87bfb8583459ee1438dfaf699b07b20e1df64cd1..5ebc203529bdf7949c18b82468dd9e6fcb05d80d 100644 (file)
@@ -1039,13 +1039,7 @@ int main(int argc, char **argv) /* {{{ */
        zend_bool remote = 0;
        int step = 0;
        zend_phpdbg_globals *settings = NULL;
-
-#ifdef _WIN32
-       char *bp_tmp_file = NULL;
-#else
-       char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX";
-#endif
-
+       char *bp_tmp = NULL;
        char *address;
        int listen = -1;
        int server = -1;
@@ -1081,29 +1075,6 @@ int main(int argc, char **argv) /* {{{ */
 #endif
 
 phpdbg_main:
-       if (!cleaning) {
-       
-#ifdef _WIN32
-               bp_tmp_file = malloc(L_tmpnam);
-
-               if (bp_tmp_file) {
-                       if (!tmpnam(bp_tmp_file)) {
-                               free(bp_tmp_file);
-                               bp_tmp_file = NULL;
-                       }
-               }
-
-               if (!bp_tmp_file) {
-                       phpdbg_error("tmpfile", "", "Unable to create temporary file");
-                       return 1;
-               }
-#else
-               if (!mkstemp(bp_tmp_file)) {
-                       memset(bp_tmp_file, 0, sizeof(bp_tmp_file));
-               }
-#endif
-
-       }
        ini_entries = NULL;
        ini_entries_len = 0;
        ini_ignore = 0;
@@ -1502,9 +1473,13 @@ phpdbg_main:
                PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING;
                zend_try {
                        phpdbg_init(init_file, init_file_len, init_file_default TSRMLS_CC);
-                       PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
-                       phpdbg_try_file_init(bp_tmp_file, strlen(bp_tmp_file), 0 TSRMLS_CC);
-                       PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
+                       if (bp_tmp) {
+                               PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
+                               phpdbg_string_init(bp_tmp TSRMLS_CC);
+                               free(bp_tmp);
+                               bp_tmp = NULL;
+                               PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
+                       }
                } zend_end_try();
                PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING;
                
@@ -1532,23 +1507,27 @@ phpdbg_interact:
                do {
                        zend_try {
                                if (phpdbg_startup_run) {
+                                       zend_bool quit_immediately = phpdbg_startup_run > 1;
+                                       phpdbg_startup_run = 0;
                                        PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC);
-                                       if (phpdbg_startup_run > 1) {
+                                       if (quit_immediately) {
                                                /* if -r is on the command line more than once just quit */
                                                EG(bailout) = __orig_bailout; /* reset zend_try */
                                                break;
                                        }
-                                       phpdbg_startup_run = 0;
                                }
 
                                phpdbg_interactive(1 TSRMLS_CC);
                        } zend_catch {
                                if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) {
-                                       FILE *bp_tmp_fp = fopen(bp_tmp_file, "w");
+                                       char *bp_tmp_str;
                                        PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
-                                       phpdbg_export_breakpoints(bp_tmp_fp TSRMLS_CC);
+                                       phpdbg_export_breakpoints_to_string(&bp_tmp_str TSRMLS_CC);
                                        PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
-                                       fclose(bp_tmp_fp);
+                                       if (bp_tmp_str) {
+                                               bp_tmp = strdup(bp_tmp_str);
+                                               efree(bp_tmp_str);
+                                       }
                                        cleaning = 1;
                                } else {
                                        cleaning = 0;
@@ -1688,11 +1667,5 @@ phpdbg_out:
                free(PHPDBG_G(sapi_name_ptr));
        }
 
-#ifdef _WIN32
-       free(bp_tmp_file);
-#else
-       unlink(bp_tmp_file);
-#endif
-
        return 0;
 } /* }}} */
index 93902f00529e22869110619a3c4a9f99ed5bc964..33824d4fec4f80b4b164dcba5416ea6bd0aa55c0 100644 (file)
@@ -110,11 +110,20 @@ PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */
 } /* }}} */
 
 PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
+{
+       char *string;
+       phpdbg_export_breakpoints_to_string(&string TSRMLS_CC);
+       fputs(string, handle);
+}
+
+PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC) /* {{{ */
 {
        HashPosition position[2];
        HashTable **table = NULL;
        zend_ulong id = 0L;
 
+       *str = "";
+
        if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
                phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
                /* this only looks like magic, it isn't */
@@ -126,55 +135,57 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
                        zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]);
 
                        for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
-                               zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
-                               zend_hash_move_forward_ex((*table), &position[1])) {
+                            zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
+                            zend_hash_move_forward_ex((*table), &position[1])) {
                                if (brake->id == id) {
+                                       char *new_str = NULL;
+
                                        switch (brake->type) {
                                                case PHPDBG_BREAK_FILE: {
-                                                       fprintf(handle,
-                                                               "break %s:%lu\n",
+                                                       phpdbg_asprintf(&new_str,
+                                                               "%sbreak %s:%lu\n", *str,
                                                                ((phpdbg_breakfile_t*)brake)->filename,
                                                                ((phpdbg_breakfile_t*)brake)->line);
                                                } break;
 
                                                case PHPDBG_BREAK_SYM: {
-                                                       fprintf(handle,
-                                                               "break %s\n",
+                                                       phpdbg_asprintf(&new_str,
+                                                               "%sbreak %s\n", *str,
                                                                ((phpdbg_breaksymbol_t*)brake)->symbol);
                                                } break;
 
                                                case PHPDBG_BREAK_METHOD: {
-                                                       fprintf(handle,
-                                                               "break %s::%s\n",
+                                                       phpdbg_asprintf(&new_str,
+                                                               "%sbreak %s::%s\n", *str,
                                                                ((phpdbg_breakmethod_t*)brake)->class_name,
                                                                ((phpdbg_breakmethod_t*)brake)->func_name);
                                                } break;
 
                                                case PHPDBG_BREAK_METHOD_OPLINE: {
-                                                       fprintf(handle,
-                                                               "break %s::%s#%ld\n",
+                                                       phpdbg_asprintf(&new_str,
+                                                               "%sbreak %s::%s#%ld\n", *str,
                                                                ((phpdbg_breakopline_t*)brake)->class_name,
                                                                ((phpdbg_breakopline_t*)brake)->func_name,
                                                                ((phpdbg_breakopline_t*)brake)->opline_num);
                                                } break;
 
                                                case PHPDBG_BREAK_FUNCTION_OPLINE: {
-                                                       fprintf(handle,
-                                                               "break %s#%ld\n",
+                                                       phpdbg_asprintf(&new_str,
+                                                               "%sbreak %s#%ld\n", *str,
                                                                ((phpdbg_breakopline_t*)brake)->func_name,
                                                                ((phpdbg_breakopline_t*)brake)->opline_num);
                                                } break;
 
                                                case PHPDBG_BREAK_FILE_OPLINE: {
-                                                       fprintf(handle,
-                                                               "break %s:#%ld\n",
+                                                       phpdbg_asprintf(&new_str,
+                                                               "%sbreak %s:#%ld\n", *str,
                                                                ((phpdbg_breakopline_t*)brake)->class_name,
                                                                ((phpdbg_breakopline_t*)brake)->opline_num);
                                                } break;
 
                                                case PHPDBG_BREAK_OPCODE: {
-                                                       fprintf(handle,
-                                                               "break %s\n",
+                                                       phpdbg_asprintf(&new_str,
+                                                               "%sbreak %s\n", *str,
                                                                ((phpdbg_breakop_t*)brake)->name);
                                                } break;
 
@@ -184,20 +195,20 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
                                                        if (conditional->paramed) {
                                                                switch (conditional->param.type) {
                                                                        case STR_PARAM:
-                                                                               fprintf(handle,
-                                                                                       "break at %s if %s\n", conditional->param.str, conditional->code);
+                                                                               phpdbg_asprintf(&new_str,
+                                                                                       "%sbreak at %s if %s\n", *str, conditional->param.str, conditional->code);
                                                                        break;
 
                                                                        case METHOD_PARAM:
-                                                                               fprintf(handle,
-                                                                                       "break at %s::%s if %s\n",
+                                                                               phpdbg_asprintf(&new_str,
+                                                                                       "%sbreak at %s::%s if %s\n", *str,
                                                                                        conditional->param.method.class, conditional->param.method.name,
                                                                                        conditional->code);
                                                                        break;
 
                                                                        case FILE_PARAM:
-                                                                               fprintf(handle,
-                                                                                       "break at %s:%lu if %s\n",
+                                                                               phpdbg_asprintf(&new_str,
+                                                                                       "%sbreak at %s:%lu if %s\n", *str,
                                                                                        conditional->param.file.name, conditional->param.file.line,
                                                                                        conditional->code);
                                                                        break;
@@ -205,15 +216,23 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
                                                                        default: { /* do nothing */ } break;
                                                                }
                                                        } else {
-                                                               fprintf(
-                                                                       handle, "break if %s\n", conditional->code);
+                                                               phpdbg_asprintf(&new_str, "%sbreak if %s\n", str, conditional->code);
                                                        }
                                                } break;
                                        }
+
+                                       if ((*str)[0]) {
+                                               efree(*str);
+                                       }
+                                       *str = new_str;
                                }
                        }
                }
        }
+
+       if (!(*str)[0]) {
+               *str = NULL;
+       }
 } /* }}} */
 
 PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */
index eca595321b34ac7d6d821d7ac6807daf3803844f..63a9961d2a876f88b85617aa309366ca77586a60 100644 (file)
@@ -157,6 +157,7 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC);
 PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC); /* }}} */
 
 /* {{{ Breakpoint Exportation API */
-PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */
+PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC);
+PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC); /* }}} */
 
 #endif /* PHPDBG_BP_H */
index 733d3cbe48abc48deed381e344c6b052a96244b4..c1fcb59a0860798685d42a3f42c42f974674e512 100644 (file)
@@ -208,98 +208,128 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
        return FAILURE;
 } /* }}} */
 
-void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
-{
-       struct stat sb;
+struct phpdbg_init_state {
+       int line;
+       zend_bool in_code;
+       char *code;
+       size_t code_len;
+       const char *init_file;
+};
 
-       if (init_file && VCWD_STAT(init_file, &sb) != -1) {
-               FILE *fp = fopen(init_file, "r");
-               if (fp) {
-                       int line = 1;
+static void phpdbg_line_init(char *cmd, struct phpdbg_init_state *state TSRMLS_DC) {
+       size_t cmd_len = strlen(cmd);
 
-                       char cmd[PHPDBG_MAX_CMD];
-                       size_t cmd_len = 0L;
-                       char *code = NULL;
-                       size_t code_len = 0L;
-                       zend_bool in_code = 0;
+       state->line++;
 
-                       while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
-                               cmd_len = strlen(cmd)-1;
-
-                               while (cmd_len > 0L && isspace(cmd[cmd_len-1]))
-                                       cmd_len--;
-
-                               cmd[cmd_len] = '\0';
-
-                               if (*cmd && cmd_len > 0L && cmd[0] != '#') {
-                                       if (cmd_len == 2) {
-                                               if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
-                                                       in_code = 1;
-                                                       goto next_line;
-                                               } else {
-                                                       if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
-                                                               in_code = 0;
-                                                               code[code_len] = '\0';
-                                                               {
-                                                                       zend_eval_stringl(code, code_len, NULL, "phpdbginit code" TSRMLS_CC);
-                                                               }
-                                                               free(code);
-                                                               code = NULL;
-                                                               goto next_line;
-                                                       }
-                                               }
-                                       }
+       while (cmd_len > 0L && isspace(cmd[cmd_len-1])) {
+               cmd_len--;
+       }
 
-                                       if (in_code) {
-                                               if (code == NULL) {
-                                                       code = malloc(cmd_len + 1);
-                                               } else code = realloc(code, code_len + cmd_len + 1);
+       cmd[cmd_len] = '\0';
 
-                                               if (code) {
-                                                       memcpy(
-                                                               &code[code_len], cmd, cmd_len);
-                                                       code_len += cmd_len;
-                                               }
-                                               goto next_line;
-                                       }
+       if (*cmd && cmd_len > 0L && cmd[0] != '#') {
+               if (cmd_len == 2) {
+                       if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
+                               state->in_code = 1;
+                               return;
+                       } else {
+                               if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
+                                       state->in_code = 0;
+                                       state->code[state->code_len] = '\0';
+                                       zend_eval_stringl(state->code, state->code_len, NULL, "phpdbginit code" TSRMLS_CC);
+                                       free(state->code);
+                                       state->code = NULL;
+                                       return;
+                               }
+                       }
+               }
 
-                                       zend_try {
-                                               char *input = phpdbg_read_input(cmd TSRMLS_CC);
-                                               phpdbg_param_t stack;
+               if (state->in_code) {
+                       if (state->code == NULL) {
+                               state->code = malloc(cmd_len + 1);
+                       } else {
+                               state->code = realloc(state->code, state->code_len + cmd_len + 1);
+                       }
 
-                                               phpdbg_init_param(&stack, STACK_PARAM);
+                       if (state->code) {
+                               memcpy(&state->code[state->code_len], cmd, cmd_len);
+                               state->code_len += cmd_len;
+                       }
 
-                                               phpdbg_activate_err_buf(1 TSRMLS_CC);
+                       return;
+               }
 
-                                               if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
-                                                       switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
-                                                               case FAILURE:
-                                                                       phpdbg_activate_err_buf(0 TSRMLS_CC);
-                                                                       if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
-                                                                               phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, init_file, line, input);
-                                                                       }
-                                                               break;
-                                                       }
-                                               }
+               zend_try {
+                       char *input = phpdbg_read_input(cmd TSRMLS_CC);
+                       phpdbg_param_t stack;
+
+                       phpdbg_init_param(&stack, STACK_PARAM);
+
+                       phpdbg_activate_err_buf(1 TSRMLS_CC);
 
+                       if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
+                               switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
+                                       case FAILURE:
                                                phpdbg_activate_err_buf(0 TSRMLS_CC);
-                                               phpdbg_free_err_buf(TSRMLS_C);
-
-                                               phpdbg_stack_free(&stack);
-                                               phpdbg_destroy_input(&input TSRMLS_CC);
-                                       } zend_catch {
-                                               PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
-                                               if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
-                                                       zend_bailout();
+                                               if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
+                                                       if (state->init_file) {
+                                                               phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, state->init_file, state->line, input);
+                                                       } else {
+                                                               phpdbg_output_err_buf("initfailure", "%b line=\"%d\" input=\"%s\"", "Unrecognized command on line %d: %s, %b!" TSRMLS_CC, state->line, input);
+                                                       }
                                                }
-                                       } zend_end_try();
+                                       break;
                                }
-next_line:
-                               line++;
                        }
 
-                       if (code) {
-                               free(code);
+                       phpdbg_activate_err_buf(0 TSRMLS_CC);
+                       phpdbg_free_err_buf(TSRMLS_C);
+
+                       phpdbg_stack_free(&stack);
+                       phpdbg_destroy_input(&input TSRMLS_CC);
+               } zend_catch {
+                       PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
+                       if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
+                               zend_bailout();
+                       }
+               } zend_end_try();
+       }
+
+}
+
+void phpdbg_string_init(char *buffer TSRMLS_DC) {
+       struct phpdbg_init_state state = {0};
+       char *str = strtok(buffer, "\n");
+
+       while (str) {
+               phpdbg_line_init(str, &state TSRMLS_CC);
+
+               str = strtok(NULL, "\n");
+       }
+
+       if (state.code) {
+               free(state.code);
+       }
+}
+
+void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
+{
+       struct stat sb;
+
+       if (init_file && VCWD_STAT(init_file, &sb) != -1) {
+               FILE *fp = fopen(init_file, "r");
+               if (fp) {
+                       char cmd[PHPDBG_MAX_CMD];
+                       struct phpdbg_init_state state = {0};
+
+                       state.init_file = init_file;
+
+                       while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
+                               phpdbg_line_init(cmd, &state TSRMLS_CC);
+                       }
+
+                       if (state.code) {
+                               free(state.code);
                        }
 
                        fclose(fp);
index 94e24df83341fc7a823150381fdda4c948866a26..f583f2cdcd6665a5c0b098610db4464fc1b2bcd1 100644 (file)
@@ -22,6 +22,7 @@
 #define PHPDBG_PROMPT_H
 
 /* {{{ */
+void phpdbg_string_init(char *buffer TSRMLS_DC);
 void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC);
 void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC);
 int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC);