1 /* We save the locks so we can reaquire them. */
6 #include <ccan/tap/tap.h>
14 static struct lock *locks;
15 int locking_errors = 0;
16 void (*unlock_callback)(int fd);
18 int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ )
24 if (cmd != F_SETLK && cmd != F_SETLKW) {
25 /* This may be totally bogus, but we don't know in general. */
27 arg3 = va_arg(ap, int);
30 return fcntl(fd, cmd, arg3);
34 fl = va_arg(ap, struct flock *);
37 if (fl->l_type == F_UNLCK) {
39 struct lock *old = NULL;
41 for (l = &locks; *l; l = &(*l)->next) {
42 if ((*l)->off == fl->l_start
43 && (*l)->len == fl->l_len) {
51 diag("Unknown unlock %u@%u",
52 (int)fl->l_len, (int)fl->l_start);
57 unsigned int fl_end = fl->l_start + fl->l_len;
59 fl_end = (unsigned int)-1;
61 /* Check for overlaps: we shouldn't do this. */
62 for (i = locks; i; i = i->next) {
63 unsigned int i_end = i->off + i->len;
65 i_end = (unsigned int)-1;
67 if (fl->l_start >= i->off && fl->l_start < i_end)
69 if (fl_end >= i->off && fl_end < i_end)
73 diag("%s lock %u@%u overlaps %u@%u",
74 fl->l_type == F_WRLCK ? "write" : "read",
75 (int)fl->l_len, (int)fl->l_start,
79 new = malloc(sizeof *new);
80 new->off = fl->l_start;
82 new->type = fl->l_type;
87 ret = fcntl(fd, cmd, fl);
88 if (ret == 0 && fl->l_type == F_UNLCK && unlock_callback)
93 int forget_locking(void)
97 struct lock *next = locks->next;