Load/save robustness: OOM-safe load, guarded open loop, save fallbacks
- OpenFromFile builds the new content in a separate PieceTable and swaps it in only when complete. A reload that ran out of memory used to leave the buffer empty (filename, journal and dirty state intact), and the next save truncated the file. - Editor::ProcessPendingOpens catches exceptions from opening (it runs in every frontend's loop, outside command dispatch, so bad_alloc on a huge file ended the editor); the terminal draw is guarded too. - The hard-link save copy uses a unique mkstemp name, so a leftover copy no longer blocks every later save; if no copy can be created the file is still written in place. - When no temp file can be created in the directory (file writable, directory not), an existing regular file is written in place instead of the save failing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
@@ -1110,3 +1110,19 @@ TEST(Audit_VisualLine_StaysInsideBuffer)
|
||||
(void) h.Undo();
|
||||
ASSERT_EQ(h.Text(), orig);
|
||||
}
|
||||
|
||||
|
||||
// A leftover copy from an interrupted hard-link save does not block saving.
|
||||
TEST(Audit_Save_HardLink_LeftoverCopyDoesNotBlock)
|
||||
{
|
||||
TempDir d("save_leftover");
|
||||
std::ofstream(d.path / "h.txt") << "old\n";
|
||||
std::filesystem::create_hard_link(d.path / "h.txt", d.path / "h2.txt");
|
||||
std::ofstream(d.path / "h.txt.kte-save") << "stale\n";
|
||||
Buffer b;
|
||||
std::string err;
|
||||
ASSERT_TRUE(b.OpenFromFile((d.path / "h.txt").string(), err));
|
||||
b.insert_text(0, 0, "new ");
|
||||
ASSERT_TRUE(b.Save(err));
|
||||
ASSERT_EQ(slurp(d.path / "h2.txt"), std::string("new old\n"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user