Repository navigation
fix: keep windows.json and stylesheet.css intact when a save fails - #587
Open
prakash-aryan wants to merge 1 commit into
Open
prakash-aryan wants to merge 1 commit into
prakash-aryan wants to merge 1 commit into
Conversation
Gio.File.replace_contents() writes to a temporary file and renames it over the destination when the stream is closed. When a write fails part way, for example with ENOSPC on a full disk, GLib still closes the stream normally, so the partially written temporary file replaces the original. On a full disk that file is empty. Forge saves windows.json every time a window is closed, so a full disk empties it and the next login fails with "JSON.parse: unexpected end of data" (forge-ext#415). The stylesheet is saved the same way. GLib.file_set_contents() removes its temporary file when a write fails and leaves the original in place. Like the REPLACE_DESTINATION flag used before, it replaces symlinks and does not keep the old permissions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #415. This complements #536 and #579, which make Forge start with the default rules when
windows.jsonis already empty or broken. This change stops Forge from emptying the file in the first place.Problem
set windowPropsandThemeManagerBase._updateCss()save withGio.File.replace_contents(). When a write inside it fails part way, for example with ENOSPC on a full disk, GLib still closes the stream normally and renames the partially written temporary file over the original. On a full disk that file is empty. This is GLib behaviour, and it is still present on GLib main.windowDestroy()callsremoveFloatOverride(), which saveswindows.jsonevery time a window is closed. Closing any window while the disk is full therefore empties the file, and the next login fails with:This matches the comment in #415 about the file being emptied when
/homefilled up. It happened to me twice, each time a few minutes after the disk filled.Change
Both saves now use
GLib.file_set_contents(), which deletes its temporary file when a write fails and leaves the original in place. Successful saves behave as before: likeREPLACE_DESTINATION, it replaces a symlink with a regular file and does not keep the old permissions.A failed save still throws, as it did before. This change only keeps the existing file intact.
Testing
GNOME Shell 46.0, GJS 1.80.2 and GLib 2.80.0 on Ubuntu 24.04.
~/.config/forgewas a 64 KiB tmpfs filled to 0 bytes free.End to end, in a headless GNOME Shell (
--headless --virtual-monitor) with its own XDG directories, D-Bus session and keyfile settings backend, running Forge from this repository:mainwindows.jsonsizeJSON.parse)Each save path called directly from GJS, each on a freshly filled filesystem:
mainconfigMgr.windowProps = ..._updateCss()No temporary files were left behind in any run. With free space, both branches save and read back the same rules, produce the same file mode and replace a symlinked
windows.jsonwith a regular file.prettier@2.7.1 --checkis clean.To reproduce by hand, mount a small tmpfs on
~/.config/forge, copy the existing files back into it, fill it withdd if=/dev/zero of=~/.config/forge/fill, close a tiled window and restart GNOME Shell.