fcntl call to check if a file is open - help needed

Discussion in 'Perl Misc' started by sa, Feb 19, 2007.

  1. sa

    sa Guest

    Hi all,

    Consider the script below. After reading some man and perldoc on
    fcntl, open, etc, I'm obviously doing something wrong - it gives me
    the same result regardless whether a file I'm checking is open or
    not.

    [root@willow tmp]# lsof disk.txt
    [root@willow tmp]# ./fcntl_test disk.txt
    flags: 4294964736
    O_TRUNC
    O_APPEND
    O_SYNC
    O_NOFOLLOW
    O_DIRECTORY
    O_DIRECT
    O_ASYNC
    O_LARGEFILE

    Now a run when the file is open.

    [root@willow tmp]# lsof disk.txt
    COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
    perl 22877 username 4w REG 104,6 18480 508036 disk.txt
    [root@willow tmp]# ./fcntl_test disk.txt
    flags: 4294964736
    O_TRUNC
    O_APPEND
    O_SYNC
    O_NOFOLLOW
    O_DIRECTORY
    O_DIRECT
    O_ASYNC
    O_LARGEFILE


    Here is the script. Any pointers will be greatly appreciated.
    =============================================
    #!/usr/bin/perl -w

    use Fcntl;
    use strict;
    use Symbol;

    my $fh = gensym;
    sysopen $fh, $ARGV[0], O_RDONLY or die "$ARGV[0]: Cannot open ($!)
    \n";
    my $buf = '';
    fcntl($fh, F_GETFL, $buf) or die "Cannot run fcntl\n";
    my $flags = unpack 's', $buf;
    printf "flags: %u\n", $flags;
    for my $f (qw[O_CREAT O_EXCL O_NOCTTY O_TRUNC O_APPEND O_NONBLOCK
    O_SYNC O_NOFOLLOW O_DIRECTORY O_DIRECT O_ASYNC
    O_LARGEFILE]) {
    no strict;
    print "$f\n" if ($flags & &$f) == &$f;
    }
    =============================================

    Thanks,
    Alex.
    sa, Feb 19, 2007
    #1
    1. Advertising

  2. sa

    sa Guest

    Re: fcntl call to check if a file is open - help needed

    On Feb 19, 3:50 pm, "sa" <> wrote:
    > Hi all,
    >
    > Consider the script below. After reading some man and perldoc on
    > fcntl, open, etc, I'm obviously doing something wrong - it gives me
    > the same result regardless whether a file I'm checking is open or
    > not.
    >
    > [root@willow tmp]# lsof disk.txt
    > [root@willow tmp]# ./fcntl_test disk.txt
    > flags: 4294964736
    > O_TRUNC
    > O_APPEND
    > O_SYNC
    > O_NOFOLLOW
    > O_DIRECTORY
    > O_DIRECT
    > O_ASYNC
    > O_LARGEFILE
    >
    > Now a run when the file is open.
    >
    > [root@willow tmp]# lsof disk.txt
    > COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
    > perl 22877 username 4w REG 104,6 18480 508036 disk.txt
    > [root@willow tmp]# ./fcntl_test disk.txt
    > flags: 4294964736
    > O_TRUNC
    > O_APPEND
    > O_SYNC
    > O_NOFOLLOW
    > O_DIRECTORY
    > O_DIRECT
    > O_ASYNC
    > O_LARGEFILE
    >
    > Here is the script. Any pointers will be greatly appreciated.
    > =============================================
    > #!/usr/bin/perl -w
    >
    > use Fcntl;
    > use strict;
    > use Symbol;
    >
    > my $fh = gensym;
    > sysopen $fh, $ARGV[0], O_RDONLY or die "$ARGV[0]: Cannot open ($!)
    > \n";
    > my $buf = '';
    > fcntl($fh, F_GETFL, $buf) or die "Cannot run fcntl\n";
    > my $flags = unpack 's', $buf;
    > printf "flags: %u\n", $flags;
    > for my $f (qw[O_CREAT O_EXCL O_NOCTTY O_TRUNC O_APPEND O_NONBLOCK
    > O_SYNC O_NOFOLLOW O_DIRECTORY O_DIRECT O_ASYNC
    > O_LARGEFILE]) {
    > no strict;
    > print "$f\n" if ($flags & &$f) == &$f;
    > }
    > =============================================
    >
    > Thanks,
    > Alex.


    Sorry, forgot to tell about my system: RHEL 2.1, kernel 2.4.9-e.
    59enterprise, perl v5.6.1
    sa, Feb 19, 2007
    #2
    1. Advertising

  3. sa wrote:
    >
    > Subject: fcntl call to check if a file is open - help needed


    perldoc -f fileno
    fileno FILEHANDLE
    Returns the file descriptor for a filehandle, or undefined if the
    filehandle is not open.


    John
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
    John W. Krahn, Feb 19, 2007
    #3
  4. sa

    sa Guest

    Re: fcntl call to check if a file is open - help needed

    > perldoc -f fileno
    > fileno FILEHANDLE
    > Returns the file descriptor for a filehandle, or undefined if the
    > filehandle is not open.
    >


    I don't see how it's going to work for me - I need to check whether a
    file is open by another process. Sorry if it wasn't clear. I need to
    copy the file and I should not do it if there is another process
    writing to it. To complicate things further, the file is located on a
    CIFS share. I'm in the process of checking if fcntl can do it for a
    network drive but I'm having problems using it on a local file.

    Alex.
    sa, Feb 20, 2007
    #4
  5. Re: fcntl call to check if a file is open - help needed

    On Feb 20, 12:46 pm, "sa" <> wrote:
    > > perldoc -f fileno
    > > fileno FILEHANDLE
    > > Returns the file descriptor for a filehandle, or undefined if the
    > > filehandle is not open.

    >
    > I don't see how it's going to work for me - I need to check whether a
    > file is open by another process. Sorry if it wasn't clear. I need to
    > copy the file and I should not do it if there is another process
    > writing to it. To complicate things further, the file is located on a
    > CIFS share. I'm in the process of checking if fcntl can do it for a
    > network drive but I'm having problems using it on a local file.


    Well, the first thing to do would be to check that the CIFS protocol
    is capable of conveying such a query (I don't think it is). If I'm
    wrong then see if the particular server implementation implements it.
    The look to see if the client implements it. Then, and only then,
    should you consider how to get Perl to tell the CIFS client to ask the
    CIFS server if the file is open.

    I think this is probably XY. The safest, most portable and widely
    accepted approach to having one process create a file and another read
    it only after creation is complete is to rename the file upon
    completion of creation.
    Brian McCauley, Feb 20, 2007
    #5
  6. sa

    sa Guest

    Re: fcntl call to check if a file is open - help needed

    > > I don't see how it's going to work for me - I need to check whether a
    > > file is open by another process. Sorry if it wasn't clear. I need to
    > > copy the file and I should not do it if there is another process
    > > writing to it. To complicate things further, the file is located on a
    > > CIFS share. I'm in the process of checking if fcntl can do it for a
    > > network drive but I'm having problems using it on a local file.

    >
    > Well, the first thing to do would be to check that the CIFS protocol
    > is capable of conveying such a query (I don't think it is). If I'm
    > wrong then see if the particular server implementation implements it.
    > The look to see if the client implements it. Then, and only then,
    > should you consider how to get Perl to tell the CIFS client to ask the
    > CIFS server if the file is open.
    >
    > I think this is probably XY. The safest, most portable and widely
    > accepted approach to having one process create a file and another read
    > it only after creation is complete is to rename the file upon
    > completion of creation.


    Ha! I wish I had control over the process of creating of those files!
    Unfortunately, this is totally out of the question.

    The CIFS protocol and client do know something - when I open a CIFS
    file in say, notepad, and try mv'ing it from the shell prompt - I get
    this:

    [root@willow tmp]# mv test.txt test.txt_
    mv: preserving ownership for `test.txt_': Operation not permitted
    mv: cannot unlink `test.txt': Text file busy
    mv: cannot remove `test.txt': Text file busy

    I get $! of "Text file busy" from perl when I try to rename. It looks
    like this info can be tapped into, I just don't know how.

    Going back to the original question - I'd also like to be able to do
    what lsof does using perl. lsof rocks but it's a bit slow.

    Thanks,
    Alex.
    sa, Feb 20, 2007
    #6
  7. Re: fcntl call to check if a file is open - help needed

    sa wrote:
    >>>I don't see how it's going to work for me - I need to check whether a
    >>>file is open by another process. Sorry if it wasn't clear. I need to
    >>>copy the file and I should not do it if there is another process
    >>>writing to it. To complicate things further, the file is located on a
    >>>CIFS share. I'm in the process of checking if fcntl can do it for a
    >>>network drive but I'm having problems using it on a local file.

    >>Well, the first thing to do would be to check that the CIFS protocol
    >>is capable of conveying such a query (I don't think it is). If I'm
    >>wrong then see if the particular server implementation implements it.
    >>The look to see if the client implements it. Then, and only then,
    >>should you consider how to get Perl to tell the CIFS client to ask the
    >>CIFS server if the file is open.
    >>
    >>I think this is probably XY. The safest, most portable and widely
    >>accepted approach to having one process create a file and another read
    >>it only after creation is complete is to rename the file upon
    >>completion of creation.

    >
    > Ha! I wish I had control over the process of creating of those files!
    > Unfortunately, this is totally out of the question.
    >
    > The CIFS protocol and client do know something - when I open a CIFS
    > file in say, notepad, and try mv'ing it from the shell prompt - I get
    > this:
    >
    > [root@willow tmp]# mv test.txt test.txt_
    > mv: preserving ownership for `test.txt_': Operation not permitted
    > mv: cannot unlink `test.txt': Text file busy
    > mv: cannot remove `test.txt': Text file busy
    >
    > I get $! of "Text file busy" from perl when I try to rename. It looks
    > like this info can be tapped into, I just don't know how.



    #!/usr/bin/perl -w
    use strict;

    my $old_file = shift or die "usage: $0 filename\n";
    my $new_file = "$old_file.$$";

    do {
    $! = '';
    rename $old_file, $new_file;
    } while $! =~ /Text file busy/;

    open my $fh, '<', $new_file or die "$new_file: Cannot open ($!)\n";

    # etc. ...




    John
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
    John W. Krahn, Feb 21, 2007
    #7
    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. wicur

    Fcntl problem

    wicur, Feb 2, 2004, in forum: Perl
    Replies:
    0
    Views:
    506
    wicur
    Feb 2, 2004
  2. Omid Fatemi

    fcntl and FCNTL

    Omid Fatemi, Oct 30, 2004, in forum: Python
    Replies:
    4
    Views:
    6,824
    Steve Holden
    Nov 1, 2004
  3. marcello

    [fcntl]how to lock a file

    marcello, Apr 6, 2006, in forum: Python
    Replies:
    5
    Views:
    624
    Donn Cave
    Apr 11, 2006
  4. Mitko Haralanov

    Invalid argument with fcntl.fcntl

    Mitko Haralanov, Jun 6, 2007, in forum: Python
    Replies:
    0
    Views:
    533
    Mitko Haralanov
    Jun 6, 2007
  5. Brian R.
    Replies:
    0
    Views:
    119
    Brian R.
    Jun 14, 2004
Loading...

Share This Page