How do I check if a file is in use?

Discussion in 'C Programming' started by Mark, Sep 8, 2006.

  1. Mark

    Mark Guest

    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.
     
    Mark, Sep 8, 2006
    #1
    1. Advertising

  2. Mark

    Ben Pfaff Guest

    Mark <> writes:

    > 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.)
    --
    "The lusers I know are so clueless, that if they were dipped in clue
    musk and dropped in the middle of pack of horny clues, on clue prom
    night during clue happy hour, they still couldn't get a clue."
    --Michael Girdwood, in the monastery
     
    Ben Pfaff, Sep 8, 2006
    #2
    1. Advertising

  3. In article <2006090818032575249-markjallan@gmailcom>,
    Mark <> wrote:

    >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 .
    --
    "law -- it's a commodity"
    -- Andrew Ryan (The Globe and Mail, 2005/11/26)
     
    Walter Roberson, Sep 8, 2006
    #3
  4. Mark

    Mark Guest

    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
     
    Mark, Sep 8, 2006
    #4
  5. Mark

    jmcgill Guest

    Mark wrote:
    > 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/
     
    jmcgill, Sep 8, 2006
    #5
  6. Mark

    Sensei Guest

    On 2006-09-08 20:14:43 +0200, jmcgill <> said:

    > Mark wrote:
    >> 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/


    <OT>
    The lsof command comes with OSX (maybe with xcode), no need of fink or
    darwinports.
    </OT>

    --
    Sensei <senseiwa@Apple's mail>

    Research (n.): a discovery already published by a chinese guy one month
    before you, copying a russian who did it in the 60s.
     
    Sensei, Sep 9, 2006
    #6
  7. On Fri, 08 Sep 2006 17:03:34 GMT, Mark <> wrote:

    > 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
     
    Dave Thompson, Sep 21, 2006
    #7
  8. Mark

    jmcgill Guest

    Mark wrote:

    > 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.
     
    jmcgill, Sep 21, 2006
    #8
  9. Mark wrote:
    > 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.
     
    Ancient_Hacker, Sep 21, 2006
    #9
  10. "Ancient_Hacker" <> writes:
    [...]
    > 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.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 21, 2006
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Davisro
    Replies:
    1
    Views:
    701
    Michael D. Ober
    Jun 14, 2004
  2. mit
    Replies:
    1
    Views:
    834
    Ramu Pulipati
    Jan 25, 2006
  3. kris
    Replies:
    0
    Views:
    531
  4. kris
    Replies:
    0
    Views:
    492
  5. kris
    Replies:
    1
    Views:
    5,290
Loading...

Share This Page