mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-20 04:28:07 -05:00
uxpty: support SS_EOF, when in pipe mode.
If the child process's standard input is provided by a pipe that's separate from its output channels, we can - and should - honour a request to cause that process to receive input EOF, by closing the output end of that pipe. As usual, we do this by setting a pending-EOF flag and calling try_write, to ensure that any buffered output data is sent before the pipe actually closes.
This commit is contained in:
parent
6b7a1cd1c1
commit
a48e897f26
22
unix/uxpty.c
22
unix/uxpty.c
@ -90,6 +90,7 @@ struct Pty {
|
|||||||
int child_dead, finished;
|
int child_dead, finished;
|
||||||
int exit_code;
|
int exit_code;
|
||||||
bufchain output_data;
|
bufchain output_data;
|
||||||
|
int pending_eof;
|
||||||
Backend backend;
|
Backend backend;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1316,6 +1317,17 @@ static void pty_try_write(Pty *pty)
|
|||||||
bufchain_consume(&pty->output_data, ret);
|
bufchain_consume(&pty->output_data, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pty->pending_eof && bufchain_size(&pty->output_data) == 0) {
|
||||||
|
/* This should only happen if pty->master_i is a pipe that
|
||||||
|
* doesn't alias either output fd */
|
||||||
|
assert(pty->master_i != pty->master_o);
|
||||||
|
assert(pty->master_i != pty->master_e);
|
||||||
|
uxsel_del(pty->master_i);
|
||||||
|
close(pty->master_i);
|
||||||
|
pty->master_i = -1;
|
||||||
|
pty->pending_eof = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
pty_uxsel_setup(pty);
|
pty_uxsel_setup(pty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1326,7 +1338,7 @@ static int pty_send(Backend *be, const char *buf, int len)
|
|||||||
{
|
{
|
||||||
Pty *pty = container_of(be, Pty, backend);
|
Pty *pty = container_of(be, Pty, backend);
|
||||||
|
|
||||||
if (pty->master_i < 0)
|
if (pty->master_i < 0 || pty->pending_eof)
|
||||||
return 0; /* ignore all writes if fd closed */
|
return 0; /* ignore all writes if fd closed */
|
||||||
|
|
||||||
bufchain_add(&pty->output_data, buf, len);
|
bufchain_add(&pty->output_data, buf, len);
|
||||||
@ -1411,6 +1423,14 @@ static void pty_special(Backend *be, SessionSpecialCode code, int arg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (code == SS_EOF) {
|
||||||
|
if (pty->master_i >= 0 && pty->master_i != pty->master_fd) {
|
||||||
|
pty->pending_eof = TRUE;
|
||||||
|
pty_try_write(pty);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int sig = -1;
|
int sig = -1;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user