How do I check if a file is in use?

M

Mark

Hi all,

This is something which has been bugging me for ages. How can I check
if a file is already in use by a different program?

It doesn't seem to matter which mode I pass to fopen, it will always
allow me to open the file. I've tried r, r+, w, w+, a, and a+ but
still the fopen call will not return null.

Basically what I'm doing is using a kqueue to watch a particular
directory to see when files are added, I'm then using the path of the
file which has just arrived as input to another program, however, I
need to be sure that the new file has completely finished
copying/downloading etc before passing it off to this other program.

What's happening just now is that the kqueue is firing as soon as the
file starts to appear in the directory and my secondary program is
being launched too early.

Can anyone offer any advice please?

Thanks in advance,

Mark

PS. If it helps to know, I'm using Mac OS X, so a platform specific
response is also fine if no ANSI/POSIX solution exists.
 
B

Ben Pfaff

Mark said:
This is something which has been bugging me for ages. How can I check
if a file is already in use by a different program?

It doesn't seem to matter which mode I pass to fopen, it will always
allow me to open the file. I've tried r, r+, w, w+, a, and a+ but
still the fopen call will not return null.

You need some kind of operating system specific mechanism here.
You'd be best off asking about it in a group specific to your OS.

(Many OSes allow any number of programs to open a single file at
once, at least by default.)
 
W

Walter Roberson

Mark said:
This is something which has been bugging me for ages. How can I check
if a file is already in use by a different program?

You can't in standard C, as standard C considers multitasking to
be non-essential behaviour outside of the standard.
Basically what I'm doing is using a kqueue to watch a particular
directory to see when files are added,

Standard C doesn't know anything about directories: those are
extensions.
PS. If it helps to know, I'm using Mac OS X, so a platform specific
response is also fine if no ANSI/POSIX solution exists.

You might be able to find something in POSIX; try asking in
comp.unix.programmer .
 
M

Mark

Hrm, I was afraid that might be the case that it's not possible in
standard C. I'll see if anyone in com.unix.programmer has any thoughts.

Thanks for the fast replies anyway.

Mark
 
J

jmcgill

Mark said:
Hrm, I was afraid that might be the case that it's not possible in
standard C. I'll see if anyone in com.unix.programmer has any thoughts.

Thanks for the fast replies anyway.

Mark

You should look at lsof and fuser sources (or just use fuser directly
via system() or whatever).

There's a lsof for macOsX:
http://lsof.darwinports.com/
 
D

Dave Thompson

This is something which has been bugging me for ages. How can I check
if a file is already in use by a different program?
Basically what I'm doing is using a kqueue to watch a particular
directory to see when files are added, I'm then [reading it]. I
need to be sure that the new file has completely finished
copying/downloading etc before passing it off to this other program.

As already said, there is no portable way.

The almost completely portable things you can do are to have the
creating/supplying program create a separate 'flag' or 'status' file
after it finishes creating the main file, and watch for that; or have
it initially write into a filename that indicates it is 'temporary' or
'in use' and when complete rename it to a different name. This can
either be a fixed temporary name, or one of a pattern, like
'work_Fred_Daily_Report_0908' to 'ready_Fred_Daily_Report_0908'.
These obviously require some control over the creating process, and
the platform must support files with somewhat controllable names in
the first case and atomic renames in the second; pretty much every
system nowadays does both of these.

Another almost almost completely portable thing you can do is check
the modtime on the file say every 10 seconds or minute or so and look
to see when it stops changing. This depends on the filesystem having
modtimes (most do) and updating them for open files (Windows
apparently still doesn't) and the creating process not going 'idle'
for longish periods during its execution (perhaps waiting for received
data, if downloading).
PS. If it helps to know, I'm using Mac OS X, so a platform specific
response is also fine if no ANSI/POSIX solution exists.

There probably is, but I wouldn't know about it.


- David.Thompson1 at worldnet.att.net
 
J

jmcgill

Mark said:
This is something which has been bugging me for ages. How can I check
if a file is already in use by a different program?

You need to consider the file locking semantics as specified by your
platform, but there is nothing in Standard C to truly deal with this
situation.
It doesn't seem to matter which mode I pass to fopen, it will always
allow me to open the file. I've tried r, r+, w, w+, a, and a+ but still
the fopen call will not return null.

Most flavors of Unix have some variety of flock and/or fcntl which can
accomplish various degrees of advisory or mandatory locks. Some of
these are portable across certain families of operating systems, some
are specific to a single platform, but all are nonportable extensions
and not part of the C language.
PS. If it helps to know, I'm using Mac OS X, so a platform specific
response is also fine if no ANSI/POSIX solution exists.

MacOSX has a POSIX-compliant flock(). Use that. Enforced by the
kernel, only one process can get an exclusive lock on a file. These are
advisory locks, which means your procedure is required to check for a
lock before writing -- which it won't be actively prevented from doing.

This is off topic for the c.l.c. group, but might be interesting on
comp.unix.programmer or one of the OSX groups.
 
A

Ancient_Hacker

Mark said:
Hi all,

This is something which has been bugging me for ages. How can I check
if a file is already in use by a different program?


There's a very basic problem here-- nobody can predict the future.

Even if there was a standard C function named FileIsFree( char * Path
), there's no way it, or any other function, could ensure that file
would still exist, be free, or contain the same data, even one CPU
clock cycle later.

So any attempt to do this is bound to fail, some of the time. I assume
that's not good enough for a production program.

What you need to do is find some operation that is "atomic", i.e.
indivisible, irrevocable, and can only happen to a unbusy file.

For example, change the program or batch file that is writing the file
to write the file to /tmp/foo.bar. When it's done, have it close the
file, then rename it to the proper destination file name. On every OS
I can forsee, "rename" is an atomic operation, i.e. you'll never see
the file in both places, or no place (well, maybe this) at any one
time.

If you can't change the source program, maybe you can wrap it in a
batch file that does the renaming.

-----

Another possibility, very non-portable, but in Windows you can make API
requests that cause a function in your program to be called every time
a file or directory changes. That's a very good low-overhead way to
do what you need, but specific to Windows.

I don't think the Unix flavors have this kind of hook but of course it
may be a recent addition or a Linux kernel addon.
 
K

Keith Thompson

Ancient_Hacker said:
For example, change the program or batch file that is writing the file
to write the file to /tmp/foo.bar. When it's done, have it close the
file, then rename it to the proper destination file name. On every OS
I can forsee, "rename" is an atomic operation, i.e. you'll never see
the file in both places, or no place (well, maybe this) at any one
time.

It's not safe to assume that renaming a file is an atomic operation.
The C standard makes no such guarantee about the rename() function.

If the original file is on different physical media than the target
file, renaming it almost certainly *isn't* atomic; it has to copy the
contents of the file to the new location. (On some systems, you can
avoid this by ensuring that the original and destination files are
both in the same directory, but since the standard has no concept of
directories, any details are off-topic.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top