d9898ee8 |
1 | |
2 | #ifndef liblockmail_h |
3 | #define liblockmail_h |
4 | |
5 | /* |
6 | ** Copyright 2002 Double Precision, Inc. See COPYING for |
7 | ** distribution information. |
8 | */ |
9 | |
10 | #ifdef __cplusplus |
11 | extern "C" { |
12 | #endif |
13 | |
14 | /* |
15 | ** Functions for mbox mail locks |
16 | */ |
17 | |
18 | struct ll_mail { |
19 | char *file; /* File being locked */ |
20 | |
21 | /* c-client type lock */ |
22 | |
23 | int cclientfd; |
24 | char *cclientfile; |
25 | |
26 | |
27 | /* dotlock */ |
28 | |
29 | char *dotlock; |
30 | }; |
31 | |
32 | struct ll_mail *ll_mail_alloc(const char *filename); |
33 | |
34 | /* |
35 | ** Create a c-client type lock. NOTE: c-clients will ping you with SIGUSR2, |
36 | ** which must be ignored for this implementation. |
37 | ** Returns: 0 - ok, < 0 - error. |
38 | ** |
39 | ** An error return from ll_mail_lock carries some additional context in |
40 | ** errno: |
41 | ** |
42 | ** errno == EAGAIN: potential race condition. The current lock holder MIGHT |
43 | ** have just terminated. The caller should sleep for AT LEAST 5 seconds, then |
44 | ** try again. |
45 | ** |
46 | ** errno == EEXIST: another process on this server DEFINITELY has the lock. |
47 | ** |
48 | ** Implementations might choose to wait and try again on EEXIST as well. |
49 | */ |
50 | |
51 | int ll_mail_lock(struct ll_mail *); |
52 | |
53 | /* |
54 | ** Open the mail file, read/write (creating a dot-lock). |
55 | ** Returns: >= 0 - file descriptor, < 0 - error (if EPERM, try ll_open_ro). |
56 | ** |
57 | ** errno == EEXIST: another process appears to hold a dot-lock. |
58 | ** |
59 | ** errno == EAGAIN: We just blew away a stale dotlock, should try again |
60 | ** in at least five seconds. Should NOT get two EAGAIN's in a row. |
61 | */ |
62 | |
63 | int ll_mail_open(struct ll_mail *); |
64 | |
65 | /* |
66 | ** Open in read-only mode. |
67 | */ |
68 | |
69 | int ll_mail_open_ro(struct ll_mail *); |
70 | |
71 | /* |
72 | ** Release all locks, deallocate structure. NOTE: file descriptor from |
73 | ** ll_mail_open(_ro)? is NOT closed, it's your responsibility to do that. |
74 | */ |
75 | |
76 | void ll_mail_free(struct ll_mail *); |
77 | |
78 | /* |
79 | ** As long as we have the logic done already, here's a generic dot-locking |
80 | ** function. |
81 | ** |
82 | ** dotlock - the actual filename of a dotlock file. |
83 | ** tmpfile - the filename of a temporary file to create first. |
84 | ** timeout - optional timeout. |
85 | ** |
86 | ** Return code: 0: dotlock is created. Just unlink(dotlock) when you're done. |
87 | ** |
88 | ** -1 error. Check errno: |
89 | ** |
90 | ** EEXIST - dotlock is locked |
91 | ** |
92 | ** EAGAIN - dotlock is stale (dotlock created on this machine, and the |
93 | ** process no longer exists, or dotlock created on another |
94 | ** machine, and timeout argument was > 0, and the dotlock's |
95 | ** timestamp was older than timeout seconds. |
96 | ** |
97 | ** E????? - something's broken. |
98 | ** |
99 | */ |
100 | |
101 | int ll_dotlock(const char *dotlock, const char *tmpfile, |
102 | int timeout); |
103 | |
104 | #ifdef __cplusplus |
8d138742 |
105 | } |
d9898ee8 |
106 | #endif |
107 | |
108 | #endif |