bonefish + mmlr:

* Add possibility to restart a complete pipe through B_KDEBUG_RESTART_PIPE.
* Implement tail in the kernel debugger making use of the former.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28154 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2008-10-15 23:43:27 +00:00
parent 669ab2141b
commit 945a6a41ac
3 changed files with 80 additions and 7 deletions

View File

@ -48,7 +48,8 @@
#endif
// command return value
#define B_KDEBUG_ERROR 4
#define B_KDEBUG_ERROR 4
#define B_KDEBUG_RESTART_PIPE 5
// command flags
#define B_KDEBUG_DONT_PARSE_ARGUMENTS (0x01)

View File

@ -148,6 +148,59 @@ cmd_head(int argc, char** argv)
}
static int
cmd_tail(int argc, char** argv)
{
debugger_command_pipe_segment* segment
= get_current_debugger_command_pipe_segment();
if (segment == NULL) {
kprintf_unfiltered("%s can only be run as part of a pipe!\n", argv[0]);
return B_KDEBUG_ERROR;
}
struct user_data {
uint64 max_lines;
int64 line_count;
bool restarted;
};
user_data* userData = (user_data*)segment->user_data;
if (segment->invocations == 0) {
if (argc > 3) {
print_debugger_command_usage(argv[0]);
return B_KDEBUG_ERROR;
}
userData->max_lines = 10;
if (argc > 2 && !evaluate_debug_expression(argv[1],
&userData->max_lines, false)) {
return B_KDEBUG_ERROR;
}
userData->line_count = 1;
userData->restarted = false;
} else if (!userData->restarted) {
if (argv[argc - 1] == NULL) {
userData->restarted = true;
userData->line_count -= userData->max_lines;
return B_KDEBUG_RESTART_PIPE;
}
++userData->line_count;
} else {
if (argv[argc - 1] == NULL)
return 0;
if (--userData->line_count < 0) {
kputs(argv[argc - 1]);
kputs("\n");
}
}
return 0;
}
static int
cmd_grep(int argc, char** argv)
{
@ -300,6 +353,13 @@ debug_builtin_commands_init()
"Should be used in a command pipe. It prints only the first\n"
"<maxLines> lines of output from the previous command in the pipe and\n"
"silently discards the rest of the output.\n", 0);
add_debugger_command_etc("tail", &cmd_tail,
"Prints only the last lines of output from another command",
"[ <maxLines> ]\n"
"Should be used in a command pipe. It prints only the last\n"
"<maxLines> (default 10) lines of output from the previous command in\n"
"the pipe and silently discards the rest of the output.\n",
B_KDEBUG_PIPE_FINAL_RERUN);
add_debugger_command_etc("grep", &cmd_grep,
"Filters output from another command",
"[ -i ] [ -v ] <pattern>\n"

View File

@ -351,13 +351,25 @@ invoke_debugger_command_pipe(debugger_command_pipe* pipe)
sOutputBuffers[i], kOutputBufferSize);
}
int result = invoke_pipe_segment(pipe, 0, NULL);
int result;
while (true) {
result = invoke_pipe_segment(pipe, 0, NULL);
// perform final rerun for all commands that want it
for (int32 i = 1; result != B_KDEBUG_ERROR && i < segments; i++) {
debugger_command_pipe_segment& segment = pipe->segments[i];
if ((segment.command->flags & B_KDEBUG_PIPE_FINAL_RERUN) != 0)
result = invoke_pipe_segment(pipe, i, NULL);
// perform final rerun for all commands that want it
for (int32 i = 1; result != B_KDEBUG_ERROR && i < segments; i++) {
debugger_command_pipe_segment& segment = pipe->segments[i];
if ((segment.command->flags & B_KDEBUG_PIPE_FINAL_RERUN) != 0) {
result = invoke_pipe_segment(pipe, i, NULL);
if (result == B_KDEBUG_RESTART_PIPE) {
for (int32 j = 0; j < i; j++)
pipe->segments[j].invocations = 0;
break;
}
}
}
if (result != B_KDEBUG_RESTART_PIPE)
break;
}
sCurrentPipe = oldPipe;