How to check if a file has been opened by another application in C++?

23,170

Solution 1

Not only the standard library does not have this funcionality, it's not even possible in general. You could (on linux) check /proc/*/fd — but it is possible that your program does not have permission to do it on processes from other users (this is the default in Ubuntu, for instance).

Solution 2

The following code may work.

int main(int argc, char ** argv)
{
    int fd = open(argv[1], O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    if (fcntl(fd, F_SETLEASE, F_WRLCK) && EAGAIN == errno) {
        puts("file has been opened");
    }
    else {
        fcntl(fd, F_SETLEASE, F_UNLCK);
        puts("file has not been opened");
    }

    close(fd);
    return 0;
}

Solution 3

If you control the other process (have source code), the best plan is to use advisory locks in both processes. This locking is defined in POSIX, and will be portable across operating systems.

In Linux, you can use the utility lsof to see what files are opened by other processes.

This is limited to what you have permissions for - you have to do the check as a privileged user, or you'll only get results for files opened by the same user as the one doing the check.

I only know of the command line utility, not of any system call you can use directly from C code.

In Linux, it's also possible to turn on mandatory locking for a given filesystem (mount -o mand), and set special flags on the file (chmod g-x,g+s). Then when your process attempts to acquire a write lock, it will fail if another process has the file open. This is hardly ever used, but if you completely control the system in question, it may be an option.

Solution 4

Perhaps you could just try and get a full write lock? It'll fail if anyone else has it open for reading or writing.

fopen("myfile.txt", "r+")

If it's not cross platform and is Win32, then you can request even more fine-grained set of locks.

See here and look at dwShareMode, value of 0, as well as the other parameters.

Share:
23,170
Admin
Author by

Admin

Updated on July 24, 2022

Comments

  • Admin
    Admin almost 2 years

    I know, that there's the is_open() function in C++, but I want one program to check if a file hasn't been opened by another application. Is there any way to do it using standard library?

    EDIT - Clarified in the answers that this is for a Linux application.

  • Kei
    Kei almost 15 years
    +1 I've been looking for an app which does exactly what handle.exe does. Thanks ZombieSheep.
  • Admin
    Admin almost 15 years
    Completely operating system dependent.
  • Brian
    Brian almost 15 years
    I could easily imagine someone adding a "fix" to an os in the future that broke this trick.
  • ephemient
    ephemient almost 15 years
    Locking is purely advisory, so this only tells you if somebody else has flocked the file.
  • Oliver Turner
    Oliver Turner almost 15 years
    In linux, you can rename the file while it's open. The files are tracked by inode, not name. You can even delete the file, and the process that has it open will keep reading it without errors.
  • Tyler McHenry
    Tyler McHenry almost 15 years
    I tried looking at the lsof source code one time to see how they did it and my head almost exploded. The source to lsof is an web of insanity and black magic.
  • Anuj Singh
    Anuj Singh almost 15 years
    I'd suggest using fuser over lsof. Parsing the results will be much simpler.
  • Kevin Doyon
    Kevin Doyon almost 15 years
    In the Explorer, you can also rename files that can't be removed because they are locked. Very useful when you want to copy files over existing ones, and can't overwrite a locked file.
  • Znik
    Znik over 9 years
    really really dirty :) and we get false info about opened file when we have not rights to rename this :P
  • uthline
    uthline over 4 years
    In my case, this example always returns 'file has not been opened' even though file is opened. ls -al /proc/21862/fd/47 l-wx------ 1 user user 64 1월 29 17:12 /proc/21862/fd/47 -> /home/user/data/201802201020.mp4. (Ubuntu)
  • Waslap
    Waslap about 4 years
    'not even possible in general' is not entirely true, see fuser program
  • Shiva Shahrokhi
    Shiva Shahrokhi over 2 years
    I think you cannot use fuser without sudo to know if another process is accessing the file, can you? @Waslap