More interesting case using recordId
[idzebra-moved-to-github.git] / index / lockutil.c
1 /* $Id: lockutil.c,v 1.21 2005-06-14 20:28:54 adam Exp $
2    Copyright (C) 1995-2005
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra.  If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.
21 */
22
23
24 #include <stdio.h>
25 #include <assert.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <sys/types.h>
30 #ifdef WIN32
31 #include <io.h>
32 #include <sys/locking.h>
33 #endif
34 #if HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include "index.h"
39
40 struct zebra_lock_info {
41     int fd;
42     int excl_flag;
43 };
44
45 char *zebra_mk_fname (const char *dir, const char *name)
46 {
47     int dlen = dir ? strlen(dir) : 0;
48     char *fname = xmalloc (dlen + strlen(name) + 3);
49
50 #ifdef WIN32
51     if (dlen)
52     {
53         int last_one = dir[dlen-1];
54
55         if (!strchr ("/\\:", last_one))
56             sprintf (fname, "%s\\%s", dir, name);
57         else
58             sprintf (fname, "%s%s", dir, name);
59     }
60     else
61         sprintf (fname, "%s", name);
62 #else
63     if (dlen)
64     {
65         int last_one = dir[dlen-1];
66
67         if (!strchr ("/", last_one))
68             sprintf (fname, "%s/%s", dir, name);
69         else
70             sprintf (fname, "%s%s", dir, name);
71     }
72     else
73         sprintf (fname, "%s", name);
74 #endif
75     return fname;
76 }
77
78 ZebraLockHandle zebra_lock_create (const char *dir,
79                                    const char *name, int excl_flag)
80 {
81     char *fname = zebra_mk_fname(dir, name);
82     ZebraLockHandle h = (ZebraLockHandle) xmalloc (sizeof(*h));
83
84     h->excl_flag = excl_flag;
85     h->fd = -1;
86
87     
88 #ifdef WIN32
89     if (!h->excl_flag)
90         h->fd = open (name, O_BINARY|O_RDONLY);
91     if (h->fd == -1)
92         h->fd = open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
93             (O_BINARY|O_CREAT|O_RDWR), 0666);
94 #else
95     h->fd= open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
96             (O_BINARY|O_CREAT|O_RDWR), 0666);
97 #endif
98     if (h->fd == -1)
99     {
100         if (h->excl_flag <= 1)
101             yaz_log (YLOG_WARN|YLOG_ERRNO, "open %s", fname);
102         xfree (h);
103         h = 0;
104     }
105     xfree (fname);
106     return h;
107 }
108
109 void zebra_lock_destroy (ZebraLockHandle h)
110 {
111     if (!h)
112         return;
113     if (h->fd != -1)
114         close (h->fd);
115     xfree (h);
116 }
117
118 void zebra_lock_prefix (Res res, char *path)
119 {
120     const char *lock_dir = res_get_def (res, "lockDir", "");
121
122     strcpy (path, lock_dir);
123     if (*path && path[strlen(path)-1] != '/')
124         strcat (path, "/");
125 }
126
127 #ifndef WIN32
128 static int unixLock (int fd, int type, int cmd)
129 {
130     struct flock area;
131     area.l_type = type;
132     area.l_whence = SEEK_SET;
133     area.l_len = area.l_start = 0L;
134     return fcntl (fd, cmd, &area);
135 }
136 #endif
137
138 int zebra_lock_w (ZebraLockHandle h)
139 {
140 #ifdef WIN32
141     return _locking (h->fd, _LK_LOCK, 1);
142 #else
143     return unixLock (h->fd, F_WRLCK, F_SETLKW);
144 #endif
145 }
146
147 int zebra_lock_r (ZebraLockHandle h)
148 {
149 #ifdef WIN32
150     return _locking (h->fd, _LK_LOCK, 1);
151 #else
152     return unixLock (h->fd, F_RDLCK, F_SETLKW);
153 #endif
154 }
155
156 int zebra_lock (ZebraLockHandle h)
157 {
158 #ifdef WIN32
159     return _locking (h->fd, _LK_LOCK, 1);
160 #else
161     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLKW);
162 #endif
163 }
164
165 int zebra_lock_nb (ZebraLockHandle h)
166 {
167 #ifdef WIN32
168     return _locking (h->fd, _LK_NBLCK, 1);
169 #else
170     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLK);
171 #endif
172 }
173
174 int zebra_unlock (ZebraLockHandle h)
175 {
176 #ifdef WIN32
177     return _locking (h->fd, _LK_UNLCK, 1);
178 #else
179     return unixLock (h->fd, F_UNLCK, F_SETLKW);
180 #endif
181 }
182
183 int zebra_lock_fd (ZebraLockHandle h)
184 {
185     return h->fd;
186 }