aboutsummaryrefslogtreecommitdiff
path: root/libbb/lineedit.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-09-04 16:12:33 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-09-04 16:12:33 +0200
commitbede215cf105377a1127532d2d710924cb58cc39 (patch)
treed0227961b7eb002cb03653f2e69211e6cf13d598 /libbb/lineedit.c
parent4840ae8a06298e987374fa3cc6d7e4969fd19344 (diff)
downloadbusybox-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.c68
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
1401void 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
1396static void save_history(char *str) 1445static 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}