1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

More fixes to stdout and stderr. When the backlog on either clears, call

the backend's unthrottle function.  If we don't, we'll deadlock.  While
we're here, also pump as much data as possible out during each call to
try_output(), rather than restricting ourselves to a single call to
write().

[originally from svn r7755]
This commit is contained in:
Ben Harris 2007-10-02 21:43:53 +00:00
parent 241c53acea
commit ea9a3bdb7d

View File

@ -384,7 +384,7 @@ void cleanup_termios(void)
bufchain stdout_data, stderr_data;
void try_output(int is_stderr)
int try_output(int is_stderr)
{
bufchain *chain = (is_stderr ? &stderr_data : &stdout_data);
int fd = (is_stderr ? STDERR_FILENO : STDOUT_FILENO);
@ -392,40 +392,36 @@ void try_output(int is_stderr)
int sendlen, ret, fl;
if (bufchain_size(chain) == 0)
return;
return bufchain_size(&stdout_data) + bufchain_size(&stderr_data);
bufchain_prefix(chain, &senddata, &sendlen);
fl = fcntl(fd, F_GETFL);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(fd, F_SETFL, fl | O_NONBLOCK);
ret = write(fd, senddata, sendlen);
do {
bufchain_prefix(chain, &senddata, &sendlen);
ret = write(fd, senddata, sendlen);
if (ret > 0)
bufchain_consume(chain, ret);
} while (ret == sendlen && bufchain_size(chain) != 0);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(fd, F_SETFL, fl);
if (ret > 0)
bufchain_consume(chain, ret);
else if (ret < 0 && errno != EAGAIN) {
if (ret < 0 && errno != EAGAIN) {
perror(is_stderr ? "stderr: write" : "stdout: write");
exit(1);
}
return bufchain_size(&stdout_data) + bufchain_size(&stderr_data);
}
int from_backend(void *frontend_handle, int is_stderr,
const char *data, int len)
{
int osize, esize;
if (is_stderr) {
bufchain_add(&stderr_data, data, len);
try_output(TRUE);
return try_output(TRUE);
} else {
bufchain_add(&stdout_data, data, len);
try_output(FALSE);
return try_output(FALSE);
}
osize = bufchain_size(&stdout_data);
esize = bufchain_size(&stderr_data);
return osize + esize;
}
int from_backend_untrusted(void *frontend_handle, const char *data, int len)
@ -1061,11 +1057,11 @@ int main(int argc, char **argv)
}
if (FD_ISSET(STDOUT_FILENO, &wset)) {
try_output(FALSE);
back->unthrottle(backhandle, try_output(FALSE));
}
if (FD_ISSET(STDERR_FILENO, &wset)) {
try_output(TRUE);
back->unthrottle(backhandle, try_output(TRUE));
}
if ((!connopen || !back->connected(backhandle)) &&