author | zautrix <zautrix> | 2004-10-19 20:16:14 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-10-19 20:16:14 (UTC) |
commit | eca49bb06a71980ef61d078904573f25890fc7f2 (patch) (unidiff) | |
tree | c5338e3b12430248979a9ac2c1c7e6646ea9ecdf /pwmanager/libcrypt/crypt/ath.c | |
parent | 53cc32b6e7b1f672bf91b2baf2df6c1e8baf3e0a (diff) | |
download | kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.zip kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.tar.gz kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.tar.bz2 |
Initial revision
Diffstat (limited to 'pwmanager/libcrypt/crypt/ath.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/crypt/ath.c | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/crypt/ath.c b/pwmanager/libcrypt/crypt/ath.c new file mode 100644 index 0000000..6788bba --- a/dev/null +++ b/pwmanager/libcrypt/crypt/ath.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* ath.c - Thread-safeness library. | ||
2 | Copyright (C) 2002, 2003, 2004 g10 Code GmbH | ||
3 | |||
4 | This file is part of Libgcrypt. | ||
5 | |||
6 | Libgcrypt is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU Lesser General Public License as | ||
8 | published by the Free Software Foundation; either version 2.1 of | ||
9 | the License, or (at your option) any later version. | ||
10 | |||
11 | Libgcrypt is distributed in the hope that it will be useful, but | ||
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Lesser General Public | ||
17 | License along with Libgcrypt; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
19 | 02111-1307, USA. */ | ||
20 | |||
21 | #ifdef HAVE_CONFIG_H | ||
22 | #include <config.h> | ||
23 | #endif | ||
24 | |||
25 | #include <assert.h> | ||
26 | #include <unistd.h> | ||
27 | #ifdef HAVE_SYS_SELECT_H | ||
28 | # include <sys/select.h> | ||
29 | #else | ||
30 | # include <sys/time.h> | ||
31 | #endif | ||
32 | #include <sys/types.h> | ||
33 | #include <sys/wait.h> | ||
34 | #include <errno.h> | ||
35 | |||
36 | #include "ath.h" | ||
37 | |||
38 | |||
39 | /* The interface table. */ | ||
40 | static struct ath_ops ops; | ||
41 | |||
42 | /* True if we should use the external callbacks. */ | ||
43 | static int ops_set; | ||
44 | |||
45 | |||
46 | /* For the dummy interface. */ | ||
47 | #define MUTEX_UNLOCKED((ath_mutex_t) 0) | ||
48 | #define MUTEX_LOCKED((ath_mutex_t) 1) | ||
49 | #define MUTEX_DESTROYED((ath_mutex_t) 2) | ||
50 | |||
51 | |||
52 | |||
53 | /* The lock we take while checking for lazy lock initialization. */ | ||
54 | static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER; | ||
55 | |||
56 | int | ||
57 | ath_init (void) | ||
58 | { | ||
59 | int err = 0; | ||
60 | |||
61 | if (ops_set) | ||
62 | { | ||
63 | if (ops.init) | ||
64 | err = (*ops.init) (); | ||
65 | if (err) | ||
66 | return err; | ||
67 | err = (*ops.mutex_init) (&check_init_lock); | ||
68 | } | ||
69 | return err; | ||
70 | } | ||
71 | |||
72 | |||
73 | /* Initialize the locking library. Returns 0 if the operation was | ||
74 | successful, EINVAL if the operation table was invalid and EBUSY if | ||
75 | we already were initialized. */ | ||
76 | gpg_err_code_t | ||
77 | ath_install (struct ath_ops *ath_ops, int check_only) | ||
78 | { | ||
79 | if (check_only) | ||
80 | { | ||
81 | enum ath_thread_option option = ATH_THREAD_OPTION_DEFAULT; | ||
82 | |||
83 | /* Check if the requested thread option is compatible to the | ||
84 | thread option we are already committed to. */ | ||
85 | if (ath_ops) | ||
86 | option = ath_ops->option; | ||
87 | |||
88 | if (!ops_set && option) | ||
89 | return GPG_ERR_NOT_SUPPORTED; | ||
90 | |||
91 | if (ops.option == ATH_THREAD_OPTION_USER | ||
92 | || option == ATH_THREAD_OPTION_USER | ||
93 | || ops.option != option) | ||
94 | return GPG_ERR_NOT_SUPPORTED; | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | if (ath_ops) | ||
100 | { | ||
101 | /* It is convenient to not require DESTROY. */ | ||
102 | if (!ath_ops->mutex_init || !ath_ops->mutex_lock | ||
103 | || !ath_ops->mutex_unlock) | ||
104 | return GPG_ERR_INV_ARG; | ||
105 | |||
106 | ops = *ath_ops; | ||
107 | ops_set = 1; | ||
108 | } | ||
109 | else | ||
110 | ops_set = 0; | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | |||
116 | static int | ||
117 | mutex_init (ath_mutex_t *lock, int just_check) | ||
118 | { | ||
119 | int err = 0; | ||
120 | |||
121 | if (just_check) | ||
122 | (*ops.mutex_lock) (&check_init_lock); | ||
123 | if (*lock == ATH_MUTEX_INITIALIZER || !just_check) | ||
124 | err = (*ops.mutex_init) (lock); | ||
125 | if (just_check) | ||
126 | (*ops.mutex_unlock) (&check_init_lock); | ||
127 | return err; | ||
128 | } | ||
129 | |||
130 | |||
131 | int | ||
132 | ath_mutex_init (ath_mutex_t *lock) | ||
133 | { | ||
134 | if (ops_set) | ||
135 | return mutex_init (lock, 0); | ||
136 | |||
137 | #ifndef NDEBUG | ||
138 | *lock = MUTEX_UNLOCKED; | ||
139 | #endif | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | |||
144 | int | ||
145 | ath_mutex_destroy (ath_mutex_t *lock) | ||
146 | { | ||
147 | if (ops_set) | ||
148 | { | ||
149 | int err = mutex_init (lock, 1); | ||
150 | |||
151 | if (err) | ||
152 | return err; | ||
153 | |||
154 | if (ops.mutex_destroy) | ||
155 | return (*ops.mutex_destroy) (lock); | ||
156 | else | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | #ifndef NDEBUG | ||
161 | assert (*lock == MUTEX_UNLOCKED); | ||
162 | |||
163 | *lock = MUTEX_DESTROYED; | ||
164 | #endif | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | |||
169 | int | ||
170 | ath_mutex_lock (ath_mutex_t *lock) | ||
171 | { | ||
172 | if (ops_set) | ||
173 | { | ||
174 | int ret = mutex_init (lock, 1); | ||
175 | if (ret) | ||
176 | return ret; | ||
177 | return (*ops.mutex_lock) (lock); | ||
178 | } | ||
179 | |||
180 | #ifndef NDEBUG | ||
181 | assert (*lock == MUTEX_UNLOCKED); | ||
182 | |||
183 | *lock = MUTEX_LOCKED; | ||
184 | #endif | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | |||
189 | int | ||
190 | ath_mutex_unlock (ath_mutex_t *lock) | ||
191 | { | ||
192 | if (ops_set) | ||
193 | { | ||
194 | int ret = mutex_init (lock, 1); | ||
195 | if (ret) | ||
196 | return ret; | ||
197 | return (*ops.mutex_unlock) (lock); | ||
198 | } | ||
199 | |||
200 | #ifndef NDEBUG | ||
201 | assert (*lock == MUTEX_LOCKED); | ||
202 | |||
203 | *lock = MUTEX_UNLOCKED; | ||
204 | #endif | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | |||
209 | ssize_t | ||
210 | ath_read (int fd, void *buf, size_t nbytes) | ||
211 | { | ||
212 | if (ops_set && ops.read) | ||
213 | return (*ops.read) (fd, buf, nbytes); | ||
214 | else | ||
215 | return read (fd, buf, nbytes); | ||
216 | } | ||
217 | |||
218 | |||
219 | ssize_t | ||
220 | ath_write (int fd, const void *buf, size_t nbytes) | ||
221 | { | ||
222 | if (ops_set && ops.write) | ||
223 | return (*ops.write) (fd, buf, nbytes); | ||
224 | else | ||
225 | return write (fd, buf, nbytes); | ||
226 | } | ||
227 | |||
228 | |||
229 | ssize_t | ||
230 | ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, | ||
231 | struct timeval *timeout) | ||
232 | { | ||
233 | if (ops_set && ops.select) | ||
234 | return (*ops.select) (nfd, rset, wset, eset, timeout); | ||
235 | else | ||
236 | return select (nfd, rset, wset, eset, timeout); | ||
237 | } | ||
238 | |||
239 | |||
240 | ssize_t | ||
241 | ath_waitpid (pid_t pid, int *status, int options) | ||
242 | { | ||
243 | if (ops_set && ops.waitpid) | ||
244 | return (*ops.waitpid) (pid, status, options); | ||
245 | else | ||
246 | return waitpid (pid, status, options); | ||
247 | } | ||
248 | |||
249 | |||
250 | int | ||
251 | ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr) | ||
252 | { | ||
253 | if (ops_set && ops.accept) | ||
254 | return (*ops.accept) (s, addr, length_ptr); | ||
255 | else | ||
256 | return accept (s, addr, length_ptr); | ||
257 | } | ||
258 | |||
259 | |||
260 | int | ||
261 | ath_connect (int s, struct sockaddr *addr, socklen_t length) | ||
262 | { | ||
263 | if (ops_set && ops.connect) | ||
264 | return (*ops.connect) (s, addr, length); | ||
265 | else | ||
266 | return connect (s, addr, length); | ||
267 | } | ||
268 | |||
269 | |||
270 | int | ||
271 | ath_sendmsg (int s, const struct msghdr *msg, int flags) | ||
272 | { | ||
273 | if (ops_set && ops.sendmsg) | ||
274 | return (*ops.sendmsg) (s, msg, flags); | ||
275 | else | ||
276 | return sendmsg (s, msg, flags); | ||
277 | } | ||
278 | |||
279 | |||
280 | int | ||
281 | ath_recvmsg (int s, struct msghdr *msg, int flags) | ||
282 | { | ||
283 | if (ops_set && ops.recvmsg) | ||
284 | return (*ops.recvmsg) (s, msg, flags); | ||
285 | else | ||
286 | return recvmsg (s, msg, flags); | ||
287 | } | ||