From: Ján Kupec Date: Fri, 29 Oct 2010 13:08:15 +0000 (+0200) Subject: clear keyboard buffer before prompt (bnc #649248) X-Git-Tag: 1.5.2~16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8cb41e7c57f04744e215e9d631b52146eeae81c5;p=platform%2Fupstream%2Fzypper.git clear keyboard buffer before prompt (bnc #649248) - console.h added - readline_get_line & get_screen_width moved to console.h - some cleanup --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e65813..b0a263b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,7 @@ SET( zypper_out_SRCS SET( zypper_utils_HEADERS utils/Augeas.h utils/colors.h + utils/console.h utils/getopt.h utils/messages.h utils/misc.h @@ -79,6 +80,7 @@ SET( zypper_utils_HEADERS SET( zypper_utils_SRCS utils/Augeas.cc utils/colors.cc + utils/console.cc utils/getopt.cc utils/messages.cc utils/misc.cc diff --git a/src/Table.cc b/src/Table.cc index 266cd19..1cd87ae 100644 --- a/src/Table.cc +++ b/src/Table.cc @@ -4,7 +4,7 @@ #include "zypp/base/Logger.h" -#include "utils/misc.h" +#include "utils/console.h" #include "utils/text.h" #include "Table.h" diff --git a/src/callbacks/keyring.h b/src/callbacks/keyring.h index 929db82..824cf77 100644 --- a/src/callbacks/keyring.h +++ b/src/callbacks/keyring.h @@ -188,6 +188,8 @@ namespace zypp // translators: help text for the 'a' option in the 'r/t/a' prompt popts.setOptionHelp(2, _("Trust the key and import it into trusted keyring.")); + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); zypper.out().prompt(PROMPT_YN_GPG_KEY_TRUST, s.str(), popts); unsigned prep = get_prompt_reply(zypper, PROMPT_YN_GPG_KEY_TRUST, popts); diff --git a/src/callbacks/media.cc b/src/callbacks/media.cc index 13c449a..ea34088 100644 --- a/src/callbacks/media.cc +++ b/src/callbacks/media.cc @@ -7,13 +7,13 @@ #include #include -#include +#include // for getpass #include "callbacks/media.h" -#include "utils/misc.h" #include "utils/messages.h" #include "utils/prompt.h" +#include "utils/misc.h" // for is_changeable_media #include "zypp/media/MediaManager.h" @@ -78,6 +78,8 @@ request_medium_https_handler(Zypper & zypper, Url & url) set_common_option_help(popts); popts.setOptionHelp(4, _("Disable SSL certificate authority check and continue.")); + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); // translators: this is a prompt text zypper.out().prompt(PROMPT_ARI_MEDIA_PROBLEM, _("Abort, retry, ignore?"), popts); int reply = get_prompt_reply(zypper, PROMPT_ARI_MEDIA_PROBLEM, popts); @@ -136,6 +138,8 @@ static void eject_drive_dialog( int devcount = devices.size(); PromptOptions popts(numbers.str(), 0); popts.setOptionHelp(devcount, _("Cancel")); + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); zypper.out().prompt(PROMPT_MEDIA_EJECT, _("Select device to eject."), popts); int reply = get_prompt_reply(zypper, PROMPT_MEDIA_EJECT, popts); if (reply == devcount) @@ -175,6 +179,8 @@ request_medium_dvd_handler( set_common_option_help(popts); popts.setOptionHelp(4, _("Eject medium.")); + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); // translators: this is a prompt text zypper.out().prompt(PROMPT_ARI_MEDIA_PROBLEM, _("Abort, retry, ignore?"), popts); int reply = get_prompt_reply(zypper, PROMPT_ARI_MEDIA_PROBLEM, popts); @@ -256,6 +262,8 @@ ZmartRecipients::MediaChangeReportReceiver::requestMedia( PromptOptions popts(_("a/r/i/u"), 0); set_common_option_help(popts); + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); // translators: this is a prompt text zypper.out().prompt(PROMPT_ARI_MEDIA_PROBLEM, _("Abort, retry, ignore?"), popts); int reply = get_prompt_reply(zypper, PROMPT_ARI_MEDIA_PROBLEM, popts); @@ -341,7 +349,7 @@ bool ZmartRecipients::AuthenticationReportReceiver::prompt( if (zypper.globalOpts().machine_readable) cin >> password; else - password = getpass(""); + password = ::getpass(""); if (password.empty()) return false; auth_data.setPassword(password); diff --git a/src/output/OutNormal.cc b/src/output/OutNormal.cc index c52adc6..3ec31d4 100644 --- a/src/output/OutNormal.cc +++ b/src/output/OutNormal.cc @@ -6,6 +6,7 @@ \*---------------------------------------------------------------------------*/ #include +#include #include #include @@ -20,11 +21,7 @@ #include "OutNormal.h" -using std::cout; -using std::cerr; -using std::endl; -using std::string; -using std::ostringstream; +using namespace std; OutNormal::OutNormal(Verbosity verbosity) : Out(TYPE_NORMAL, verbosity), diff --git a/src/solve-commit.cc b/src/solve-commit.cc index 9dfd66d..c511956 100755 --- a/src/solve-commit.cc +++ b/src/solve-commit.cc @@ -115,6 +115,8 @@ static TriBool show_problem (Zypper & zypper, popts.setOptions(numbers.str() + _("c"), default_reply); } + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); zypper.out().prompt(PROMPT_DEP_RESOLVE, prompt_text, popts, desc_stm.str()); unsigned int reply = get_prompt_reply(zypper, PROMPT_DEP_RESOLVE, popts); @@ -481,6 +483,8 @@ static void show_update_messages(Zypper & zypper, const UpdateNotifications & me string prompt_text = _("View the notifications now?"); unsigned int reply; + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); zypper.out().prompt(PROMPT_YN_INST_REMOVE_CONTINUE, prompt_text, popts); reply = get_prompt_reply(zypper, PROMPT_YN_INST_REMOVE_CONTINUE, popts); @@ -661,6 +665,8 @@ void solve_and_commit (Zypper & zypper) unsigned int reply; do { + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); zypper.out().prompt(PROMPT_YN_INST_REMOVE_CONTINUE, prompt_text, popts); reply = get_prompt_reply(zypper, PROMPT_YN_INST_REMOVE_CONTINUE, popts); diff --git a/src/utils/console.cc b/src/utils/console.cc new file mode 100644 index 0000000..387f39d --- /dev/null +++ b/src/utils/console.cc @@ -0,0 +1,85 @@ +/*---------------------------------------------------------------------------*\ + ____ _ _ __ _ __ ___ _ _ + |_ / || | '_ \ '_ \/ -_) '_| + /__|\_, | .__/ .__/\___|_| + |__/|_| |_| +\*---------------------------------------------------------------------------*/ + +/** \file console.cc + * Miscellaneous console utilities. + */ + +#include +#include +#include +#include +#include +#include + +using namespace std; + +// ---------------------------------------------------------------------------- + +// Read a string. "\004" (^D) on EOF. +string readline_getline() +{ + // A static variable for holding the line. + static char *line_read = NULL; + + /* If the buffer has already been allocated, + return the memory to the free pool. */ + if (line_read) { + free (line_read); + line_read = NULL; + } + + //::rl_catch_signals = 0; + /* Get a line from the user. */ + line_read = ::readline ("zypper> "); + + /* If the line has any text in it, + save it on the history. */ + if (line_read && *line_read) + ::add_history (line_read); + + if (line_read) + return line_read; + else + return "\004"; +} + +// ---------------------------------------------------------------------------- + +unsigned get_screen_width() +{ + if (!::isatty(STDOUT_FILENO)) + return -1; // no clipping + + int width = 80; + + const char *cols_env = getenv("COLUMNS"); + if (cols_env) + width = ::atoi (cols_env); + else + { + ::rl_initialize(); + //::rl_reset_screen_size(); + ::rl_get_screen_size (NULL, &width); + } + + // safe default + if (!width) + width = 80; + + return width; +} + +// ---------------------------------------------------------------------------- + +void clear_keyboard_buffer() +{ + // note: this will not clear characters typed after the last \n + ifstream stm("/dev/tty", ifstream::in); + char s[8]; + while (stm.good() && stm.readsome(s, 8)); +} diff --git a/src/utils/console.h b/src/utils/console.h new file mode 100644 index 0000000..5fc6262 --- /dev/null +++ b/src/utils/console.h @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ____ _ _ __ _ __ ___ _ _ + |_ / || | '_ \ '_ \/ -_) '_| + /__|\_, | .__/ .__/\___|_| + |__/|_| |_| +\*---------------------------------------------------------------------------*/ + +/** \file console.h + * Miscellaneous console utilities. + */ + +#ifndef CONSOLE_H_ +#define CONSOLE_H_ + +/** Use readline to get line of input. */ +std::string readline_getline(); + +/** + * Reads COLUMNS environment variable or gets the screen width from readline, + * in that order. Falls back to 80 if all that fails. + * + * \NOTE In case stdout is not connected to a terminal max. unsigned + * is returned. This should prevent clipping when output is redirected. + */ +unsigned get_screen_width(); + + +/** + * Clear the keyboard buffer. + * Useful before showing the user prompt message to catch any unwanted + * key hits (bnc #649248). + * + * \NOTE This will not clear characters typed after the last \n + */ +void clear_keyboard_buffer(); + + +#endif /* CONSOLE_H_ */ diff --git a/src/utils/misc.cc b/src/utils/misc.cc index 2d94d52..9467a3f 100644 --- a/src/utils/misc.cc +++ b/src/utils/misc.cc @@ -5,12 +5,9 @@ |__/|_| |_| \*---------------------------------------------------------------------------*/ -#include #include #include -#include -#include -#include +#include // for getcwd() #include "zypp/base/Logger.h" #include "zypp/base/String.h" @@ -35,60 +32,6 @@ using namespace std; using namespace zypp; -// Read a string. "\004" (^D) on EOF. -string readline_getline() -{ - // A static variable for holding the line. - static char *line_read = NULL; - - /* If the buffer has already been allocated, - return the memory to the free pool. */ - if (line_read) { - free (line_read); - line_read = NULL; - } - - //::rl_catch_signals = 0; - /* Get a line from the user. */ - line_read = ::readline ("zypper> "); - - /* If the line has any text in it, - save it on the history. */ - if (line_read && *line_read) - add_history (line_read); - - if (line_read) - return line_read; - else - return "\004"; -} - -// ---------------------------------------------------------------------------- - -unsigned get_screen_width() -{ - if (!::isatty(STDOUT_FILENO)) - return -1; // no clipping - - int width = 80; - - const char *cols_env = getenv("COLUMNS"); - if (cols_env) - width = ::atoi (cols_env); - else - { - ::rl_initialize(); - //::rl_reset_screen_size(); - ::rl_get_screen_size (NULL, &width); - } - - // safe default - if (!width) - width = 80; - - return width; -} - // ---------------------------------------------------------------------------- bool is_changeable_media(const zypp::Url & url) @@ -226,7 +169,7 @@ Url make_url (const string & url_s) else { char buf[PATH_MAX]; - if (getcwd(buf, PATH_MAX) != NULL) + if (::getcwd(buf, PATH_MAX) != NULL) { DBG << "current working directory: " << buf << endl; path = string(buf) + "/" + url_s; diff --git a/src/utils/misc.h b/src/utils/misc.h index f2274c8..81a3b94 100644 --- a/src/utils/misc.h +++ b/src/utils/misc.h @@ -8,9 +8,9 @@ #ifndef ZYPPER_UTILS_H #define ZYPPER_UTILS_H -#include #include #include +#include #include "zypp/Url.h" #include "zypp/Pathname.h" @@ -32,16 +32,6 @@ namespace zypp typedef std::set ResKindSet; -std::string readline_getline(); - -/** - * Reads COLUMNS environment variable or gets the screen width from readline, - * in that order. Falls back to 80 if all that fails. - * \NOTE In case stdout is not connected to a terminal max. unsigned - * is returned. This should prevent clipping when output is redirected. - */ -unsigned get_screen_width(); - bool is_changeable_media(const zypp::Url & url); /** Converts user-supplied kind to zypp::ResKind object. diff --git a/src/utils/prompt.cc b/src/utils/prompt.cc index 15f92ad..3fd06c7 100644 --- a/src/utils/prompt.cc +++ b/src/utils/prompt.cc @@ -263,6 +263,8 @@ int read_action_ari (PromptId pid, int default_action) // correspond to abort/retry/ignore in that order. // The answers should be lower case letters. PromptOptions popts(_("a/r/i"), (unsigned int) default_action); + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); zypper.out().prompt(pid, _("Abort, retry, ignore?"), popts); return get_prompt_reply(zypper, pid, popts); } @@ -274,6 +276,8 @@ bool read_bool_answer(PromptId pid, const string & question, bool default_answer Zypper & zypper = *Zypper::instance(); string yn = string(_("yes")) + "/" + _("no"); PromptOptions popts(yn, default_answer ? 0 : 1); + if (!zypper.globalOpts().non_interactive) + clear_keyboard_buffer(); zypper.out().prompt(pid, question, popts); return !get_prompt_reply(zypper, pid, popts); } diff --git a/src/utils/prompt.h b/src/utils/prompt.h index 474dc5b..9456ccc 100644 --- a/src/utils/prompt.h +++ b/src/utils/prompt.h @@ -11,6 +11,7 @@ #include #include "output/prompt.h" +#include "utils/console.h" #include "main.h" // for gettext macros /**