summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2023-01-18 02:00:10 +0000
committerDamien Miller <djm@mindrot.org>2023-01-18 13:21:00 +1100
commit35253af01d8c0ab444c8377402121816e71c71f5 (patch)
tree7c53bab1ad578467d88c0b97032ce35d9724ddd9 /channels.c
parent7d17ea151c0b2519f023bd9cc7f141128833ac47 (diff)
downloadopenssh-git-35253af01d8c0ab444c8377402121816e71c71f5.tar.gz
upstream: when restoring non-blocking mode to stdio fds, restore
exactly the flags that ssh started with and don't just clobber them with zero, as this could also remove the append flag from the set; bz3523; ok dtucker@ OpenBSD-Commit-ID: 1336b03e881db7564a4b66014eb24c5230e9a0c0
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/channels.c b/channels.c
index 981746eb..0d26358c 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.426 2023/01/06 02:47:18 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.427 2023/01/18 02:00:10 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -417,16 +417,19 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
*/
if (rfd != -1 && !isatty(rfd) &&
(val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
+ c->restore_flags[0] = val;
c->restore_block |= CHANNEL_RESTORE_RFD;
set_nonblock(rfd);
}
if (wfd != -1 && !isatty(wfd) &&
(val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
+ c->restore_flags[1] = val;
c->restore_block |= CHANNEL_RESTORE_WFD;
set_nonblock(wfd);
}
if (efd != -1 && !isatty(efd) &&
(val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
+ c->restore_flags[2] = val;
c->restore_block |= CHANNEL_RESTORE_EFD;
set_nonblock(efd);
}
@@ -510,10 +513,16 @@ channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
if (fd == -1)
return 0;
- if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) ||
- (*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) ||
- (*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0))
- (void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */
+ /* restore blocking */
+ if (*fdp == c->rfd &&
+ (c->restore_block & CHANNEL_RESTORE_RFD) != 0)
+ (void)fcntl(*fdp, F_SETFL, c->restore_flags[0]);
+ else if (*fdp == c->wfd &&
+ (c->restore_block & CHANNEL_RESTORE_WFD) != 0)
+ (void)fcntl(*fdp, F_SETFL, c->restore_flags[1]);
+ else if (*fdp == c->efd &&
+ (c->restore_block & CHANNEL_RESTORE_EFD) != 0)
+ (void)fcntl(*fdp, F_SETFL, c->restore_flags[2]);
if (*fdp == c->rfd) {
c->io_want &= ~SSH_CHAN_IO_RFD;