mirror of
https://github.com/sheumann/hush.git
synced 2024-08-20 19:29:02 +00:00
lineedit: add support for history saving on exit
Based on the patch by Dennis Groenen <tj.groenen@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
4840ae8a06
commit
bede215cf1
@ -1421,6 +1421,12 @@ typedef struct line_input_t {
|
|||||||
int cur_history;
|
int cur_history;
|
||||||
int max_history; /* must never be <= 0 */
|
int max_history; /* must never be <= 0 */
|
||||||
# if ENABLE_FEATURE_EDITING_SAVEHISTORY
|
# if ENABLE_FEATURE_EDITING_SAVEHISTORY
|
||||||
|
/* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT:
|
||||||
|
* if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are
|
||||||
|
* in on-disk history"
|
||||||
|
* if FEATURE_EDITING_SAVE_ON_EXIT: "how many in-memory lines are
|
||||||
|
* also in on-disk history (and thus need to be skipped on save)"
|
||||||
|
*/
|
||||||
unsigned cnt_history_in_file;
|
unsigned cnt_history_in_file;
|
||||||
const char *hist_file;
|
const char *hist_file;
|
||||||
# endif
|
# endif
|
||||||
@ -1446,6 +1452,9 @@ line_input_t *new_line_input_t(int flags) FAST_FUNC;
|
|||||||
* >0 length of input string, including terminating '\n'
|
* >0 length of input string, including terminating '\n'
|
||||||
*/
|
*/
|
||||||
int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC;
|
int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC;
|
||||||
|
# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
|
void save_history(line_input_t *st);
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
#define MAX_HISTORY 0
|
#define MAX_HISTORY 0
|
||||||
int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
|
int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
|
||||||
|
@ -94,6 +94,13 @@ config FEATURE_EDITING_SAVEHISTORY
|
|||||||
help
|
help
|
||||||
Enable history saving in shells.
|
Enable history saving in shells.
|
||||||
|
|
||||||
|
config FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
|
bool "Save history on shell exit, not after every command"
|
||||||
|
default n
|
||||||
|
depends on FEATURE_EDITING_SAVEHISTORY
|
||||||
|
help
|
||||||
|
Save history on shell exit, not after every command.
|
||||||
|
|
||||||
config FEATURE_REVERSE_SEARCH
|
config FEATURE_REVERSE_SEARCH
|
||||||
bool "Reverse history search"
|
bool "Reverse history search"
|
||||||
default y
|
default y
|
||||||
|
@ -1351,7 +1351,9 @@ static void load_history(line_input_t *st_parm)
|
|||||||
|
|
||||||
/* fill temp_h[], retaining only last MAX_HISTORY lines */
|
/* fill temp_h[], retaining only last MAX_HISTORY lines */
|
||||||
memset(temp_h, 0, sizeof(temp_h));
|
memset(temp_h, 0, sizeof(temp_h));
|
||||||
st_parm->cnt_history_in_file = idx = 0;
|
idx = 0;
|
||||||
|
if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
|
||||||
|
st_parm->cnt_history_in_file = 0;
|
||||||
while ((line = xmalloc_fgetline(fp)) != NULL) {
|
while ((line = xmalloc_fgetline(fp)) != NULL) {
|
||||||
if (line[0] == '\0') {
|
if (line[0] == '\0') {
|
||||||
free(line);
|
free(line);
|
||||||
@ -1359,7 +1361,8 @@ static void load_history(line_input_t *st_parm)
|
|||||||
}
|
}
|
||||||
free(temp_h[idx]);
|
free(temp_h[idx]);
|
||||||
temp_h[idx] = line;
|
temp_h[idx] = line;
|
||||||
st_parm->cnt_history_in_file++;
|
if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
|
||||||
|
st_parm->cnt_history_in_file++;
|
||||||
idx++;
|
idx++;
|
||||||
if (idx == st_parm->max_history)
|
if (idx == st_parm->max_history)
|
||||||
idx = 0;
|
idx = 0;
|
||||||
@ -1389,15 +1392,66 @@ static void load_history(line_input_t *st_parm)
|
|||||||
st_parm->history[i++] = line;
|
st_parm->history[i++] = line;
|
||||||
}
|
}
|
||||||
st_parm->cnt_history = i;
|
st_parm->cnt_history = i;
|
||||||
|
if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
|
||||||
|
st_parm->cnt_history_in_file = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* state->flags is already checked to be nonzero */
|
# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
|
void save_history(line_input_t *st)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (!(st->flags & SAVE_HISTORY))
|
||||||
|
return;
|
||||||
|
if (!st->hist_file)
|
||||||
|
return;
|
||||||
|
if (st->cnt_history <= st->cnt_history_in_file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fp = fopen(st->hist_file, "a");
|
||||||
|
if (fp) {
|
||||||
|
int i, fd;
|
||||||
|
char *new_name;
|
||||||
|
line_input_t *st_temp;
|
||||||
|
|
||||||
|
for (i = st->cnt_history_in_file; i < st->cnt_history; i++)
|
||||||
|
fprintf(fp, "%s\n", st->history[i]);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
/* we may have concurrently written entries from others.
|
||||||
|
* load them */
|
||||||
|
st_temp = new_line_input_t(st->flags);
|
||||||
|
st_temp->hist_file = st->hist_file;
|
||||||
|
st_temp->max_history = st->max_history;
|
||||||
|
load_history(st_temp);
|
||||||
|
|
||||||
|
/* write out temp file and replace hist_file atomically */
|
||||||
|
new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid());
|
||||||
|
fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
if (fd >= 0) {
|
||||||
|
fp = xfdopen_for_write(fd);
|
||||||
|
for (i = 0; i < st_temp->cnt_history; i++)
|
||||||
|
fprintf(fp, "%s\n", st_temp->history[i]);
|
||||||
|
fclose(fp);
|
||||||
|
if (rename(new_name, st->hist_file) == 0)
|
||||||
|
st->cnt_history_in_file = st_temp->cnt_history;
|
||||||
|
}
|
||||||
|
free(new_name);
|
||||||
|
free_line_input_t(st_temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# else
|
||||||
static void save_history(char *str)
|
static void save_history(char *str)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int len, len2;
|
int len, len2;
|
||||||
|
|
||||||
|
if (!(state->flags & SAVE_HISTORY))
|
||||||
|
return;
|
||||||
|
if (!state->hist_file)
|
||||||
|
return;
|
||||||
|
|
||||||
fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600);
|
fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return;
|
return;
|
||||||
@ -1441,6 +1495,7 @@ static void save_history(char *str)
|
|||||||
free_line_input_t(st_temp);
|
free_line_input_t(st_temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define load_history(a) ((void)0)
|
# define load_history(a) ((void)0)
|
||||||
# define save_history(a) ((void)0)
|
# define save_history(a) ((void)0)
|
||||||
@ -1469,15 +1524,16 @@ static void remember_in_history(char *str)
|
|||||||
for (i = 0; i < state->max_history-1; i++)
|
for (i = 0; i < state->max_history-1; i++)
|
||||||
state->history[i] = state->history[i+1];
|
state->history[i] = state->history[i+1];
|
||||||
/* i == state->max_history-1 */
|
/* i == state->max_history-1 */
|
||||||
|
if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT && state->cnt_history_in_file)
|
||||||
|
state->cnt_history_in_file--;
|
||||||
}
|
}
|
||||||
/* i <= state->max_history-1 */
|
/* i <= state->max_history-1 */
|
||||||
state->history[i++] = xstrdup(str);
|
state->history[i++] = xstrdup(str);
|
||||||
/* i <= state->max_history */
|
/* i <= state->max_history */
|
||||||
state->cur_history = i;
|
state->cur_history = i;
|
||||||
state->cnt_history = i;
|
state->cnt_history = i;
|
||||||
# if ENABLE_FEATURE_EDITING_SAVEHISTORY
|
# if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
if ((state->flags & SAVE_HISTORY) && state->hist_file)
|
save_history(str);
|
||||||
save_history(str);
|
|
||||||
# endif
|
# endif
|
||||||
IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
|
IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
|
||||||
}
|
}
|
||||||
|
@ -12888,6 +12888,10 @@ exitshell(void)
|
|||||||
char *p;
|
char *p;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
|
save_history(line_input_state);
|
||||||
|
#endif
|
||||||
|
|
||||||
status = exitstatus;
|
status = exitstatus;
|
||||||
TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
|
TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
|
||||||
if (setjmp(loc.loc)) {
|
if (setjmp(loc.loc)) {
|
||||||
|
@ -1541,6 +1541,10 @@ static sighandler_t pick_sighandler(unsigned sig)
|
|||||||
static void hush_exit(int exitcode) NORETURN;
|
static void hush_exit(int exitcode) NORETURN;
|
||||||
static void hush_exit(int exitcode)
|
static void hush_exit(int exitcode)
|
||||||
{
|
{
|
||||||
|
#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
|
save_history(G.line_input_state);
|
||||||
|
#endif
|
||||||
|
|
||||||
fflush_all();
|
fflush_all();
|
||||||
if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) {
|
if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) {
|
||||||
char *argv[3];
|
char *argv[3];
|
||||||
|
Loading…
Reference in New Issue
Block a user