Skip to content
This repository was archived by the owner on Mar 28, 2018. It is now read-only.

Commit 635f9f8

Browse files
author
Damien Lespiau
committed
shim: Fix stdin handling
We were doing a few things wrong: - The local pty handed out by docker hasn't been configured to do anything special, it's a "default" canonical terminal with the line discipline configured to line buffer input, display a local echo and send signals on ctrl+c, ... - We had ported a bit of code from runv to locally buffer the input on top of the above. Unfortunately that wasn't helping and was intended for something else in runv (telnet client for debugging) So, the strategy to solve the input with cc-shim is as follow: - Configure the local pty in raw mode. The goal here is to just forward the raw content of stdin to the pty allocated for the process inside the VM. The process inside the VM will have the pty there configured as it wishes (canonical Vs raw) and we bypass the treatment of the line discipline on the host side. - We try to read BUFSIZE data on stdin. In raw mode (pty allocation), the read() can return with only 1 byte of data, ie. 1 key press. When using stdin to pipe data to the process, we should benefit from buffering. I've also removed an unnecessary copy between buf and wbuf. Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
1 parent 1d309ea commit 635f9f8

File tree

1 file changed

+25
-42
lines changed

1 file changed

+25
-42
lines changed

shim/shim.c

+25-42
Original file line numberDiff line numberDiff line change
@@ -279,59 +279,31 @@ handle_signals(struct cc_shim *shim) {
279279
void
280280
handle_stdin(struct cc_shim *shim)
281281
{
282-
ssize_t nread;
283-
int ret;
284-
ssize_t len;
285-
static char buf[BUFSIZ-STREAM_HEADER_SIZE] = {0};
286-
static char wbuf[BUFSIZ] = {0};
287-
static bool cr = false;
288-
static bool emit = false;
289-
static int cnt = 0;
290-
char ch;
282+
ssize_t nread;
283+
int ret;
284+
ssize_t len;
285+
static uint8_t buf[BUFSIZ+STREAM_HEADER_SIZE];
291286

292287
if (! shim || shim->proxy_io_fd < 0) {
293288
return;
294289
}
295290

296-
nread = read(STDIN_FILENO , &ch, 1);
291+
nread = read(STDIN_FILENO , buf+STREAM_HEADER_SIZE, BUFSIZ);
297292
if (nread <= 0) {
298293
shim_warning("Error while reading stdin char :%s\n", strerror(errno));
299294
return;
300295
}
301296

302-
if (ch == '\n') {
303-
emit = !cr;
304-
cr = false;
305-
if (emit) {
306-
buf[cnt++] = ch;
307-
}
308-
} else if (ch == '\r') {
309-
emit = true;
310-
cr = true;
311-
buf[cnt++] = '\n';
312-
} else {
313-
cr = false;
314-
buf[cnt++] = ch;
315-
}
316-
if (emit || cnt == (BUFSIZ-STREAM_HEADER_SIZE)) {
317-
len = cnt + STREAM_HEADER_SIZE;
318-
set_big_endian_64 ((uint8_t*)wbuf, shim->io_seq_no);
319-
set_big_endian_32 ((uint8_t*)wbuf + STREAM_HEADER_LENGTH_OFFSET, (uint32_t)len);
320-
strncpy(wbuf + STREAM_HEADER_SIZE, buf, (size_t)cnt);
321-
322-
// TODO: handle write in the poll loop to account for write blocking
323-
ret = (int)write(shim->proxy_io_fd, wbuf, (size_t)len);
324-
if (ret == -1) {
325-
shim_warning("Error writing from fd %d to fd %d: %s\n",
326-
STDIN_FILENO, shim->proxy_io_fd, strerror(errno));
327-
return;
328-
}
297+
len = nread + STREAM_HEADER_SIZE;
298+
set_big_endian_64 (buf, shim->io_seq_no);
299+
set_big_endian_32 (buf + STREAM_HEADER_LENGTH_OFFSET, (uint32_t)len);
329300

330-
memset(buf, 0, BUFSIZ-STREAM_HEADER_SIZE);
331-
memset(wbuf, 0, BUFSIZ);
332-
cnt = 0;
333-
cr = false;
334-
emit = false;
301+
// TODO: handle write in the poll loop to account for write blocking
302+
ret = (int)write(shim->proxy_io_fd, buf, (size_t)len);
303+
if (ret == -1) {
304+
shim_warning("Error writing from fd %d to fd %d: %s\n",
305+
STDIN_FILENO, shim->proxy_io_fd, strerror(errno));
306+
return;
335307
}
336308
}
337309

@@ -685,6 +657,17 @@ main(int argc, char **argv)
685657
* this causes continuous close events to be generated on the poll loop.
686658
*/
687659
if (isatty(STDIN_FILENO)) {
660+
/*
661+
* Set raw mode on the slave side of the PTY. The local pty
662+
* (ie. the one on the host side) is configured in raw mode to
663+
* be a dumb pipe and forward data to the pty on the VM side.
664+
*/
665+
struct termios term_settings;
666+
667+
tcgetattr(STDIN_FILENO, &term_settings);
668+
cfmakeraw(&term_settings);
669+
tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_settings);
670+
688671
add_pollfd(poll_fds, &nfds, STDIN_FILENO, POLLIN | POLLPRI);
689672
}
690673

0 commit comments

Comments
 (0)