security: Add documentation
[Samba/gbeck.git] / lib / ntdb / test / api-82-lockattr.c
blob4fbe1d232a6ac1f78005929fe65ddb1f2b38568a
1 #include "private.h" // for ntdb_fcntl_unlock
2 #include "ntdb.h"
3 #include "tap-interface.h"
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include "logging.h"
10 static int mylock(int fd, int rw, off_t off, off_t len, bool waitflag,
11 void *_err)
13 int *lock_err = _err;
14 struct flock fl;
15 int ret;
17 if (*lock_err) {
18 errno = *lock_err;
19 return -1;
22 do {
23 fl.l_type = rw;
24 fl.l_whence = SEEK_SET;
25 fl.l_start = off;
26 fl.l_len = len;
28 if (waitflag)
29 ret = fcntl(fd, F_SETLKW, &fl);
30 else
31 ret = fcntl(fd, F_SETLK, &fl);
32 } while (ret != 0 && errno == EINTR);
34 return ret;
37 static int trav_err;
38 static int trav(struct ntdb_context *ntdb, NTDB_DATA k, NTDB_DATA d, int *terr)
40 *terr = trav_err;
41 return 0;
44 int main(int argc, char *argv[])
46 unsigned int i;
47 struct ntdb_context *ntdb;
48 int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
49 NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };
50 union ntdb_attribute lock_attr;
51 NTDB_DATA key = ntdb_mkdata("key", 3);
52 NTDB_DATA data = ntdb_mkdata("data", 4);
53 int lock_err;
55 lock_attr.base.attr = NTDB_ATTRIBUTE_FLOCK;
56 lock_attr.base.next = &tap_log_attr;
57 lock_attr.flock.lock = mylock;
58 lock_attr.flock.unlock = ntdb_fcntl_unlock;
59 lock_attr.flock.data = &lock_err;
61 plan_tests(sizeof(flags) / sizeof(flags[0]) * 81);
63 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
64 NTDB_DATA d;
66 /* Nonblocking open; expect no error message. */
67 lock_err = EAGAIN;
68 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
69 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
70 ok(errno == lock_err, "Errno is %u", errno);
71 ok1(!ntdb);
72 ok1(tap_log_messages == 0);
74 lock_err = EINTR;
75 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
76 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
77 ok(errno == lock_err, "Errno is %u", errno);
78 ok1(!ntdb);
79 ok1(tap_log_messages == 0);
81 /* Forced fail open. */
82 lock_err = ENOMEM;
83 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
84 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
85 ok1(errno == lock_err);
86 ok1(!ntdb);
87 ok1(tap_log_messages == 1);
88 tap_log_messages = 0;
90 lock_err = 0;
91 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
92 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
93 if (!ok1(ntdb))
94 continue;
95 ok1(tap_log_messages == 0);
97 /* Nonblocking store. */
98 lock_err = EAGAIN;
99 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
100 ok1(tap_log_messages == 0);
101 lock_err = EINTR;
102 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
103 ok1(tap_log_messages == 0);
104 lock_err = ENOMEM;
105 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
106 ok1(tap_log_messages == 1);
107 tap_log_messages = 0;
109 /* Nonblocking fetch. */
110 lock_err = EAGAIN;
111 ok1(!ntdb_exists(ntdb, key));
112 ok1(tap_log_messages == 0);
113 lock_err = EINTR;
114 ok1(!ntdb_exists(ntdb, key));
115 ok1(tap_log_messages == 0);
116 lock_err = ENOMEM;
117 ok1(!ntdb_exists(ntdb, key));
118 ok1(tap_log_messages == 1);
119 tap_log_messages = 0;
121 lock_err = EAGAIN;
122 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
123 ok1(tap_log_messages == 0);
124 lock_err = EINTR;
125 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
126 ok1(tap_log_messages == 0);
127 lock_err = ENOMEM;
128 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
129 ok1(tap_log_messages == 1);
130 tap_log_messages = 0;
132 /* Nonblocking delete. */
133 lock_err = EAGAIN;
134 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
135 ok1(tap_log_messages == 0);
136 lock_err = EINTR;
137 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
138 ok1(tap_log_messages == 0);
139 lock_err = ENOMEM;
140 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
141 ok1(tap_log_messages == 1);
142 tap_log_messages = 0;
144 /* Nonblocking locks. */
145 lock_err = EAGAIN;
146 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
147 ok1(tap_log_messages == 0);
148 lock_err = EINTR;
149 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
150 ok1(tap_log_messages == 0);
151 lock_err = ENOMEM;
152 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
153 ok1(tap_log_messages == 1);
154 tap_log_messages = 0;
156 lock_err = EAGAIN;
157 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
158 ok1(tap_log_messages == 0);
159 lock_err = EINTR;
160 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
161 ok1(tap_log_messages == 0);
162 lock_err = ENOMEM;
163 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
164 ok1(tap_log_messages == 1);
165 tap_log_messages = 0;
167 lock_err = EAGAIN;
168 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
169 ok1(tap_log_messages == 0);
170 lock_err = EINTR;
171 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
172 ok1(tap_log_messages == 0);
173 lock_err = ENOMEM;
174 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
175 /* This actually does divide and conquer. */
176 ok1(tap_log_messages > 0);
177 tap_log_messages = 0;
179 lock_err = EAGAIN;
180 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
181 ok1(tap_log_messages == 0);
182 lock_err = EINTR;
183 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
184 ok1(tap_log_messages == 0);
185 lock_err = ENOMEM;
186 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
187 ok1(tap_log_messages > 0);
188 tap_log_messages = 0;
190 /* Nonblocking traverse; go nonblock partway through. */
191 lock_err = 0;
192 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
193 /* Need two entries to ensure two lock attempts! */
194 ok1(ntdb_store(ntdb, ntdb_mkdata("key2", 4), data,
195 NTDB_REPLACE) == 0);
196 trav_err = EAGAIN;
197 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
198 ok1(tap_log_messages == 0);
199 trav_err = EINTR;
200 lock_err = 0;
201 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
202 ok1(tap_log_messages == 0);
203 trav_err = ENOMEM;
204 lock_err = 0;
205 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
206 ok1(tap_log_messages == 1);
207 tap_log_messages = 0;
209 /* Nonblocking transactions. */
210 lock_err = EAGAIN;
211 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
212 ok1(tap_log_messages == 0);
213 lock_err = EINTR;
214 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
215 ok1(tap_log_messages == 0);
216 lock_err = ENOMEM;
217 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
218 ok1(tap_log_messages == 1);
219 tap_log_messages = 0;
221 /* Nonblocking transaction prepare. */
222 lock_err = 0;
223 ok1(ntdb_transaction_start(ntdb) == 0);
224 ok1(ntdb_delete(ntdb, key) == 0);
226 lock_err = EAGAIN;
227 ok1(ntdb_transaction_prepare_commit(ntdb) == NTDB_ERR_LOCK);
228 ok1(tap_log_messages == 0);
230 lock_err = 0;
231 ok1(ntdb_transaction_prepare_commit(ntdb) == 0);
232 ok1(ntdb_transaction_commit(ntdb) == 0);
234 /* And the transaction was committed, right? */
235 ok1(!ntdb_exists(ntdb, key));
236 ntdb_close(ntdb);
237 ok1(tap_log_messages == 0);
239 return exit_status();