qrexec: in write_stdin, remove dependency on write size
Previous code could barf when write was partial; probably can happen only if we increase vchan buffer size, but it is better isolated now.
This commit is contained in:
parent
1d24ef9d1a
commit
7f6a06c354
@ -58,24 +58,30 @@ int flush_client_data(int fd, int clid, struct buffer *buffer)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int write_stdin(int fd, int clid, char *data, int len,
|
int write_stdin(int fd, int clid, char *data, int len,
|
||||||
struct buffer *buffer)
|
struct buffer *buffer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
int written = 0;
|
||||||
|
|
||||||
if (buffer_len(buffer)) {
|
if (buffer_len(buffer)) {
|
||||||
buffer_append(buffer, data, len);
|
buffer_append(buffer, data, len);
|
||||||
return WRITE_STDIN_BUFFERED;
|
return WRITE_STDIN_BUFFERED;
|
||||||
}
|
}
|
||||||
|
while (written < len) {
|
||||||
ret = write(fd, data, len);
|
ret = write(fd, data + written, len - written);
|
||||||
if (ret == len)
|
if (ret == 0) {
|
||||||
return WRITE_STDIN_OK;
|
perror("write_stdin: write returns 0 ???");
|
||||||
if (ret == -1) {
|
exit(1);
|
||||||
if (errno == EAGAIN) {
|
}
|
||||||
|
if (ret == -1) {
|
||||||
struct server_header s_hdr;
|
struct server_header s_hdr;
|
||||||
buffer_append(buffer, data, len);
|
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
return WRITE_STDIN_ERROR;
|
||||||
|
|
||||||
|
buffer_append(buffer, data + written,
|
||||||
|
len - written);
|
||||||
|
|
||||||
s_hdr.type = MSG_XOFF;
|
s_hdr.type = MSG_XOFF;
|
||||||
s_hdr.clid = clid;
|
s_hdr.clid = clid;
|
||||||
@ -83,13 +89,10 @@ int write_stdin(int fd, int clid, char *data, int len,
|
|||||||
write_all_vchan_ext(&s_hdr, sizeof s_hdr);
|
write_all_vchan_ext(&s_hdr, sizeof s_hdr);
|
||||||
|
|
||||||
return WRITE_STDIN_BUFFERED;
|
return WRITE_STDIN_BUFFERED;
|
||||||
} else
|
}
|
||||||
return WRITE_STDIN_ERROR;
|
written += ret;
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"writes < PIPE_BUF were supposed to be atomic ?\n");
|
|
||||||
return WRITE_STDIN_ERROR;
|
|
||||||
}
|
}
|
||||||
|
return WRITE_STDIN_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user