I wonder how killer applications such as Thunderbird or Firefox can be updated via the system's package manager while they are still running. What happens with the old code while they are being updated? What do I have to do when I want to write a program a.out that updates itself while it is running?
Replacing files in general
First, there are several strategies to replace a file:
I won't list all the differences between the strategies, I'll just mention some that are important here. With stategy 1, if any process is currently using the file, the process sees the new content as it's being updated. This can cause some confusion if the process expects the file content to remain the same. Note that this is only about processes that have the file open (as visible in
With strategies 2 and 3, if some process has the file
With strategy 3, the step of moving the new file to the existing name removes the directory entry leading to the old content and creates a directory entry leading to the new content. This is done in one atomic operation, so this strategy has a major advantage: if a process opens the file at any time, it will either see the old content or the new content — there's no risk of getting mixed content or of the file not existing.
If you try strategy 1 with a running executable on Linux, you'll get an error.
A “text file” means a file containing executable code for obscure historical reasons. Linux, like many other unix variants, refuses to overwrite the code of a running program; a few unix variants allow this, leading to crashes unless the new code was a very well though-out modification of the old code.
On Linux, you can overwrite the code of a dynamically loaded library. It's likely to lead to a crash of the program that's using it. (You might not be able to observe this with
If an interpreter is running a script, the script file is opened in an ordinary way by the interpreter, so there is no protection against overwriting the script. Some interpreters read and parse the whole script before they start executing the first line, others read the script as needed. See What happens if you edit a script during execution? and How Does Linux deal with shell scripts? for more details.
Strategies 2 and 3 are safe for executables as well: although running executables (and dynamically loaded libraries) aren't open files in the sense of having a file descriptor, they behave in a very similar way. As long as some program is running the code, the file remains on disk even without a directory entry.
Upgrading an application
Most package managers use strategy 3 to replace files, because of the major advantage mentioned above — at any point in time, opening the file leads to a valid version of it.
Where application upgrades can break is that while upgrading one file is atomic, upgrading the application as a whole isn't if the application consists of multiple files (program, libraries, data, …). Consider the following sequence of events:
In step 3, the running instance of the old version of the application is opening a data file from the new version. Whether this works or not depends on the application, of which file it is and how much the file has been modified.
After an upgrade, you'll note that the old program is still running. If you want to run the new version, you'll have to exit the old program and run the new version. Package managers usually kill and restart daemons on an upgrade, but leave end-user applications alone.
A few daemons have special procedures to handle upgrades without having to kill the daemon and wait for the new instance to restart (which causes a service disruption). This is necessary in the case of init, which cannot be killed; init systems provide a way to request that the running instance call
The upgrade can be run while the program runs, but the running program you see is actually the old version of it. The old binary remains on the disk until you close the program.
Explanation: on Linux systems, a file is just an inode, which can have several links to it. Eg. the
If you want to write a program that "upgrades" itself while running, the only possible solution I can think of is to periodically check the timestamp of its own binary file, and if it's newer than the program's start time, then reload itself.
I wonder how killer applications such as Thunderbird or Firefox can be updated via the system's package manager while they are still running? Well, I can tell you that this doesn't really work well... I've had Firefox break on me quite horribly if I left it open while a package update was running. I had to kill it forcefully sometimes and restart it, because it was so broken I couldn't even close it properly.
What happens with the old code while they are being updated? Normally on Linux a program is loaded into memory, so the executable on disk isn't needed or used while the program is running. In fact you can even delete the executable and the program shouldn't care... However, some programs may need the executable, and certain OSs (like Windows) will lock the executable file, preventing deletion or even renames/moves, while the program is running. Firefox breaks, because its actually quite complex and uses a bunch of data files that tell it how to build its GUI (user interface). During a package update these files get overwritten (updated), so when an older Firefox executable (in memory) tries to use the new GUI files, weird things can happen...
What do I have to do when I want to write a program a.out that updates itself while it is running? There are lots of answers to your question already. Check this out: http://stackoverflow.com/questions/232347/how-should-i-implement-an-auto-updater By the way, questions about programming are better off on StackOverflow.