views:

1602

answers:

10

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.

+3  A: 

No, the standard library has no such functionality.

anon
A: 

Nope. Unless other application uses advisory locks.

See http://docs.sun.com/app/docs/doc/816-0213/6m6ne37v5?a=view

HMage
A: 

Non-natively, you could call out to Sysinternals' handle.exe as a last resort...

ZombieSheep
+1 I've been looking for an app which does exactly what handle.exe does. Thanks ZombieSheep.
Kei
+2  A: 
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: http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx and look at dwShareMode, value of 0, as well as the other parameters.

Pod
Completely operating system dependent.
anon
A: 

As @Neil Butterworth says, the standard library doesnt.

In unix you can use fcntl to use file locks.

You could write a wrapper for your open function, that checks for a lock (and locks if none exists) a file if its open by no one else. You shold write a wrapper for close as well, that releases that lock on file close.

Tom
Locking is purely advisory, so this only tells you if somebody else has flocked the file.
ephemient
A: 

I forgot to mension it's a linux app ;)

FYI,this should be an edit to your question rather than an answer.
Steve Fallows
A: 

In Windows this little and dirty trick will work (if the file exists and you have the right permissions)

  if (  0 != rename("c:/foo.txt", "c:/foo.txt")  ) {
     printf("already opened\n");
  }

It's likely to work also in Linux.

Nick D
This is really dirty :-)
Totonga
: )
Nick D
I could easily imagine someone adding a "fix" to an os in the future that broke this trick.
Brian
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.
jmanning2k
@jmanning2k, thanks for the info. Very interesting.
Nick D
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.
Kevin
hmm, I didn't know that. Good info, thank you Kevin.
Nick D
A: 

Why don't you write one set of funtions for one OS, and then write other set with the same function names for another OS ?

dempl_dempl
+1  A: 
CesarB
A: 

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.

jmanning2k
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.
Tyler McHenry
I'd suggest using fuser over lsof. Parsing the results will be much simpler.
AFoglia