On Tue, Mar 14, 2017 at 10:05 PM, Dennis Lee Bieber <wlfr...@ix.netcom.com> wrote: > On Wed, 15 Mar 2017 00:07:32 +1100, Chris Angelico <ros...@gmail.com> > >>Yes, but you can't always control the process that opens them. For >>example, it's annoyingly difficult to update a running executable. >> > I wouldn't be surprised if Windows mmap()'s running executables into > swap space, rather than actually swapping in-core image to the normal swap > file.
Executables are memory mapped, and this also applies to memory-mapped data files (i.e. CreateFileMapping / MapViewOfFile) like with Python's mmap module. Notice how the fastfat driver's function that sets the delete disposition, FatSetDispositionInfo [1], has to check for this by calling the kernel memory-manager function MmFlushImageSection [2] (note that a flush type of MmFlushForDelete also checks the number of views of the data section). If the mapped view prevents deleting the file it returns STATUS_CANNOT_DELETE. This status code gets translated to the Windows error code ERROR_ACCESS_DENIED, for which Python raises a PermissionError. This is misleading because you were probably granted delete access. The file just can't be deleted. Typically you can still open such files with delete access to allow renaming (relinking) them to another directory on the volume. You're just not allowed to unlink them. [1]: https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/fileinfo.c#L2417 [2]: https://msdn.microsoft.com/en-us/library/ff549808 It's also interesting that the sharing mode is special cased. Normally if write access isn't shared you're denied the right to open the file with either write or append access. But with executables mapped by the loader, you can still open them for append access. The C runtime's POSIX (low) I/O layer has its own implementation of append mode that requires opening the file with both write and append access (O_WRONLY | O_APPEND), which is what Python's "a" mode uses. So you have to call CreateFile directly to get append-only access. For example, using a virtual environment copy of python.exe: append = 4 h = _winapi.CreateFile(sys.executable, append, 7, 0, 3, 0, 0) _winapi.WriteFile(h, b'spam') f = open(sys.executable, 'rb') f.seek(-4, os.SEEK_END) >>> f.read() b'spam' -- https://mail.python.org/mailman/listinfo/python-list