How to check if a file has been opened by another application in C++?
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.
Admin
Updated on July 24, 2022Comments
-
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 almost 15 years+1 I've been looking for an app which does exactly what handle.exe does. Thanks ZombieSheep.
-
Admin almost 15 yearsCompletely operating system dependent.
-
Brian almost 15 yearsI could easily imagine someone adding a "fix" to an os in the future that broke this trick.
-
ephemient almost 15 yearsLocking is purely advisory, so this only tells you if somebody else has flocked the file.
-
Oliver Turner almost 15 yearsIn 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 almost 15 yearsI 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 almost 15 yearsI'd suggest using fuser over lsof. Parsing the results will be much simpler.
-
Kevin Doyon almost 15 yearsIn 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 over 9 yearsreally really dirty :) and we get false info about opened file when we have not rights to rename this :P
-
uthline over 4 yearsIn 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 about 4 years'not even possible in general' is not entirely true, see fuser program
-
Shiva Shahrokhi over 2 yearsI think you cannot use fuser without sudo to know if another process is accessing the file, can you? @Waslap