Search code examples
cfile-iofreebsd

ETXTBSY and how to override it


I need to write to an executable file that is being executed, but I can't open it for writing. For example:

#include <stdio.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
    int fd = open(argv[0], O_RDWR);
    if (fd == -1) perror(NULL);
    return 0;
}
% uname -rs
FreeBSD 8.0-STABLE
% ./example_ETXTBSY
Text file busy

There are some explanations what the heck is ETXTBSY in Linux, but nevertheless, is it possible to override this error?

P.S.
I'm not trying to write a virus.


Solution

  • If you are trying to replace an executing file, as opposed to modifying an executable on the fly, you can unlink() it first and then open it for writing.

    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    
    int main(int argc, char **argv)
    {
        unlink(argv[0]);
        int fd = open(argv[0], O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
            if (fd == -1) perror(NULL);
                return 0;
    }
    

    If you are trying to get access to the actual running process, your best bet is ptrace().

    (Edited to add the mode bits.)