123f7e6f4f38c8c8cf41e75e6d5d93be3702af23
[idzebra-moved-to-github.git] / index / lockutil.c
1 /*
2  * Copyright (C) 1994-1999, Index Data
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: lockutil.c,v $
7  * Revision 1.12  1999-05-26 07:49:13  adam
8  * C++ compilation.
9  *
10  * Revision 1.11  1999/02/02 14:50:59  adam
11  * Updated WIN32 code specific sections. Changed header.
12  *
13  * Revision 1.10  1997/09/29 09:08:36  adam
14  * Revised locking system to be thread safe for the server.
15  *
16  * Revision 1.9  1997/09/25 14:54:43  adam
17  * WIN32 files lock support.
18  *
19  * Revision 1.8  1997/09/17 12:19:15  adam
20  * Zebra version corresponds to YAZ version 1.4.
21  * Changed Zebra server so that it doesn't depend on global common_resource.
22  *
23  * Revision 1.7  1997/09/09 13:38:08  adam
24  * Partial port to WIN95/NT.
25  *
26  * Revision 1.6  1996/10/29 14:08:14  adam
27  * Uses resource lockDir instead of lockPath.
28  *
29  * Revision 1.5  1996/03/26 16:01:13  adam
30  * New setting lockPath: directory of various lock files.
31  *
32  * Revision 1.4  1995/12/13  08:46:10  adam
33  * Locking uses F_WRLCK and F_RDLCK again!
34  *
35  * Revision 1.3  1995/12/12  16:00:57  adam
36  * System call sync(2) used after update/commit.
37  * Locking (based on fcntl) uses F_EXLCK and F_SHLCK instead of F_WRLCK
38  * and F_RDLCK.
39  *
40  * Revision 1.2  1995/12/11  11:43:29  adam
41  * Locking based on fcntl instead of flock.
42  * Setting commitEnable removed. Command line option -n can be used to
43  * prevent commit if commit setting is defined in the configuration file.
44  *
45  * Revision 1.1  1995/12/07  17:38:47  adam
46  * Work locking mechanisms for concurrent updates/commit.
47  *
48  */
49 #include <stdio.h>
50 #include <assert.h>
51 #include <string.h>
52 #include <errno.h>
53 #include <fcntl.h>
54 #include <sys/types.h>
55 #ifdef WIN32
56 #include <io.h>
57 #include <sys/locking.h>
58 #else
59 #include <unistd.h>
60 #endif
61
62 #include "index.h"
63
64 struct zebra_lock_info {
65     int fd;
66     int excl_flag;
67 };
68
69 ZebraLockHandle zebra_lock_create (const char *name, int excl_flag)
70 {
71     ZebraLockHandle h = (ZebraLockHandle) xmalloc (sizeof(*h));
72     h->excl_flag = excl_flag;
73     h->fd = -1;
74 #ifdef WIN32
75     if (!h->excl_flag)
76         h->fd = open (name, O_BINARY|O_RDONLY);
77     if (h->fd == -1)
78         h->fd = open (name, ((h->excl_flag > 1) ? O_EXCL : 0)|
79             (O_BINARY|O_CREAT|O_RDWR), 0666);
80 #else
81     h->fd= open (name, ((h->excl_flag > 1) ? O_EXCL : 0)|
82             (O_BINARY|O_CREAT|O_RDWR|O_SYNC), 0666);
83 #endif
84     if (h->fd == -1)
85     {
86         if (h->excl_flag <= 1)
87             logf (LOG_WARN|LOG_ERRNO, "open %s", name);
88         xfree (h);
89         return NULL;
90     }
91     return h;
92 }
93
94 void zebra_lock_destroy (ZebraLockHandle h)
95 {
96     if (!h)
97         return;
98     if (h->fd != -1)
99         close (h->fd);
100     xfree (h);
101 }
102
103 void zebra_lock_prefix (Res res, char *path)
104 {
105     char *lock_dir = res_get_def (res, "lockDir", "");
106
107     strcpy (path, lock_dir);
108     if (*path && path[strlen(path)-1] != '/')
109         strcat (path, "/");
110 }
111
112 #ifndef WIN32
113 static int unixLock (int fd, int type, int cmd)
114 {
115     struct flock area;
116     area.l_type = type;
117     area.l_whence = SEEK_SET;
118     area.l_len = area.l_start = 0L;
119     return fcntl (fd, cmd, &area);
120 }
121 #endif
122
123 int zebra_lock (ZebraLockHandle h)
124 {
125 #ifdef WIN32
126     return _locking (h->fd, _LK_LOCK, 1);
127 #else
128     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLKW);
129 #endif
130 }
131
132 int zebra_lock_nb (ZebraLockHandle h)
133 {
134 #ifdef WIN32
135     return _locking (h->fd, _LK_NBLCK, 1);
136 #else
137     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLK);
138 #endif
139 }
140
141 int zebra_unlock (ZebraLockHandle h)
142 {
143 #ifdef WIN32
144     return _locking (h->fd, _LK_UNLCK, 1);
145 #else
146     return unixLock (h->fd, F_UNLCK, F_SETLKW);
147 #endif
148 }
149
150 int zebra_lock_fd (ZebraLockHandle h)
151 {
152     return h->fd;
153 }