3 ms·
> On POSIX systems, in theory, we can just update the files in place. Except for dynamically loaded assets, this should work just fine. The OS treats file locki
by saagarjha 1y ago
> On POSIX systems, in theory, we can just update the files in place. Except for dynamically loaded assets, this should work just fine. The OS treats file locking as advisory and open file descriptors are irrelevant, so even if the file is running you overwrite it in place and the user will get the freshest version on the next launch.
If you do this on macOS, and your code is codesigned, you are setting yourself for pain. Instead you should replace the file entirely so the file gets a new vnode.
- piker 1y agoThat's super interesting. Tritium is signed and notarized (as is required) and uses the clean second-binary approach on all platforms, so I never ran into this. One thing that did come up was the requirement to use `ditto` rather than a standard unzipping utility to preserve some macOS-sensitive metadata. [EDIT: the post has been updated for this point. Thanks so much. https://tritium.legal/blog/update#3 https://tritium.legal/blog/update#3.]
- saagarjha 1y agoFWIW https://developer.apple.com/documentation/security/updating-mac-software https://developer.apple.com/documentation/security/updating-... is the relevant documentation for this if you want more details.
- silon42 1y agoNot just MacOS, on Linux this is the correct strategy too. It covers more cases: either a new instance is starting, or it hasn't fully loaded the file yet.
- formerly_proven 1y agoBinaries are memory-mapped, there is no guarantee for code to be resident. Modifying a running binary hence can cause a mixture of code to be paged into a running application. Which is why unix traditionally has a special "non-advisory" file locking for mapped binaries, which tries to give you an ETXTBSY error. This is nowhere near fool-proof though, e.g. Linux stopped doing this for mapped .so files, it probably doesn't work on NFS etc.
- fulafel 1y agoTraditionally if you update the contents of a running binary in-place in Unix you're liable to get a SIGBUS. The way to do it is unlink the existing binary and create a new one with the same name. Which is eg what install(1) does.
- amluto 1y agoSIGBUS or SIGSEGV if you’re lucky. It’s really an outrageous memory safety violation and could do anything, even allow RCE (in a narrow window).
- kelnos 1y agoThat isn't robust to failures, though. What you sould be doing is first writing the new binary using a temporary file name, and then you can rename the new file to the correct binary name, which is an atomic operation.