summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2014-04-03 11:55:04 +0200
committerSébastien Helleu <flashcode@flashtux.org>2014-04-03 11:55:04 +0200
commit7c55cbb38b6d42073eacf7decc4d08eb8677e60e (patch)
tree1545f21225f14009812c9f02c464d385a7f118cd /src
parent936d5559f40ff7a977cd78da3251b17c9b7d3d27 (diff)
downloadweechat-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.c18
-rw-r--r--src/plugins/exec/exec-command.h1
-rw-r--r--src/plugins/exec/exec.c300
-rw-r--r--src/plugins/exec/exec.h10
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 */