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;
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");
}
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");
}