unix: allow tty raw mode to be turned off
This commit is contained in:
parent
e53d125d5c
commit
153d3c7c57
@ -37,7 +37,7 @@
|
|||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
/* Note: May be cast to struct iovec. See writev(2). */
|
/* Note: May be cast to struct iovec. See writev(2). */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -184,6 +184,8 @@ typedef int uv_file;
|
|||||||
#define UV_WORK_PRIVATE_FIELDS \
|
#define UV_WORK_PRIVATE_FIELDS \
|
||||||
eio_req* eio;
|
eio_req* eio;
|
||||||
|
|
||||||
#define UV_TTY_PRIVATE_FIELDS /* empty */
|
#define UV_TTY_PRIVATE_FIELDS \
|
||||||
|
struct termios orig_termios; \
|
||||||
|
int mode;
|
||||||
|
|
||||||
#endif /* UV_UNIX_H */
|
#endif /* UV_UNIX_H */
|
||||||
|
|||||||
@ -34,38 +34,51 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd) {
|
|||||||
uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
|
uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
|
||||||
uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE | UV_WRITABLE);
|
uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE | UV_WRITABLE);
|
||||||
loop->counters.tty_init++;
|
loop->counters.tty_init++;
|
||||||
|
tty->mode = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_tty_set_mode(uv_tty_t* tty, int mode) {
|
int uv_tty_set_mode(uv_tty_t* tty, int mode) {
|
||||||
int fd = tty->fd;
|
int fd = tty->fd;
|
||||||
struct termios orig_termios; /* in order to restore at exit */
|
|
||||||
struct termios raw;
|
struct termios raw;
|
||||||
|
|
||||||
if (tcgetattr(fd, &orig_termios) == -1) goto fatal;
|
if (mode && tty->mode == 0) {
|
||||||
|
/* on */
|
||||||
|
|
||||||
raw = orig_termios; /* modify the original mode */
|
if (tcgetattr(fd, &tty->orig_termios)) {
|
||||||
/* input modes: no break, no CR to NL, no parity check, no strip char,
|
goto fatal;
|
||||||
* no start/stop output control. */
|
}
|
||||||
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
|
||||||
/* output modes */
|
|
||||||
raw.c_oflag |= (ONLCR);
|
|
||||||
/* control modes - set 8 bit chars */
|
|
||||||
raw.c_cflag |= (CS8);
|
|
||||||
/* local modes - echoing off, canonical off, no extended functions,
|
|
||||||
* no signal chars (^Z,^C) */
|
|
||||||
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
|
||||||
/* control chars - set return condition: min number of bytes and timer.
|
|
||||||
* We want read to return every single byte, without timeout. */
|
|
||||||
raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
|
|
||||||
|
|
||||||
/* put terminal in raw mode after flushing */
|
raw = tty->orig_termios;
|
||||||
if (tcsetattr(fd, TCSAFLUSH, &raw) < 0) goto fatal;
|
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
||||||
return 0;
|
raw.c_oflag |= (ONLCR);
|
||||||
|
raw.c_cflag |= (CS8);
|
||||||
|
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
||||||
|
raw.c_cc[VMIN] = 1;
|
||||||
|
raw.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
/* Put terminal in raw mode after flushing */
|
||||||
|
if (tcsetattr(fd, TCSAFLUSH, &raw)) {
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty->mode = 1;
|
||||||
|
return 0;
|
||||||
|
} else if (mode == 0 && tty->mode) {
|
||||||
|
/* off */
|
||||||
|
|
||||||
|
/* Put terminal in original mode after flushing */
|
||||||
|
if (tcsetattr(fd, TCSAFLUSH, &tty->orig_termios)) {
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty->mode = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fatal:
|
fatal:
|
||||||
uv__set_sys_error(tty->loop, ENOTTY);
|
uv__set_sys_error(tty->loop, errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,16 @@ TEST_IMPL(tty) {
|
|||||||
ASSERT(width > 10);
|
ASSERT(width > 10);
|
||||||
ASSERT(height > 10);
|
ASSERT(height > 10);
|
||||||
|
|
||||||
|
/* Turn on raw mode. */
|
||||||
|
r = uv_tty_set_mode(&tty, 1);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* Turn off raw mode. */
|
||||||
|
r = uv_tty_set_mode(&tty, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* TODO check the actual mode! */
|
||||||
|
|
||||||
uv_close((uv_handle_t*)&tty, NULL);
|
uv_close((uv_handle_t*)&tty, NULL);
|
||||||
|
|
||||||
uv_run(loop);
|
uv_run(loop);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user