LRN
2011-10-07 05:29:14 UTC
I've been wondering about the way cygwin forks W32 processes.
One of the things W32 seems to be unable to do is to let you delete an
executable file that is being executed (AFAIU, there's a file handle
opened somewhere within w32 subsystem, preventing that).
One of the most prominent self-deleting techniques is to run another
process, have it wait upon the main process, and once the main process
terminates, also delete main process' executable, and then terminate
itself (special delete-on-close behaviour is used to remove the
executable of the second process). This is, again, due to the fact
that the main process can't delete its own executable while it is running.
When fork() runs, it usually creates the forked process based on the
same executable image file, which is (usually) replaced later by the
contents of another executable file (using exec()).
However, AFAICS, nothing really prevents me from creating a fork()
variant that creates a new process using a *copy* of the original
executable image file, and then closing the original. This way it
should be possible to release the handle W32 subsystem keeps on the
original image file, so that it can be removed or replaced.
However we all remember the base addresses problem that arises when
forking in cygwin (and maybe other problems that i am not aware of),
so maybe forking is not a viable solution here (assuming that
arbitrary non-cygwin processes are going to be "moved" this way)? Are
matching base addresses for DLLs simply one of the POSIX requirements,
or is it a practical requirement (i.e. things break if this
requirement is not fulfilled)?
One of the things W32 seems to be unable to do is to let you delete an
executable file that is being executed (AFAIU, there's a file handle
opened somewhere within w32 subsystem, preventing that).
One of the most prominent self-deleting techniques is to run another
process, have it wait upon the main process, and once the main process
terminates, also delete main process' executable, and then terminate
itself (special delete-on-close behaviour is used to remove the
executable of the second process). This is, again, due to the fact
that the main process can't delete its own executable while it is running.
When fork() runs, it usually creates the forked process based on the
same executable image file, which is (usually) replaced later by the
contents of another executable file (using exec()).
However, AFAICS, nothing really prevents me from creating a fork()
variant that creates a new process using a *copy* of the original
executable image file, and then closing the original. This way it
should be possible to release the handle W32 subsystem keeps on the
original image file, so that it can be removed or replaced.
However we all remember the base addresses problem that arises when
forking in cygwin (and maybe other problems that i am not aware of),
so maybe forking is not a viable solution here (assuming that
arbitrary non-cygwin processes are going to be "moved" this way)? Are
matching base addresses for DLLs simply one of the POSIX requirements,
or is it a practical requirement (i.e. things break if this
requirement is not fulfilled)?