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:
parent
241c53acea
commit
ea9a3bdb7d
@ -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)) &&
|
||||
|
Loading…
Reference in New Issue
Block a user