Bump year. Change Aps->ApS
[idzebra-moved-to-github.git] / index / lockutil.c
1 /* $Id: lockutil.c,v 1.20 2005-01-15 19:38:26 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 #else
34 #include <unistd.h>
35 #endif
36
37 #include "index.h"
38
39 struct zebra_lock_info {
40     int fd;
41     int excl_flag;
42 };
43
44 char *zebra_mk_fname (const char *dir, const char *name)
45 {
46     int dlen = dir ? strlen(dir) : 0;
47     char *fname = xmalloc (dlen + strlen(name) + 3);
48
49 #ifdef WIN32
50     if (dlen)
51     {
52         int last_one = dir[dlen-1];
53
54         if (!strchr ("/\\:", last_one))
55             sprintf (fname, "%s\\%s", dir, name);
56         else
57             sprintf (fname, "%s%s", dir, name);
58     }
59     else
60         sprintf (fname, "%s", name);
61 #else
62     if (dlen)
63     {
64         int last_one = dir[dlen-1];
65
66         if (!strchr ("/", last_one))
67             sprintf (fname, "%s/%s", dir, name);
68         else
69             sprintf (fname, "%s%s", dir, name);
70     }
71     else
72         sprintf (fname, "%s", name);
73 #endif
74     return fname;
75 }
76
77 ZebraLockHandle zebra_lock_create (const char *dir,
78                                    const char *name, int excl_flag)
79 {
80     char *fname = zebra_mk_fname(dir, name);
81     ZebraLockHandle h = (ZebraLockHandle) xmalloc (sizeof(*h));
82
83     h->excl_flag = excl_flag;
84     h->fd = -1;
85
86     
87 #ifdef WIN32
88     if (!h->excl_flag)
89         h->fd = open (name, O_BINARY|O_RDONLY);
90     if (h->fd == -1)
91         h->fd = open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
92             (O_BINARY|O_CREAT|O_RDWR), 0666);
93 #else
94     h->fd= open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
95             (O_BINARY|O_CREAT|O_RDWR), 0666);
96 #endif
97     if (h->fd == -1)
98     {
99         if (h->excl_flag <= 1)
100             yaz_log (YLOG_WARN|YLOG_ERRNO, "open %s", fname);
101         xfree (h);
102         h = 0;
103     }
104     xfree (fname);
105     return h;
106 }
107
108 void zebra_lock_destroy (ZebraLockHandle h)
109 {
110     if (!h)
111         return;
112     if (h->fd != -1)
113         close (h->fd);
114     xfree (h);
115 }
116
117 void zebra_lock_prefix (Res res, char *path)
118 {
119     const char *lock_dir = res_get_def (res, "lockDir", "");
120
121     strcpy (path, lock_dir);
122     if (*path && path[strlen(path)-1] != '/')
123         strcat (path, "/");
124 }
125
126 #ifndef WIN32
127 static int unixLock (int fd, int type, int cmd)
128 {
129     struct flock area;
130     area.l_type = type;
131     area.l_whence = SEEK_SET;
132     area.l_len = area.l_start = 0L;
133     return fcntl (fd, cmd, &area);
134 }
135 #endif
136
137 int zebra_lock_w (ZebraLockHandle h)
138 {
139 #ifdef WIN32
140     return _locking (h->fd, _LK_LOCK, 1);
141 #else
142     return unixLock (h->fd, F_WRLCK, F_SETLKW);
143 #endif
144 }
145
146 int zebra_lock_r (ZebraLockHandle h)
147 {
148 #ifdef WIN32
149     return _locking (h->fd, _LK_LOCK, 1);
150 #else
151     return unixLock (h->fd, F_RDLCK, F_SETLKW);
152 #endif
153 }
154
155 int zebra_lock (ZebraLockHandle h)
156 {
157 #ifdef WIN32
158     return _locking (h->fd, _LK_LOCK, 1);
159 #else
160     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLKW);
161 #endif
162 }
163
164 int zebra_lock_nb (ZebraLockHandle h)
165 {
166 #ifdef WIN32
167     return _locking (h->fd, _LK_NBLCK, 1);
168 #else
169     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLK);
170 #endif
171 }
172
173 int zebra_unlock (ZebraLockHandle h)
174 {
175 #ifdef WIN32
176     return _locking (h->fd, _LK_UNLCK, 1);
177 #else
178     return unixLock (h->fd, F_UNLCK, F_SETLKW);
179 #endif
180 }
181
182 int zebra_lock_fd (ZebraLockHandle h)
183 {
184     return h->fd;
185 }