Mercurial > hgrepos > hgweb.cgi > imapext
comparison src/osdep/unix/flockcyg.c @ 0:ada5e610ab86
imap-2007e
author | yuuji@gentei.org |
---|---|
date | Mon, 14 Sep 2009 15:17:45 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ada5e610ab86 |
---|---|
1 /* ======================================================================== | |
2 * Copyright 1988-2006 University of Washington | |
3 * | |
4 * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 * you may not use this file except in compliance with the License. | |
6 * You may obtain a copy of the License at | |
7 * | |
8 * http://www.apache.org/licenses/LICENSE-2.0 | |
9 * | |
10 * | |
11 * ======================================================================== | |
12 */ | |
13 | |
14 /* | |
15 * Program: flock emulation via fcntl() locking | |
16 * | |
17 * Author: Mark Crispin | |
18 * Networks and Distributed Computing | |
19 * Computing & Communications | |
20 * University of Washington | |
21 * Administration Building, AG-44 | |
22 * Seattle, WA 98195 | |
23 * Internet: MRC@CAC.Washington.EDU | |
24 * | |
25 * Date: 10 April 2001 | |
26 * Last Edited: 30 August 2006 | |
27 */ | |
28 | |
29 | |
30 /* Cygwin does not seem to have the design flaw in fcntl() locking that | |
31 * most other systems do (see flocksim.c for details). If some cretin | |
32 * decides to implement that design flaw, then Cygwin will have to use | |
33 * flocksim. Also, we don't test NFS either. | |
34 * | |
35 * However, Cygwin does have the Windows misfeature (introduced in NT 4.0) | |
36 * that you can not write to any segment which has a shared lock, and you | |
37 * can't lock a zero-byte segment either. This screws up the shared-write | |
38 * mailbox drivers (mbx, mtx, mx, and tenex). As a workaround, we'll only | |
39 * lock the first byte of the file, meaning that you can't write that byte | |
40 * shared. It's been suggested to lock the maximum off_t type, but that | |
41 * risks having a future version of Windows (or Cygwin) deciding that this | |
42 * also means "no lock". | |
43 */ | |
44 | |
45 #undef flock /* name is used as a struct for fcntl */ | |
46 | |
47 /* Emulator for flock() call | |
48 * Accepts: file descriptor | |
49 * operation bitmask | |
50 * Returns: 0 if successful, -1 if failure under BSD conditions | |
51 */ | |
52 | |
53 int flocksim (int fd,int op) | |
54 { | |
55 char tmp[MAILTMPLEN]; | |
56 int logged = 0; | |
57 struct flock fl; | |
58 /* lock one bytes at byte 0 */ | |
59 fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 1; | |
60 fl.l_pid = getpid (); /* shouldn't be necessary */ | |
61 switch (op & ~LOCK_NB) { /* translate to fcntl() operation */ | |
62 case LOCK_EX: /* exclusive */ | |
63 fl.l_type = F_WRLCK; | |
64 break; | |
65 case LOCK_SH: /* shared */ | |
66 fl.l_type = F_RDLCK; | |
67 break; | |
68 case LOCK_UN: /* unlock */ | |
69 fl.l_type = F_UNLCK; | |
70 break; | |
71 default: /* default */ | |
72 errno = EINVAL; | |
73 return -1; | |
74 } | |
75 while (fcntl (fd,(op & LOCK_NB) ? F_SETLK : F_SETLKW,&fl)) | |
76 if (errno != EINTR) { | |
77 /* Can't use switch here because these error codes may resolve to the | |
78 * same value on some systems. | |
79 */ | |
80 if ((errno != EWOULDBLOCK) && (errno != EAGAIN) && (errno != EACCES)) { | |
81 sprintf (tmp,"Unexpected file locking failure: %s",strerror (errno)); | |
82 /* give the user a warning of what happened */ | |
83 MM_NOTIFY (NIL,tmp,WARN); | |
84 if (!logged++) syslog (LOG_ERR,"%s",tmp); | |
85 if (op & LOCK_NB) return -1; | |
86 sleep (5); /* slow things down for loops */ | |
87 } | |
88 /* return failure for non-blocking lock */ | |
89 else if (op & LOCK_NB) return -1; | |
90 } | |
91 return 0; /* success */ | |
92 } |