Permalink
Browse files

Merge branch 'new-tty-binding'

  • Loading branch information...
2 parents f5bdce9 + 41d811f commit f63a1f84097c6e81eacc5001c8ffa8458ae1f846 @ry ry committed Sep 27, 2011
View
@@ -32,6 +32,11 @@
'LinkIncremental': 2, # enable incremental linking
},
},
+ 'conditions': [
+ ['OS != "win"', {
+ 'defines': [ 'EV_VERIFY=2' ],
+ }],
+ ]
},
'Release': {
'defines': [ 'NDEBUG' ],
@@ -117,6 +117,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE pipeHandle; \
struct uv_pipe_accept_s* next_pending; \
} uv_pipe_accept_t; \
+ \
typedef struct uv_tcp_accept_s { \
UV_REQ_FIELDS \
SOCKET accept_socket; \
@@ -181,6 +182,31 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { uv_pipe_connection_fields }; \
};
+/* TODO: put the parser states in an union - TTY handles are always */
+/* half-duplex so read-state can safely overlap write-state. */
+#define UV_TTY_PRIVATE_FIELDS \
+ HANDLE handle; \
+ HANDLE read_line_handle; \
+ uv_buf_t read_line_buffer; \
+ HANDLE read_raw_wait; \
+ DWORD original_console_mode; \
+ /* Fields used for translating win */ \
+ /* keystrokes into vt100 characters */ \
+ char last_key[8]; \
+ unsigned char last_key_offset; \
+ unsigned char last_key_len; \
+ INPUT_RECORD last_input_record; \
+ WCHAR last_utf16_high_surrogate; \
+ /* utf8-to-utf16 conversion state */ \
+ unsigned char utf8_bytes_left; \
+ unsigned int utf8_codepoint; \
+ /* eol conversion state */ \
+ unsigned char previous_eol; \
+ /* ansi parser state */ \
+ unsigned char ansi_parser_state; \
+ unsigned char ansi_csi_argc; \
+ unsigned short ansi_csi_argv[4];
+
#define UV_TIMER_PRIVATE_FIELDS \
RB_ENTRY(uv_timer_s) tree_entry; \
int64_t due; \
@@ -273,8 +299,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
int is_path_dir; \
char* buffer;
-#define UV_TTY_PRIVATE_FIELDS /* empty */
-
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
View
@@ -67,6 +67,7 @@ static uv_ares_task_t* uv__ares_task_create(int fd) {
if (h == NULL) {
uv_fatal_error(ENOMEM, "malloc");
+ return NULL;
}
h->sock = fd;
View
@@ -149,19 +149,20 @@ static int uv__fs_after(eio_req* eio) {
case UV_FS_READLINK:
if (req->result == -1) {
req->ptr = NULL;
- } else {
- assert(req->result > 0);
-
- if ((name = realloc(req->eio->ptr2, req->result + 1)) == NULL) {
- /* Not enough memory. Reuse buffer, chop off last byte. */
- name = req->eio->ptr2;
- req->result--;
- }
+ break;
+ }
+ assert(req->result > 0);
+ /* Make zero-terminated copy of req->eio->ptr2 */
+ if ((req->ptr = name = malloc(req->result + 1))) {
+ memcpy(name, req->eio->ptr2, req->result);
name[req->result] = '\0';
- req->ptr = name;
req->result = 0;
}
+ else {
+ req->errorno = ENOMEM;
+ req->result = -1;
+ }
break;
default:
View
@@ -301,6 +301,7 @@ static int uv__udp_bind(uv_udp_t* handle,
saved_errno = errno;
status = -1;
+ fd = -1;
/* Check for bad flags. */
if (flags & ~UV_UDP_IPV6ONLY) {
View
@@ -48,6 +48,9 @@ static void uv_init(void) {
/* Initialize FS */
uv_fs_init();
+
+ /* Initialize console */
+ uv_console_init();
}
View
@@ -20,11 +20,36 @@
*/
#include <assert.h>
+#include <io.h>
#include "uv.h"
#include "internal.h"
+uv_handle_type uv_guess_handle(uv_file file) {
+ HANDLE handle = (HANDLE) _get_osfhandle(file);
+ DWORD mode;
+
+ switch (GetFileType(handle)) {
+ case FILE_TYPE_CHAR:
+ if (GetConsoleMode(handle, &mode)) {
+ return UV_TTY;
+ } else {
+ return UV_UNKNOWN_HANDLE;
+ }
+
+ case FILE_TYPE_PIPE:
+ return UV_NAMED_PIPE;
+
+ case FILE_TYPE_DISK:
+ return UV_FILE;
+
+ default:
+ return UV_UNKNOWN_HANDLE;
+ }
+}
+
+
int uv_is_active(uv_handle_t* handle) {
switch (handle->type) {
case UV_TIMER:
@@ -80,6 +105,10 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
}
return;
+ case UV_TTY:
+ uv_tty_close((uv_tty_t*) handle);
+ return;
+
case UV_UDP:
udp = (uv_udp_t*) handle;
uv_udp_recv_stop(udp);
@@ -159,6 +188,10 @@ void uv_process_endgames(uv_loop_t* loop) {
uv_pipe_endgame(loop, (uv_pipe_t*) handle);
break;
+ case UV_TTY:
+ uv_tty_endgame(loop, (uv_tty_t*) handle);
+ break;
+
case UV_UDP:
uv_udp_endgame(loop, (uv_udp_t*) handle);
break;
View
@@ -64,6 +64,7 @@ void uv_process_timers(uv_loop_t* loop);
#define UV_HANDLE_UV_ALLOCED 0x20000
#define UV_HANDLE_SYNC_BYPASS_IOCP 0x40000
#define UV_HANDLE_ZERO_READ 0x80000
+#define UV_HANDLE_TTY_RAW 0x100000
void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle);
void uv_process_endgames(uv_loop_t* loop);
@@ -173,6 +174,33 @@ void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_shutdown_t* req);
+
+/*
+ * TTY
+ */
+void uv_console_init();
+
+int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb);
+int uv_tty_read_stop(uv_tty_t* handle);
+int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
+ uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
+void uv_tty_close(uv_tty_t* handle);
+
+void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* req);
+void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_write_t* req);
+/* TODO: remove me */
+void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* raw_req);
+/* TODO: remove me */
+void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_connect_t* req);
+
+void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle);
+
+
/*
* Loop watchers
*/
View
@@ -231,6 +231,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (result) {
/* Mark the handle as shut now to avoid going through this again. */
handle->flags |= UV_HANDLE_SHUT;
+ return;
} else {
/* Failure. */
@@ -678,6 +679,8 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
/* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(loop, req);
+
+ handle->flags |= UV_HANDLE_READ_PENDING;
handle->reqs_pending++;
return;
}
View
@@ -87,6 +87,12 @@ static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {
req); \
break; \
\
+ case UV_TTY: \
+ uv_process_tty_##method##_req(loop, \
+ (uv_tty_t*) ((req)->handle_at), \
+ req); \
+ break; \
+ \
default: \
assert(0); \
} \
View
@@ -83,6 +83,8 @@ int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
case UV_NAMED_PIPE:
return uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb);
+ case UV_TTY:
+ return uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb);
default:
assert(0);
return -1;
@@ -91,9 +93,12 @@ int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
int uv_read_stop(uv_stream_t* handle) {
- handle->flags &= ~UV_HANDLE_READING;
-
- return 0;
+ if (handle->type = UV_TTY) {
+ return uv_tty_read_stop((uv_tty_t*) handle);
+ } else {
+ handle->flags &= ~UV_HANDLE_READING;
+ return 0;
+ }
}
@@ -106,6 +111,8 @@ int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
return uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
case UV_NAMED_PIPE:
return uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, bufcnt, cb);
+ case UV_TTY:
+ return uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, bufcnt, cb);
default:
assert(0);
uv_set_sys_error(loop, WSAEINVAL);
View
@@ -128,7 +128,9 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
}
handle->shutdown_req->cb(handle->shutdown_req, status);
}
- handle->reqs_pending--;
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+ return;
}
if (handle->flags & UV_HANDLE_CLOSING &&
Oops, something went wrong.

0 comments on commit f63a1f8

Please sign in to comment.