guile: Fix `priorities' test to use `run-test'.
[gnutls.git] / lib / system.c
blob5b7dbedfb8b7e0055c73a0e21443dc78f2080dc1
1 /*
2 * Copyright (C) 2010 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <system.h>
24 #include <gnutls_int.h>
25 #include <gnutls_errors.h>
27 #include <errno.h>
29 #ifdef _WIN32
30 #include <windows.h>
32 #else
33 #ifdef HAVE_PTHREAD_LOCKS
34 #include <pthread.h>
35 #endif
36 #endif
38 /* We need to disable gnulib's replacement wrappers to get native
39 Windows interfaces. */
40 #undef recv
41 #undef send
43 /* System specific function wrappers.
46 /* wrappers for write() and writev()
48 #ifdef _WIN32
50 int
51 system_errno (gnutls_transport_ptr p)
53 int tmperr = WSAGetLastError ();
54 int ret = 0;
55 switch (tmperr)
57 case WSAEWOULDBLOCK:
58 ret = EAGAIN;
59 break;
60 case NO_ERROR:
61 ret = 0;
62 break;
63 case WSAEINTR:
64 ret = EINTR;
65 break;
66 default:
67 ret = EIO;
68 break;
70 WSASetLastError (tmperr);
72 return ret;
75 ssize_t
76 system_write (gnutls_transport_ptr ptr, const void *data, size_t data_size)
78 return send (GNUTLS_POINTER_TO_INT (ptr), data, data_size, 0);
80 #else /* POSIX */
81 int
82 system_errno (gnutls_transport_ptr_t ptr)
84 return errno;
87 ssize_t
88 system_writev (gnutls_transport_ptr_t ptr, const giovec_t * iovec,
89 int iovec_cnt)
91 return writev (GNUTLS_POINTER_TO_INT (ptr), (struct iovec *) iovec,
92 iovec_cnt);
95 #endif
97 ssize_t
98 system_read (gnutls_transport_ptr_t ptr, void *data, size_t data_size)
100 return recv (GNUTLS_POINTER_TO_INT (ptr), data, data_size, 0);
103 ssize_t
104 system_read_peek (gnutls_transport_ptr_t ptr, void *data, size_t data_size)
106 return recv (GNUTLS_POINTER_TO_INT (ptr), data, data_size, MSG_PEEK);
109 /* Wait for data to be received within a timeout period in milliseconds.
110 * If data_size > 0 it will return the specified amount of data in
111 * peek mode.
113 * Returns -1 on error, 0 on timeout.
115 int system_recv_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
117 fd_set rfds;
118 struct timeval tv;
119 int ret, ret2;
121 FD_ZERO(&rfds);
122 FD_SET(GNUTLS_POINTER_TO_INT(ptr), &rfds);
124 tv.tv_sec = 0;
125 tv.tv_usec = ms * 1000;
127 ret = select(GNUTLS_POINTER_TO_INT(ptr)+1, &rfds, NULL, NULL, &tv);
128 if (ret <= 0)
129 return ret;
132 ret2 = recv(GNUTLS_POINTER_TO_INT(ptr), NULL, 0, MSG_PEEK);
133 if (ret2 == -1)
134 return ret2;
136 return ret;
139 /* Thread stuff */
141 #ifdef HAVE_WIN32_LOCKS
144 /* FIXME: win32 locks are untested */
145 static int
146 gnutls_system_mutex_init (void **priv)
148 CRITICAL_SECTION *lock = malloc (sizeof (CRITICAL_SECTION));
150 if (lock == NULL)
151 return GNUTLS_E_MEMORY_ERROR;
153 InitializeCriticalSection (lock);
155 *priv = lock;
157 return 0;
160 static int
161 gnutls_system_mutex_deinit (void **priv)
163 DeleteCriticalSection ((CRITICAL_SECTION *) * priv);
164 free (*priv);
166 return 0;
169 static int
170 gnutls_system_mutex_lock (void **priv)
172 EnterCriticalSection ((CRITICAL_SECTION *) * priv);
173 return 0;
176 static int
177 gnutls_system_mutex_unlock (void **priv)
179 LeaveCriticalSection ((CRITICAL_SECTION *) * priv);
180 return 0;
184 _gnutls_atfork (void (*prepare) (void), void (*parent) (void),
185 void (*child) (void))
187 return 0;
191 #endif /* WIN32_LOCKS */
193 #ifdef HAVE_PTHREAD_LOCKS
195 static int
196 gnutls_system_mutex_init (void **priv)
198 pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
199 int ret;
201 if (lock == NULL)
202 return GNUTLS_E_MEMORY_ERROR;
204 ret = pthread_mutex_init (lock, NULL);
205 if (ret)
207 free (lock);
208 gnutls_assert ();
209 return GNUTLS_E_LOCKING_ERROR;
212 *priv = lock;
214 return 0;
217 static int
218 gnutls_system_mutex_deinit (void **priv)
220 pthread_mutex_destroy ((pthread_mutex_t *) * priv);
221 free (*priv);
222 return 0;
225 static int
226 gnutls_system_mutex_lock (void **priv)
228 if (pthread_mutex_lock ((pthread_mutex_t *) * priv))
230 gnutls_assert ();
231 return GNUTLS_E_LOCKING_ERROR;
234 return 0;
237 static int
238 gnutls_system_mutex_unlock (void **priv)
240 if (pthread_mutex_unlock ((pthread_mutex_t *) * priv))
242 gnutls_assert ();
243 return GNUTLS_E_LOCKING_ERROR;
246 return 0;
250 _gnutls_atfork (void (*prepare) (void), void (*parent) (void),
251 void (*child) (void))
253 return pthread_atfork (prepare, parent, child);
256 #endif /* PTHREAD_LOCKS */
258 #ifdef HAVE_NO_LOCKS
260 static int
261 gnutls_system_mutex_init (void **priv)
263 return 0;
266 static int
267 gnutls_system_mutex_deinit (void **priv)
269 return 0;
272 static int
273 gnutls_system_mutex_lock (void **priv)
275 return 0;
278 static int
279 gnutls_system_mutex_unlock (void **priv)
281 return 0;
285 _gnutls_atfork (void (*prepare) (void), void (*parent) (void),
286 void (*child) (void))
288 return 0;
291 #endif /* NO_LOCKS */
293 gnutls_time_func gnutls_time = time;
294 mutex_init_func gnutls_mutex_init = gnutls_system_mutex_init;
295 mutex_deinit_func gnutls_mutex_deinit = gnutls_system_mutex_deinit;
296 mutex_lock_func gnutls_mutex_lock = gnutls_system_mutex_lock;
297 mutex_unlock_func gnutls_mutex_unlock = gnutls_system_mutex_unlock;