Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^3: fcntl failure after eval

by Animator (Hermit)
on Aug 12, 2011 at 08:09 UTC ( [id://919994]=note: print w/replies, xml ) Need Help??


in reply to Re^2: fcntl failure after eval
in thread fcntl failure after eval

This does look like the right answer.

There are 3 different cases to consider:

  1. a 32 bit system with large file support (-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64)
  2. a 32 bit system without large file support
  3. a 64 bit system

ikegami's c program for each of the three:

  1. 32 bit system with LFS:
    $ gcc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall a.c -o a && a
    flock:          24
    flock.l_type:   2 @  0
    flock.l_whence: 2 @  2
    flock.l_start:  8 @  4
    flock.l_len:    8 @ 12
    flock.l_pid:    4 @ 20
    
  2. 32 bit system without LFS:
    $ gcc  -Wall a.c -o a && a
    flock:          16
    flock.l_type:   2 @  0
    flock.l_whence: 2 @  2
    flock.l_start:  4 @  4
    flock.l_len:    4 @  8
    flock.l_pid:    4 @ 12
    
  3. 64 bit system:
    $ gcc  -Wall a.c -o a && a
    flock:          32
    flock.l_type:   2 @  0
    flock.l_whence: 2 @  2
    flock.l_start:  8 @  8
    flock.l_len:    8 @ 16
    flock.l_pid:    4 @ 24
    

The test perls:

  1. stock perl-5.10.0, running on a 32 bit system with large file support
  2. debian perl-5.10.0, running on a 32 bit system with large file support
  3. debian perl-5.10.1, running on a 64 bit system

Changing the op's code to:

  • my $flags = pack('sslli', F_WRLCK, SEEK_SET, 5, 0);
    • perl 1: length of flags: 16 bits, expected length: 24 bits
      fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=5, len=0}, 0x9d827d0) = 0
      => this probably works by accident
      
    • perl 2: length of flags: 16 bits, expected length: 24 bits (running as a normal user)
      fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=5, len=0}, 0x819b4a8) = 0
      => this probably works by accident
      
    • perl 2: length of flags: 16 bits, expected length: 24 bits (running as root)
      fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=5, len=2314885392840523776}, 0x81ed670) = 0
      => the length parameter does not contain the expected value
    • perl 3: length of flags: 16 bits, expected length: 32 bits
      fcntl(3, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0
      => not correct, start is 0 but 'expected' value is 5
      
  • my $flags = pack('sslllli', F_WRLCK, SEEK_SET, 5, 0, 2, 0, 0);
    • perl 1: length of flags: 24 bits, expected length: 24 bits
      fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=5, len=2}, 0x970c7d0) = 0
      
    • perl 2: length of flags: 24 bits, expected length: 24 bits (running as a normal user and as root)
      fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=5, len=2}, 0x819b4a8) = 0
      
    • perl 3: length of flags: 24 bits, expected length: 32 bits
      fcntl(3, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=8589934592, len=0}) = 0
      
  • my $flags = pack("s s x4 q q L x4", F_WRLCK, SEEK_SET, 5, 2, 0);
    • perl 3: length of flags: 32 bits, expected length: 32 bits
      fcntl(3, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=5, len=2}) = 0
      

What this all means is that the value you need for $flags depends highly on the system it is running.. Which makes me wonder wheter or not there is a better way to accomplish what the op wants..

Replies are listed 'Best First'.
Re^4: fcntl failure after eval
by ikegami (Patriarch) on Aug 12, 2011 at 08:30 UTC

    pack('sslllli',

    Aside from the fact that it's very weird that you're mixing specific width specifiers (like "l") with loose width specifiers (like "i"), "ll" is not right. Won't handle negative offsets.

    Which makes me wonder wheter or not there is a better way to accomplish what the op wants..

    Use C to create the structure.

      Many thanks for the responses. I'm not super-confident with pack or C... My man fcntl says:

      struct flock { ... short l_type; /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */ short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */ off_t l_start; /* Starting offset for lock */ off_t l_len; /* Number of bytes to lock */ pid_t l_pid; /* PID of process blocking our lock (F_GETLK only) */ ... };

      So you're saying that the size of off_t, which appears from /usr/include to be a long, depends on the system I'm running on, and the only way to be sure is to compile a program which includes the definition of this type, and see what size it is in the result.

      Does perl not know what this type is, as it's been compiled for the system on which it's running? If not (or there's no way for my script to get the information from the interpreter), I guess there's no portable pure perl solution? That's a bit of a pain - I need to lock files on NFS, flock doesn't work there and manually managing lockfiles seems a bit of a crummy solution.

      On my systems, doing or not doing the eval consistenly makes the program work or not work - is this just some fluke side effect of uninitialised memory?

      Thanks again,

      Pete

        Does perl not know what this type is, as it's been compiled for the system on which it's running? If not (or there's no way for my script to get the information from the interpreter),

        $ perl -V:ldflags ldflags='-s -L"c:\perl\5.14.1\lib\MSWin32-x86-multi-thread\CORE" -L"C: +\MinGW\lib"'; $ perl -V:archlib archlib='c:\perl\5.14.1\lib\MSWin32-x86-multi-thread'; $ grep -ri "define off_t " C:\perl\5.14.1\lib\MSWin32-x86-multi-thread +\CORE C:\perl\5.14.1\lib\MSWin32-x86-multi-thread\CORE/config.h:#define Off_ +t long long /* <offset> type */ C:\perl\5.14.1\lib\MSWin32-x86-multi-thread\CORE/perl.h:# define + Off_t off64_t C:\perl\5.14.1\lib\MSWin32-x86-multi-thread\CORE/uconfig.h:#define Off +_t int /* <offset> type */
        You want to read $Config::Config{archlib}/CORE/config.h
        /* Off_t: * This symbol holds the type used to declare offsets in the kernel +. * It can be int, long, off_t, etc... It may be necessary to includ +e * <sys/types.h> to get any typedef'ed information. */ /* LSEEKSIZE: * This symbol holds the number of bytes used by the Off_t. */ /* Off_t_size: * This symbol holds the number of bytes used by the Off_t. */ #define Off_t long long /* <offset> type */ #define LSEEKSIZE 8 /* <offset> size */ #define Off_t_size 8 /* <offset> size */
        $ perl "-V:.+?seek.+?" d_fseeko='undef'; d_lseekproto='define'; d_seekdir='define'; lseeksize='8'; lseektype='long long';
        See also Convert::Binary::C/ccconfig

        man fcntl says the even the order of the fields if system specific. Padding between the fields is compiler and system specific. The size of some of these fields is system specific.

        Does perl not know what this type is

        Perl surely does #include <fcntl.h>, so it does know.

        I guess there's no portable pure perl solution?

        fcntl itself is not portable.

        Aside from that, it's most definitely possible.

        You're asking for a Pure Perl way of getting the structure your C compiler would created from the info the system provides in fcntl.h.

        Perl (via Config) does provide the info you need to launch the C compiler using system, although Inline::C will simplify the process.

        This could even be done by your installer.

        You could even do this at development time. Perl (via Config) does specify which compiler and system it's running on, so you could look up the right structure at run-time.

        That's a bit of a pain

        That the system specifies its input as compiler-specific C code? yeah.

        I've just found File::NFSLock on CPAN - it seems to use manual lockfiles, you have to specify timeouts for stale locks - not a great solution.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://919994]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-03-29 00:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found