]>
Commit | Line | Data |
---|---|---|
9f95a23c | 1 | #!/usr/bin/python3 |
7c673cae | 2 | |
9f95a23c | 3 | from contextlib import contextmanager |
7c673cae FG |
4 | import errno |
5 | import fcntl | |
6 | import signal | |
7 | import struct | |
8 | ||
9f95a23c TL |
9 | @contextmanager |
10 | def timeout(seconds): | |
11 | def timeout_handler(signum, frame): | |
12 | raise InterruptedError | |
13 | ||
14 | orig_handler = signal.signal(signal.SIGALRM, timeout_handler) | |
15 | try: | |
16 | signal.alarm(seconds) | |
17 | yield | |
18 | finally: | |
19 | signal.alarm(0) | |
20 | signal.signal(signal.SIGALRM, orig_handler) | |
21 | ||
22 | ||
7c673cae FG |
23 | """ |
24 | introduced by Linux 3.15 | |
25 | """ | |
20effc67 TL |
26 | setattr(fcntl, "F_OFD_GETLK", 36) |
27 | setattr(fcntl, "F_OFD_SETLK", 37) | |
28 | setattr(fcntl, "F_OFD_SETLKW", 38) | |
7c673cae FG |
29 | |
30 | ||
7c673cae FG |
31 | def main(): |
32 | f1 = open("testfile", 'w') | |
33 | f2 = open("testfile", 'w') | |
34 | ||
35 | fcntl.flock(f1, fcntl.LOCK_SH | fcntl.LOCK_NB) | |
36 | ||
37 | """ | |
11fdf7f2 | 38 | is flock interruptible? |
7c673cae | 39 | """ |
9f95a23c TL |
40 | with timeout(5): |
41 | try: | |
42 | fcntl.flock(f2, fcntl.LOCK_EX) | |
43 | except InterruptedError: | |
44 | pass | |
45 | else: | |
46 | raise RuntimeError("expect flock to block") | |
7c673cae FG |
47 | |
48 | fcntl.flock(f1, fcntl.LOCK_UN) | |
49 | ||
50 | lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 10, 0, 0) | |
51 | try: | |
52 | fcntl.fcntl(f1, fcntl.F_OFD_SETLK, lockdata) | |
53 | except IOError as e: | |
54 | if e.errno != errno.EINVAL: | |
55 | raise | |
56 | else: | |
57 | print('kernel does not support fcntl.F_OFD_SETLK') | |
58 | return | |
59 | ||
60 | lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 10, 10, 0, 0) | |
61 | fcntl.fcntl(f2, fcntl.F_OFD_SETLK, lockdata) | |
62 | ||
63 | """ | |
11fdf7f2 | 64 | is posix lock interruptible? |
7c673cae | 65 | """ |
9f95a23c TL |
66 | with timeout(5): |
67 | try: | |
68 | lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) | |
69 | fcntl.fcntl(f2, fcntl.F_OFD_SETLKW, lockdata) | |
70 | except InterruptedError: | |
71 | pass | |
72 | else: | |
73 | raise RuntimeError("expect posix lock to block") | |
7c673cae FG |
74 | |
75 | """ | |
76 | file handler 2 should still hold lock on 10~10 | |
77 | """ | |
78 | try: | |
79 | lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 10, 10, 0, 0) | |
80 | fcntl.fcntl(f1, fcntl.F_OFD_SETLK, lockdata) | |
81 | except IOError as e: | |
82 | if e.errno == errno.EAGAIN: | |
83 | pass | |
84 | else: | |
85 | raise RuntimeError("expect file handler 2 to hold lock on 10~10") | |
86 | ||
87 | lockdata = struct.pack('hhllhh', fcntl.F_UNLCK, 0, 0, 0, 0, 0) | |
88 | fcntl.fcntl(f1, fcntl.F_OFD_SETLK, lockdata) | |
89 | fcntl.fcntl(f2, fcntl.F_OFD_SETLK, lockdata) | |
90 | ||
91 | print('ok') | |
92 | ||
93 | ||
94 | main() |