mirror of https://gitee.com/openkylin/libvirt.git
virsh: Add persistent history using libreadline
This commit is contained in:
parent
96ceb12443
commit
a4a38ffda1
|
@ -41,6 +41,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
@ -197,6 +198,8 @@ typedef struct __vshControl {
|
||||||
*/
|
*/
|
||||||
char *logfile; /* log file name */
|
char *logfile; /* log file name */
|
||||||
int log_fd; /* log file descriptor */
|
int log_fd; /* log file descriptor */
|
||||||
|
char *historydir; /* readline history directory name */
|
||||||
|
char *historyfile; /* readline history file name */
|
||||||
} __vshControl;
|
} __vshControl;
|
||||||
|
|
||||||
|
|
||||||
|
@ -8689,9 +8692,11 @@ vshReadlineCompletion(const char *text, int start,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static int
|
||||||
vshReadlineInit(void)
|
vshReadlineInit(vshControl *ctl)
|
||||||
{
|
{
|
||||||
|
char *userdir = NULL;
|
||||||
|
|
||||||
/* Allow conditional parsing of the ~/.inputrc file. */
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
||||||
rl_readline_name = "virsh";
|
rl_readline_name = "virsh";
|
||||||
|
|
||||||
|
@ -8700,6 +8705,49 @@ vshReadlineInit(void)
|
||||||
|
|
||||||
/* Limit the total size of the history buffer */
|
/* Limit the total size of the history buffer */
|
||||||
stifle_history(500);
|
stifle_history(500);
|
||||||
|
|
||||||
|
/* Prepare to read/write history from/to the ~/.virsh/history file */
|
||||||
|
userdir = virGetUserDirectory(NULL, getuid());
|
||||||
|
|
||||||
|
if (userdir == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virAsprintf(&ctl->historydir, "%s/.virsh", userdir) < 0) {
|
||||||
|
vshError(ctl, "%s", _("Out of memory"));
|
||||||
|
free(userdir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virAsprintf(&ctl->historyfile, "%s/history", ctl->historydir) < 0) {
|
||||||
|
vshError(ctl, "%s", _("Out of memory"));
|
||||||
|
free(userdir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(userdir);
|
||||||
|
|
||||||
|
read_history(ctl->historyfile);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vshReadlineDeinit (vshControl *ctl)
|
||||||
|
{
|
||||||
|
if (ctl->historyfile != NULL) {
|
||||||
|
if (mkdir(ctl->historydir, 0755) < 0 && errno != EEXIST) {
|
||||||
|
char ebuf[1024];
|
||||||
|
vshError(ctl, _("Failed to create '%s': %s"),
|
||||||
|
ctl->historydir, virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
} else
|
||||||
|
write_history(ctl->historyfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ctl->historydir);
|
||||||
|
free(ctl->historyfile);
|
||||||
|
|
||||||
|
ctl->historydir = NULL;
|
||||||
|
ctl->historyfile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
@ -8710,8 +8758,15 @@ vshReadline (vshControl *ctl ATTRIBUTE_UNUSED, const char *prompt)
|
||||||
|
|
||||||
#else /* !USE_READLINE */
|
#else /* !USE_READLINE */
|
||||||
|
|
||||||
|
static int
|
||||||
|
vshReadlineInit (vshControl *ctl ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
/* empty */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vshReadlineInit (void)
|
vshReadlineDeinit (vshControl *ctl ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
@ -8743,6 +8798,7 @@ vshReadline (vshControl *ctl, const char *prompt)
|
||||||
static int
|
static int
|
||||||
vshDeinit(vshControl *ctl)
|
vshDeinit(vshControl *ctl)
|
||||||
{
|
{
|
||||||
|
vshReadlineDeinit(ctl);
|
||||||
vshCloseLogFile(ctl);
|
vshCloseLogFile(ctl);
|
||||||
free(ctl->name);
|
free(ctl->name);
|
||||||
if (ctl->conn) {
|
if (ctl->conn) {
|
||||||
|
@ -8969,7 +9025,12 @@ main(int argc, char **argv)
|
||||||
_("Type: 'help' for help with commands\n"
|
_("Type: 'help' for help with commands\n"
|
||||||
" 'quit' to quit\n\n"));
|
" 'quit' to quit\n\n"));
|
||||||
}
|
}
|
||||||
vshReadlineInit();
|
|
||||||
|
if (vshReadlineInit(ctl) < 0) {
|
||||||
|
vshDeinit(ctl);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const char *prompt = ctl->readonly ? VSH_PROMPT_RO : VSH_PROMPT_RW;
|
const char *prompt = ctl->readonly ? VSH_PROMPT_RO : VSH_PROMPT_RW;
|
||||||
ctl->cmdstr =
|
ctl->cmdstr =
|
||||||
|
|
Loading…
Reference in New Issue