summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/crypt/ath.c
Unidiff
Diffstat (limited to 'pwmanager/libcrypt/crypt/ath.c') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/libcrypt/crypt/ath.c287
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. */
40static struct ath_ops ops;
41
42/* True if we should use the external callbacks. */
43static 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. */
54static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER;
55
56int
57ath_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. */
76gpg_err_code_t
77ath_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
116static int
117mutex_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
131int
132ath_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
144int
145ath_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
169int
170ath_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
189int
190ath_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
209ssize_t
210ath_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
219ssize_t
220ath_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
229ssize_t
230ath_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
240ssize_t
241ath_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
250int
251ath_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
260int
261ath_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
270int
271ath_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
280int
281ath_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}