1# Non-Blocking Exclusive Lock Test
2
3use Test;
4use File::NFSLock;
5use Fcntl qw(O_CREAT O_RDWR O_RDONLY O_TRUNC LOCK_EX LOCK_NB);
6
7$| = 1; # Buffer must be autoflushed because of fork() below.
8plan tests => 8;
9
10my $datafile = "testfile.dat";
11
12# Create a blank file
13sysopen ( FH, $datafile, O_CREAT | O_RDWR | O_TRUNC );
14close (FH);
15ok (-e $datafile && !-s _);
16
17
18ok (pipe(RD1,WR1)); # Connected pipe for child1
19if (!fork) {
20  # Child #1 process
21  my $lock = new File::NFSLock {
22    file => $datafile,
23    lock_type => LOCK_EX | LOCK_NB,
24  };
25  print WR1 !!$lock; # Send boolean success status down pipe
26  close(WR1); # Signal to parent that the Non-Blocking lock is done
27  close(RD1);
28  if ($lock) {
29    sleep 2;  # hold the lock for a moment
30    sysopen(FH, $datafile, O_RDWR);
31    # now put a magic word into the file
32    print FH "child1\n";
33    close FH;
34  }
35  exit;
36}
37ok 1; # Fork successful
38close (WR1);
39# Waiting for child1 to finish its lock status
40my $child1_lock = <RD1>;
41close (RD1);
42# Report status of the child1_lock.
43# It should have been successful
44ok ($child1_lock);
45
46
47ok (pipe(RD2,WR2)); # Connected pipe for child2
48if (!fork) {
49  # Child #2 process
50  my $lock = new File::NFSLock {
51    file => $datafile,
52    lock_type => LOCK_EX | LOCK_NB,
53  };
54  print WR2 !!$lock; # Send boolean success status down pipe
55  close(WR2); # Signal to parent that the Non-Blocking lock is done
56  close(RD2);
57  if ($lock) {
58    sysopen(FH, $datafile, O_RDWR);
59    # now put a magic word into the file
60    print FH "child2\n";
61    close FH;
62  }
63  exit;
64}
65ok 1; # Fork successful
66close (WR2);
67# Waiting for child2 to finish its lock status
68my $child2_lock = <RD2>;
69close (RD2);
70# Report status of the child2_lock.
71# This lock should not have been obtained since
72# the child1 lock should still have been established.
73ok (!$child2_lock);
74
75# Wait until the children have finished.
76wait; wait;
77
78# Load up whatever the file says now
79sysopen(FH, $datafile, O_RDONLY);
80$_ = <FH>;
81close FH;
82
83# It should be child1 if it was really nonblocking
84# since it got the lock first.
85ok /child1/;
86
87# Wipe the temporary file
88unlink $datafile;
89