diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index ff895c72acf5..56d3ed1f87d3 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -344,6 +344,7 @@ db_command(last_cmdp, cmd_table, aux_cmd_tablep, aux_cmd_tablep_end) * Execute the command. */ (*cmd->fcn)(addr, have_addr, count, modif); + db_setup_paging(NULL, NULL, -1); if (cmd->flag & CS_SET_DOT) { /* diff --git a/sys/ddb/db_output.c b/sys/ddb/db_output.c index b1efb45ae01a..2fa8554488dd 100644 --- a/sys/ddb/db_output.c +++ b/sys/ddb/db_output.c @@ -62,6 +62,10 @@ db_expr_t db_tab_stop_width = 8; /* how wide are tab stops? */ #define NEXT_TAB(i) \ ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width) db_expr_t db_max_width = 79; /* output line width */ +static int db_newlines; /* # lines this page */ +static int db_maxlines = -1; /* max lines per page */ +static db_page_calloutfcn_t *db_page_callout = NULL; +static void *db_page_callout_arg = NULL; static void db_putchar(int c, void *arg); @@ -98,6 +102,7 @@ db_putchar(c, arg) int c; /* character to output */ void * arg; { + if (c > ' ' && c <= '~') { /* * Printing character. @@ -115,6 +120,13 @@ db_putchar(c, arg) db_output_position = 0; db_last_non_space = 0; db_check_interrupt(); + if (db_maxlines > 0 && db_page_callout != NULL) { + db_newlines++; + if (db_newlines >= db_maxlines) { + db_maxlines = -1; + db_page_callout(db_page_callout_arg); + } + } } else if (c == '\r') { /* Return */ @@ -138,6 +150,60 @@ db_putchar(c, arg) /* other characters are assumed non-printing */ } +/* + * Register callout for providing a pager for output. + */ +void +db_setup_paging(db_page_calloutfcn_t *callout, void *arg, int maxlines) +{ + + db_page_callout = callout; + db_page_callout_arg = arg; + db_maxlines = maxlines; + db_newlines = 0; +} + +/* + * A simple paging callout function. If the argument is not null, it + * points to an integer that will be set to 1 if the user asks to quit. + */ +void +db_simple_pager(void *arg) +{ + int c; + + db_printf("--More--\r"); + for (;;) { + c = cngetc(); + switch (c) { + case '\n': + /* Just one more line. */ + db_setup_paging(db_simple_pager, arg, 1); + return; + case ' ': + /* Another page. */ + db_setup_paging(db_simple_pager, arg, + DB_LINES_PER_PAGE); + return; + case 'q': + case 'Q': + case 'x': + case 'X': + /* Quit */ + if (arg != NULL) { + *(int *)arg = 1; + db_printf("\n"); + return; + } +#if 0 + /* FALLTHROUGH */ + default: + cnputc('\007'); +#endif + } + } +} + /* * Return output position */ diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h index 7259e97b6637..1ef452cfd440 100644 --- a/sys/ddb/ddb.h +++ b/sys/ddb/ddb.h @@ -39,9 +39,13 @@ #include /* type definitions */ +#define DB_LINES_PER_PAGE 20 + typedef void db_cmdfcn_t(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif); +typedef void db_page_calloutfcn_t(void *arg); + #define DB_COMMAND(cmd_name, func_name) \ DB_SET(cmd_name, func_name, db_cmd_set, 0, NULL) #define DB_SHOW_COMMAND(cmd_name, func_name) \ @@ -100,6 +104,8 @@ void db_read_bytes(vm_offset_t addr, size_t size, char *data); int db_readline(char *lstart, int lsize); void db_restart_at_pc(boolean_t watchpt); void db_set_watchpoints(void); +void db_setup_paging(db_page_calloutfcn_t *callout, void *arg, + int maxlines); void db_skip_to_eol(void); boolean_t db_stop_at_pc(boolean_t *is_breakpoint); #define db_strcpy strcpy @@ -139,6 +145,8 @@ db_cmdfcn_t ipc_port_print; db_cmdfcn_t vm_page_print; #endif +db_page_calloutfcn_t db_simple_pager; + /* Scare the user with backtrace of curthread to console. */ void db_print_backtrace(void);