Is it possible to write a program in C that upon execution deletes itself (the binary) and then terminates successfully. If so, what's the easiest way of doing this?
-
3It is probably possible to write a program that deletes the .exe file or whatever, though you may have to jump through some hoops since in some environments the OS locks the .exe while executing it. – Hot Licks Apr 01 '12 at 14:34
5 Answers
Yes.
#include <unistd.h>
int main(int argc, char* argv[])
{
return unlink(argv[0]);
}
(Tested and works.)
Note that if argv[0]
does not point to the binary (rewritten by caller) this will not work.
Similarly if run through a symlink then the symlink, not the binary, will be deleted.
Also if the file has multiple hard links, only the called link will be removed.

- 6,742
- 2
- 39
- 63
-
6Here we get into the usual business about the reliability of `argv[0]` as the path to the binary. POSIX says that is *should* point to the binary, but does not require it and the API allows programs to set it to something else. The end result is, this usually works, but is not reliable. Moreover, even if you have a correct path, the binary may be hardlinked in more than one place. – dmckee --- ex-moderator kitten Apr 01 '12 at 14:48
-
Doesn't actually work. @LuchianGrigore is right, after calling unlink add a sleep(30), then while the program is asleep run "lsof" in another terminal (this is a *nix utility) and you will see that the OS still has a handle to the file open. The file is gone from "ls" but it does still exist until the program ends and the OS closes its handle. – SoapBox Apr 01 '12 at 14:50
-
1@SoapBox - Yes it does. Upon completing execution, is it or is it not gone from the file system? At least that's what I was asking how to do. – Alex Coplan Apr 01 '12 at 14:51
-
1@dmckee I'm interested in an example that deals with that situation. – blueshift Apr 01 '12 at 14:52
-
As far as I know there *isn't* a completely standard solution. You may be able to finesse it on linux using the `/proc` pseudo-filesystem. – dmckee --- ex-moderator kitten Apr 01 '12 at 14:59
-
1This answer could be **really fun** if it's a suid-root binary trying to delete itself... ;-) – R.. GitHub STOP HELPING ICE Apr 01 '12 at 16:25
-
This is not a solution using **C**. `unlink` is POSIX, not part of the requirement. – Jens Gustedt Apr 01 '12 at 19:45
I do not know that one can conveniently do it in a truly platform-independent way, but you didn't specify platform independence, so try the following, Linux-style code:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv) {
printf("Read carefully! You cannot print this message again.\n");
return unlink(argv[0]);
}
How close is that to what you want?

- 13,796
- 3
- 40
- 68
-
11That is the wackiest typing of arguments to main() I have ever seen. – blueshift Apr 01 '12 at 14:42
-
2Those are non-standard arguments to `main`, incidentally. Given that, it only serves to make your example code harder for a newcomer to understand... – Oliver Charlesworth Apr 01 '12 at 15:22
-
By popular demand, I am revising my answer now! [I will however note that my GCC 4.4 compiler, if invoked with the `-Wall` and `-Wextra` switches, emits a warning if I fail to precede `int argc` with `__attribute__((unused))` in this particular example. The reason is, of course, that `argc` is here unused.] – thb Apr 01 '12 at 15:30
-
@OliCharlesworth is rightly a stickler for the standard. I had thought that I was, too, until I encountered him, but he takes it to another level. But for his comment, I would say that it lay in the freedom of the programmer to receive variable arguments as constant parameters, and that it were prudent to make most objects const when one does not mean to vary them. However, there may remain some hidden problem with my consts that Oli sees and I do not. Nonetheless, my consts have proved a distraction, so I have removed them. They weren't the main point of my answer, anyway. – thb Apr 01 '12 at 15:36
-
1@thb: In practice, it won't hurt anything in this situation. But in the general case, a `T**` is not convertible to a `const T**`, so it's best not to conflate the two. – Oliver Charlesworth Apr 01 '12 at 15:38
-
1Well, I have learned something today. @OliCharlesworth [has earlier noted](http://stackoverflow.com/questions/7108957/c-const-convert) http://c-faq.com/ansi/constmismatch.html, which explains his point. Interesting. – thb Apr 01 '12 at 15:54
If you operating system allows a running program to delete its own binary, then just look for the API for file deletion, or execute a corresponding system()
command.
If the OS doesn't allow this, your program (let's call it A) could construct another binary, containing another program (let's call it B). Then, A would immediately quit.
Program B would have a single loop checking if A is still running and as soon as A quits, B would erase A's binary.

- 8,409
- 1
- 25
- 36
-
1Well, the mission was to kill A, wasn't it? B can rest in some temp folder and wait to be swept off sometime. – Imp Apr 01 '12 at 14:48
-
@Imp if the objective was to destroy any evidence of the original file then that will certainly work – Alex Coplan Apr 01 '12 at 14:53
-
-
3@AlexCoplan Ok, to destroy _any_ evidence we should also write some zeros onto the file's original position on disk ;) – Imp Apr 01 '12 at 15:01
You could try to just delete the executable in the program (FILE* and stuff)... but seeing as that executable is what's being run it might not work. I see it like eating yourself, and as far as I know it's not possible, but you could certainly give it a try using the method I mentioned above.
I think it is dependent on the platform you are using. Basically, once the executable is loaded, any subsequent change to the binary does not affect the running program. In Unix, this is the case, and you can use the unlink system call.
I am not sure whether this is true on Windows or not. It may not be allowed to delete the executable image. You can try the DeleteFile() api in Windows.

- 183
- 7