Executor: if no user tooltip is set, display stderr output
This commit is contained in:
parent
ece3bc4d85
commit
f45e107207
4 changed files with 191 additions and 69 deletions
|
@ -700,6 +700,7 @@ void add_entry(char *key, char *value)
|
||||||
Execp *execp = get_or_create_last_execp();
|
Execp *execp = get_or_create_last_execp();
|
||||||
free_and_null(execp->backend->tooltip);
|
free_and_null(execp->backend->tooltip);
|
||||||
execp->backend->tooltip = strdup(value);
|
execp->backend->tooltip = strdup(value);
|
||||||
|
execp->backend->has_user_tooltip = TRUE;
|
||||||
} else if (strcmp(key, "execp_font") == 0) {
|
} else if (strcmp(key, "execp_font") == 0) {
|
||||||
Execp *execp = get_or_create_last_execp();
|
Execp *execp = get_or_create_last_execp();
|
||||||
pango_font_description_free(execp->backend->font_desc);
|
pango_font_description_free(execp->backend->font_desc);
|
||||||
|
|
|
@ -30,9 +30,10 @@ void default_execp()
|
||||||
|
|
||||||
Execp *create_execp()
|
Execp *create_execp()
|
||||||
{
|
{
|
||||||
Execp *execp = calloc(1, sizeof(Execp));
|
Execp *execp = (Execp *)calloc(1, sizeof(Execp));
|
||||||
execp->backend = calloc(1, sizeof(ExecpBackend));
|
execp->backend = (ExecpBackend *)calloc(1, sizeof(ExecpBackend));
|
||||||
execp->backend->child_pipe = -1;
|
execp->backend->child_pipe_stdout = -1;
|
||||||
|
execp->backend->child_pipe_stderr = -1;
|
||||||
execp->backend->cmd_pids = g_tree_new(cmp_ptr);
|
execp->backend->cmd_pids = g_tree_new(cmp_ptr);
|
||||||
execp->backend->interval = 30;
|
execp->backend->interval = 30;
|
||||||
execp->backend->cache_icon = TRUE;
|
execp->backend->cache_icon = TRUE;
|
||||||
|
@ -45,10 +46,10 @@ gpointer create_execp_frontend(gconstpointer arg, gpointer data)
|
||||||
{
|
{
|
||||||
Execp *execp_backend = (Execp *)arg;
|
Execp *execp_backend = (Execp *)arg;
|
||||||
|
|
||||||
Execp *execp_frontend = calloc(1, sizeof(Execp));
|
Execp *execp_frontend = (Execp *)calloc(1, sizeof(Execp));
|
||||||
execp_frontend->backend = execp_backend->backend;
|
execp_frontend->backend = execp_backend->backend;
|
||||||
execp_backend->backend->instances = g_list_append(execp_backend->backend->instances, execp_frontend);
|
execp_backend->backend->instances = g_list_append(execp_backend->backend->instances, execp_frontend);
|
||||||
execp_frontend->frontend = calloc(1, sizeof(ExecpFrontend));
|
execp_frontend->frontend = (ExecpFrontend *)calloc(1, sizeof(ExecpFrontend));
|
||||||
return execp_frontend;
|
return execp_frontend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,16 +73,20 @@ void destroy_execp(void *obj)
|
||||||
imlib_free_image();
|
imlib_free_image();
|
||||||
execp->backend->icon = NULL;
|
execp->backend->icon = NULL;
|
||||||
}
|
}
|
||||||
free_and_null(execp->backend->buf_output);
|
free_and_null(execp->backend->buf_stdout);
|
||||||
free_and_null(execp->backend->text);
|
free_and_null(execp->backend->text);
|
||||||
free_and_null(execp->backend->icon_path);
|
free_and_null(execp->backend->icon_path);
|
||||||
if (execp->backend->child) {
|
if (execp->backend->child) {
|
||||||
kill(-execp->backend->child, SIGHUP);
|
kill(-execp->backend->child, SIGHUP);
|
||||||
execp->backend->child = 0;
|
execp->backend->child = 0;
|
||||||
}
|
}
|
||||||
if (execp->backend->child_pipe >= 0) {
|
if (execp->backend->child_pipe_stdout >= 0) {
|
||||||
close(execp->backend->child_pipe);
|
close(execp->backend->child_pipe_stdout);
|
||||||
execp->backend->child_pipe = -1;
|
execp->backend->child_pipe_stdout = -1;
|
||||||
|
}
|
||||||
|
if (execp->backend->child_pipe_stderr >= 0) {
|
||||||
|
close(execp->backend->child_pipe_stderr);
|
||||||
|
execp->backend->child_pipe_stderr = -1;
|
||||||
}
|
}
|
||||||
if (execp->backend->cmd_pids) {
|
if (execp->backend->cmd_pids) {
|
||||||
g_tree_destroy(execp->backend->cmd_pids);
|
g_tree_destroy(execp->backend->cmd_pids);
|
||||||
|
@ -138,8 +143,10 @@ void init_execp()
|
||||||
// Set missing config options
|
// Set missing config options
|
||||||
if (!execp->backend->bg)
|
if (!execp->backend->bg)
|
||||||
execp->backend->bg = &g_array_index(backgrounds, Background, 0);
|
execp->backend->bg = &g_array_index(backgrounds, Background, 0);
|
||||||
execp->backend->buf_capacity = 1024;
|
execp->backend->buf_stdout_capacity = 1024;
|
||||||
execp->backend->buf_output = calloc(execp->backend->buf_capacity, 1);
|
execp->backend->buf_stdout = calloc(execp->backend->buf_stdout_capacity, 1);
|
||||||
|
execp->backend->buf_stderr_capacity = 1024;
|
||||||
|
execp->backend->buf_stderr = calloc(execp->backend->buf_stderr_capacity, 1);
|
||||||
execp->backend->text = strdup("");
|
execp->backend->text = strdup("");
|
||||||
execp->backend->icon_path = NULL;
|
execp->backend->icon_path = NULL;
|
||||||
}
|
}
|
||||||
|
@ -530,7 +537,7 @@ void execp_dump_geometry(void *obj, int indent)
|
||||||
|
|
||||||
void execp_force_update(Execp *execp)
|
void execp_force_update(Execp *execp)
|
||||||
{
|
{
|
||||||
if (execp->backend->child_pipe > 0) {
|
if (execp->backend->child_pipe_stdout > 0) {
|
||||||
// Command currently running, nothing to do
|
// Command currently running, nothing to do
|
||||||
} else {
|
} else {
|
||||||
if (execp->backend->timer)
|
if (execp->backend->timer)
|
||||||
|
@ -592,32 +599,48 @@ void execp_timer_callback(void *arg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Still running!
|
// Still running!
|
||||||
if (execp->backend->child_pipe > 0)
|
if (execp->backend->child_pipe_stdout > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int pipe_fd[2];
|
int pipe_fd_stdout[2];
|
||||||
if (pipe(pipe_fd)) {
|
if (pipe(pipe_fd_stdout)) {
|
||||||
// TODO maybe write this in tooltip, but if this happens we're screwed anyways
|
// TODO maybe write this in tooltip, but if this happens we're screwed anyways
|
||||||
fprintf(stderr, "Execp: Creating pipe failed!\n");
|
fprintf(stderr, "Execp: Creating pipe failed!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK | fcntl(pipe_fd[0], F_GETFL));
|
fcntl(pipe_fd_stdout[0], F_SETFL, O_NONBLOCK | fcntl(pipe_fd_stdout[0], F_GETFL));
|
||||||
|
|
||||||
|
int pipe_fd_stderr[2];
|
||||||
|
if (pipe(pipe_fd_stderr)) {
|
||||||
|
close(pipe_fd_stdout[1]);
|
||||||
|
close(pipe_fd_stdout[0]);
|
||||||
|
// TODO maybe write this in tooltip, but if this happens we're screwed anyways
|
||||||
|
fprintf(stderr, "Execp: Creating pipe failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fcntl(pipe_fd_stderr[0], F_SETFL, O_NONBLOCK | fcntl(pipe_fd_stderr[0], F_GETFL));
|
||||||
|
|
||||||
// Fork and run command, capturing stdout in pipe
|
// Fork and run command, capturing stdout in pipe
|
||||||
pid_t child = fork();
|
pid_t child = fork();
|
||||||
if (child == -1) {
|
if (child == -1) {
|
||||||
// TODO maybe write this in tooltip, but if this happens we're screwed anyways
|
// TODO maybe write this in tooltip, but if this happens we're screwed anyways
|
||||||
fprintf(stderr, "Fork failed.\n");
|
fprintf(stderr, "Fork failed.\n");
|
||||||
close(pipe_fd[1]);
|
close(pipe_fd_stdout[1]);
|
||||||
close(pipe_fd[0]);
|
close(pipe_fd_stdout[0]);
|
||||||
|
close(pipe_fd_stderr[1]);
|
||||||
|
close(pipe_fd_stderr[0]);
|
||||||
return;
|
return;
|
||||||
} else if (child == 0) {
|
} else if (child == 0) {
|
||||||
fprintf(stderr, "Executing: %s\n", execp->backend->command);
|
fprintf(stderr, "Executing: %s\n", execp->backend->command);
|
||||||
// We are in the child
|
// We are in the child
|
||||||
close(pipe_fd[0]);
|
close(pipe_fd_stdout[0]);
|
||||||
dup2(pipe_fd[1], 1); // 1 is stdout
|
dup2(pipe_fd_stdout[1], 1); // 1 is stdout
|
||||||
close(pipe_fd[1]);
|
close(pipe_fd_stdout[1]);
|
||||||
|
close(pipe_fd_stderr[0]);
|
||||||
|
dup2(pipe_fd_stderr[1], 2); // 2 is stderr
|
||||||
|
close(pipe_fd_stderr[1]);
|
||||||
setpgid(0, 0);
|
setpgid(0, 0);
|
||||||
execl("/bin/sh", "/bin/sh", "-c", execp->backend->command, NULL);
|
execl("/bin/sh", "/bin/sh", "-c", execp->backend->command, NULL);
|
||||||
// This should never happen!
|
// This should never happen!
|
||||||
|
@ -625,39 +648,38 @@ void execp_timer_callback(void *arg)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
close(pipe_fd[1]);
|
close(pipe_fd_stdout[1]);
|
||||||
|
close(pipe_fd_stderr[1]);
|
||||||
execp->backend->child = child;
|
execp->backend->child = child;
|
||||||
execp->backend->child_pipe = pipe_fd[0];
|
execp->backend->child_pipe_stdout = pipe_fd_stdout[0];
|
||||||
execp->backend->buf_length = 0;
|
execp->backend->child_pipe_stderr = pipe_fd_stderr[0];
|
||||||
execp->backend->buf_output[execp->backend->buf_length] = '\0';
|
execp->backend->buf_stdout_length = 0;
|
||||||
|
execp->backend->buf_stdout[execp->backend->buf_stdout_length] = '\0';
|
||||||
|
execp->backend->buf_stderr_length = 0;
|
||||||
|
execp->backend->buf_stderr[execp->backend->buf_stderr_length] = '\0';
|
||||||
execp->backend->last_update_start_time = time(NULL);
|
execp->backend->last_update_start_time = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean read_execp(void *obj)
|
void read_from_pipe(int fd, char **buffer, ssize_t *buffer_length, ssize_t *buffer_capacity, gboolean *eof)
|
||||||
{
|
{
|
||||||
Execp *execp = (Execp *)obj;
|
*eof = FALSE;
|
||||||
|
|
||||||
if (execp->backend->child_pipe < 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
gboolean command_finished = FALSE;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// Make sure there is free space in the buffer
|
// Make sure there is free space in the buffer
|
||||||
if (execp->backend->buf_capacity - execp->backend->buf_length < 1024) {
|
if (*buffer_capacity - *buffer_length < 1024) {
|
||||||
execp->backend->buf_capacity *= 2;
|
*buffer_capacity *= 2;
|
||||||
execp->backend->buf_output = realloc(execp->backend->buf_output, execp->backend->buf_capacity);
|
*buffer = (char *)realloc(*buffer, *buffer_capacity);
|
||||||
}
|
}
|
||||||
ssize_t count = read(execp->backend->child_pipe,
|
ssize_t count = read(fd,
|
||||||
execp->backend->buf_output + execp->backend->buf_length,
|
*buffer + *buffer_length,
|
||||||
execp->backend->buf_capacity - execp->backend->buf_length - 1);
|
*buffer_capacity - *buffer_length - 1);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
// Successful read
|
// Successful read
|
||||||
execp->backend->buf_length += count;
|
*buffer_length += count;
|
||||||
execp->backend->buf_output[execp->backend->buf_length] = '\0';
|
(*buffer)[*buffer_length] = '\0';
|
||||||
continue;
|
continue;
|
||||||
} else if (count == 0) {
|
} else if (count == 0) {
|
||||||
// End of file
|
// End of file
|
||||||
command_finished = TRUE;
|
*eof = TRUE;
|
||||||
break;
|
break;
|
||||||
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||||
// No more data available at the moment
|
// No more data available at the moment
|
||||||
|
@ -667,28 +689,87 @@ gboolean read_execp(void *obj)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// Error
|
// Error
|
||||||
command_finished = TRUE;
|
*eof = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean starts_with(char *s, char *prefix)
|
||||||
|
{
|
||||||
|
char *p, *q;
|
||||||
|
for (p = s, q = prefix; *p && *q; p++, q++) {
|
||||||
|
if (*p != *q)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return *q == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char *last_substring(char *s, char *sub)
|
||||||
|
{
|
||||||
|
char *result = NULL;
|
||||||
|
for (char *p = s; *p; p++) {
|
||||||
|
if (starts_with(p, sub))
|
||||||
|
result = p;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rstrip(char *s)
|
||||||
|
{
|
||||||
|
size_t len = strlen(s);
|
||||||
|
while (len > 0) {
|
||||||
|
if (s[len-1] == ' ' || s[len-1] == '\n') {
|
||||||
|
s[len-1] = 0;
|
||||||
|
len--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean read_execp(void *obj)
|
||||||
|
{
|
||||||
|
Execp *execp = (Execp *)obj;
|
||||||
|
|
||||||
|
if (execp->backend->child_pipe_stdout < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
gboolean stdout_eof, stderr_eof;
|
||||||
|
read_from_pipe(execp->backend->child_pipe_stdout,
|
||||||
|
&execp->backend->buf_stdout,
|
||||||
|
&execp->backend->buf_stdout_length,
|
||||||
|
&execp->backend->buf_stdout_capacity,
|
||||||
|
&stdout_eof);
|
||||||
|
read_from_pipe(execp->backend->child_pipe_stderr,
|
||||||
|
&execp->backend->buf_stderr,
|
||||||
|
&execp->backend->buf_stderr_length,
|
||||||
|
&execp->backend->buf_stderr_capacity,
|
||||||
|
&stderr_eof);
|
||||||
|
|
||||||
|
gboolean command_finished = stdout_eof && stderr_eof;
|
||||||
|
|
||||||
if (command_finished) {
|
if (command_finished) {
|
||||||
execp->backend->child = 0;
|
execp->backend->child = 0;
|
||||||
close(execp->backend->child_pipe);
|
close(execp->backend->child_pipe_stdout);
|
||||||
execp->backend->child_pipe = -1;
|
execp->backend->child_pipe_stdout = -1;
|
||||||
|
close(execp->backend->child_pipe_stderr);
|
||||||
|
execp->backend->child_pipe_stderr = -1;
|
||||||
if (execp->backend->interval)
|
if (execp->backend->interval)
|
||||||
execp->backend->timer =
|
execp->backend->timer =
|
||||||
add_timeout(execp->backend->interval * 1000, 0, execp_timer_callback, execp, &execp->backend->timer);
|
add_timeout(execp->backend->interval * 1000, 0, execp_timer_callback, execp, &execp->backend->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ansi_clear_screen = (char*)"\x1b[2J";
|
||||||
if (!execp->backend->continuous && command_finished) {
|
if (!execp->backend->continuous && command_finished) {
|
||||||
|
// Handle stdout
|
||||||
free_and_null(execp->backend->text);
|
free_and_null(execp->backend->text);
|
||||||
free_and_null(execp->backend->icon_path);
|
free_and_null(execp->backend->icon_path);
|
||||||
if (!execp->backend->has_icon) {
|
if (!execp->backend->has_icon) {
|
||||||
execp->backend->text = strdup(execp->backend->buf_output);
|
execp->backend->text = strdup(execp->backend->buf_stdout);
|
||||||
} else {
|
} else {
|
||||||
char *text = strchr(execp->backend->buf_output, '\n');
|
char *text = strchr(execp->backend->buf_stdout, '\n');
|
||||||
if (text) {
|
if (text) {
|
||||||
*text = '\0';
|
*text = '\0';
|
||||||
text++;
|
text++;
|
||||||
|
@ -696,22 +777,52 @@ gboolean read_execp(void *obj)
|
||||||
} else {
|
} else {
|
||||||
execp->backend->text = strdup("");
|
execp->backend->text = strdup("");
|
||||||
}
|
}
|
||||||
execp->backend->icon_path = strdup(execp->backend->buf_output);
|
execp->backend->icon_path = strdup(execp->backend->buf_stdout);
|
||||||
}
|
}
|
||||||
int len = strlen(execp->backend->text);
|
int len = strlen(execp->backend->text);
|
||||||
if (len > 0 && execp->backend->text[len - 1] == '\n')
|
if (len > 0 && execp->backend->text[len - 1] == '\n')
|
||||||
execp->backend->text[len - 1] = '\0';
|
execp->backend->text[len - 1] = '\0';
|
||||||
execp->backend->buf_length = 0;
|
execp->backend->buf_stdout_length = 0;
|
||||||
execp->backend->buf_output[execp->backend->buf_length] = '\0';
|
execp->backend->buf_stdout[execp->backend->buf_stdout_length] = '\0';
|
||||||
|
// Handle stderr
|
||||||
|
if (!execp->backend->has_user_tooltip) {
|
||||||
|
free_and_null(execp->backend->tooltip);
|
||||||
|
char *start = last_substring(execp->backend->buf_stderr, ansi_clear_screen);
|
||||||
|
if (start)
|
||||||
|
start += strlen(ansi_clear_screen);
|
||||||
|
else
|
||||||
|
start = execp->backend->buf_stderr;
|
||||||
|
execp->backend->tooltip = strdup(start);
|
||||||
|
rstrip(execp->backend->tooltip);
|
||||||
|
}
|
||||||
|
execp->backend->buf_stderr_length = 0;
|
||||||
|
execp->backend->buf_stderr[execp->backend->buf_stderr_length] = '\0';
|
||||||
|
//
|
||||||
execp->backend->last_update_finish_time = time(NULL);
|
execp->backend->last_update_finish_time = time(NULL);
|
||||||
execp->backend->last_update_duration =
|
execp->backend->last_update_duration =
|
||||||
execp->backend->last_update_finish_time - execp->backend->last_update_start_time;
|
execp->backend->last_update_finish_time - execp->backend->last_update_start_time;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else if (execp->backend->continuous > 0) {
|
} else if (execp->backend->continuous > 0) {
|
||||||
|
// Handle stderr
|
||||||
|
if (!execp->backend->has_user_tooltip) {
|
||||||
|
free_and_null(execp->backend->tooltip);
|
||||||
|
char *start = last_substring(execp->backend->buf_stderr, ansi_clear_screen);
|
||||||
|
if (start) {
|
||||||
|
start += strlen(ansi_clear_screen);
|
||||||
|
memmove(execp->backend->buf_stderr, start, strlen(start) + 1);
|
||||||
|
execp->backend->buf_stderr_length = (ssize_t)strlen(execp->backend->buf_stderr);
|
||||||
|
}
|
||||||
|
execp->backend->tooltip = strdup(execp->backend->buf_stderr);
|
||||||
|
rstrip(execp->backend->tooltip);
|
||||||
|
} else {
|
||||||
|
execp->backend->buf_stderr_length = 0;
|
||||||
|
execp->backend->buf_stderr[execp->backend->buf_stderr_length] = '\0';
|
||||||
|
}
|
||||||
|
// Handle stdout
|
||||||
// Count lines in buffer
|
// Count lines in buffer
|
||||||
int num_lines = 0;
|
int num_lines = 0;
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
for (char *c = execp->backend->buf_output; *c; c++) {
|
for (char *c = execp->backend->buf_stdout; *c; c++) {
|
||||||
if (*c == '\n') {
|
if (*c == '\n') {
|
||||||
num_lines++;
|
num_lines++;
|
||||||
if (num_lines == execp->backend->continuous)
|
if (num_lines == execp->backend->continuous)
|
||||||
|
@ -724,9 +835,9 @@ gboolean read_execp(void *obj)
|
||||||
free_and_null(execp->backend->text);
|
free_and_null(execp->backend->text);
|
||||||
free_and_null(execp->backend->icon_path);
|
free_and_null(execp->backend->icon_path);
|
||||||
if (!execp->backend->has_icon) {
|
if (!execp->backend->has_icon) {
|
||||||
execp->backend->text = strdup(execp->backend->buf_output);
|
execp->backend->text = strdup(execp->backend->buf_stdout);
|
||||||
} else {
|
} else {
|
||||||
char *text = strchr(execp->backend->buf_output, '\n');
|
char *text = strchr(execp->backend->buf_stdout, '\n');
|
||||||
if (text) {
|
if (text) {
|
||||||
*text = '\0';
|
*text = '\0';
|
||||||
text++;
|
text++;
|
||||||
|
@ -734,23 +845,23 @@ gboolean read_execp(void *obj)
|
||||||
} else {
|
} else {
|
||||||
execp->backend->text = strdup("");
|
execp->backend->text = strdup("");
|
||||||
}
|
}
|
||||||
execp->backend->icon_path = strdup(execp->backend->buf_output);
|
execp->backend->icon_path = strdup(execp->backend->buf_stdout);
|
||||||
}
|
}
|
||||||
int len = strlen(execp->backend->text);
|
size_t len = strlen(execp->backend->text);
|
||||||
if (len > 0 && execp->backend->text[len - 1] == '\n')
|
if (len > 0 && execp->backend->text[len - 1] == '\n')
|
||||||
execp->backend->text[len - 1] = '\0';
|
execp->backend->text[len - 1] = '\0';
|
||||||
|
|
||||||
if (end) {
|
if (end) {
|
||||||
char *next = end + 1;
|
char *next = end + 1;
|
||||||
int copied = next - execp->backend->buf_output;
|
ssize_t copied = next - execp->backend->buf_stdout;
|
||||||
int remaining = execp->backend->buf_length - copied;
|
ssize_t remaining = execp->backend->buf_stdout_length - copied;
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
memmove(execp->backend->buf_output, next, remaining);
|
memmove(execp->backend->buf_stdout, next, (size_t)remaining);
|
||||||
execp->backend->buf_length = remaining;
|
execp->backend->buf_stdout_length = remaining;
|
||||||
execp->backend->buf_output[execp->backend->buf_length] = '\0';
|
execp->backend->buf_stdout[execp->backend->buf_stdout_length] = '\0';
|
||||||
} else {
|
} else {
|
||||||
execp->backend->buf_length = 0;
|
execp->backend->buf_stdout_length = 0;
|
||||||
execp->backend->buf_output[execp->backend->buf_length] = '\0';
|
execp->backend->buf_stdout[execp->backend->buf_stdout_length] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,7 +910,7 @@ char *execp_get_tooltip(void *obj)
|
||||||
char tmp_buf1[256];
|
char tmp_buf1[256];
|
||||||
char tmp_buf2[256];
|
char tmp_buf2[256];
|
||||||
char tmp_buf3[256];
|
char tmp_buf3[256];
|
||||||
if (execp->backend->child_pipe < 0) {
|
if (execp->backend->child_pipe_stdout < 0) {
|
||||||
// Not executing command
|
// Not executing command
|
||||||
if (execp->backend->last_update_finish_time) {
|
if (execp->backend->last_update_finish_time) {
|
||||||
// We updated at least once
|
// We updated at least once
|
||||||
|
|
|
@ -27,6 +27,7 @@ typedef struct ExecpBackend {
|
||||||
gboolean cache_icon;
|
gboolean cache_icon;
|
||||||
int icon_w;
|
int icon_w;
|
||||||
int icon_h;
|
int icon_h;
|
||||||
|
gboolean has_user_tooltip;
|
||||||
char *tooltip;
|
char *tooltip;
|
||||||
gboolean centered;
|
gboolean centered;
|
||||||
gboolean has_font;
|
gboolean has_font;
|
||||||
|
@ -46,20 +47,24 @@ typedef struct ExecpBackend {
|
||||||
|
|
||||||
// Backend state:
|
// Backend state:
|
||||||
timeout *timer;
|
timeout *timer;
|
||||||
int child_pipe;
|
int child_pipe_stdout;
|
||||||
|
int child_pipe_stderr;
|
||||||
pid_t child;
|
pid_t child;
|
||||||
|
|
||||||
// Command output buffer
|
// Command output buffer
|
||||||
char *buf_output;
|
char *buf_stdout;
|
||||||
int buf_length;
|
ssize_t buf_stdout_length;
|
||||||
int buf_capacity;
|
ssize_t buf_stdout_capacity;
|
||||||
|
char *buf_stderr;
|
||||||
|
ssize_t buf_stderr_length;
|
||||||
|
ssize_t buf_stderr_capacity;
|
||||||
|
|
||||||
// Text extracted from the output buffer
|
// Text extracted from the output buffer
|
||||||
char *text;
|
char *text;
|
||||||
// Icon path extracted from the output buffer
|
// Icon path extracted from the output buffer
|
||||||
char *icon_path;
|
char *icon_path;
|
||||||
Imlib_Image icon;
|
Imlib_Image icon;
|
||||||
char tooltip_text[512];
|
gchar tooltip_text[512];
|
||||||
|
|
||||||
// The time the last command was started
|
// The time the last command was started
|
||||||
time_t last_update_start_time;
|
time_t last_update_start_time;
|
||||||
|
|
|
@ -1832,7 +1832,12 @@ start:
|
||||||
}
|
}
|
||||||
for (GList *l = panel_config.execp_list; l; l = l->next) {
|
for (GList *l = panel_config.execp_list; l; l = l->next) {
|
||||||
Execp *execp = (Execp *)l->data;
|
Execp *execp = (Execp *)l->data;
|
||||||
int fd = execp->backend->child_pipe;
|
int fd = execp->backend->child_pipe_stdout;
|
||||||
|
if (fd > 0) {
|
||||||
|
FD_SET(fd, &fdset);
|
||||||
|
maxfd = maxfd < fd ? fd : maxfd;
|
||||||
|
}
|
||||||
|
fd = execp->backend->child_pipe_stderr;
|
||||||
if (fd > 0) {
|
if (fd > 0) {
|
||||||
FD_SET(fd, &fdset);
|
FD_SET(fd, &fdset);
|
||||||
maxfd = maxfd < fd ? fd : maxfd;
|
maxfd = maxfd < fd ? fd : maxfd;
|
||||||
|
@ -1861,7 +1866,7 @@ start:
|
||||||
if (read_execp(execp)) {
|
if (read_execp(execp)) {
|
||||||
GList *l_instance;
|
GList *l_instance;
|
||||||
for (l_instance = execp->backend->instances; l_instance; l_instance = l_instance->next) {
|
for (l_instance = execp->backend->instances; l_instance; l_instance = l_instance->next) {
|
||||||
Execp *instance = l_instance->data;
|
Execp *instance = (Execp *)l_instance->data;
|
||||||
execp_update_post_read(instance);
|
execp_update_post_read(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue