191 |
return 0; |
return 0; |
192 |
} |
} |
193 |
|
|
194 |
|
/* Just like open(2), but if a open with O_EXCL fails, retry with |
195 |
|
GUARDED semantics. This might be necessary because some filesystems |
196 |
|
(such as NFS filesystems mounted from a unfsd server) doesn't |
197 |
|
support O_EXCL. GUARDED semantics are subject to race conditions, |
198 |
|
but we can live with that. |
199 |
|
*/ |
200 |
|
static int |
201 |
|
open_weak_exclusive(const char *pathname, int flags, mode_t mode) |
202 |
|
{ |
203 |
|
int ret; |
204 |
|
struct stat statbuf; |
205 |
|
|
206 |
|
ret = open(pathname, flags, mode); |
207 |
|
if (ret != -1 || !(flags & O_EXCL)) |
208 |
|
{ |
209 |
|
/* Success, or not using O_EXCL */ |
210 |
|
return ret; |
211 |
|
} |
212 |
|
|
213 |
|
/* An error occured, and we are using O_EXCL. In case the FS |
214 |
|
doesn't support O_EXCL, some kind of error will be |
215 |
|
returned. Unfortunately, we don't know which one. Linux |
216 |
|
2.6.8 seems to return 524, but I cannot find a documented |
217 |
|
#define for this case. So, we'll return only on errors that |
218 |
|
we know aren't related to O_EXCL. */ |
219 |
|
switch (errno) |
220 |
|
{ |
221 |
|
case EACCES: |
222 |
|
case EEXIST: |
223 |
|
case EINTR: |
224 |
|
case EISDIR: |
225 |
|
case ELOOP: |
226 |
|
case ENAMETOOLONG: |
227 |
|
case ENOENT: |
228 |
|
case ENOTDIR: |
229 |
|
return ret; |
230 |
|
} |
231 |
|
|
232 |
|
/* Retry with GUARDED semantics */ |
233 |
|
if (stat(pathname, &statbuf) != -1) |
234 |
|
{ |
235 |
|
/* File exists */ |
236 |
|
errno = EEXIST; |
237 |
|
return -1; |
238 |
|
} |
239 |
|
else |
240 |
|
{ |
241 |
|
return open(pathname, flags & ~O_EXCL, mode); |
242 |
|
} |
243 |
|
} |
244 |
|
|
245 |
/* Enumeration of devices from rdesktop.c */ |
/* Enumeration of devices from rdesktop.c */ |
246 |
/* returns numer of units found and initialized. */ |
/* returns numer of units found and initialized. */ |
384 |
flags |= O_RDONLY; |
flags |= O_RDONLY; |
385 |
} |
} |
386 |
|
|
387 |
handle = open(path, flags, mode); |
handle = open_weak_exclusive(path, flags, mode); |
388 |
if (handle == -1) |
if (handle == -1) |
389 |
{ |
{ |
390 |
switch (errno) |
switch (errno) |