db8c1482f0d1909d82db55cbe089970d7bc00516
[idzebra-moved-to-github.git] / index / lockutil.c
1 /*
2  * Copyright (C) 1994-2002, Index Data
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Id: lockutil.c,v 1.14 2002-03-21 10:25:42 adam Exp $
7  */
8 #include <stdio.h>
9 #include <assert.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <sys/types.h>
14 #ifdef WIN32
15 #include <io.h>
16 #include <sys/locking.h>
17 #else
18 #include <unistd.h>
19 #endif
20
21 #include "index.h"
22
23 struct zebra_lock_info {
24     int fd;
25     int excl_flag;
26 };
27
28 char *zebra_mk_fname (const char *dir, const char *name)
29 {
30     int dlen = dir ? strlen(dir) : 0;
31     char *fname = xmalloc (dlen + strlen(name) + 3);
32
33 #ifdef WIN32
34     if (dlen)
35     {
36         int last_one = dir[dlen-1];
37
38         if (!strchr ("/\\:", last_one))
39             sprintf (fname, "%s\\%s", dir, name);
40         else
41             sprintf (fname, "%s%s", dir, name);
42     }
43     else
44         sprintf (fname, "%s", name);
45 #else
46     if (dlen)
47     {
48         int last_one = dir[dlen-1];
49
50         if (!strchr ("/", last_one))
51             sprintf (fname, "%s/%s", dir, name);
52         else
53             sprintf (fname, "%s%s", dir, name);
54     }
55     else
56         sprintf (fname, "%s", name);
57 #endif
58     return fname;
59 }
60
61 ZebraLockHandle zebra_lock_create (const char *dir,
62                                    const char *name, int excl_flag)
63 {
64     int dlen = dir ? strlen(dir) : 0;
65     char *fname = zebra_mk_fname(dir, name);
66     ZebraLockHandle h = (ZebraLockHandle) xmalloc (sizeof(*h));
67
68     h->excl_flag = excl_flag;
69     h->fd = -1;
70
71     
72 #ifdef WIN32
73     if (!h->excl_flag)
74         h->fd = open (name, O_BINARY|O_RDONLY);
75     if (h->fd == -1)
76         h->fd = open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
77             (O_BINARY|O_CREAT|O_RDWR), 0666);
78 #else
79     h->fd= open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
80             (O_BINARY|O_CREAT|O_RDWR|O_SYNC), 0666);
81 #endif
82     if (h->fd == -1)
83     {
84         if (h->excl_flag <= 1)
85             logf (LOG_WARN|LOG_ERRNO, "open %s", fname);
86         xfree (h);
87         h = 0;
88     }
89     xfree (fname);
90     return h;
91 }
92
93 void zebra_lock_destroy (ZebraLockHandle h)
94 {
95     if (!h)
96         return;
97     if (h->fd != -1)
98         close (h->fd);
99     xfree (h);
100 }
101
102 void zebra_lock_prefix (Res res, char *path)
103 {
104     char *lock_dir = res_get_def (res, "lockDir", "");
105
106     strcpy (path, lock_dir);
107     if (*path && path[strlen(path)-1] != '/')
108         strcat (path, "/");
109 }
110
111 #ifndef WIN32
112 static int unixLock (int fd, int type, int cmd)
113 {
114     struct flock area;
115     area.l_type = type;
116     area.l_whence = SEEK_SET;
117     area.l_len = area.l_start = 0L;
118     return fcntl (fd, cmd, &area);
119 }
120 #endif
121
122 int zebra_lock_w (ZebraLockHandle h)
123 {
124 #ifdef WIN32
125     return _locking (h->fd, _LK_LOCK, 1);
126 #else
127     return unixLock (h->fd, F_WRLCK, F_SETLKW);
128 #endif
129 }
130
131 int zebra_lock_r (ZebraLockHandle h)
132 {
133 #ifdef WIN32
134     return _locking (h->fd, _LK_LOCK, 1);
135 #else
136     return unixLock (h->fd, F_RDLCK, F_SETLKW);
137 #endif
138 }
139
140 int zebra_lock (ZebraLockHandle h)
141 {
142 #ifdef WIN32
143     return _locking (h->fd, _LK_LOCK, 1);
144 #else
145     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLKW);
146 #endif
147 }
148
149 int zebra_lock_nb (ZebraLockHandle h)
150 {
151 #ifdef WIN32
152     return _locking (h->fd, _LK_NBLCK, 1);
153 #else
154     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLK);
155 #endif
156 }
157
158 int zebra_unlock (ZebraLockHandle h)
159 {
160 #ifdef WIN32
161     return _locking (h->fd, _LK_UNLCK, 1);
162 #else
163     return unixLock (h->fd, F_UNLCK, F_SETLKW);
164 #endif
165 }
166
167 int zebra_lock_fd (ZebraLockHandle h)
168 {
169     return h->fd;
170 }