void *init_stdio_handle(uv_file fd,int readable) { void *handle; uv_handle_type type = uv_guess_handle(fd); switch(type) { case UV_TTY: handle = malloc(sizeof(uv_tty_t)); uv_tty_init(jl_io_loop,(uv_tty_t*)handle,fd,readable); ((uv_tty_t*)handle)->data=0; uv_tty_set_mode((void*)handle,0); //cooked stdio break; case UV_NAMED_PIPE: case UV_FILE: handle = malloc(sizeof(uv_pipe_t)); uv_pipe_init(jl_io_loop, (uv_pipe_t*)handle,(readable?UV_PIPE_READABLE:UV_PIPE_WRITEABLE)); uv_pipe_open((uv_pipe_t*)handle,fd); ((uv_pipe_t*)handle)->data=0; break; case UV_TCP: case UV_UDP: default: handle=NULL; jl_errorf("This type of handle for stdio is not yet supported (%d)!\n",type); break; } return handle; }
DLLEXPORT void jl_close_uv(uv_handle_t *handle) { if (handle->type==UV_TTY) uv_tty_set_mode((uv_tty_t*)handle,0); if ((handle->type == UV_NAMED_PIPE || handle->type == UV_TCP) && uv_is_writable((uv_stream_t*)handle)) { uv_shutdown_t *req = (uv_shutdown_t*)malloc(sizeof(uv_shutdown_t)); req->data = 0; /* * We are explicity ignoring the error here for the following reason: * There is only two scenarios in which this returns an error: * a) In case the stream is already shut down, in which case we're likely * in the process of closing this stream (since there's no other call to * uv_shutdown). * b) In case the stream is already closed, in which case uv_close would * cause an assertion failure. */ uv_shutdown(req, (uv_stream_t*)handle, &jl_uv_shutdownCallback); } else if (handle->type == UV_FILE) { uv_fs_t req; jl_uv_file_t *fd = (jl_uv_file_t*)handle; if (fd->file != -1) { uv_fs_close(handle->loop, &req, fd->file, NULL); fd->file = -1; } } else if (!uv_is_closing((uv_handle_t*)handle)) { uv_close(handle,&jl_uv_closeHandle); } }
void jl_prep_terminal(int meta_flag) { FILE *rl_in = rl_instream; rl_instream = stdin; rl_prep_terminal(1); rl_instream = rl_in; #ifdef __WIN32__ if (jl_uv_stdin->type == UV_TTY) uv_tty_set_mode((uv_tty_t*)jl_uv_stdin,1); //raw (and libuv-processed) if (!repl_sigint_handler_installed) { if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)repl_sigint_handler,1)) repl_sigint_handler_installed = 1; } #else if (jl_sigint_act.sa_sigaction == NULL) { struct sigaction oldact, repl_sigint_act; memset(&repl_sigint_act, 0, sizeof(struct sigaction)); sigemptyset(&repl_sigint_act.sa_mask); repl_sigint_act.sa_sigaction = repl_sigint_handler; repl_sigint_act.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &repl_sigint_act, &oldact) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } if (repl_sigint_act.sa_sigaction != oldact.sa_sigaction && jl_sigint_act.sa_sigaction != oldact.sa_sigaction) jl_sigint_act = oldact; } #endif }
DLLEXPORT void jl_close_uv(uv_handle_t *handle) { if (!handle || uv_is_closing(handle)) return; if (handle->type==UV_TTY) uv_tty_set_mode((uv_tty_t*)handle,0); if ( (handle->type == UV_NAMED_PIPE || handle->type == UV_TCP) && uv_is_writable( (uv_stream_t *) handle)) { // Make sure that the stream has not already been marked closed in Julia. // A double shutdown would cause the process to hang on exit. JULIA_CB(isopen, handle->data, 0); if (!jl_is_int32(ret)) { jl_error("jl_close_uv: _uv_hook_isopen must return an int32."); } if (!jl_unbox_int32(ret)){ return; } uv_shutdown_t *req = malloc(sizeof(uv_shutdown_t)); int err = uv_shutdown(req, (uv_stream_t*)handle, &shutdownCallback); if (err != 0) { printf("shutdown err: %s\n", uv_strerror(uv_last_error(jl_global_event_loop()))); uv_close(handle, &closeHandle); } } else { uv_close(handle,&closeHandle); } }
static int luv_tty_set_mode(lua_State* L) { uv_tty_t* handle = luv_check_tty(L, 1); int mode = luaL_checkinteger(L, 2); int ret = uv_tty_set_mode(handle, mode); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; }
DLLEXPORT void jl_close_uv(uv_handle_t *handle) { if (!handle) return; if (handle->type==UV_TTY) uv_tty_set_mode((uv_tty_t*)handle,0); uv_close(handle,&closeHandle); }
JL_DLLEXPORT int jl_tty_set_mode(uv_tty_t *handle, int mode) { if (handle->type != UV_TTY) return 0; uv_tty_mode_t mode_enum = UV_TTY_MODE_NORMAL; if (mode) mode_enum = UV_TTY_MODE_RAW; return uv_tty_set_mode(handle, mode_enum); }
SCM TTY::SetMode(SCM id, SCM mode){ assert_object_type(id); CheckArgType(mode, scm_integer_p, "tty-set-mode", 2); TTY * t = (TTY *)get_object(id); assert(t!=NULL); int r = uv_tty_set_mode(GetHandle(t), scm_to_int(mode)); if(r) Logger::Err("uv_tty_set_mode failed! : %d", r); return id; }
/* Restore the terminal's normal settings and modes. */ void jl_deprep_terminal () { FILE *rl_in = rl_instream; rl_instream = stdin; rl_deprep_terminal(); rl_instream = rl_in; #ifdef __WIN32__ if (jl_uv_stdin->type == UV_TTY) uv_tty_set_mode((uv_tty_t*)jl_uv_stdin,0); // cooked #endif }
JL_DLLEXPORT void jl_close_uv(uv_handle_t *handle) { if (handle->type == UV_FILE) { uv_fs_t req; jl_uv_file_t *fd = (jl_uv_file_t*)handle; if (fd->file != -1) { uv_fs_close(handle->loop, &req, fd->file, NULL); fd->file = -1; } jl_uv_closeHandle(handle); // synchronous (ok since the callback is known to not interact with any global state) return; } if (handle->type == UV_NAMED_PIPE || handle->type == UV_TCP) { #ifdef _OS_WINDOWS_ if (((uv_stream_t*)handle)->stream.conn.shutdown_req) { #else if (((uv_stream_t*)handle)->shutdown_req) { #endif // don't close the stream while attempting a graceful shutdown return; } if (uv_is_writable((uv_stream_t*)handle)) { // attempt graceful shutdown of writable streams to give them a chance to flush first uv_shutdown_t *req = (uv_shutdown_t*)malloc(sizeof(uv_shutdown_t)); req->data = 0; /* * We are explicitly ignoring the error here for the following reason: * There is only two scenarios in which this returns an error: * a) In case the stream is already shut down, in which case we're likely * in the process of closing this stream (since there's no other call to * uv_shutdown). * b) In case the stream is already closed, in which case uv_close would * cause an assertion failure. */ uv_shutdown(req, (uv_stream_t*)handle, &jl_uv_shutdownCallback); return; } } if (!uv_is_closing((uv_handle_t*)handle)) { // avoid double-closing the stream if (handle->type == UV_TTY) uv_tty_set_mode((uv_tty_t*)handle, UV_TTY_MODE_NORMAL); uv_close(handle, &jl_uv_closeHandle); } } JL_DLLEXPORT void jl_forceclose_uv(uv_handle_t *handle) { uv_close(handle,&jl_uv_closeHandle); }
int luv_tty_set_mode(lua_State* L) { int before = lua_gettop(L); uv_tty_t* handle = (uv_tty_t*)luv_checkudata(L, 1, "tty"); int mode = luaL_checkint(L, 2); if (uv_tty_set_mode(handle, mode)) { uv_err_t err = uv_last_error(uv_default_loop()); return luaL_error(L, "tcp_set_mode: %s", uv_strerror(err)); } assert(lua_gettop(L) == before); return 0; }
int main() { loop = uv_default_loop(); uv_tty_init(loop, &tty, 1, 0); uv_tty_set_mode(&tty, 0); if (uv_tty_get_winsize(&tty, &width, &height)) { fprintf(stderr, "Could not get TTY information\n"); uv_tty_reset_mode(); return 1; } fprintf(stderr, "Width %d, height %d\n", width, height); uv_timer_init(loop, &tick); uv_timer_start(&tick, update, 200, 200); return uv_run(loop, UV_RUN_DEFAULT); }
DLLEXPORT void jl_close_uv(uv_handle_t *handle) { if (handle->type==UV_TTY) uv_tty_set_mode((uv_tty_t*)handle,0); if ((handle->type == UV_NAMED_PIPE || handle->type == UV_TCP) && uv_is_writable((uv_stream_t*)handle)) { // Make sure that the stream has not already been marked closed in Julia. // A double shutdown would cause the process to hang on exit. if (handle->data) { JULIA_CB(isopen, handle->data, 0); if (!jl_is_int32(ret)) { jl_error("jl_close_uv: _uv_hook_isopen must return an int32."); } if (!jl_unbox_int32(ret)){ return; } } uv_shutdown_t *req = (uv_shutdown_t*)malloc(sizeof(uv_shutdown_t)); req->data = 0; /* * We are explicity ignoring the error here for the following reason: * There is only two scenarios in which this returns an error: * a) In case the stream is already shut down, in which case we're likely * in the process of closing this stream (since there's no other call to * uv_shutdown). * b) In case the stream is already closed, in which case uv_close would * cause an assertion failure. */ uv_shutdown(req, (uv_stream_t*)handle, &jl_uv_shutdownCallback); } else if (handle->type == UV_FILE) { uv_fs_t req; jl_uv_file_t *fd = (jl_uv_file_t*)handle; if (fd->file != -1) { uv_fs_close(handle->loop, &req, fd->file, NULL); fd->file = -1; } } else if (!uv_is_closing((uv_handle_t*)handle)) { uv_close(handle,&jl_uv_closeHandle); } }
void *init_stdio_handle(uv_file fd,int readable) { void *handle; uv_handle_type type = uv_guess_handle(fd); //printf("%d: %d -- %d\n", fd, type); switch(type) { case UV_TTY: handle = malloc(sizeof(uv_tty_t)); if (uv_tty_init(jl_io_loop,(uv_tty_t*)handle,fd,readable)) { jl_errorf("Error initializing stdio in uv_tty_init (%d, %d)\n", fd, type); abort(); } ((uv_tty_t*)handle)->data=0; uv_tty_set_mode((void*)handle,0); //cooked stdio break; case UV_FILE: #ifdef _WIN32 jl_errorf("This type of handle for stdio is not yet supported on Windows (%d, %d)!\n", fd, type); handle = NULL; break; #endif case UV_NAMED_PIPE: handle = malloc(sizeof(uv_pipe_t)); if (uv_pipe_init(jl_io_loop, (uv_pipe_t*)handle, (readable?UV_PIPE_READABLE:UV_PIPE_WRITEABLE))) { jl_errorf("Error initializing stdio in uv_pipe_init (%d, %d)\n", fd, type); abort(); } if (uv_pipe_open((uv_pipe_t*)handle,fd)) { jl_errorf("Error initializing stdio in uv_pipe_open (%d, %d)\n", fd, type); abort(); } ((uv_pipe_t*)handle)->data=0; break; case UV_TCP: case UV_UDP: default: jl_errorf("This type of handle for stdio is not yet supported (%d, %d)!\n", fd, type); handle = NULL; break; } return handle; }
static PyObject * TTY_func_set_mode(TTY *self, PyObject *args) { int r, mode; RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL); if (!PyArg_ParseTuple(args, "i:set_mode", &mode)) { return NULL; } r = uv_tty_set_mode((uv_tty_t *)UV_HANDLE(self), mode); if (r != 0) { RAISE_UV_EXCEPTION(UV_HANDLE_LOOP(self), PyExc_TTYError); return NULL; } Py_RETURN_NONE; }
int main(int argc, char **argv) { if (!owns_tty()) { fprintf(stderr, "process does not own the terminal\n"); exit(2); } if (!is_terminal(stdin)) { fprintf(stderr, "stdin is not a terminal\n"); exit(2); } if (!is_terminal(stdout)) { fprintf(stderr, "stdout is not a terminal\n"); exit(2); } if (!is_terminal(stderr)) { fprintf(stderr, "stderr is not a terminal\n"); exit(2); } if (argc > 1) { errno = 0; int count = (int)strtol(argv[1], NULL, 10); if (errno != 0) { abort(); } count = (count < 0 || count > 99999) ? 0 : count; for (int i = 0; i < count; i++) { printf("line%d\n", i); } fflush(stdout); return 0; } int interrupted = 0; uv_prepare_t prepare; uv_prepare_init(uv_default_loop(), &prepare); uv_prepare_start(&prepare, prepare_cb); #ifndef WIN32 uv_tty_init(uv_default_loop(), &tty, fileno(stderr), 1); #else uv_tty_init(uv_default_loop(), &tty, fileno(stdin), 1); uv_tty_init(uv_default_loop(), &tty_out, fileno(stdout), 0); int width, height; uv_tty_get_winsize(&tty_out, &width, &height); #endif uv_tty_set_mode(&tty, UV_TTY_MODE_RAW); tty.data = &interrupted; uv_read_start(STRUCT_CAST(uv_stream_t, &tty), alloc_cb, read_cb); #ifndef WIN32 struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = sig_handler; sigaction(SIGHUP, &sa, NULL); sigaction(SIGWINCH, &sa, NULL); #else uv_signal_t sigwinch_watcher; uv_signal_init(uv_default_loop(), &sigwinch_watcher); uv_signal_start(&sigwinch_watcher, sigwinch_cb, SIGWINCH); #endif uv_run(uv_default_loop(), UV_RUN_DEFAULT); #ifndef WIN32 // XXX: Without this the SIGHUP handler is skipped on some systems. sleep(100); #endif return 0; }
extern "C" int rust_uv_tty_set_mode(uv_tty_t *tty, int mode) { return uv_tty_set_mode(tty, mode); }
JL_DLLEXPORT int jl_tty_set_mode(uv_tty_t *handle, int mode) { if (handle->type != UV_TTY) return 0; return uv_tty_set_mode(handle, mode); }
void *init_stdio_handle(uv_file fd,int readable) { void *handle; uv_handle_type type = uv_guess_handle(fd); jl_uv_file_t *file; #ifndef _OS_WINDOWS_ // Duplicate the file descritor so we can later dup it over if we want to redirect // STDIO without having to worry about closing the associated libuv object. // On windows however, libuv objects remember streams by their HANDLE, so this is // unnessecary. fd = dup(fd); #endif //printf("%d: %d -- %d\n", fd, type); switch(type) { case UV_TTY: handle = malloc(sizeof(uv_tty_t)); if (uv_tty_init(jl_io_loop,(uv_tty_t*)handle,fd,readable)) { jl_errorf("Error initializing stdio in uv_tty_init (%d, %d)\n", fd, type); abort(); } ((uv_tty_t*)handle)->data=0; uv_tty_set_mode((void*)handle,0); //cooked stdio break; case UV_FILE: file = malloc(sizeof(jl_uv_file_t)); file->loop = jl_io_loop; file->type = UV_FILE; file->file = fd; file->data = 0; handle = file; break; case UV_NAMED_PIPE: handle = malloc(sizeof(uv_pipe_t)); if (uv_pipe_init(jl_io_loop, (uv_pipe_t*)handle, (readable?UV_PIPE_READABLE:UV_PIPE_WRITABLE))) { jl_errorf("Error initializing stdio in uv_pipe_init (%d, %d)\n", fd, type); abort(); } if (uv_pipe_open((uv_pipe_t*)handle,fd)) { jl_errorf("Error initializing stdio in uv_pipe_open (%d, %d)\n", fd, type); abort(); } ((uv_pipe_t*)handle)->data=0; break; case UV_TCP: handle = malloc(sizeof(uv_tcp_t)); if (uv_tcp_init(jl_io_loop, (uv_tcp_t*)handle)) { jl_errorf("Error initializing stdio in uv_tcp_init (%d, %d)\n", fd, type); abort(); } if (uv_tcp_open((uv_tcp_t*)handle,fd)) { jl_errorf("Error initializing stdio in uv_tcp_open (%d, %d)\n", fd, type); abort(); } ((uv_tcp_t*)handle)->data=0; break; case UV_UDP: default: jl_errorf("This type of handle for stdio is not yet supported (%d, %d)!\n", fd, type); handle = NULL; break; } return handle; }