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