Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Self Deletion
by andreychek (Parson) on Jul 07, 2001 at 08:46 UTC | |
However, I'm happy to announce that this code is tested, it does work, and I'll describe what it does so you know what you're getting yourself into :-) Update: Code has been removed until the original posted states why they want it.. while there are many legitimate reasons for this, there are also plenty of malicious ones. Update 2: The original poster has posted a very legitimate reason for requiring this functionality. So without further ado, I have re-posted this code. I appologize for the delay, but unfortunatly not everyone is honest these days. Good luck! -Eric | [reply] [d/l] |
by tadman (Prior) on Jul 07, 2001 at 12:16 UTC | |
This wasn't a suspicious request like: calculating criticle massJust as knives could be used to hurt people, they are most often used for cooking or other peaceful and productive purposes. | [reply] |
by stuffy (Monk) on Jul 07, 2001 at 13:44 UTC | |
Stuffy That's my story, and I'm sticking to it, unless I'm wrong in which case I will probably change it ;~) may be reproduced under the SDL | [reply] |
by John M. Dlugosz (Monsignor) on Jul 08, 2001 at 00:32 UTC | |
by Anonymous Monk on Jul 09, 2001 at 01:51 UTC | |
| [reply] |
|
Re: Self Deletion
by clintp (Curate) on Jul 07, 2001 at 17:50 UTC | |
I wrote a user-space filesystem caching program for Ford Motor, and one of the problems was trying to delete (cache out) a file in use. The support scripts for the caching program often had to be removed and couldn't. The error returned by unlink is ETXTBUSY. A workaround is to detect ETXTBUSY on unlink, and move the file up a directory in the tree with link, and then delete the original with unlink. The i-node isn't removed (and this makes the OS happy) but the directory is emptied (and this makes the programmer happy). | [reply] |
by bluto (Curate) on Jul 07, 2001 at 19:43 UTC | |
FWIW, unlinking a running executable is usually only a problem when it resides on an NFS server, since in that case the code really does go away immediately (leading to interesting results). So I imagine this is pretty much the same on HPUX since it is really just a way to keep someone from hurting themselves, but not an absolute necessity. Of course I'm probably mistaken... bluto | [reply] |
by Anonymous Monk on Jul 07, 2001 at 20:37 UTC | |
It's not just AIX, it's most unices. When a program is run, part of the program is mmap'd so copying over the file would corrupt the program's memory (whereas deleting the file would not, due to the way unix handles open files with a 0 link count). | [reply] |
|
Re: Self Deletion
by cLive ;-) (Prior) on Jul 07, 2001 at 13:41 UTC | |
Then: should do the trick* cLive ;-) PS -for some reason, I'm assuming it's a CGI script. *I am reasonably drunk, so if I'm wrong, take it with a pinch of salt... | [reply] [d/l] |
|
Re: Self Deletion
by John M. Dlugosz (Monsignor) on Jul 07, 2001 at 21:33 UTC | |
| [reply] [d/l] |
by tye (Sage) on Jul 08, 2001 at 09:02 UTC | |
I recall being surprised when I found out that vi was writing a new file with the same name rather than overwriting the existing contents of the file. But testing today shows vi overwriting existing contents. I think this may have changed when truncate became a standard function (or my memory may just be confused, especially since I did a lot of VMS before that). I'd be very surprised if any of these were false: But this all got me curious. I checked Bleach.pm and find that it does overwrite the existing script contents (which is what I expected). Perl having the script file open doesn't prevent this from happening. Win32 is one of the few places where just having the script open would prevent you from deleting it. This makes it convenient for testing this. For example, this script: unlink($0) or warn $!,$/,$^E,$/; successfully deletes itself under Win32 while these two: and BEGIN { unlink($0) or warn $!,$/,$^E,$/ } both fail with So note that your own process can qualify as "another process" as far as this error is concerned. It really should say "via another file handle". So Perl has the script open while it is parsing it but closes it after that unless you have a __DATA__ or __END__ token. So updating the script while it is running would only cause a problem if you did it while the script was still being parsed or if the script had __DATA__/__END__. So the script should also be able to delete itself (unless if has __END__/__DATA__ and you haven't closed DATA yet) even under Win32. However, the script probably won't be able to delete the directory that it is in under Win32. If any process is currently chdired to a directory, then you aren't allowed to delete that directory under Win32. (Under Unix, you should be able to delete the script and the directory no matter who has them open.) So you might have to chdir("..") under Win32 and even that might not be enough. Then again, under Win32 you can also use Win32API::File to request that files/directories that are currently in use be deleted during the next reboot. Finally, the reason that you can't delete the Perl script while Perl still has it open is because the C run-time library under Win32 defaults to specifying sharing of "rw" and not "rwd". I wish they had opted for "rwd", but my time machine is still broken. When you open a file in Win32, you specify what type of sharing you would like. Many Win32 programs that don't use the C run-time library's I/O layer specify 0 for the sharing (probably as much because they didn't bother to think about what type of sharing they should be allowing as for any logical reason) so that you can't even look at the file contents while the programming is running. This sucks. But that is plenty of rambling for now... - tye (but my friends call me "Tye") | [reply] [d/l] [select] |
by John M. Dlugosz (Monsignor) on Jul 08, 2001 at 09:55 UTC | |
I checked Bleach.pm and find that it does overwrite the existing script contents (which is what I expected). Perl having the script file open doesn't prevent this from happening.You mean opening $0 for writing will overwrite the existing file's contents, and although Perl may still have it open, the way it was opened doesn't prevent it from being opened for writing (at least by the same process or same security context). I suppose that the normal ">" mode of Perl truncates the file to zero length. But, in Win32, the deleting of a file is prohibited if it's open at all, regardless of what sharing modes are specified. In my experience of saving changes to a PM while it was still running, when the editor saves by writing to a temp file first, then if successful deleting the old and renaming the new, would fail if __DATA__ was being used. The fact that it may close or leave open, depending, explains differing observations on the subject. I thank you for sheding light on this. So you might have to chdir("..") under Win32 and even that might not be enough.It should be enough, unless spawned tasks are still using it. It's enough for that script.
Then again, under Win32 you can also use Win32API::File to request that files/directories that are currently in use be deleted during the next reboot.The mechanism is totally different for NT/2000 than it is for Win 3.1/95/98/ME. The function in Win32API::File is only present on the former. Finally, the reason that you can't delete the Perl script while Perl still has it open is because the C run-time library under Win32 defaults to specifying sharing of "rw" and not "rwd". I wish they had opted for "rwd", but my time machine is still broken.Are you sure that's possible on Win32? If it's just a matter of the defaults passed to the underlying functions, you could change the Perl source. —John | [reply] |
by tye (Sage) on Jul 08, 2001 at 10:43 UTC | |
by John M. Dlugosz (Monsignor) on Jul 22, 2001 at 07:49 UTC | |
For compatibility with older scripts written before __DATA__ was introduced, __END__ behaves like __DATA__ in the toplevel script (but not in files loaded with require or do) and leaves the remaining contents of the file accessible via main::DATA.So, I wonder if an __END__ in a .pm file will not have the unwanted side effect of holding that file open, like it does in the main file. This is good news for those who want to continue putting the pod at the end. —John | [reply] |