Mercurial > hg > octave-jordi > gnulib-hg
annotate lib/flock.c @ 17587:344018b6e5d7
maint: update copyright
I ran 'make update-copyright'.
Signed-off-by: Eric Blake <eblake@redhat.com>
author | Eric Blake <eblake@redhat.com> |
---|---|
date | Wed, 01 Jan 2014 00:04:40 -0700 |
parents | e542fd46ad6f |
children | ab58d4870664 |
rev | line source |
---|---|
10598 | 1 /* Emulate flock on platforms that lack it, primarily Windows and MinGW. |
2 | |
3 This is derived from sqlite3 sources. | |
4 http://www.sqlite.org/cvstrac/rlog?f=sqlite/src/os_win.c | |
5 http://www.sqlite.org/copyright.html | |
6 | |
7 Written by Richard W.M. Jones <rjones.at.redhat.com> | |
8 | |
17587 | 9 Copyright (C) 2008-2014 Free Software Foundation, Inc. |
10598 | 10 |
11 This library is free software; you can redistribute it and/or | |
12 modify it under the terms of the GNU Lesser General Public | |
13 License as published by the Free Software Foundation; either | |
14 version 2.1 of the License, or (at your option) any later version. | |
15 | |
16 This library is distributed in the hope that it will be useful, | |
17 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 Lesser General Public License for more details. | |
20 | |
14317 | 21 You should have received a copy of the GNU Lesser General Public License |
10598 | 22 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
23 | |
24 #include <config.h> | |
25 #include <sys/file.h> | |
26 | |
27 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | |
28 | |
29 /* LockFileEx */ | |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
30 # define WIN32_LEAN_AND_MEAN |
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
31 # include <windows.h> |
10598 | 32 |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
33 # include <errno.h> |
10598 | 34 |
15752
b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents:
14379
diff
changeset
|
35 /* _get_osfhandle */ |
b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents:
14379
diff
changeset
|
36 # include "msvc-nothrow.h" |
b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents:
14379
diff
changeset
|
37 |
10598 | 38 /* Determine the current size of a file. Because the other braindead |
39 * APIs we'll call need lower/upper 32 bit pairs, keep the file size | |
40 * like that too. | |
41 */ | |
42 static BOOL | |
43 file_size (HANDLE h, DWORD * lower, DWORD * upper) | |
44 { | |
45 *lower = GetFileSize (h, upper); | |
46 return 1; | |
47 } | |
48 | |
49 /* LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. */ | |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
50 # ifndef LOCKFILE_FAIL_IMMEDIATELY |
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
51 # define LOCKFILE_FAIL_IMMEDIATELY 1 |
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
52 # endif |
10598 | 53 |
54 /* Acquire a lock. */ | |
55 static BOOL | |
56 do_lock (HANDLE h, int non_blocking, int exclusive) | |
57 { | |
58 BOOL res; | |
59 DWORD size_lower, size_upper; | |
60 OVERLAPPED ovlp; | |
61 int flags = 0; | |
62 | |
63 /* We're going to lock the whole file, so get the file size. */ | |
64 res = file_size (h, &size_lower, &size_upper); | |
65 if (!res) | |
66 return 0; | |
67 | |
68 /* Start offset is 0, and also zero the remaining members of this struct. */ | |
69 memset (&ovlp, 0, sizeof ovlp); | |
70 | |
71 if (non_blocking) | |
72 flags |= LOCKFILE_FAIL_IMMEDIATELY; | |
73 if (exclusive) | |
74 flags |= LOCKFILE_EXCLUSIVE_LOCK; | |
75 | |
76 return LockFileEx (h, flags, 0, size_lower, size_upper, &ovlp); | |
77 } | |
78 | |
79 /* Unlock reader or exclusive lock. */ | |
80 static BOOL | |
81 do_unlock (HANDLE h) | |
82 { | |
83 int res; | |
84 DWORD size_lower, size_upper; | |
85 | |
86 res = file_size (h, &size_lower, &size_upper); | |
87 if (!res) | |
88 return 0; | |
89 | |
90 return UnlockFile (h, 0, 0, size_lower, size_upper); | |
91 } | |
92 | |
93 /* Now our BSD-like flock operation. */ | |
94 int | |
95 flock (int fd, int operation) | |
96 { | |
97 HANDLE h = (HANDLE) _get_osfhandle (fd); | |
98 DWORD res; | |
99 int non_blocking; | |
100 | |
101 if (h == INVALID_HANDLE_VALUE) | |
102 { | |
103 errno = EBADF; | |
104 return -1; | |
105 } | |
106 | |
107 non_blocking = operation & LOCK_NB; | |
108 operation &= ~LOCK_NB; | |
109 | |
110 switch (operation) | |
111 { | |
112 case LOCK_SH: | |
113 res = do_lock (h, non_blocking, 0); | |
114 break; | |
115 case LOCK_EX: | |
116 res = do_lock (h, non_blocking, 1); | |
117 break; | |
118 case LOCK_UN: | |
119 res = do_unlock (h); | |
120 break; | |
121 default: | |
122 errno = EINVAL; | |
123 return -1; | |
124 } | |
125 | |
126 /* Map Windows errors into Unix errnos. As usual MSDN fails to | |
127 * document the permissible error codes. | |
128 */ | |
129 if (!res) | |
130 { | |
131 DWORD err = GetLastError (); | |
132 switch (err) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
133 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
134 /* This means someone else is holding a lock. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
135 case ERROR_LOCK_VIOLATION: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
136 errno = EAGAIN; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
137 break; |
10598 | 138 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
139 /* Out of memory. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
140 case ERROR_NOT_ENOUGH_MEMORY: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
141 errno = ENOMEM; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
142 break; |
10598 | 143 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
144 case ERROR_BAD_COMMAND: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
145 errno = EINVAL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
146 break; |
10598 | 147 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
148 /* Unlikely to be other errors, but at least don't lose the |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
149 * error code. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
150 */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
151 default: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
152 errno = err; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10903
diff
changeset
|
153 } |
10598 | 154 |
155 return -1; | |
156 } | |
157 | |
158 return 0; | |
159 } | |
160 | |
161 #else /* !Windows */ | |
162 | |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
163 # ifdef HAVE_STRUCT_FLOCK_L_TYPE |
10598 | 164 /* We know how to implement flock in terms of fcntl. */ |
165 | |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
166 # include <fcntl.h> |
10598 | 167 |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
168 # ifdef HAVE_UNISTD_H |
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
169 # include <unistd.h> |
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
170 # endif |
10598 | 171 |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
172 # include <errno.h> |
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
173 # include <string.h> |
10903
81b06acec5ca
flock: Fix trivial mistakes.
Simon Josefsson <simon@josefsson.org>
parents:
10598
diff
changeset
|
174 |
10598 | 175 int |
176 flock (int fd, int operation) | |
177 { | |
178 int cmd, r; | |
179 struct flock fl; | |
180 | |
181 if (operation & LOCK_NB) | |
182 cmd = F_SETLK; | |
183 else | |
184 cmd = F_SETLKW; | |
185 operation &= ~LOCK_NB; | |
186 | |
187 memset (&fl, 0, sizeof fl); | |
188 fl.l_whence = SEEK_SET; | |
189 /* l_start & l_len are 0, which as a special case means "whole file". */ | |
190 | |
191 switch (operation) | |
192 { | |
193 case LOCK_SH: | |
194 fl.l_type = F_RDLCK; | |
195 break; | |
196 case LOCK_EX: | |
197 fl.l_type = F_WRLCK; | |
198 break; | |
199 case LOCK_UN: | |
200 fl.l_type = F_UNLCK; | |
201 break; | |
202 default: | |
203 errno = EINVAL; | |
204 return -1; | |
205 } | |
206 | |
207 r = fcntl (fd, cmd, &fl); | |
208 if (r == -1 && errno == EACCES) | |
209 errno = EAGAIN; | |
210 | |
211 return r; | |
212 } | |
213 | |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
214 # else /* !HAVE_STRUCT_FLOCK_L_TYPE */ |
10598 | 215 |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
216 # error "This platform lacks flock function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib." |
10598 | 217 |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14317
diff
changeset
|
218 # endif /* !HAVE_STRUCT_FLOCK_L_TYPE */ |
10598 | 219 |
220 #endif /* !Windows */ |