static char * readline_until_enter_or_signal(const char *prompt, int *signal) { char * not_done_reading = ""; fd_set selectset; *signal = 0; #ifdef HAVE_RL_CATCH_SIGNAL rl_catch_signals = 0; #endif rl_callback_handler_install (prompt, rlhandler); FD_ZERO(&selectset); completed_input_string = not_done_reading; while (completed_input_string == not_done_reading) { int has_input = 0, err = 0; while (!has_input) { struct timeval timeout = {0, 100000}; /* 0.1 seconds */ /* [Bug #1552726] Only limit the pause if an input hook has been defined. */ struct timeval *timeoutp = NULL; if (PyOS_InputHook) timeoutp = &timeout; #ifdef HAVE_RL_RESIZE_TERMINAL /* Update readline's view of the window size after SIGWINCH */ if (sigwinch_received) { sigwinch_received = 0; rl_resize_terminal(); } #endif FD_SET(fileno(rl_instream), &selectset); /* select resets selectset if no input was available */ has_input = select(fileno(rl_instream) + 1, &selectset, NULL, NULL, timeoutp); err = errno; if(PyOS_InputHook) PyOS_InputHook(); } if (has_input > 0) { rl_callback_read_char(); } else if (err == EINTR) { int s; PyEval_RestoreThread(_PyOS_ReadlineTState); s = PyErr_CheckSignals(); PyEval_SaveThread(); if (s < 0) { rl_free_line_state(); #if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0700 rl_callback_sigcleanup(); #endif rl_cleanup_after_signal(); rl_callback_handler_remove(); *signal = 1; completed_input_string = NULL; } } } return completed_input_string; }
/** * nmc_cleanup_readline: * * Cleanup readline when nmcli is terminated with a signal. * It makes sure the terminal is not garbled. */ void nmc_cleanup_readline (void) { rl_free_line_state (); rl_cleanup_after_signal (); }