7
7
#![ allow( non_camel_case_types) ]
8
8
#![ allow( nonstandard_style) ]
9
9
10
+ use std:: fs:: { File , OpenOptions } ;
10
11
use std:: io;
11
12
use std:: path:: Path ;
12
13
13
14
cfg_if ! {
14
- if #[ cfg( unix ) ] {
15
+ if #[ cfg( target_os = "linux" ) ] {
15
16
use std:: os:: unix:: prelude:: * ;
16
- use std:: fs:: { File , OpenOptions } ;
17
17
18
18
#[ derive( Debug ) ]
19
19
pub struct Lock {
@@ -27,11 +27,11 @@ cfg_if! {
27
27
exclusive: bool )
28
28
-> io:: Result <Lock > {
29
29
let file = OpenOptions :: new( )
30
- . read( true )
31
- . write( true )
32
- . create( create)
33
- . mode( libc:: S_IRWXU as u32 )
34
- . open( p) ?;
30
+ . read( true )
31
+ . write( true )
32
+ . create( create)
33
+ . mode( libc:: S_IRWXU as u32 )
34
+ . open( p) ?;
35
35
36
36
let mut operation = if exclusive {
37
37
libc:: LOCK_EX
@@ -44,8 +44,7 @@ cfg_if! {
44
44
45
45
let ret = unsafe { libc:: flock( file. as_raw_fd( ) , operation) } ;
46
46
if ret == -1 {
47
- let err = io:: Error :: last_os_error( ) ;
48
- Err ( err)
47
+ Err ( io:: Error :: last_os_error( ) )
49
48
} else {
50
49
Ok ( Lock { _file: file } )
51
50
}
@@ -55,10 +54,68 @@ cfg_if! {
55
54
// Note that we don't need a Drop impl to execute `flock(fd, LOCK_UN)`. Lock acquired by
56
55
// `flock` is associated with the file descriptor and closing the file release it
57
56
// automatically.
57
+ } else if #[ cfg( unix) ] {
58
+ use std:: mem;
59
+ use std:: os:: unix:: prelude:: * ;
60
+
61
+ #[ derive( Debug ) ]
62
+ pub struct Lock {
63
+ file: File ,
64
+ }
65
+
66
+ impl Lock {
67
+ pub fn new( p: & Path ,
68
+ wait: bool ,
69
+ create: bool ,
70
+ exclusive: bool )
71
+ -> io:: Result <Lock > {
72
+ let file = OpenOptions :: new( )
73
+ . read( true )
74
+ . write( true )
75
+ . create( create)
76
+ . mode( libc:: S_IRWXU as u32 )
77
+ . open( p) ?;
78
+
79
+ let lock_type = if exclusive {
80
+ libc:: F_WRLCK
81
+ } else {
82
+ libc:: F_RDLCK
83
+ } ;
84
+
85
+ let mut flock: libc:: flock = unsafe { mem:: zeroed( ) } ;
86
+ flock. l_type = lock_type as libc:: c_short;
87
+ flock. l_whence = libc:: SEEK_SET as libc:: c_short;
88
+ flock. l_start = 0 ;
89
+ flock. l_len = 0 ;
90
+
91
+ let cmd = if wait { libc:: F_SETLKW } else { libc:: F_SETLK } ;
92
+ let ret = unsafe {
93
+ libc:: fcntl( file. as_raw_fd( ) , cmd, & flock)
94
+ } ;
95
+ if ret == -1 {
96
+ Err ( io:: Error :: last_os_error( ) )
97
+ } else {
98
+ Ok ( Lock { file } )
99
+ }
100
+ }
101
+ }
102
+
103
+ impl Drop for Lock {
104
+ fn drop( & mut self ) {
105
+ let mut flock: libc:: flock = unsafe { mem:: zeroed( ) } ;
106
+ flock. l_type = libc:: F_UNLCK as libc:: c_short;
107
+ flock. l_whence = libc:: SEEK_SET as libc:: c_short;
108
+ flock. l_start = 0 ;
109
+ flock. l_len = 0 ;
110
+
111
+ unsafe {
112
+ libc:: fcntl( self . file. as_raw_fd( ) , libc:: F_SETLK , & flock) ;
113
+ }
114
+ }
115
+ }
58
116
} else if #[ cfg( windows) ] {
59
117
use std:: mem;
60
118
use std:: os:: windows:: prelude:: * ;
61
- use std:: fs:: { File , OpenOptions } ;
62
119
63
120
use winapi:: um:: minwinbase:: { OVERLAPPED , LOCKFILE_FAIL_IMMEDIATELY , LOCKFILE_EXCLUSIVE_LOCK } ;
64
121
use winapi:: um:: fileapi:: LockFileEx ;
0 commit comments