Find the PID of the process that locked the file

I need to find who has locked a file using python (posix / linux). I am currently using this method:

flk = struct.pack('hhqql', fcntl.F_WRLCK, 0, 0, 0, 0)
flk = struct.unpack('hhqql', fcntl.fcntl(self.__file, fcntl.F_GETLK , flk))

if flk[0] == fcntl.F_UNLCK:
    # file is unlocked ...
    pid = flk[4]


This solution is not architecture independent. The structure passed to fcntl contains fields such as off_t or pid_t. I cannot make assumptions about the sizes of these types.

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) */


Is there any other way to find the PID? Or maybe the off_t and pid_t sizes? The solution must be completely portable across different architectures.

Edit I decided to use the lsof program as suggested below. Another option is to parse the / proc / locks.


source to share

2 answers

Maybe you can try using an external program, lsof, to do this?

   Lsof revision 4.85 lists on its standard output file information 
   about files opened by processes for the following UNIX dialects:

        AIX 5.3
        Apple Darwin 9 and Mac OS X 10.[56]
        FreeBSD 4.9 and 6.4 for x86-based systems
        FreeBSD 8.[02] and 9.0 for AMD64-based systems
        Linux 2.1.72 and above for x86-based systems
        Solaris 9, 10 and 11




I used to use 'hhllh'

it because I thought it would display most closely off_t

on different platforms. But I ended up settling on 'hhqqh'

which works for me on 32bit and 64bit systems.

I was surprised at this solution, but what seems to be happening for the 32 bit boxes I was looking at is it bits/fcntl.h

creates a structure flock

with off64_t

if the system doesn't already detect __USE_FILE_OFFSET64

(in this case it just uses the normal "ol off_t

), so the size l_start

and l_len

is always 8 (python char structure format 'q'

is long long


This is probably not entirely portable, I can't say that all modern 32-bit systems are going to do this, but it worked well enough for me, so I thought I'd mention it if others (like me) are more likely to , you don't have to do another process and do a bunch of string parsing, YMMV. Also if I am misunderstanding (or explaining poorly) why this format string works on both platforms - maybe someone can fix me?



All Articles