diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2014-04-03 11:55:04 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2014-04-03 11:55:04 +0200 |
commit | 7c55cbb38b6d42073eacf7decc4d08eb8677e60e (patch) | |
tree | 1545f21225f14009812c9f02c464d385a7f118cd /src | |
parent | 936d5559f40ff7a977cd78da3251b17c9b7d3d27 (diff) | |
download | weechat-7c55cbb38b6d42073eacf7decc4d08eb8677e60e.zip |
exec: display output of commands in real time, add options -flush/-noflush in command /exec
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/exec/exec-command.c | 18 | ||||
-rw-r--r-- | src/plugins/exec/exec-command.h | 1 | ||||
-rw-r--r-- | src/plugins/exec/exec.c | 300 | ||||
-rw-r--r-- | src/plugins/exec/exec.h | 10 |
4 files changed, 197 insertions, 132 deletions
diff --git a/src/plugins/exec/exec-command.c b/src/plugins/exec/exec-command.c index c8fe49e9c..f3d7084f8 100644 --- a/src/plugins/exec/exec-command.c +++ b/src/plugins/exec/exec-command.c @@ -268,6 +268,14 @@ exec_command_parse_options (struct t_exec_cmd_options *cmd_options, { cmd_options->line_numbers = 0; } + else if (weechat_strcasecmp (argv[i], "-flush") == 0) + { + cmd_options->flush = 1; + } + else if (weechat_strcasecmp (argv[i], "-noflush") == 0) + { + cmd_options->flush = 0; + } else if (weechat_strcasecmp (argv[i], "-color") == 0) { if (i + 1 >= argc) @@ -405,6 +413,7 @@ exec_command_run (struct t_gui_buffer *buffer, cmd_options.new_buffer_clear = 0; cmd_options.switch_to_buffer = 1; cmd_options.line_numbers = -1; + cmd_options.flush = 1; cmd_options.color = EXEC_COLOR_AUTO; cmd_options.display_rc = 1; cmd_options.ptr_command_name = NULL; @@ -470,6 +479,8 @@ exec_command_run (struct t_gui_buffer *buffer, weechat_hashtable_set (process_options, "stdin", "1"); if (cmd_options.detached) weechat_hashtable_set (process_options, "detached", "1"); + if (cmd_options.flush) + weechat_hashtable_set (process_options, "buffer_flush", "1"); /* set variables in new command (before running the command) */ new_exec_cmd->name = (cmd_options.ptr_command_name) ? @@ -775,7 +786,7 @@ exec_command_init () N_("-list" " || [-sh|-nosh] [-bg|-nobg] [-stdin|-nostdin] [-buffer <name>] " "[-l|-o|-n|-nf] [-cl|-nocl] [-sw|-nosw] [-ln|-noln] " - "[-color ansi|auto|irc|weechat|strip] [-rc|-norc] " + "[-flush|-noflush] [-color ansi|auto|irc|weechat|strip] [-rc|-norc] " "[-timeout <timeout>] [-name <name>] [-pipe <command>] " "[-hsignal <name>] <command>" " || -in <id> <text>" @@ -814,6 +825,8 @@ exec_command_init () " -nosw: don't switch to the output buffer\n" " -ln: display line numbers (default in new buffer only)\n" " -noln: don't display line numbers\n" + " -flush: display output of command in real time (default)\n" + "-noflush: display output of command after its end\n" " -color: action on ANSI colors in output:\n" " ansi: keep ANSI codes as-is\n" " auto: convert ANSI colors to WeeChat/IRC (default)\n" @@ -863,7 +876,8 @@ exec_command_init () " /exec -pipe \"/print Machine uptime:\" uptime"), "-list" " || -sh|-nosh|-bg|-nobg|-stdin|-nostdin|-buffer|-l|-o|-n|-nf|" - "-cl|-nocl|-sw|-nosw|-ln|-noln|-color|-timeout|-name|-pipe|-hsignal|%*" + "-cl|-nocl|-sw|-nosw|-ln|-noln|-flush|-noflush|-color|-timeout|-name|" + "-pipe|-hsignal|%*" " || -in|-inclose|-signal|-kill %(exec_commands_ids)" " || -killall" " || -set %(exec_commands_ids) stdin|stdin_close|signal" diff --git a/src/plugins/exec/exec-command.h b/src/plugins/exec/exec-command.h index 6b9e195d0..fa314318c 100644 --- a/src/plugins/exec/exec-command.h +++ b/src/plugins/exec/exec-command.h @@ -34,6 +34,7 @@ struct t_exec_cmd_options int new_buffer_clear; /* 1 to clear buffer before output */ int switch_to_buffer; /* switch to the output buffer */ int line_numbers; /* 1 to display line numbers */ + int flush; /* 1 to flush lines immediately */ int color; /* what to do with ANSI colors */ int display_rc; /* 1 to display return code */ const char *ptr_command_name; /* name of command */ diff --git a/src/plugins/exec/exec.c b/src/plugins/exec/exec.c index 5d8eccbea..a5521ed39 100644 --- a/src/plugins/exec/exec.c +++ b/src/plugins/exec/exec.c @@ -114,7 +114,7 @@ struct t_exec_cmd * exec_add () { struct t_exec_cmd *new_exec_cmd, *ptr_exec_cmd; - int number; + int i, number; /* find first available number */ number = (last_exec_cmd) ? last_exec_cmd->number + 1 : 0; @@ -153,10 +153,12 @@ exec_add () new_exec_cmd->buffer_full_name = NULL; new_exec_cmd->line_numbers = 0; new_exec_cmd->display_rc = 0; - new_exec_cmd->out_size = 0; - new_exec_cmd->out = NULL; - new_exec_cmd->err_size = 0; - new_exec_cmd->err = NULL; + new_exec_cmd->output_line_nb = 0; + for (i = 0; i < 2; i++) + { + new_exec_cmd->output_size[i] = 0; + new_exec_cmd->output[i] = NULL; + } new_exec_cmd->return_code = -1; new_exec_cmd->pipe_command = NULL; new_exec_cmd->hsignal = NULL; @@ -196,27 +198,6 @@ exec_timer_delete_cb (void *data, int remaining_calls) } /* - * Concatenates some text to stdout/stderr of a command. - */ - -void -exec_concat_output (int *size, char **output, const char *text) -{ - int length, new_size; - char *new_output; - - length = strlen (text); - new_size = *size + length; - new_output = realloc (*output, new_size + 1); - if (!new_output) - return; - - *output = new_output; - memcpy (*output + *size, text, length + 1); - *size = new_size; -} - -/* * Decodes colors in a string (from stdout/stderr). * * Returns string with colors as-is, decoded or removed. @@ -258,19 +239,22 @@ exec_decode_color (struct t_exec_cmd *exec_cmd, const char *string) } /* - * Displays output of a command. + * Displays a line of output. */ void -exec_display_output (struct t_exec_cmd *exec_cmd, - struct t_gui_buffer *buffer, int out) +exec_display_line (struct t_exec_cmd *exec_cmd, struct t_gui_buffer *buffer, + int out, const char *line) { + char *line_color, *line2, str_number[32], str_tags[1024]; + int length; + /* char *ptr_output, *ptr_line, *line, *line2, *pos; char str_number[32], str_tags[1024]; - int line_nb, length; + int length; + */ - ptr_output = (out) ? exec_cmd->out : exec_cmd->err; - if (!ptr_output) + if (!exec_cmd || !line) return; /* @@ -280,99 +264,149 @@ exec_display_output (struct t_exec_cmd *exec_cmd, if (exec_cmd->output_to_buffer && !exec_cmd->pipe_command && !buffer) return; - ptr_line = ptr_output; - line_nb = 1; - while (ptr_line) - { - /* ignore last empty line */ - if (!ptr_line[0]) - break; - - /* search end of line */ - pos = strchr (ptr_line, '\n'); - line = (pos) ? - weechat_strndup (ptr_line, pos - ptr_line) : strdup (ptr_line); - if (!line) - break; + /* decode colors */ + line_color = exec_decode_color (exec_cmd, line); + if (!line_color) + return; - /* decode colors */ - line2 = exec_decode_color (exec_cmd, line); - free (line); - if (!line2) - break; - line = line2; + exec_cmd->output_line_nb++; - if (exec_cmd->pipe_command) + if (exec_cmd->pipe_command) + { + if (strstr (exec_cmd->pipe_command, "$line")) { - if (strstr (exec_cmd->pipe_command, "$line")) + /* replace $line by line content */ + line2 = weechat_string_replace (exec_cmd->pipe_command, + "$line", line_color); + if (line2) { - /* replace $line by line content */ - line2 = weechat_string_replace (exec_cmd->pipe_command, - "$line", line); - if (line2) - { - weechat_command (buffer, line2); - free (line2); - } + weechat_command (buffer, line2); + free (line2); } - else + } + else + { + /* add line at the end of command, after a space */ + length = strlen (exec_cmd->pipe_command) + 1 + strlen (line_color) + 1; + line2 = malloc (length); + if (line2) { - /* add line at the end of command, after a space */ - length = strlen (exec_cmd->pipe_command) + 1 + strlen (line) + 1; - line2 = malloc (length); - if (line2) - { - snprintf (line2, length, "%s %s", exec_cmd->pipe_command, line); - weechat_command (buffer, line2); - free (line2); - } + snprintf (line2, length, + "%s %s", exec_cmd->pipe_command, line_color); + weechat_command (buffer, line2); + free (line2); } } - else if (exec_cmd->output_to_buffer) + } + else if (exec_cmd->output_to_buffer) + { + if (exec_cmd->line_numbers) { - if (exec_cmd->line_numbers) + length = 32 + strlen (line_color) + 1; + line2 = malloc (length); + if (line2) { - length = 32 + strlen (line) + 1; - line2 = malloc (length); - if (line2) - { - snprintf (line2, length, "%d. %s", line_nb, line); - weechat_command (buffer, line2); - free (line2); - } + snprintf (line2, length, + "%d. %s", exec_cmd->output_line_nb, line_color); + weechat_command (buffer, line2); + free (line2); } - else - weechat_command (buffer, (line[0]) ? line : " "); } else + weechat_command (buffer, (line_color[0]) ? line_color : " "); + } + else + { + snprintf (str_number, sizeof (str_number), "%d", exec_cmd->number); + snprintf (str_tags, sizeof (str_tags), + "exec_%s,exec_cmd_%s", + (out) ? "stdout" : "stderr", + (exec_cmd->name) ? exec_cmd->name : str_number); + if (weechat_buffer_get_integer (buffer, "type") == 1) { + snprintf (str_number, sizeof (str_number), + "%d. ", exec_cmd->output_line_nb); + weechat_printf_y (buffer, -1, + "%s%s", + (exec_cmd->line_numbers) ? str_number : " ", + line_color); + } + else + { + snprintf (str_number, sizeof (str_number), + "%d\t", exec_cmd->output_line_nb); + weechat_printf_tags (buffer, str_tags, + "%s%s", + (exec_cmd->line_numbers) ? str_number : " \t", + line_color); + } + } +} - snprintf (str_number, sizeof (str_number), "%d", exec_cmd->number); - snprintf (str_tags, sizeof (str_tags), - "exec_%s,exec_cmd_%s", - (out) ? "stdout" : "stderr", - (exec_cmd->name) ? exec_cmd->name : str_number); - if (weechat_buffer_get_integer (buffer, "type") == 1) +/* + * Concatenates some text to stdout/stderr of a command. + */ + +void +exec_concat_output (struct t_exec_cmd *exec_cmd, struct t_gui_buffer *buffer, + int out, const char *text) +{ + int length, new_size; + const char *ptr_text; + char *new_output, *pos, *line; + + ptr_text = text; + + /* if output is not sent as hsignal, display lines (ending with '\n') */ + if (!exec_cmd->hsignal) + { + ptr_text = text; + while (ptr_text[0]) + { + pos = strchr (ptr_text, '\n'); + if (!pos) + break; + if (exec_cmd->output_size[out] > 0) { - snprintf (str_number, sizeof (str_number), "%d. ", line_nb); - weechat_printf_y (buffer, -1, - "%s%s", - (exec_cmd->line_numbers) ? str_number : " ", - line); + length = exec_cmd->output_size[out] + (pos - ptr_text) + 1; + line = malloc (length); + if (line) + { + memcpy (line, exec_cmd->output[out], + exec_cmd->output_size[out]); + memcpy (line + exec_cmd->output_size[out], + ptr_text, pos - ptr_text); + line[length - 1] = '\0'; + } } else + line = weechat_strndup (ptr_text, pos - ptr_text); + if (!line) + break; + if (exec_cmd->output[out]) { - snprintf (str_number, sizeof (str_number), "%d\t", line_nb); - weechat_printf_tags (buffer, str_tags, - "%s%s", - (exec_cmd->line_numbers) ? str_number : " \t", - line); + free (exec_cmd->output[out]); + exec_cmd->output[out] = NULL; } + exec_cmd->output_size[out] = 0; + exec_display_line (exec_cmd, buffer, out, line); + free (line); + ptr_text = pos + 1; } + } - free (line); - line_nb++; - ptr_line = (pos) ? pos + 1 : NULL; + /* concatenate ptr_text to output buffer */ + length = strlen (ptr_text); + if (length > 0) + { + new_size = exec_cmd->output_size[out] + length; + new_output = realloc (exec_cmd->output[out], new_size + 1); + if (!new_output) + return; + exec_cmd->output[out] = new_output; + memcpy (exec_cmd->output[out] + exec_cmd->output_size[out], + ptr_text, length + 1); + exec_cmd->output_size[out] = new_size; } } @@ -386,7 +420,7 @@ exec_end_command (struct t_exec_cmd *exec_cmd, int return_code) struct t_gui_buffer *ptr_buffer; struct t_hashtable *hashtable; char str_number[32], *output; - int buffer_type; + int i, buffer_type; if (exec_cmd->hsignal) { @@ -401,11 +435,11 @@ exec_end_command (struct t_exec_cmd *exec_cmd, int return_code) snprintf (str_number, sizeof (str_number), "%d", exec_cmd->number); weechat_hashtable_set (hashtable, "number", str_number); weechat_hashtable_set (hashtable, "name", exec_cmd->name); - output = exec_decode_color (exec_cmd, exec_cmd->out); + output = exec_decode_color (exec_cmd, exec_cmd->output[EXEC_STDOUT]); weechat_hashtable_set (hashtable, "out", output); if (output) free (output); - output = exec_decode_color (exec_cmd, exec_cmd->err); + output = exec_decode_color (exec_cmd, exec_cmd->output[EXEC_STDERR]); weechat_hashtable_set (hashtable, "err", output); if (output) free (output); @@ -419,8 +453,11 @@ exec_end_command (struct t_exec_cmd *exec_cmd, int return_code) { ptr_buffer = weechat_buffer_search ("==", exec_cmd->buffer_full_name); - exec_display_output (exec_cmd, ptr_buffer, 1); - exec_display_output (exec_cmd, ptr_buffer, 0); + /* display the last line of output (if not ending with '\n') */ + exec_display_line (exec_cmd, ptr_buffer, EXEC_STDOUT, + exec_cmd->output[EXEC_STDOUT]); + exec_display_line (exec_cmd, ptr_buffer, EXEC_STDERR, + exec_cmd->output[EXEC_STDERR]); /* * display return code (only if command is not detached, if output is @@ -477,6 +514,15 @@ exec_end_command (struct t_exec_cmd *exec_cmd, int return_code) exec_cmd->pid = 0; exec_cmd->end_time = time (NULL); exec_cmd->return_code = return_code; + for (i = 0; i < 2; i++) + { + if (exec_cmd->output[i]) + { + free (exec_cmd->output[i]); + exec_cmd->output[i] = NULL; + } + exec_cmd->output_size[i] = 0; + } /* schedule a timer to remove the executed command */ if (weechat_config_integer (exec_config_command_purge_delay) >= 0) @@ -496,6 +542,7 @@ exec_process_cb (void *data, const char *command, int return_code, const char *out, const char *err) { struct t_exec_cmd *ptr_exec_cmd; + struct t_gui_buffer *ptr_buffer; /* make C compiler happy */ (void) command; @@ -516,17 +563,14 @@ exec_process_cb (void *data, const char *command, int return_code, (err) ? strlen (err) : 0); } - if (out) - { - exec_concat_output (&ptr_exec_cmd->out_size, - &ptr_exec_cmd->out, - out); - } - if (err) + if (out || err) { - exec_concat_output (&ptr_exec_cmd->err_size, - &ptr_exec_cmd->err, - err); + ptr_buffer = weechat_buffer_search ("==", + ptr_exec_cmd->buffer_full_name); + if (out) + exec_concat_output (ptr_exec_cmd, ptr_buffer, EXEC_STDOUT, out); + if (err) + exec_concat_output (ptr_exec_cmd, ptr_buffer, EXEC_STDERR, err); } if (return_code == WEECHAT_HOOK_PROCESS_ERROR) @@ -544,6 +588,8 @@ exec_process_cb (void *data, const char *command, int return_code, void exec_free (struct t_exec_cmd *exec_cmd) { + int i; + if (!exec_cmd) return; @@ -566,10 +612,11 @@ exec_free (struct t_exec_cmd *exec_cmd) free (exec_cmd->command); if (exec_cmd->buffer_full_name) free (exec_cmd->buffer_full_name); - if (exec_cmd->out) - free (exec_cmd->out); - if (exec_cmd->err) - free (exec_cmd->err); + for (i = 0; i < 2; i++) + { + if (exec_cmd->output[i]) + free (exec_cmd->output[i]); + } if (exec_cmd->pipe_command) free (exec_cmd->pipe_command); if (exec_cmd->hsignal) @@ -619,10 +666,11 @@ exec_print_log () weechat_log_printf (" buffer_full_name. . . . : '%s'", ptr_exec_cmd->buffer_full_name); weechat_log_printf (" line_numbers. . . . . . : %d", ptr_exec_cmd->line_numbers); weechat_log_printf (" display_rc. . . . . . . : %d", ptr_exec_cmd->display_rc); - weechat_log_printf (" out_size. . . . . . . . : %d", ptr_exec_cmd->out_size); - weechat_log_printf (" out . . . . . . . . . . : '%s'", ptr_exec_cmd->out); - weechat_log_printf (" err_size. . . . . . . . : %d", ptr_exec_cmd->err_size); - weechat_log_printf (" err . . . . . . . . . . : '%s'", ptr_exec_cmd->err); + weechat_log_printf (" output_line_nb. . . . . : %d", ptr_exec_cmd->output_line_nb); + weechat_log_printf (" output_size[stdout] . . : %d", ptr_exec_cmd->output_size[EXEC_STDOUT]); + weechat_log_printf (" output[stdout]. . . . . : '%s'", ptr_exec_cmd->output[EXEC_STDOUT]); + weechat_log_printf (" output_size[stderr] . . : %d", ptr_exec_cmd->output_size[EXEC_STDERR]); + weechat_log_printf (" output[stderr]. . . . . : '%s'", ptr_exec_cmd->output[EXEC_STDERR]); weechat_log_printf (" return_code . . . . . . : %d", ptr_exec_cmd->return_code); weechat_log_printf (" pipe_command. . . . . . : '%s'", ptr_exec_cmd->pipe_command); weechat_log_printf (" hsignal . . . . . . . . : '%s'", ptr_exec_cmd->hsignal); diff --git a/src/plugins/exec/exec.h b/src/plugins/exec/exec.h index 3cb50d56d..51924fa3a 100644 --- a/src/plugins/exec/exec.h +++ b/src/plugins/exec/exec.h @@ -25,6 +25,9 @@ #define weechat_plugin weechat_exec_plugin #define EXEC_PLUGIN_NAME "exec" +#define EXEC_STDOUT 0 +#define EXEC_STDERR 1 + enum t_exec_color { EXEC_COLOR_ANSI = 0, @@ -56,10 +59,9 @@ struct t_exec_cmd int display_rc; /* 1 if return code is displayed */ /* command output */ - int out_size; /* number of bytes in stdout */ - char *out; /* stdout of command */ - int err_size; /* number of bytes in stderr */ - char *err; /* stderr of command */ + int output_line_nb; /* line number */ + int output_size[2]; /* number of bytes in stdout/stderr */ + char *output[2]; /* stdout/stderr of command */ int return_code; /* command return code */ /* pipe/hsignal */ |