diff --git a/include/uv.h b/include/uv.h index 98328a22..c9c5c9ab 100644 --- a/include/uv.h +++ b/include/uv.h @@ -624,6 +624,17 @@ int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd); */ int uv_tty_set_mode(uv_tty_t*, int mode); +/* + * Gets the current Window size. On success zero is returned. + */ +int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); + +/* + * Used to detect what type of stream should be used with a given file + * descriptor. Usually this will be used during initialization to guess the + * type of the stdio streams. + */ +uv_handle_type uv_guess_handle(uv_file file); /* * uv_pipe_t is a subclass of uv_stream_t diff --git a/src/unix/tty.c b/src/unix/tty.c index 621d4ae7..88ce52a2 100644 --- a/src/unix/tty.c +++ b/src/unix/tty.c @@ -72,3 +72,43 @@ fatal: int uv_is_tty(uv_file file) { return isatty(file); } + + +int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { + struct winsize ws; + + if (ioctl(tty->fd, TIOCGWINSZ, &ws) < 0) { + uv_err_new(tty->loop, errno); + return -1; + } + + *width = ws.ws_col; + *height = ws.ws_row; + + return 0; +} + + +uv_handle_type uv_guess_handle(uv_file file) { + struct stat s; + + if (file < 0) { + uv_err_new(NULL, EINVAL); /* XXX Need loop? */ + return -1; + } + + if (isatty(file)) { + return UV_TTY; + } + + if (fstat(file, &s)) { + uv_err_new(NULL, errno); /* XXX Need loop? */ + return -1; + } + + if (!S_ISSOCK(s.st_mode) && !S_ISFIFO(s.st_mode)) { + return UV_FILE; + } + + return UV_NAMED_PIPE; +} diff --git a/src/win/tty.c b/src/win/tty.c index c451a99d..dc477c76 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -42,3 +42,15 @@ int uv_is_tty(uv_file file) { int r = GetConsoleMode((HANDLE)_get_osfhandle(file), &result); return r ? 1 : 0; } + + +int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { + assert(0 && "implement me"); + return -1; +} + + +uv_handle_type uv_guess_handle(uv_file file) { + assert(0 && "implement me"); + return UV_UNKNOWN_HANDLE; +} diff --git a/test/test-tty.c b/test/test-tty.c index 4f9fd546..f41c5e54 100644 --- a/test/test-tty.c +++ b/test/test-tty.c @@ -23,10 +23,35 @@ #include "task.h" TEST_IMPL(tty) { + int r, width, height; + uv_tty_t tty; uv_loop_t* loop = uv_default_loop(); + /* + * Not necessarally a problem if this assert goes off. E.G you are piping + * this test to a file. 0 == stdin. + */ ASSERT(uv_is_tty(0) == 1); + r = uv_tty_init(uv_default_loop(), &tty, 0); + ASSERT(r == 0); + + ASSERT(UV_TTY == uv_guess_handle(0)); + + r = uv_tty_get_winsize(&tty, &width, &height); + ASSERT(r == 0); + + printf("width=%d height=%d\n", width, height); + + /* + * Is it a safe assumption that most people have terminals larger than + * 10x10? + */ + ASSERT(width > 10); + ASSERT(height > 10); + + uv_close((uv_handle_t*)&tty, NULL); + uv_run(loop); return 0;