This source file includes following definitions.
- file_size
- do_lock
- do_unlock
- flock
- flock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <config.h>
25 #include <sys/file.h>
26
27 #if defined _WIN32 && ! defined __CYGWIN__
28
29
30 # define WIN32_LEAN_AND_MEAN
31 # include <windows.h>
32
33 # include <errno.h>
34
35
36 # if GNULIB_MSVC_NOTHROW
37 # include "msvc-nothrow.h"
38 # else
39 # include <io.h>
40 # endif
41
42
43
44
45
46 static BOOL
47 file_size (HANDLE h, DWORD * lower, DWORD * upper)
48 {
49 *lower = GetFileSize (h, upper);
50 return 1;
51 }
52
53
54 # ifndef LOCKFILE_FAIL_IMMEDIATELY
55 # define LOCKFILE_FAIL_IMMEDIATELY 1
56 # endif
57
58
59 static BOOL
60 do_lock (HANDLE h, int non_blocking, int exclusive)
61 {
62 BOOL res;
63 DWORD size_lower, size_upper;
64 OVERLAPPED ovlp;
65 int flags = 0;
66
67
68 res = file_size (h, &size_lower, &size_upper);
69 if (!res)
70 return 0;
71
72
73 memset (&ovlp, 0, sizeof ovlp);
74
75 if (non_blocking)
76 flags |= LOCKFILE_FAIL_IMMEDIATELY;
77 if (exclusive)
78 flags |= LOCKFILE_EXCLUSIVE_LOCK;
79
80 return LockFileEx (h, flags, 0, size_lower, size_upper, &ovlp);
81 }
82
83
84 static BOOL
85 do_unlock (HANDLE h)
86 {
87 int res;
88 DWORD size_lower, size_upper;
89
90 res = file_size (h, &size_lower, &size_upper);
91 if (!res)
92 return 0;
93
94 return UnlockFile (h, 0, 0, size_lower, size_upper);
95 }
96
97
98 int
99 flock (int fd, int operation)
100 {
101 HANDLE h = (HANDLE) _get_osfhandle (fd);
102 DWORD res;
103 int non_blocking;
104
105 if (h == INVALID_HANDLE_VALUE)
106 {
107 errno = EBADF;
108 return -1;
109 }
110
111 non_blocking = operation & LOCK_NB;
112 operation &= ~LOCK_NB;
113
114 switch (operation)
115 {
116 case LOCK_SH:
117 res = do_lock (h, non_blocking, 0);
118 break;
119 case LOCK_EX:
120 res = do_lock (h, non_blocking, 1);
121 break;
122 case LOCK_UN:
123 res = do_unlock (h);
124 break;
125 default:
126 errno = EINVAL;
127 return -1;
128 }
129
130
131
132
133 if (!res)
134 {
135 DWORD err = GetLastError ();
136 switch (err)
137 {
138
139 case ERROR_LOCK_VIOLATION:
140 errno = EAGAIN;
141 break;
142
143
144 case ERROR_NOT_ENOUGH_MEMORY:
145 errno = ENOMEM;
146 break;
147
148 case ERROR_BAD_COMMAND:
149 errno = EINVAL;
150 break;
151
152
153
154
155 default:
156 errno = err;
157 }
158
159 return -1;
160 }
161
162 return 0;
163 }
164
165 #else
166
167 # ifdef HAVE_STRUCT_FLOCK_L_TYPE
168
169
170 # include <fcntl.h>
171
172 # ifdef HAVE_UNISTD_H
173 # include <unistd.h>
174 # endif
175
176 # include <errno.h>
177 # include <string.h>
178
179 int
180 flock (int fd, int operation)
181 {
182 int cmd, r;
183 struct flock fl;
184
185 if (operation & LOCK_NB)
186 cmd = F_SETLK;
187 else
188 cmd = F_SETLKW;
189 operation &= ~LOCK_NB;
190
191 memset (&fl, 0, sizeof fl);
192 fl.l_whence = SEEK_SET;
193
194
195 switch (operation)
196 {
197 case LOCK_SH:
198 fl.l_type = F_RDLCK;
199 break;
200 case LOCK_EX:
201 fl.l_type = F_WRLCK;
202 break;
203 case LOCK_UN:
204 fl.l_type = F_UNLCK;
205 break;
206 default:
207 errno = EINVAL;
208 return -1;
209 }
210
211 r = fcntl (fd, cmd, &fl);
212 if (r == -1 && errno == EACCES)
213 errno = EAGAIN;
214
215 return r;
216 }
217
218 # else
219
220 # error "This platform lacks flock function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib."
221
222 # endif
223
224 #endif