77#![ allow( non_camel_case_types) ]
88#![ allow( nonstandard_style) ]
99
10+ use std:: fs:: { File , OpenOptions } ;
1011use std:: io;
1112use std:: path:: Path ;
1213
1314cfg_if ! {
14- if #[ cfg( unix ) ] {
15+ if #[ cfg( target_os = "linux" ) ] {
1516 use std:: os:: unix:: prelude:: * ;
16- use std:: fs:: { File , OpenOptions } ;
1717
1818 #[ derive( Debug ) ]
1919 pub struct Lock {
@@ -27,11 +27,11 @@ cfg_if! {
2727 exclusive: bool )
2828 -> io:: Result <Lock > {
2929 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) ?;
3535
3636 let mut operation = if exclusive {
3737 libc:: LOCK_EX
@@ -44,8 +44,7 @@ cfg_if! {
4444
4545 let ret = unsafe { libc:: flock( file. as_raw_fd( ) , operation) } ;
4646 if ret == -1 {
47- let err = io:: Error :: last_os_error( ) ;
48- Err ( err)
47+ Err ( io:: Error :: last_os_error( ) )
4948 } else {
5049 Ok ( Lock { _file: file } )
5150 }
@@ -55,10 +54,68 @@ cfg_if! {
5554 // Note that we don't need a Drop impl to execute `flock(fd, LOCK_UN)`. Lock acquired by
5655 // `flock` is associated with the file descriptor and closing the file release it
5756 // 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+ }
58116 } else if #[ cfg( windows) ] {
59117 use std:: mem;
60118 use std:: os:: windows:: prelude:: * ;
61- use std:: fs:: { File , OpenOptions } ;
62119
63120 use winapi:: um:: minwinbase:: { OVERLAPPED , LOCKFILE_FAIL_IMMEDIATELY , LOCKFILE_EXCLUSIVE_LOCK } ;
64121 use winapi:: um:: fileapi:: LockFileEx ;
0 commit comments