mirror of
https://github.com/clearml/dropbear
synced 2025-04-16 13:31:37 +00:00
Bring back recently removed channel->flushing
This resolves the "sleep 10&echo hello" case which should return immediately
This commit is contained in:
parent
043b0fbd1b
commit
a7ef149463
@ -71,6 +71,9 @@ struct Channel {
|
|||||||
/* whether close/eof messages have been exchanged */
|
/* whether close/eof messages have been exchanged */
|
||||||
int sent_close, recv_close;
|
int sent_close, recv_close;
|
||||||
int recv_eof, sent_eof;
|
int recv_eof, sent_eof;
|
||||||
|
/* once flushing is set, readfd will close once no more data is available
|
||||||
|
(not waiting for EOF) */
|
||||||
|
int flushing;
|
||||||
|
|
||||||
struct dropbear_progress_connection *conn_pending;
|
struct dropbear_progress_connection *conn_pending;
|
||||||
int initconn; /* used for TCP forwarding, whether the channel has been
|
int initconn; /* used for TCP forwarding, whether the channel has been
|
||||||
@ -93,9 +96,9 @@ struct ChanType {
|
|||||||
const char *name;
|
const char *name;
|
||||||
/* Sets up the channel */
|
/* Sets up the channel */
|
||||||
int (*inithandler)(struct Channel*);
|
int (*inithandler)(struct Channel*);
|
||||||
/* Called to check whether a channel should close, separately from the FD being closed.
|
/* Called to check whether a channel should close, separately from the FD being EOF.
|
||||||
Used for noticing process exiting */
|
Used for noticing process exiting */
|
||||||
int (*check_close)(const struct Channel*);
|
int (*check_close)(struct Channel*);
|
||||||
/* Handler for ssh_msg_channel_request */
|
/* Handler for ssh_msg_channel_request */
|
||||||
void (*reqhandler)(struct Channel*);
|
void (*reqhandler)(struct Channel*);
|
||||||
/* Called prior to sending ssh_msg_channel_close, used for sending exit status */
|
/* Called prior to sending ssh_msg_channel_close, used for sending exit status */
|
||||||
|
@ -293,6 +293,19 @@ static void check_close(struct Channel *channel) {
|
|||||||
close_allowed = 1;
|
close_allowed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In flushing mode we close FDs as soon as pipes are empty.
|
||||||
|
This is used to drain out FDs when the process exits, in the case
|
||||||
|
where the FD doesn't have EOF - "sleep 10&echo hello" case */
|
||||||
|
if (channel->flushing) {
|
||||||
|
if (channel->readfd >= 0 && !fd_read_pending(channel->readfd)) {
|
||||||
|
close_chan_fd(channel, channel->readfd, SHUT_RD);
|
||||||
|
}
|
||||||
|
if (ERRFD_IS_READ(channel)
|
||||||
|
&& channel->errfd >= 0 && !fd_read_pending(channel->errfd)) {
|
||||||
|
close_chan_fd(channel, channel->errfd, SHUT_RD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (channel->recv_close && !write_pending(channel) && close_allowed) {
|
if (channel->recv_close && !write_pending(channel) && close_allowed) {
|
||||||
if (!channel->sent_close) {
|
if (!channel->sent_close) {
|
||||||
TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
|
TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
|
||||||
|
19
dbutil.c
19
dbutil.c
@ -715,3 +715,22 @@ void fsync_parent_dir(const char* fn) {
|
|||||||
m_free(fn_dir);
|
m_free(fn_dir);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fd_read_pending(int fd) {
|
||||||
|
fd_set fds;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
DROPBEAR_FD_ZERO(&fds);
|
||||||
|
FD_SET(fd, &fds);
|
||||||
|
while (1) {
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
if (select(fd+1, &fds, NULL, NULL, &timeout) < 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return FD_ISSET(fd, &fds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
dbutil.h
2
dbutil.h
@ -90,6 +90,8 @@ char * expand_homedir_path(const char *inpath);
|
|||||||
|
|
||||||
void fsync_parent_dir(const char* fn);
|
void fsync_parent_dir(const char* fn);
|
||||||
|
|
||||||
|
int fd_read_pending(int fd);
|
||||||
|
|
||||||
#if DROPBEAR_MSAN
|
#if DROPBEAR_MSAN
|
||||||
/* FD_ZERO seems to leave some memory uninitialized. clear it to avoid false positives */
|
/* FD_ZERO seems to leave some memory uninitialized. clear it to avoid false positives */
|
||||||
#define DROPBEAR_FD_ZERO(fds) do { memset((fds), 0x0, sizeof(fd_set)); FD_ZERO(fds); } while(0)
|
#define DROPBEAR_FD_ZERO(fds) do { memset((fds), 0x0, sizeof(fd_set)); FD_ZERO(fds); } while(0)
|
||||||
|
@ -54,7 +54,7 @@ static void closechansess(const struct Channel *channel);
|
|||||||
static void cleanupchansess(const struct Channel *channel);
|
static void cleanupchansess(const struct Channel *channel);
|
||||||
static int newchansess(struct Channel *channel);
|
static int newchansess(struct Channel *channel);
|
||||||
static void chansessionrequest(struct Channel *channel);
|
static void chansessionrequest(struct Channel *channel);
|
||||||
static int sesscheckclose(const struct Channel *channel);
|
static int sesscheckclose(struct Channel *channel);
|
||||||
|
|
||||||
static void send_exitsignalstatus(const struct Channel *channel);
|
static void send_exitsignalstatus(const struct Channel *channel);
|
||||||
static void send_msg_chansess_exitstatus(const struct Channel * channel,
|
static void send_msg_chansess_exitstatus(const struct Channel * channel,
|
||||||
@ -77,9 +77,13 @@ extern char** environ;
|
|||||||
|
|
||||||
/* Returns whether the channel is ready to close. The child process
|
/* Returns whether the channel is ready to close. The child process
|
||||||
must not be running (has never started, or has exited) */
|
must not be running (has never started, or has exited) */
|
||||||
static int sesscheckclose(const struct Channel *channel) {
|
static int sesscheckclose(struct Channel *channel) {
|
||||||
struct ChanSess *chansess = (struct ChanSess*)channel->typedata;
|
struct ChanSess *chansess = (struct ChanSess*)channel->typedata;
|
||||||
TRACE(("sesscheckclose, pid %d, exitpid %d", chansess->pid, chansess->exit.exitpid))
|
TRACE(("sesscheckclose, pid %d, exitpid %d", chansess->pid, chansess->exit.exitpid))
|
||||||
|
|
||||||
|
if (chansess->exit.exitpid != -1) {
|
||||||
|
channel->flushing = 1;
|
||||||
|
}
|
||||||
return chansess->pid == 0 || chansess->exit.exitpid != -1;
|
return chansess->pid == 0 || chansess->exit.exitpid != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user