mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
virsh: Allow other escape characters for console
Currently virsh supports only ^] as escape character for console. However, some users might want to use something else. This patch creates such ability by specifying '-e' switch on virsh command line.
This commit is contained in:
parent
0763a26dfe
commit
7a79648532
@ -44,9 +44,11 @@
|
||||
# include "threads.h"
|
||||
# include "virterror_internal.h"
|
||||
|
||||
|
||||
/* ie Ctrl-] as per telnet */
|
||||
# define CTRL_CLOSE_BRACKET '\35'
|
||||
/*
|
||||
* Convert given character to control character.
|
||||
* Basically, we assume ASCII, and take lower 6 bits.
|
||||
*/
|
||||
# define CONTROL(c) ((c) ^ 0x40)
|
||||
|
||||
# define VIR_FROM_THIS VIR_FROM_NONE
|
||||
|
||||
@ -69,6 +71,8 @@ struct virConsole {
|
||||
|
||||
struct virConsoleBuffer streamToTerminal;
|
||||
struct virConsoleBuffer terminalToStream;
|
||||
|
||||
char escapeChar;
|
||||
};
|
||||
|
||||
static int got_signal = 0;
|
||||
@ -219,7 +223,7 @@ virConsoleEventOnStdin(int watch ATTRIBUTE_UNUSED,
|
||||
virConsoleShutdown(con);
|
||||
return;
|
||||
}
|
||||
if (con->terminalToStream.data[con->terminalToStream.offset] == CTRL_CLOSE_BRACKET) {
|
||||
if (con->terminalToStream.data[con->terminalToStream.offset] == con->escapeChar) {
|
||||
virConsoleShutdown(con);
|
||||
return;
|
||||
}
|
||||
@ -282,7 +286,18 @@ virConsoleEventOnStdout(int watch ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
int vshRunConsole(virDomainPtr dom, const char *dev_name)
|
||||
static char
|
||||
vshGetEscapeChar(const char *s)
|
||||
{
|
||||
if (*s == '^')
|
||||
return CONTROL(s[1]);
|
||||
|
||||
return *s;
|
||||
}
|
||||
|
||||
int vshRunConsole(virDomainPtr dom,
|
||||
const char *dev_name,
|
||||
const char *escape_seq)
|
||||
{
|
||||
int ret = -1;
|
||||
struct termios ttyattr, rawattr;
|
||||
@ -330,6 +345,7 @@ int vshRunConsole(virDomainPtr dom, const char *dev_name)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
con->escapeChar = vshGetEscapeChar(escape_seq);
|
||||
con->st = virStreamNew(virDomainGetConnect(dom),
|
||||
VIR_STREAM_NONBLOCK);
|
||||
if (!con->st)
|
||||
|
@ -25,7 +25,9 @@
|
||||
|
||||
# ifndef WIN32
|
||||
|
||||
int vshRunConsole(virDomainPtr dom, const char *dev_name);
|
||||
int vshRunConsole(virDomainPtr dom,
|
||||
const char *dev_name,
|
||||
const char *escape_seq);
|
||||
|
||||
# endif /* !WIN32 */
|
||||
|
||||
|
@ -76,6 +76,9 @@ static char *progname;
|
||||
((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \
|
||||
((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0)
|
||||
|
||||
/* Default escape char Ctrl-] as per telnet */
|
||||
#define CTRL_CLOSE_BRACKET "^]"
|
||||
|
||||
/**
|
||||
* The log configuration
|
||||
*/
|
||||
@ -254,6 +257,9 @@ typedef struct __vshControl {
|
||||
virMutex lock;
|
||||
bool eventLoopStarted;
|
||||
bool quit;
|
||||
|
||||
const char *escapeChar; /* String representation of
|
||||
console escape character */
|
||||
} __vshControl;
|
||||
|
||||
typedef struct vshCmdGrp {
|
||||
@ -801,8 +807,8 @@ cmdRunConsole(vshControl *ctl, virDomainPtr dom, const char *name)
|
||||
}
|
||||
|
||||
vshPrintExtra(ctl, _("Connected to domain %s\n"), virDomainGetName(dom));
|
||||
vshPrintExtra(ctl, "%s", _("Escape character is ^]\n"));
|
||||
if (vshRunConsole(dom, name) == 0)
|
||||
vshPrintExtra(ctl, _("Escape character is %s\n"), ctl->escapeChar);
|
||||
if (vshRunConsole(dom, name, ctl->escapeChar) == 0)
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
@ -17544,15 +17550,17 @@ vshUsage(void)
|
||||
fprintf(stdout, _("\n%s [options]... [<command_string>]"
|
||||
"\n%s [options]... <command> [args...]\n\n"
|
||||
" options:\n"
|
||||
" -c | --connect <uri> hypervisor connection URI\n"
|
||||
" -c | --connect=URI hypervisor connection URI\n"
|
||||
" -r | --readonly connect readonly\n"
|
||||
" -d | --debug <num> debug level [0-4]\n"
|
||||
" -d | --debug=NUM debug level [0-4]\n"
|
||||
" -h | --help this help\n"
|
||||
" -q | --quiet quiet mode\n"
|
||||
" -t | --timing print timing information\n"
|
||||
" -l | --log <file> output logging to file\n"
|
||||
" -v | --version[=short] program version\n"
|
||||
" -V | --version=long version and full options\n\n"
|
||||
" -l | --log=FILE output logging to file\n"
|
||||
" -v short version\n"
|
||||
" -V long version\n"
|
||||
" --version[=TYPE] version, TYPE is short or long (default short)\n"
|
||||
" -e | --escape <char> set escape sequence for console\n\n"
|
||||
" commands (non interactive mode):\n\n"), progname, progname);
|
||||
|
||||
for (grp = cmdGroups; grp->name; grp++) {
|
||||
@ -17703,7 +17711,7 @@ static bool
|
||||
vshParseArgv(vshControl *ctl, int argc, char **argv)
|
||||
{
|
||||
bool help = false;
|
||||
int arg;
|
||||
int arg, len;
|
||||
struct option opt[] = {
|
||||
{"debug", required_argument, NULL, 'd'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
@ -17713,13 +17721,14 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
|
||||
{"connect", required_argument, NULL, 'c'},
|
||||
{"readonly", no_argument, NULL, 'r'},
|
||||
{"log", required_argument, NULL, 'l'},
|
||||
{"escape", required_argument, NULL, 'e'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Standard (non-command) options. The leading + ensures that no
|
||||
* argument reordering takes place, so that command options are
|
||||
* not confused with top-level virsh options. */
|
||||
while ((arg = getopt_long(argc, argv, "+d:hqtc:vVrl:", opt, NULL)) != -1) {
|
||||
while ((arg = getopt_long(argc, argv, "+d:hqtc:vVrl:e:", opt, NULL)) != -1) {
|
||||
switch (arg) {
|
||||
case 'd':
|
||||
if (virStrToLong_i(optarg, NULL, 10, &ctl->debug) < 0) {
|
||||
@ -17754,6 +17763,18 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
|
||||
case 'l':
|
||||
ctl->logfile = vshStrdup(ctl, optarg);
|
||||
break;
|
||||
case 'e':
|
||||
len = strlen(optarg);
|
||||
|
||||
if ((len == 2 && *optarg == '^') ||
|
||||
(len == 1 && *optarg != '^')) {
|
||||
ctl->escapeChar = optarg;
|
||||
} else {
|
||||
vshError(ctl, _("Invalid string '%s' for escape sequence"),
|
||||
optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vshError(ctl, _("unsupported option '-%c'. See --help."), arg);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -17795,6 +17816,8 @@ main(int argc, char **argv)
|
||||
ctl->imode = true; /* default is interactive mode */
|
||||
ctl->log_fd = -1; /* Initialize log file descriptor */
|
||||
ctl->debug = VSH_DEBUG_DEFAULT;
|
||||
ctl->escapeChar = CTRL_CLOSE_BRACKET;
|
||||
|
||||
|
||||
if (!setlocale(LC_ALL, "")) {
|
||||
perror("setlocale");
|
||||
|
@ -92,6 +92,11 @@ option of the B<connect> command.
|
||||
|
||||
Output elapsed time information for each command.
|
||||
|
||||
=item B<-e>, B<--escape> I<string>
|
||||
|
||||
Set alternative escape sequence for I<console> command. By default,
|
||||
telnet's B<^]> is used.
|
||||
|
||||
=back
|
||||
|
||||
=head1 NOTES
|
||||
|
Loading…
Reference in New Issue
Block a user