gh-123018: Keep the libedit history file header when truncating - #157165
Conversation
| static int | ||
| _py_libedit_history_truncate_file(const char *filename, int nlines) | ||
| { | ||
| static const char cookie[] = "_HiStOrY_V2_\n"; |
There was a problem hiding this comment.
over in #121160 the earlier choice was not to do a workaround because it seemed fragile. yes this PR intentionally decides the other way. libedit is not likely to change or a fix to it become widely distributed any time soon. apple patched theirs rather than push on upstream. if netbsd libedit does adopt a new history format version, this marker won't match and this function basically becomes a no-op that does nothing.
There was a problem hiding this comment.
It looks like someone did at least file a NetBSD bug this year https://gnats.netbsd.org/60322
9ac2d9c to
39d13be
Compare
libedit's history_truncate_file() keeps the last N lines of the file, which drops the "_HiStOrY_V2_" header line that its own write_history() emits and that its read_history() requires. So on a libedit build, readline.write_history_file() or readline.append_history_file() after readline.set_history_length() produced a file that readline.read_history_file() rejected with EINVAL. Under the libedit emulation, truncate the file ourselves and keep the header, resolving the default "~/.history" the same way libedit does. Apple's libedit fork already preserves the header, so the workaround is not compiled on macOS.
39d13be to
9b6d270
Compare
|
Thanks @gpshead for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15. |
|
GH-157172 is a backport of this pull request to the 3.15 branch. |
|
Sorry, @gpshead, I could not cleanly backport this to |
|
GH-157173 is a backport of this pull request to the 3.14 branch. |
|
Yay! Thank you. |
GH-157165) (#157173) gh-123018: Keep the libedit history file header when truncating (GH-157165) libedit's history_truncate_file() keeps the last N lines of the file, which drops the "_HiStOrY_V2_" header line that its own write_history() emits and that its read_history() requires. So on a libedit build, readline.write_history_file() or readline.append_history_file() after readline.set_history_length() produced a file that readline.read_history_file() rejected with EINVAL. Under the libedit emulation, truncate the file ourselves and keep the header, resolving the default "~/.history" the same way libedit does. Apple's libedit fork already preserves the header, so the workaround is not compiled on macOS. (cherry picked from commit 2638785) Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
libedit's history_truncate_file() keeps the last N lines of the file, which drops the
"_HiStOrY_V2_"header line that its own write_history() emits and that its read_history() requires. So on a libedit build, readline.write_history_file() or readline.append_history_file() after readline.set_history_length() produced a file that readline.read_history_file() rejected with EINVAL.Under the libedit emulation, truncate the file ourselves and keep the header, resolving the default "~/.history" the same way libedit does. Apple's libedit fork already preserves the header, so the workaround is not compiled on macOS.