Saving writes to a new file, not the one opened
Describe the bug
When opening a script using the GUI and then saving it the text is saved to a new file [with the original file's name]. The save should be made to the original file.
To Reproduce
(Steps 1–3 and 7 performed from the command line.)
- Create a script:
echo 'a=1;' > test_1.scad - Create a hard-linked copy of it:
ln test_1.scad test_2.scad - Verify that both point to the same file:
ls -1i test_1.scad test_2.scadThe same number [inode] should be shown for both, e.g.:
6467257 test_1.scad
6467257 test_2.scad
- Open
test_1.scadwith OpenSCAD. - Make changes to the script.
- Save the script.
- Check whether the script file was modified in-place:
ls -1i test_1.scad test_2.scad
6467275 test_1.scad
6467257 test_2.scad
Observe that the script has been saved to a new file [the inode number has changed].
Expected behaviour
When saving to an existing file the text should be updated in-place, not written to a new file.
Additional notes
The same in-place write behaviour should occur whenever a file is written to by OpenSCAD (e.g. PNG export); I have not checked the current behaviour in these cases.
Unexpected behaviour [by OpenSCAD] could occur if a script is saved by the user whilst in the process of being evaluated by another OpenSCAD instance. The likelihood of this occurring is extremely low and the ramifications of such are probably minor; this is thus probably not a concern.
Environment and Version info:
- OS: Ubuntu 22.04 LTS
- System: Intel PC 64-bit
- OpenSCAD Version 2025.11.30 (built from source)
Write and rename-into-place is a standard mechanism; it means that a crash during write doesn't trash your file. (It also avoids writing a file that OpenSCAD is reading.)
It does mean that hard links get broken. IMO, c'est la vie, better that than any chance of losing the file.
Not a bug, save uses the Qt mechanism doing what @jordanbrown0 described:
https://github.com/openscad/openscad/blob/dc495e2f12255d9f4474441a232053cbb3a0e47d/src/gui/TabManager.cc#L604-L616
What's the argument for changing this behavior? Not trashing the existing file on save (e.g. on disk full) seems a strong argument for having this behavior for the manually edited text files.
@bitbasher I found your note 😁. What's other way you have seen?
What's the argument for changing this behavior?
One use case is for a library file that is used (via use or include) in multiple projects. Each project has a local copy of the library but a change (e.g. a bug fix) in one copy should be applied to all copies. With hard links and in-place saves this is the case.
With a soft link the linked-to file is the one that OpenSCAD modifies on save.¹ However, using soft links to a single library file has multiple downsides; a few examples:
- Soft links are brittle, e.g.:
- Moving the canonical (linked-to) copy to a new location breaks all the links.
- With a relative link moving the link (the one in the project, not the linked-to file) to a new location will break the link unless the relative location is equivalent.
- Projects are no longer self-contained; e.g. copying or archiving them² only copies the link, not the contents of the file it points to.
¹ e.g.:
echo 'a=1;' > 1.scad; ln -s 1.scad 2.scad- Edit
2.scadin OpenSCAD and save it 1.scadhas been modified (it's a new file, i.e. new inode) and the link is untouched.
² e.g. with cp -a or rsync -a --link-dest=…
@bitbasher I found your note 😁. What's other way you have seen?
Saw that note as well and was similarly curious.
FWIW, one common way to handle this is to copy the file to a backup (e.g. filename.scad.bck) and then, if the backup was successful, perform an in-place write to the original file. Optionally the backup file could be removed if the save is successful (to prevent inadvertently overwriting the backup in this case, attempts to save could be blocked [with user notification] if the backup file is present).
* Soft links are brittle, e.g.: * Moving the canonical (linked-to) copy to a new location breaks all the links.
Leave a forwarding link.
Also hard links cannot be used across mount points, so if you need to you can't with hard links.
* With a relative link moving the link (the one in the project, not the linked-to file) to a new location will break the link unless the relative location is equivalent.
Don't use relative links.
* Projects are no longer self-contained; e.g. copying or archiving them² only copies the link, not the contents of the file it points to.
Use --copy-links with rsync.
Hard links have just as many downsides as symbolic links. IMO this proposal is worse than the existing behaviour for the benefit of an approach which is worse than one which works now.
Don't use relative links.
There are times to use relative links, and times to use absolute links. Getting either wrong will hurt you.