Reputation: 68
I need to find who locked a file using python (posix/linux). Currently I use 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. Structure passed to fcntl contains fields such as off_t or pid_t. I cannot make assumptions about sizes of those 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 sizes of off_t and pid_t? The solution must be fully portable between different architectures.
Edit I decided to use lsof program as suggested below. Another option is to parse /proc/locks file.
Upvotes: 3
Views: 2057
Reputation: 347
I had previously used 'hhllh'
because I thought it would most closely map to off_t
across platforms. But eventually I settled on 'hhqqh'
, which works for me on 32bit and 64bit systems.
I was surprised by this solution, but what seems to be going on for the the 32bit boxes I was looking at is bits/fcntl.h
creates the flock
struct with off64_t
unless the system already defines __USE_FILE_OFFSET64
(in which case it just uses the regular 'ol off_t
) so it seems like the size of l_start
and l_len
is always 8 (the python struct format char 'q'
is long long
).
This is probably not entirely portable, I can't say all modern 32bit systems are going to do this, but it was good enough for me for now - so I thought I'd mention it in case others (like myself) would rather not have to exec another process and do a bunch of string parsing, YMMV. Also if I'm misunderstanding (or poorly explaining) why this format string seems to work on both platforms - maybe someone could correct me?
Upvotes: 0
Reputation: 2361
Maybe you can try use external program, lsof, to do that?
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
Upvotes: 4