mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-10 06:56:06 +00:00
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.
This commit is contained in:
parent
3c1ff6448d
commit
8ceb531958
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user