662
|
1 #include <string.h>
|
|
2 #include <stdio.h>
|
|
3 #include "lock.h"
|
|
4
|
738
|
5 #if defined(__NetBSD__) || defined(sun) || defined(hpux)
|
|
6 #define _SEM_SEMUN_UNDEFINED /**/
|
|
7 #endif
|
|
8
|
662
|
9 /* ************ Locking functions ***************** */
|
|
10 #ifndef FSP_NOLOCKING
|
|
11
|
|
12 static char code_str[] =
|
|
13 "0123456789:_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
14
|
|
15 static void make_key_string( FSP_LOCK *lock,
|
|
16 unsigned long server_addr,
|
|
17 unsigned long server_port)
|
|
18 {
|
|
19 unsigned long v1, v2;
|
|
20 char *p;
|
|
21
|
|
22 strcpy(lock->key_string,FSP_KEY_PREFIX);
|
|
23 for(p = lock->key_string; *p; p++);
|
|
24 v1 = server_addr;
|
|
25 v2 = server_port;
|
|
26
|
|
27 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
28 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
29 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
30 v1 = v1 | (v2 << (32-3*6));
|
|
31 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
32 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
33 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
34 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
35 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
36 *p = 0;
|
|
37 }
|
|
38 #endif
|
|
39
|
|
40 /********************************************************************/
|
|
41 /******* For those systems that has SysV shared memory + semop ******/
|
|
42 /********************************************************************/
|
|
43 #ifdef FSP_USE_SHAREMEM_AND_SEMOP
|
|
44
|
|
45 #include <sys/types.h>
|
|
46 #include <sys/ipc.h>
|
|
47 #include <sys/shm.h>
|
|
48 #include <sys/sem.h>
|
|
49 #include <fcntl.h>
|
|
50 #include <sys/stat.h>
|
|
51 #include <unistd.h>
|
|
52
|
|
53 #ifdef _SEM_SEMUN_UNDEFINED
|
|
54 union semun
|
|
55 {
|
|
56 int val;
|
|
57 struct semid_ds *buf;
|
|
58 unsigned short int *array;
|
|
59 struct seminfo *__buf;
|
|
60 };
|
|
61 #endif
|
|
62
|
|
63 unsigned short client_get_key (FSP_LOCK *lock)
|
|
64 {
|
|
65 struct sembuf sem;
|
|
66 sem.sem_num = 0;
|
|
67 sem.sem_op = -1;
|
|
68 sem.sem_flg = SEM_UNDO;
|
|
69
|
|
70 if(semop(lock->lock_sem,&sem,1) == -1 )
|
|
71 {
|
|
72 perror("semop lock");
|
|
73 }
|
|
74 return(*lock->share_key);
|
|
75 }
|
|
76
|
|
77 void client_set_key (FSP_LOCK *lock,unsigned short key)
|
|
78 {
|
|
79 struct sembuf sem;
|
|
80
|
|
81 sem.sem_num = 0;
|
|
82 sem.sem_op = 1;
|
|
83 sem.sem_flg = SEM_UNDO;
|
|
84
|
|
85 *lock->share_key = key;
|
|
86 if(semop(lock->lock_sem,&sem,1) == -1) {
|
|
87 perror("semop unlock");
|
|
88 }
|
|
89 }
|
|
90
|
|
91 int client_init_key (FSP_LOCK *lock,
|
|
92 unsigned long server_addr,
|
|
93 unsigned short server_port)
|
|
94 {
|
|
95 mode_t omask;
|
|
96 key_t lock_key;
|
|
97 int fd;
|
|
98 union semun sun;
|
|
99 struct sembuf sem;
|
|
100
|
|
101 make_key_string(lock,server_addr,server_port);
|
|
102
|
|
103 omask = umask(0);
|
|
104 fd = open(lock->key_string,O_RDWR|O_CREAT,0666);
|
|
105 umask(omask);
|
|
106 close(fd);
|
|
107
|
|
108 if((lock_key = ftok(lock->key_string,238)) == -1) {
|
|
109 perror("ftok");
|
|
110 return -1;
|
|
111 }
|
|
112
|
|
113 if((lock->lock_shm = shmget(lock_key,2*sizeof(unsigned int),IPC_CREAT|0666)) == -1) {
|
|
114 perror("shmget");
|
|
115 return -1;
|
|
116 }
|
|
117
|
|
118 if(!(lock->share_key = (unsigned int *) shmat(lock->lock_shm,NULL,0))) {
|
|
119 perror("shmat");
|
|
120 return -1;
|
|
121 }
|
|
122
|
|
123 if((lock->lock_sem = semget(lock_key,0,0)) == -1) {
|
|
124 /* create a new semaphore and init it */
|
|
125 if((lock->lock_sem = semget(lock_key,2,IPC_CREAT|0666)) == -1) {
|
|
126 perror("semget");
|
|
127 return -1;
|
|
128 }
|
|
129 /* we need to init this semaphore */
|
|
130 sun.val=1;
|
|
131 if(semctl(lock->lock_sem,0,SETVAL,sun) == -1)
|
|
132 {
|
|
133 perror("semctl setval");
|
|
134 return -1;
|
|
135 }
|
|
136 }
|
|
137
|
|
138 /* increase in use counter */
|
|
139 sem.sem_num = 1;
|
|
140 sem.sem_op = 1;
|
|
141 sem.sem_flg = SEM_UNDO;
|
|
142
|
|
143 if(semop(lock->lock_sem,&sem,1) == -1) {
|
|
144 perror("semop incuse");
|
|
145 }
|
|
146
|
|
147 return 0;
|
|
148 }
|
|
149
|
|
150 void client_destroy_key(FSP_LOCK *lock)
|
|
151 {
|
|
152 int rc;
|
|
153 struct sembuf sem;
|
|
154
|
|
155 if (shmdt(lock->share_key) < 0)
|
|
156 {
|
|
157 perror("shmdt");
|
|
158 return;
|
|
159 }
|
|
160 /* check if we are only one process holding lock */
|
|
161 rc = semctl(lock->lock_sem,1,GETVAL);
|
|
162 if (rc == 1)
|
|
163 {
|
|
164 /* safe to destroy */
|
|
165 if (
|
|
166 (semctl(lock->lock_sem,0,IPC_RMID) < 0) ||
|
|
167 (shmctl(lock->lock_shm,IPC_RMID,NULL) < 0) ||
|
|
168 (unlink(lock->key_string) < 0) )
|
|
169 rc=0;/* ignore cleanup errors */
|
|
170 }
|
|
171 else
|
|
172 if(rc > 1)
|
|
173 {
|
|
174 /* we need to decrease sem. */
|
|
175 sem.sem_num = 1;
|
|
176 sem.sem_op = -1;
|
|
177 sem.sem_flg = SEM_UNDO;
|
|
178
|
|
179 if(semop(lock->lock_sem,&sem,1) == -1) {
|
|
180 perror("semop decuse");
|
|
181 }
|
|
182 }
|
|
183 }
|
|
184 #endif
|
|
185
|
|
186
|
|
187 /********************************************************************/
|
|
188 /******* For those who do not want to use locking *******************/
|
|
189 /********************************************************************/
|
|
190 #ifdef FSP_NOLOCKING
|
|
191
|
|
192 unsigned short client_get_key (FSP_LOCK *lock)
|
|
193 {
|
|
194 return lock->share_key;
|
|
195 }
|
|
196
|
|
197 void client_set_key (FSP_LOCK *lock,unsigned short key)
|
|
198 {
|
|
199 lock->share_key=key;
|
|
200 }
|
|
201
|
|
202 int client_init_key (FSP_LOCK *lock,
|
|
203 unsigned long server_addr,
|
|
204 unsigned short server_port)
|
|
205 {
|
|
206 return 0;
|
|
207 }
|
|
208
|
|
209 void client_destroy_key(FSP_LOCK *lock)
|
|
210 {
|
|
211 return;
|
|
212 }
|
|
213 #endif
|
|
214
|
|
215 /********************************************************************/
|
|
216 /******* For those systems that has lockf function call *************/
|
|
217 /********************************************************************/
|
|
218 #ifdef FSP_USE_LOCKF
|
|
219
|
|
220 #include <sys/stat.h>
|
|
221 #include <fcntl.h>
|
|
222 #include <unistd.h>
|
|
223
|
|
224 unsigned short client_get_key (FSP_LOCK *lock)
|
|
225 {
|
|
226 unsigned int okey;
|
|
227
|
|
228 if (lockf(lock->lock_fd, F_LOCK, sizeof(okey)) < 0)
|
|
229 {
|
|
230 perror("lockf");
|
|
231 }
|
|
232
|
|
233 if (read(lock->lock_fd, &okey, sizeof(okey)) < 0)
|
|
234 {
|
|
235 perror("readlk");
|
|
236 }
|
|
237
|
|
238 if (lseek(lock->lock_fd, 0L, 0) < 0)
|
|
239 {
|
|
240 perror("seek");
|
|
241 }
|
|
242
|
|
243 return(okey);
|
|
244 }
|
|
245
|
|
246 void client_set_key (FSP_LOCK *lock,unsigned short nkey)
|
|
247 {
|
|
248 unsigned int key;
|
|
249
|
|
250 key=nkey;
|
|
251
|
|
252 if (write(lock->lock_fd, &key, sizeof(key)) < 0)
|
|
253 {
|
|
254 perror("write");
|
|
255 }
|
|
256 if (lseek(lock->lock_fd, 0L, 0) < 0)
|
|
257 {
|
|
258 perror("seek");
|
|
259 }
|
|
260 if (lockf(lock->lock_fd, F_ULOCK, sizeof(key)) < 0)
|
|
261 {
|
|
262 perror("unlockf");
|
|
263 }
|
|
264 }
|
|
265
|
|
266 int client_init_key (FSP_LOCK *lock,
|
|
267 unsigned long server_addr,
|
|
268 unsigned short server_port)
|
|
269 {
|
|
270 mode_t omask;
|
|
271
|
|
272 make_key_string(lock,server_addr, server_port);
|
|
273
|
|
274 omask = umask(0);
|
|
275 lock->lock_fd = open(lock->key_string, O_RDWR | O_CREAT, 0666);
|
|
276 (void)umask(omask);
|
|
277
|
|
278 if(lock->lock_fd < 0)
|
|
279 return -1;
|
|
280 else
|
|
281 return 0;
|
|
282 }
|
|
283
|
|
284 void
|
|
285 client_destroy_key(FSP_LOCK *lock)
|
|
286 {
|
|
287 (void)close(lock->lock_fd);
|
|
288 }
|
|
289 #endif
|