mirror of
https://github.com/clearml/dropbear
synced 2025-02-08 21:54:13 +00:00
Add some code for testing whether a writefd is closed (by read()ing from it)
--HG-- branch : channel-fix extra : convert_revision : 1dfbc5ef92391d01b576c8506061927869a89887
This commit is contained in:
parent
e1d3a8a6e9
commit
4e09d27c6f
@ -186,6 +186,29 @@ struct Channel* getchannel() {
|
|||||||
return getchannel_msg(NULL);
|
return getchannel_msg(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In order to tell if a writefd is closed, we put it in the readfd FD_SET.
|
||||||
|
We then just try reading a single byte from it. It'll give EAGAIN or something
|
||||||
|
if the socket is still alive (but the FD probably shouldn't be set anyway?)*/
|
||||||
|
static void check_closed_writefd(struct Channel* channel, int fd) {
|
||||||
|
char c;
|
||||||
|
int ret;
|
||||||
|
TRACE(("enter check_closed_writefd fd %d", fd))
|
||||||
|
if (fd < 0) {
|
||||||
|
TRACE(("leave check_closed_writefd."))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read something. doing read(fd,x,0) seems to become a NOP on some platforms */
|
||||||
|
ret = read(fd, &c, 1);
|
||||||
|
TRACE(("ret %d errno %d", ret, errno))
|
||||||
|
if (ret > 0 || (ret < 0 && (errno == EINTR || errno == EAGAIN))) {
|
||||||
|
TRACE(("leave check_closed_writefd"))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
close_chan_fd(channel, fd, SHUT_WR);
|
||||||
|
TRACE(("leave check_closed_writefd after closing %d", fd))
|
||||||
|
}
|
||||||
|
|
||||||
/* Iterate through the channels, performing IO if available */
|
/* Iterate through the channels, performing IO if available */
|
||||||
void channelio(fd_set *readfds, fd_set *writefds) {
|
void channelio(fd_set *readfds, fd_set *writefds) {
|
||||||
|
|
||||||
@ -229,6 +252,16 @@ void channelio(fd_set *readfds, fd_set *writefds) {
|
|||||||
writechannel(channel, channel->errfd, channel->extrabuf);
|
writechannel(channel, channel->errfd, channel->extrabuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check writefds for close, even if we don't have anything
|
||||||
|
to write into them. */
|
||||||
|
if (channel->writefd >= 0) {
|
||||||
|
check_closed_writefd(channel, channel->writefd);
|
||||||
|
}
|
||||||
|
if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0) {
|
||||||
|
check_closed_writefd(channel, channel->errfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* handle any channel closing etc */
|
/* handle any channel closing etc */
|
||||||
check_close(channel);
|
check_close(channel);
|
||||||
|
|
||||||
@ -439,6 +472,16 @@ void setchannelfds(fd_set *readfds, fd_set *writefds) {
|
|||||||
FD_SET(channel->errfd, writefds);
|
FD_SET(channel->errfd, writefds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We also set the writefds for reading, so that we will be notified of close */
|
||||||
|
if (channel->writefd >= 0) {
|
||||||
|
FD_SET(channel->writefd, readfds);
|
||||||
|
}
|
||||||
|
if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0) {
|
||||||
|
FD_SET(channel->errfd, readfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} /* foreach channel */
|
} /* foreach channel */
|
||||||
|
|
||||||
#ifdef USING_LISTENERS
|
#ifdef USING_LISTENERS
|
||||||
|
Loading…
Reference in New Issue
Block a user