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 ...
else:
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
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
source to share
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?
source to share