diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-09-04 16:12:33 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-09-04 16:12:33 +0200 |
commit | bede215cf105377a1127532d2d710924cb58cc39 (patch) | |
tree | d0227961b7eb002cb03653f2e69211e6cf13d598 /libbb/lineedit.c | |
parent | 4840ae8a06298e987374fa3cc6d7e4969fd19344 (diff) | |
download | busybox-w32-bede215cf105377a1127532d2d710924cb58cc39.tar.gz busybox-w32-bede215cf105377a1127532d2d710924cb58cc39.tar.bz2 busybox-w32-bede215cf105377a1127532d2d710924cb58cc39.zip |
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>
Diffstat (limited to 'libbb/lineedit.c')
-rw-r--r-- | libbb/lineedit.c | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 5d139043a..0786f9ae6 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -1351,7 +1351,9 @@ static void load_history(line_input_t *st_parm) | |||
1351 | 1351 | ||
1352 | /* fill temp_h[], retaining only last MAX_HISTORY lines */ | 1352 | /* fill temp_h[], retaining only last MAX_HISTORY lines */ |
1353 | memset(temp_h, 0, sizeof(temp_h)); | 1353 | memset(temp_h, 0, sizeof(temp_h)); |
1354 | st_parm->cnt_history_in_file = idx = 0; | 1354 | idx = 0; |
1355 | if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) | ||
1356 | st_parm->cnt_history_in_file = 0; | ||
1355 | while ((line = xmalloc_fgetline(fp)) != NULL) { | 1357 | while ((line = xmalloc_fgetline(fp)) != NULL) { |
1356 | if (line[0] == '\0') { | 1358 | if (line[0] == '\0') { |
1357 | free(line); | 1359 | free(line); |
@@ -1359,7 +1361,8 @@ static void load_history(line_input_t *st_parm) | |||
1359 | } | 1361 | } |
1360 | free(temp_h[idx]); | 1362 | free(temp_h[idx]); |
1361 | temp_h[idx] = line; | 1363 | temp_h[idx] = line; |
1362 | st_parm->cnt_history_in_file++; | 1364 | if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) |
1365 | st_parm->cnt_history_in_file++; | ||
1363 | idx++; | 1366 | idx++; |
1364 | if (idx == st_parm->max_history) | 1367 | if (idx == st_parm->max_history) |
1365 | idx = 0; | 1368 | idx = 0; |
@@ -1389,15 +1392,66 @@ static void load_history(line_input_t *st_parm) | |||
1389 | st_parm->history[i++] = line; | 1392 | st_parm->history[i++] = line; |
1390 | } | 1393 | } |
1391 | st_parm->cnt_history = i; | 1394 | st_parm->cnt_history = i; |
1395 | if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) | ||
1396 | st_parm->cnt_history_in_file = i; | ||
1392 | } | 1397 | } |
1393 | } | 1398 | } |
1394 | 1399 | ||
1395 | /* state->flags is already checked to be nonzero */ | 1400 | # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT |
1401 | void save_history(line_input_t *st) | ||
1402 | { | ||
1403 | FILE *fp; | ||
1404 | |||
1405 | if (!(st->flags & SAVE_HISTORY)) | ||
1406 | return; | ||
1407 | if (!st->hist_file) | ||
1408 | return; | ||
1409 | if (st->cnt_history <= st->cnt_history_in_file) | ||
1410 | return; | ||
1411 | |||
1412 | fp = fopen(st->hist_file, "a"); | ||
1413 | if (fp) { | ||
1414 | int i, fd; | ||
1415 | char *new_name; | ||
1416 | line_input_t *st_temp; | ||
1417 | |||
1418 | for (i = st->cnt_history_in_file; i < st->cnt_history; i++) | ||
1419 | fprintf(fp, "%s\n", st->history[i]); | ||
1420 | fclose(fp); | ||
1421 | |||
1422 | /* we may have concurrently written entries from others. | ||
1423 | * load them */ | ||
1424 | st_temp = new_line_input_t(st->flags); | ||
1425 | st_temp->hist_file = st->hist_file; | ||
1426 | st_temp->max_history = st->max_history; | ||
1427 | load_history(st_temp); | ||
1428 | |||
1429 | /* write out temp file and replace hist_file atomically */ | ||
1430 | new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid()); | ||
1431 | fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); | ||
1432 | if (fd >= 0) { | ||
1433 | fp = xfdopen_for_write(fd); | ||
1434 | for (i = 0; i < st_temp->cnt_history; i++) | ||
1435 | fprintf(fp, "%s\n", st_temp->history[i]); | ||
1436 | fclose(fp); | ||
1437 | if (rename(new_name, st->hist_file) == 0) | ||
1438 | st->cnt_history_in_file = st_temp->cnt_history; | ||
1439 | } | ||
1440 | free(new_name); | ||
1441 | free_line_input_t(st_temp); | ||
1442 | } | ||
1443 | } | ||
1444 | # else | ||
1396 | static void save_history(char *str) | 1445 | static void save_history(char *str) |
1397 | { | 1446 | { |
1398 | int fd; | 1447 | int fd; |
1399 | int len, len2; | 1448 | int len, len2; |
1400 | 1449 | ||
1450 | if (!(state->flags & SAVE_HISTORY)) | ||
1451 | return; | ||
1452 | if (!state->hist_file) | ||
1453 | return; | ||
1454 | |||
1401 | fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); | 1455 | fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); |
1402 | if (fd < 0) | 1456 | if (fd < 0) |
1403 | return; | 1457 | return; |
@@ -1441,6 +1495,7 @@ static void save_history(char *str) | |||
1441 | free_line_input_t(st_temp); | 1495 | free_line_input_t(st_temp); |
1442 | } | 1496 | } |
1443 | } | 1497 | } |
1498 | # endif | ||
1444 | # else | 1499 | # else |
1445 | # define load_history(a) ((void)0) | 1500 | # define load_history(a) ((void)0) |
1446 | # define save_history(a) ((void)0) | 1501 | # define save_history(a) ((void)0) |
@@ -1469,15 +1524,16 @@ static void remember_in_history(char *str) | |||
1469 | for (i = 0; i < state->max_history-1; i++) | 1524 | for (i = 0; i < state->max_history-1; i++) |
1470 | state->history[i] = state->history[i+1]; | 1525 | state->history[i] = state->history[i+1]; |
1471 | /* i == state->max_history-1 */ | 1526 | /* i == state->max_history-1 */ |
1527 | if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT && state->cnt_history_in_file) | ||
1528 | state->cnt_history_in_file--; | ||
1472 | } | 1529 | } |
1473 | /* i <= state->max_history-1 */ | 1530 | /* i <= state->max_history-1 */ |
1474 | state->history[i++] = xstrdup(str); | 1531 | state->history[i++] = xstrdup(str); |
1475 | /* i <= state->max_history */ | 1532 | /* i <= state->max_history */ |
1476 | state->cur_history = i; | 1533 | state->cur_history = i; |
1477 | state->cnt_history = i; | 1534 | state->cnt_history = i; |
1478 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1535 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT |
1479 | if ((state->flags & SAVE_HISTORY) && state->hist_file) | 1536 | save_history(str); |
1480 | save_history(str); | ||
1481 | # endif | 1537 | # endif |
1482 | IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) | 1538 | IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) |
1483 | } | 1539 | } |