From: Trent Huber Date: Thu, 4 Sep 2025 19:18:46 +0000 (-0400) Subject: Fix history when running multiple sessions X-Git-Url: https://trenthuber.com/code?a=commitdiff_plain;h=3c1d0429d62a82b76a037989ce9bf12fe21cdad7;p=thus.git Fix history when running multiple sessions --- diff --git a/src/history.c b/src/history.c index 899eaf9..2c50ba5 100644 --- a/src/history.c +++ b/src/history.c @@ -16,9 +16,18 @@ static struct { char path[PATH_MAX], entries[MAXHIST + 1][MAXCHARS + 1]; - size_t b, c, t; + size_t b, s, c, t; } history; +static void readhistory(FILE *file) { + history.b = history.t = 0; + while (fgets(history.entries[history.t], sizeof*history.entries, file)) { + history.entries[history.t][strlen(history.entries[history.t]) - 1] = '\0'; + if (INC(t) == history.b) INC(b); + } + history.s = history.c = history.t; +} + void inithistory(void) { FILE *file; @@ -29,12 +38,8 @@ void inithistory(void) { if (errno == ENOENT) return; fatal("Unable to open history file for reading"); } - while (fgets(history.entries[history.t], sizeof*history.entries, file)) { - history.entries[history.t][strlen(history.entries[history.t]) - 1] = '\0'; - if ((history.c = INC(t)) == history.b) INC(b); - } - if (ferror(file) || !feof(file)) - fatal("Unable to read from history file"); + readhistory(file); + if (ferror(file) || !feof(file)) fatal("Unable to read from history file"); if (fclose(file) == EOF) fatal("Unable to close history file"); } @@ -52,33 +57,50 @@ int gethistory(int back, char *buffer) { void sethistory(char *buffer) { strcpy(history.entries[history.t], buffer); - if ((history.c = INC(t)) == history.b) INC(b); + history.c = INC(t); + if (history.t == history.b) INC(b); + if (history.t == history.s) INC(s); *history.entries[history.t] = '\0'; } +static void writehistory(FILE *file) { + for (history.c = history.b; history.c != history.t; INC(c)) { + if (fputs(history.entries[history.c], file) == EOF) { + note("Unable to write to history file"); + break; + } + if (fputc('\n', file) == EOF) { + note("Unable to terminate line of history file"); + break; + } + } +} + void deinithistory(void) { int fd; FILE *file; if (!interactive) return; - if ((fd = open(history.path, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1) { + if ((fd = open(history.path, O_WRONLY | O_CREAT | O_APPEND, 0600)) == -1) { note("Unable to open history file for writing"); return; } - if (!(file = fdopen(fd, "w"))) { + if (!(file = fdopen(fd, "a"))) { note("Unable to open history file descriptor as FILE pointer"); return; } - for (history.c = history.b; history.c != history.t; INC(c)) { - if (fputs(history.entries[history.c], file) == EOF) { - note("Unable to write to history file"); - break; - } - if (fputc('\n', file) == EOF) { - note("Unable to terminate line of history file"); - break; - } + history.b = history.s; + writehistory(file); + if (!freopen(history.path, "r", file)) { + note("Unable to reopen history file for reading"); + return; + } + readhistory(file); + if (!freopen(history.path, "w", file)) { + note("Unable to reopen history file for writing"); + return; } + writehistory(file); if (fclose(file) == EOF) note("Unable to close history stream"); }