1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-30 14:56:39 +02:00

api: fix truncated process output in hook_process() (closes #266)

This commit is contained in:
Sébastien Helleu
2014-11-22 19:33:48 +01:00
parent 81e337645c
commit 3fac3b1bf9
2 changed files with 78 additions and 1 deletions
+1
View File
@@ -60,6 +60,7 @@ http://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
* core: display time in bare display only if option
weechat.look.buffer_time_format is not an empty string
* core: fix translation of message displayed after /upgrade
* api: fix truncated process output in hook_process() (closes #266)
* api: fix crash when reading config options with NULL value (closes #238)
* irc: use option irc.look.nick_mode_empty to display nick prefix in bar item
"input_prompt"
+77 -1
View File
@@ -1708,7 +1708,7 @@ void
hook_process_child_read (struct t_hook *hook_process, int fd,
int index_buffer, struct t_hook **hook_fd)
{
char buffer[4096];
char buffer[HOOK_PROCESS_BUFFER_SIZE / 8];
int num_read;
if (hook_process->deleted)
@@ -1763,6 +1763,80 @@ hook_process_child_read_stderr_cb (void *arg_hook_process, int fd)
return WEECHAT_RC_OK;
}
/*
* Reads process output from child process until EOF
* (called when the child process has ended).
*/
void
hook_process_child_read_until_eof (struct t_hook *hook_process)
{
struct timeval tv_timeout;
fd_set read_fds, write_fds, except_fds;
int count, fd_stdout, fd_stderr, max_fd, ready;
fd_stdout = HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDOUT]);
fd_stderr = HOOK_PROCESS(hook_process, child_read[HOOK_PROCESS_STDERR]);
/*
* use a counter to prevent any infinite loop
* (if child's output is very very long...)
*/
count = 0;
while (count < 1024)
{
FD_ZERO (&read_fds);
FD_ZERO (&write_fds);
FD_ZERO (&except_fds);
max_fd = -1;
if (HOOK_PROCESS(hook_process, hook_fd[HOOK_PROCESS_STDOUT])
&& ((fcntl (fd_stdout, F_GETFD) != -1) || (errno != EBADF)))
{
FD_SET (fd_stdout, &read_fds);
if (fd_stdout > max_fd)
max_fd = fd_stdout;
}
if (HOOK_PROCESS(hook_process, hook_fd[HOOK_PROCESS_STDERR])
&& ((fcntl (fd_stderr, F_GETFD) != -1) || (errno != EBADF)))
{
FD_SET (fd_stderr, &read_fds);
if (fd_stderr > max_fd)
max_fd = fd_stderr;
}
if (max_fd < 0)
break;
tv_timeout.tv_sec = 0;
tv_timeout.tv_usec = 0;
ready = select (max_fd + 1,
&read_fds, &write_fds, &except_fds,
&tv_timeout);
if (ready <= 0)
break;
if (FD_ISSET(fd_stdout, &read_fds))
{
(void) hook_process_child_read_stdout_cb (
hook_process,
HOOK_PROCESS(hook_process,
child_read[HOOK_PROCESS_STDOUT]));
}
if (FD_ISSET(fd_stderr, &read_fds))
{
(void) hook_process_child_read_stderr_cb (
hook_process,
HOOK_PROCESS(hook_process,
child_read[HOOK_PROCESS_STDERR]));
}
count++;
}
}
/*
* Checks if child process is still alive.
*/
@@ -1804,12 +1878,14 @@ hook_process_timer_cb (void *arg_hook_process, int remaining_calls)
{
/* child terminated normally */
rc = WEXITSTATUS(status);
hook_process_child_read_until_eof (hook_process);
hook_process_send_buffers (hook_process, rc);
unhook (hook_process);
}
else if (WIFSIGNALED(status))
{
/* child terminated by a signal */
hook_process_child_read_until_eof (hook_process);
hook_process_send_buffers (hook_process,
WEECHAT_HOOK_PROCESS_ERROR);
unhook (hook_process);