366f93627d9a7bcfc8a6cabd6890aa57e4a6f5d8
[idzebra-moved-to-github.git] / index / lockutil.c
1 /*
2  * Copyright (C) 1994-1997, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: lockutil.c,v $
7  * Revision 1.9  1997-09-25 14:54:43  adam
8  * WIN32 files lock support.
9  *
10  * Revision 1.8  1997/09/17 12:19:15  adam
11  * Zebra version corresponds to YAZ version 1.4.
12  * Changed Zebra server so that it doesn't depend on global common_resource.
13  *
14  * Revision 1.7  1997/09/09 13:38:08  adam
15  * Partial port to WIN95/NT.
16  *
17  * Revision 1.6  1996/10/29 14:08:14  adam
18  * Uses resource lockDir instead of lockPath.
19  *
20  * Revision 1.5  1996/03/26 16:01:13  adam
21  * New setting lockPath: directory of various lock files.
22  *
23  * Revision 1.4  1995/12/13  08:46:10  adam
24  * Locking uses F_WRLCK and F_RDLCK again!
25  *
26  * Revision 1.3  1995/12/12  16:00:57  adam
27  * System call sync(2) used after update/commit.
28  * Locking (based on fcntl) uses F_EXLCK and F_SHLCK instead of F_WRLCK
29  * and F_RDLCK.
30  *
31  * Revision 1.2  1995/12/11  11:43:29  adam
32  * Locking based on fcntl instead of flock.
33  * Setting commitEnable removed. Command line option -n can be used to
34  * prevent commit if commit setting is defined in the configuration file.
35  *
36  * Revision 1.1  1995/12/07  17:38:47  adam
37  * Work locking mechanisms for concurrent updates/commit.
38  *
39  */
40 #include <stdio.h>
41 #include <assert.h>
42 #include <string.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <sys/types.h>
46 #ifdef WINDOWS
47 #include <io.h>
48 #include <sys/locking.h>
49 #else
50 #include <unistd.h>
51 #endif
52
53 #include "index.h"
54
55 static char *lockDir = NULL;
56
57 struct zebra_lock_info {
58     int fd;
59     int excl_flag;
60 };
61
62 ZebraLockHandle zebra_lock_create (const char *name, int excl_flag)
63 {
64     ZebraLockHandle h = xmalloc (sizeof(*h));
65     h->excl_flag = excl_flag;
66     h->fd = -1;
67 #ifdef WINDOWS
68     if (!h->excl_flag)
69         h->fd = open (name, O_BINARY|O_RDONLY);
70     if (h->fd == -1)
71         h->fd = open (name, ((h->excl_flag > 1) ? O_EXCL : 0)|
72             (O_BINARY|O_CREAT|O_RDWR), 0666);
73 #else
74     h->fd= open (name, ((h->excl_flag > 1) ? O_EXCL : 0)|
75             (O_BINARY|O_CREAT|O_RDWR|O_SYNC), 0666);
76 #endif
77     if (h->fd == -1)
78     {
79         if (h->excl_flag <= 1)
80             logf (LOG_WARN|LOG_ERRNO, "open %s", name);
81         xfree (h);
82         return NULL;
83     }
84     return h;
85 }
86
87 void zebra_lock_destroy (ZebraLockHandle h)
88 {
89     if (!h)
90         return;
91     if (h->fd != -1)
92         close (h->fd);
93     xfree (h);
94 }
95
96 void zebraLockPrefix (Res res, char *pathPrefix)
97 {
98     if (!lockDir)
99         lockDir = res_get_def (res, "lockDir", "");
100     assert (lockDir);
101     
102     strcpy (pathPrefix, lockDir);
103     if (*pathPrefix && pathPrefix[strlen(pathPrefix)-1] != '/')
104         strcat (pathPrefix, "/");
105 }
106
107 #ifdef WINDOWS
108
109 #else
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 WINDOWS
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 WINDOWS
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 WINDOWS
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 }