Moved file locking utilities from index/lockutil.c to util/flock.c
[idzebra-moved-to-github.git] / util / flock.c
1 /* $Id: flock.c,v 1.1 2006-03-23 09:15:25 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 <idzebra/flock.h>
39 #include <yaz/xmalloc.h>
40
41 struct zebra_lock_info {
42     int fd;
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, const char *name)
79 {
80     char *fname = zebra_mk_fname(dir, name);
81     ZebraLockHandle h = (ZebraLockHandle) xmalloc (sizeof(*h));
82
83     h->fd = -1;
84 #ifdef WIN32
85     h->fd = open (name, O_BINARY|O_RDONLY);
86     if (h->fd == -1)
87         h->fd = open (fname, (O_BINARY|O_CREAT|O_RDWR), 0666);
88 #else
89     h->fd= open (fname, (O_BINARY|O_CREAT|O_RDWR), 0666);
90 #endif
91     if (h->fd == -1)
92     {
93         xfree (h);
94         h = 0;
95     }
96     xfree (fname);
97     return h;
98 }
99
100 void zebra_lock_destroy (ZebraLockHandle h)
101 {
102     if (!h)
103         return;
104     if (h->fd != -1)
105         close (h->fd);
106     xfree (h);
107 }
108
109 #ifndef WIN32
110 static int unixLock (int fd, int type, int cmd)
111 {
112     struct flock area;
113     area.l_type = type;
114     area.l_whence = SEEK_SET;
115     area.l_len = area.l_start = 0L;
116     return fcntl (fd, cmd, &area);
117 }
118 #endif
119
120 int zebra_lock_w (ZebraLockHandle h)
121 {
122 #ifdef WIN32
123     return _locking (h->fd, _LK_LOCK, 1);
124 #else
125     return unixLock (h->fd, F_WRLCK, F_SETLKW);
126 #endif
127 }
128
129 int zebra_lock_r (ZebraLockHandle h)
130 {
131 #ifdef WIN32
132     return _locking (h->fd, _LK_LOCK, 1);
133 #else
134     return unixLock (h->fd, F_RDLCK, F_SETLKW);
135 #endif
136 }
137
138 int zebra_unlock (ZebraLockHandle h)
139 {
140 #ifdef WIN32
141     return _locking (h->fd, _LK_UNLCK, 1);
142 #else
143     return unixLock (h->fd, F_UNLCK, F_SETLKW);
144 #endif
145 }
146