431cb9c748b5b11ab4b6a15d7a6d9505c5febb0f
[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.11  1999-02-02 14:50:59  adam
8  * Updated WIN32 code specific sections. Changed header.
9  *
10  * Revision 1.10  1997/09/29 09:08:36  adam
11  * Revised locking system to be thread safe for the server.
12  *
13  * Revision 1.9  1997/09/25 14:54:43  adam
14  * WIN32 files lock support.
15  *
16  * Revision 1.8  1997/09/17 12:19:15  adam
17  * Zebra version corresponds to YAZ version 1.4.
18  * Changed Zebra server so that it doesn't depend on global common_resource.
19  *
20  * Revision 1.7  1997/09/09 13:38:08  adam
21  * Partial port to WIN95/NT.
22  *
23  * Revision 1.6  1996/10/29 14:08:14  adam
24  * Uses resource lockDir instead of lockPath.
25  *
26  * Revision 1.5  1996/03/26 16:01:13  adam
27  * New setting lockPath: directory of various lock files.
28  *
29  * Revision 1.4  1995/12/13  08:46:10  adam
30  * Locking uses F_WRLCK and F_RDLCK again!
31  *
32  * Revision 1.3  1995/12/12  16:00:57  adam
33  * System call sync(2) used after update/commit.
34  * Locking (based on fcntl) uses F_EXLCK and F_SHLCK instead of F_WRLCK
35  * and F_RDLCK.
36  *
37  * Revision 1.2  1995/12/11  11:43:29  adam
38  * Locking based on fcntl instead of flock.
39  * Setting commitEnable removed. Command line option -n can be used to
40  * prevent commit if commit setting is defined in the configuration file.
41  *
42  * Revision 1.1  1995/12/07  17:38:47  adam
43  * Work locking mechanisms for concurrent updates/commit.
44  *
45  */
46 #include <stdio.h>
47 #include <assert.h>
48 #include <string.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <sys/types.h>
52 #ifdef WIN32
53 #include <io.h>
54 #include <sys/locking.h>
55 #else
56 #include <unistd.h>
57 #endif
58
59 #include "index.h"
60
61 struct zebra_lock_info {
62     int fd;
63     int excl_flag;
64 };
65
66 ZebraLockHandle zebra_lock_create (const char *name, int excl_flag)
67 {
68     ZebraLockHandle h = xmalloc (sizeof(*h));
69     h->excl_flag = excl_flag;
70     h->fd = -1;
71 #ifdef WIN32
72     if (!h->excl_flag)
73         h->fd = open (name, O_BINARY|O_RDONLY);
74     if (h->fd == -1)
75         h->fd = open (name, ((h->excl_flag > 1) ? O_EXCL : 0)|
76             (O_BINARY|O_CREAT|O_RDWR), 0666);
77 #else
78     h->fd= open (name, ((h->excl_flag > 1) ? O_EXCL : 0)|
79             (O_BINARY|O_CREAT|O_RDWR|O_SYNC), 0666);
80 #endif
81     if (h->fd == -1)
82     {
83         if (h->excl_flag <= 1)
84             logf (LOG_WARN|LOG_ERRNO, "open %s", name);
85         xfree (h);
86         return NULL;
87     }
88     return h;
89 }
90
91 void zebra_lock_destroy (ZebraLockHandle h)
92 {
93     if (!h)
94         return;
95     if (h->fd != -1)
96         close (h->fd);
97     xfree (h);
98 }
99
100 void zebra_lock_prefix (Res res, char *path)
101 {
102     char *lock_dir = res_get_def (res, "lockDir", "");
103
104     strcpy (path, lock_dir);
105     if (*path && path[strlen(path)-1] != '/')
106         strcat (path, "/");
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 (ZebraLockHandle h)
121 {
122 #ifdef WIN32
123     return _locking (h->fd, _LK_LOCK, 1);
124 #else
125     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLKW);
126 #endif
127 }
128
129 int zebra_lock_nb (ZebraLockHandle h)
130 {
131 #ifdef WIN32
132     return _locking (h->fd, _LK_NBLCK, 1);
133 #else
134     return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLK);
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
147 int zebra_lock_fd (ZebraLockHandle h)
148 {
149     return h->fd;
150 }