summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaniv Kamay <ykamay@redhat.com>2010-01-11 19:57:29 +0200
committerYaniv Kamay <ykamay@redhat.com>2010-01-11 19:57:29 +0200
commit8ceb531958cb649b7cc7f16f2f504125cb430fe4 (patch)
tree847f4325a37ce7bfccf6a469659b11f775cc3e62
parent3c1ff6448d847e6e96425fa166446b99bac5e592 (diff)
downloadspice-8ceb531958cb649b7cc7f16f2f504125cb430fe4.tar.gz
spice-8ceb531958cb649b7cc7f16f2f504125cb430fe4.tar.xz
spice-8ceb531958cb649b7cc7f16f2f504125cb430fe4.zip
client: add Platform::term_printf
Platform::term_printf is a variant of printf that on windows dynamically opens console in order to have visible output during command line processing.
-rw-r--r--client/application.cpp66
-rw-r--r--client/application.h9
-rw-r--r--client/cmd_line_parser.cpp29
-rw-r--r--client/platform.h1
-rw-r--r--client/windows/main.cpp28
-rw-r--r--client/windows/platform.cpp64
-rw-r--r--client/x11/platform.cpp8
-rw-r--r--common/red_error_codes.h1
8 files changed, 134 insertions, 72 deletions
diff --git a/client/application.cpp b/client/application.cpp
index 839885d8..7655809d 100644
--- a/client/application.cpp
+++ b/client/application.cpp
@@ -1635,7 +1635,8 @@ const std::string& Application::get_password()
//controller interface end
-bool Application::set_channels_security(CmdLineParser& parser, bool on, char *val)
+bool Application::set_channels_security(CmdLineParser& parser, bool on, char *val,
+ const char* arg0)
{
RedPeer::ConnectionOptions::Type option;
option = (on) ? RedPeer::ConnectionOptions::CON_OP_SECURE :
@@ -1653,7 +1654,8 @@ bool Application::set_channels_security(CmdLineParser& parser, bool on, char *va
if (!strcmp(val, "all")) {
if ((val = parser.next_argument())) {
- std::cout << "\"all\" is exclusive in secure-channels\n";
+ Platform::term_printf("%s: \"all\" is exclusive in secure-channels\n", arg0);
+ _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
PeerConnectionOptMap::iterator iter = _peer_con_opt.begin();
@@ -1666,7 +1668,8 @@ bool Application::set_channels_security(CmdLineParser& parser, bool on, char *va
do {
ChannelsNamesMap::iterator iter = channels_names.find(val);
if (iter == channels_names.end()) {
- std::cout << "bad channel name \"" << val << "\" in secure-channels\n";
+ Platform::term_printf("%s: bad channel name \"%s\" in secure-channels\n", arg0, val);
+ _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
_peer_con_opt[(*iter).second] = option;
@@ -1674,7 +1677,7 @@ bool Application::set_channels_security(CmdLineParser& parser, bool on, char *va
return true;
}
-bool Application::set_canvas_option(CmdLineParser& parser, char *val)
+bool Application::set_canvas_option(CmdLineParser& parser, char *val, const char* arg0)
{
typedef std::map< std::string, CanvasOption> CanvasNamesMap;
CanvasNamesMap canvas_types;
@@ -1688,19 +1691,23 @@ bool Application::set_canvas_option(CmdLineParser& parser, char *val)
canvas_types["gl_pbuff"] = CANVAS_OPTION_OGL_PBUFF;
#endif
_canvas_types.clear();
+
do {
CanvasNamesMap::iterator iter = canvas_types.find(val);
if (iter == canvas_types.end()) {
- std::cout << "bad canvas type \"" << val << "\"\n";
+ Platform::term_printf("%s: bad canvas type \"%s\"\n", arg0, val);
+ _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
_canvas_types.resize(_canvas_types.size() + 1);
_canvas_types[_canvas_types.size() - 1] = (*iter).second;
} while ((val = parser.next_argument()));
+
return true;
}
-bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *val)
+bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *val,
+ const char* arg0)
{
typedef std::map< std::string, int> ChannelsNamesMap;
ChannelsNamesMap channels_names;
@@ -1713,7 +1720,8 @@ bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *
if (!strcmp(val, "all")) {
if ((val = parser.next_argument())) {
- std::cout << "\"all\" is exclusive\n";
+ Platform::term_printf("%s: \"all\" is exclusive\n", arg0);
+ _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
for (unsigned int i = 0; i < _enabled_channels.size(); i++) {
@@ -1725,7 +1733,8 @@ bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *
do {
ChannelsNamesMap::iterator iter = channels_names.find(val);
if (iter == channels_names.end()) {
- std::cout << "bad channel name \"" << val << "\"\n";
+ Platform::term_printf("%s: bad channel name \"%s\"\n", arg0, val);
+ _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
return false;
}
_enabled_channels[(*iter).second] = enable;
@@ -1733,6 +1742,12 @@ bool Application::set_enable_channels(CmdLineParser& parser, bool enable, char *
return true;
}
+void Application::on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val)
+{
+ Platform::term_printf("%s: invalid %s value %s\n", arg0, what, val);
+ _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
+}
+
void Application::register_channels()
{
if (_enabled_channels[RED_CHANNEL_DISPLAY]) {
@@ -1838,16 +1853,14 @@ bool Application::process_cmd_line(int argc, char** argv)
break;
case SPICE_OPT_PORT: {
if ((port = str_to_port(val)) == -1) {
- std::cout << "invalid port " << val << "\n";
- _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
+ on_cmd_line_invalid_arg(argv[0], "port", val);
return false;
}
break;
}
case SPICE_OPT_SPORT: {
if ((sport = str_to_port(val)) == -1) {
- std::cout << "invalid secure port " << val << "\n";
- _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
+ on_cmd_line_invalid_arg(argv[0], "secure port", val);
return false;
}
break;
@@ -1855,8 +1868,7 @@ bool Application::process_cmd_line(int argc, char** argv)
case SPICE_OPT_FULL_SCREEN:
if (val) {
if (strcmp(val, "auto-conf")) {
- std::cout << "invalid full screen mode " << val << "\n";
- _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
+ on_cmd_line_invalid_arg(argv[0], "full screen mode", val);
return false;
}
auto_display_res = true;
@@ -1867,33 +1879,27 @@ bool Application::process_cmd_line(int argc, char** argv)
password = val;
break;
case SPICE_OPT_SECURE_CHANNELS:
- if (!set_channels_security(parser, true, val)) {
+ if (!set_channels_security(parser, true, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_UNSECURE_CHANNELS:
- if (!set_channels_security(parser, false, val)) {
+ if (!set_channels_security(parser, false, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_ENABLE_CHANNELS:
- if (!set_enable_channels(parser, true, val)) {
- std::cout << "invalid channels " << val << "\n";
- _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
+ if (!set_enable_channels(parser, true, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_DISABLE_CHANNELS:
- if (!set_enable_channels(parser, false, val)) {
- std::cout << "invalid channels " << val << "\n";
- _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
+ if (!set_enable_channels(parser, false, val, argv[0])) {
return false;
}
break;
case SPICE_OPT_CANVAS_TYPE:
- if (!set_canvas_option(parser, val)) {
- std::cout << "invalid canvas option " << val << "\n";
- _exit_code = SPICEC_ERROR_CODE_INVALID_ARG;
+ if (!set_canvas_option(parser, val, argv[0])) {
return false;
}
break;
@@ -1901,14 +1907,16 @@ bool Application::process_cmd_line(int argc, char** argv)
parser.show_help();
return false;
case CmdLineParser::OPTION_ERROR:
+ _exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR;
return false;
default:
- throw Exception("cmd line error");
+ throw Exception("cmd line error", SPICEC_ERROR_CODE_CMD_LINE_ERROR);
}
}
if (parser.is_set(SPICE_OPT_SECURE_CHANNELS) && !parser.is_set(SPICE_OPT_SPORT)) {
- std::cout << "missing --secure-port\n";
+ Platform::term_printf("%s: missing --secure-port\n", argv[0]);
+ _exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR;
return false;
}
@@ -1936,7 +1944,9 @@ bool Application::process_cmd_line(int argc, char** argv)
(*iter).second = RedPeer::ConnectionOptions::CON_OP_SECURE;
continue;
}
- std::cout << "missing --port or --sport\n";
+
+ Platform::term_printf("%s: missing --port or --sport\n", argv[0]);
+ _exit_code = SPICEC_ERROR_CODE_CMD_LINE_ERROR;
return false;
}
diff --git a/client/application.h b/client/application.h
index e1c702db..47cf29ef 100644
--- a/client/application.h
+++ b/client/application.h
@@ -216,11 +216,12 @@ public:
static int main(int argc, char** argv, const char* version_str);
private:
- bool set_channels_security(CmdLineParser& parser, bool on, char *val);
- bool set_enable_channels(CmdLineParser& parser, bool enable, char *val);
- bool set_canvas_option(CmdLineParser& parser, char *val);
- void register_channels();
+ bool set_channels_security(CmdLineParser& parser, bool on, char *val, const char* arg0);
+ bool set_enable_channels(CmdLineParser& parser, bool enable, char *val, const char* arg0);
+ bool set_canvas_option(CmdLineParser& parser, char *val, const char* arg0);
+ void on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val);
bool process_cmd_line(int argc, char** argv);
+ void register_channels();
void abort();
void init_menu();
void unpress_all();
diff --git a/client/cmd_line_parser.cpp b/client/cmd_line_parser.cpp
index 65ae404a..caa4b034 100644
--- a/client/cmd_line_parser.cpp
+++ b/client/cmd_line_parser.cpp
@@ -344,7 +344,7 @@ int CmdLineParser::get_option(char** val)
int name_pos = (opt_obj->type == REQUIRED_ARGUMENT) ? optind - 2 : optind - 1;
std::string cmd_name(_argv[name_pos] + 2);
if (cmd_name.find(opt_obj->name) != 0) {
- std::cout << _argv[0] << ": invalid option '--" << cmd_name << "'\n";
+ Platform::term_printf("%s: invalid option '--%s'\n", _argv[0], cmd_name.c_str());
return OPTION_ERROR;
}
#endif
@@ -360,11 +360,11 @@ int CmdLineParser::get_option(char** val)
case -1: {
*val = NULL;
if (!_positional_args && optind != _argc) {
- std::cout << _argv[0] << ": unexpected positional arguments\n";
+ Platform::term_printf("%s: unexpected positional arguments\n", _argv[0]);
return OPTION_ERROR;
}
if ((opt_obj = find_missing_opt())) {
- std::cout << _argv[0] << ": option --" << opt_obj->name << " is required\n";
+ Platform::term_printf("%s: option --%s is required\n", _argv[0], opt_obj->name.c_str());
return OPTION_ERROR;
}
_done = true;
@@ -378,18 +378,19 @@ int CmdLineParser::get_option(char** val)
#ifdef DISABLE_ABBREVIATE
std::string cmd_name(_argv[optind - 1] + 2);
if (cmd_name.find(opt_obj->name) != 0) {
- std::cout << _argv[0] << ": invalid option '--" << cmd_name << "'\n";
+ Platform::term_printf("%s: invalid option '--%s'\n", _argv[0], cmd_name.c_str());
return OPTION_ERROR;
}
#endif
- std::cout << _argv[0] << ": option --" << opt_obj->name << " requires an argument\n";
+ Platform::term_printf("%s: option --%s requires an argument\n",
+ _argv[0], opt_obj->name.c_str());
} else if (optopt == 0) {
- std::cout << _argv[0] << ": invalid option '" << _argv[optind - 1] << "'\n";
+ Platform::term_printf("%s: invalid option '%s'\n", _argv[0], _argv[optind - 1]);
} else if ((opt_obj = find((char)optopt))) {
- std::cout << _argv[0] << ": option '-" << opt_obj->short_name <<
- "' requires an argument\n";
+ Platform::term_printf("%s: option '-%c' requires an argument\n",
+ _argv[0], opt_obj->short_name);
} else {
- std::cout << _argv[0] << ": invalid option '-" << char(optopt) << "'\n";
+ Platform::term_printf("%s: invalid option '-%c'\n", _argv[0], char(optopt));
}
return OPTION_ERROR;
default:
@@ -447,13 +448,13 @@ void CmdLineParser::show_help()
{
static const int HELP_START_POS = 30;
static const int HELP_WIDTH = 80 - HELP_START_POS;
+ std::ostringstream os;
- std::cout << basename(_argv[0]) << " - " << _description.c_str() << "\n\noptions:\n\n";
+ os << basename(_argv[0]) << " - " << _description.c_str() << "\n\noptions:\n\n";
Options::iterator iter = _options.begin();
for (; iter != _options.end(); ++iter) {
CmdLineParser::Option* opt = *iter;
- std::ostringstream os;
if (opt->short_name) {
os << " -" << opt->short_name << ", ";
@@ -516,9 +517,9 @@ void CmdLineParser::show_help()
line.clear();
}
} while (line.size() || std::getline(is, line));
-
- std::cout << os.str();
}
- std::cout << "\n";
+
+ os << "\n";
+ Platform::term_printf(os.str().c_str());
}
diff --git a/client/platform.h b/client/platform.h
index ec335540..5eb909dd 100644
--- a/client/platform.h
+++ b/client/platform.h
@@ -42,6 +42,7 @@ public:
static void path_append(std::string& path, const std::string& partial_path);
static uint64_t get_process_id();
static uint64_t get_thread_id();
+ static void term_printf(const char* format, ...);
static void error_beep();
static const MonitorsList& init_monitors();
diff --git a/client/windows/main.cpp b/client/windows/main.cpp
index a1575e90..afc98c97 100644
--- a/client/windows/main.cpp
+++ b/client/windows/main.cpp
@@ -22,12 +22,6 @@ extern "C" {
#include "pthread.h"
}
-//#define OPEN_CONSOLE
-#ifdef OPEN_CONSOLE
-#include <io.h>
-#include <conio.h>
-#endif
-
#include "application.h"
#include "debug.h"
#include "utils.h"
@@ -83,23 +77,6 @@ int WINAPI WinMain(HINSTANCE hInstance,
try {
init_version_string();
-#ifdef OPEN_CONSOLE
- AllocConsole();
- HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
- int hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
- FILE * fp = _fdopen(hConHandle, "w");
- *stdout = *fp;
-
- h = GetStdHandle(STD_INPUT_HANDLE);
- hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
- fp = _fdopen(hConHandle, "r");
- *stdin = *fp;
-
- h = GetStdHandle(STD_ERROR_HANDLE);
- hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
- fp = _fdopen(hConHandle, "w");
- *stderr = *fp;
-#endif
pthread_win32_process_attach_np();
init_winsock();
exit_val = Application::main(__argc, __argv, version_string);
@@ -114,11 +91,10 @@ int WINAPI WinMain(HINSTANCE hInstance,
LOG_ERROR("unhandled exception");
exit_val = SPICEC_ERROR_CODE_ERROR;
}
+
log4cpp::Category::shutdown();
-#ifdef OPEN_CONSOLE
- _getch();
-#endif
pthread_win32_process_detach_np();
+
return exit_val;
}
diff --git a/client/windows/platform.cpp b/client/windows/platform.cpp
index 67bb1a02..c364b35d 100644
--- a/client/windows/platform.cpp
+++ b/client/windows/platform.cpp
@@ -18,6 +18,8 @@
#include "common.h"
#include <shlobj.h>
+#include <io.h>
+#include <conio.h>
#include "platform.h"
#include "win_platform.h"
@@ -745,3 +747,65 @@ void WinPlatform::exit_modal_loop()
KillTimer(paltform_win, MODAL_LOOP_TIMER_ID);
modal_loop_active = false;
}
+
+static bool has_console = false;
+
+static void create_console()
+{
+ static Mutex console_mutex;
+
+ Lock lock(console_mutex);
+
+ if (has_console) {
+ return;
+ }
+
+ AllocConsole();
+ HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
+ int hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
+ FILE * fp = _fdopen(hConHandle, "w");
+ *stdout = *fp;
+
+ h = GetStdHandle(STD_INPUT_HANDLE);
+ hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
+ fp = _fdopen(hConHandle, "r");
+ *stdin = *fp;
+
+ h = GetStdHandle(STD_ERROR_HANDLE);
+ hConHandle = _open_osfhandle((intptr_t)h, _O_TEXT);
+ fp = _fdopen(hConHandle, "w");
+ *stderr = *fp;
+
+ has_console = true;
+
+ HWND consol_window = GetConsoleWindow();
+
+ if (consol_window) {
+ SetForegroundWindow(consol_window);
+ }
+}
+
+class ConsoleWait {
+public:
+ ~ConsoleWait()
+ {
+ if (has_console) {
+ Platform::term_printf("\n\nPress any key to exit...");
+ _getch();
+ }
+ }
+
+} console_wait;
+
+
+void Platform::term_printf(const char* format, ...)
+{
+ if (!has_console) {
+ create_console();
+ }
+
+ va_list ap;
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+}
diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp
index 02250f11..6f550135 100644
--- a/client/x11/platform.cpp
+++ b/client/x11/platform.cpp
@@ -268,6 +268,14 @@ void Platform::yield()
pthread_yield();
}
+void Platform::term_printf(const char* format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+}
+
void Platform::set_thread_priority(void* thread, Platform::ThreadPriority in_priority)
{
ASSERT(thread == NULL);
diff --git a/common/red_error_codes.h b/common/red_error_codes.h
index c08fd510..0c068997 100644
--- a/common/red_error_codes.h
+++ b/common/red_error_codes.h
@@ -45,6 +45,7 @@
#define SPICEC_ERROR_CODE_VERSION_MISMATCH (-11)
#define SPICEC_ERROR_CODE_PERMISSION_DENIED (-12)
#define SPICEC_ERROR_CODE_INVALID_ARG (-13)
+#define SPICEC_ERROR_CODE_CMD_LINE_ERROR (-14)
#endif