2 * Copyright (C) 2010-2012 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/>
24 #include <gnutls_int.h>
25 #include <gnutls_errors.h>
29 #include <sys/types.h>
35 # ifdef HAVE_PTHREAD_LOCKS
39 # if defined(HAVE_GETPWUID_R)
44 /* We need to disable gnulib's replacement wrappers to get native
45 Windows interfaces. */
50 /* System specific function wrappers.
53 /* wrappers for write() and writev()
58 system_errno (gnutls_transport_ptr p
)
60 int tmperr
= WSAGetLastError ();
80 WSASetLastError (tmperr
);
86 system_write (gnutls_transport_ptr ptr
, const void *data
, size_t data_size
)
88 return send (GNUTLS_POINTER_TO_INT (ptr
), data
, data_size
, 0);
92 system_errno (gnutls_transport_ptr_t ptr
)
94 #if defined(_AIX) || defined(AIX)
95 if (errno
== 0) errno
= EAGAIN
;
102 system_writev (gnutls_transport_ptr_t ptr
, const giovec_t
* iovec
,
105 return writev (GNUTLS_POINTER_TO_INT (ptr
), (struct iovec
*) iovec
,
112 system_read (gnutls_transport_ptr_t ptr
, void *data
, size_t data_size
)
114 return recv (GNUTLS_POINTER_TO_INT (ptr
), data
, data_size
, 0);
117 /* Wait for data to be received within a timeout period in milliseconds.
118 * To catch a termination it will also try to receive 0 bytes from the
119 * socket if select reports to proceed.
121 * Returns -1 on error, 0 on timeout, positive value if data are available for reading.
123 int system_recv_timeout(gnutls_transport_ptr_t ptr
, unsigned int ms
)
128 int fd
= GNUTLS_POINTER_TO_INT(ptr
);
134 tv
.tv_usec
= ms
* 1000;
136 while(tv
.tv_usec
>= 1000000)
138 tv
.tv_usec
-= 1000000;
142 ret
= select(fd
+1, &rfds
, NULL
, NULL
, &tv
);
146 ret2
= recv(fd
, NULL
, 0, MSG_PEEK
);
155 #ifdef HAVE_WIN32_LOCKS
158 /* FIXME: win32 locks are untested */
160 gnutls_system_mutex_init (void **priv
)
162 CRITICAL_SECTION
*lock
= malloc (sizeof (CRITICAL_SECTION
));
165 return GNUTLS_E_MEMORY_ERROR
;
167 InitializeCriticalSection (lock
);
175 gnutls_system_mutex_deinit (void **priv
)
177 DeleteCriticalSection ((CRITICAL_SECTION
*) * priv
);
184 gnutls_system_mutex_lock (void **priv
)
186 EnterCriticalSection ((CRITICAL_SECTION
*) * priv
);
191 gnutls_system_mutex_unlock (void **priv
)
193 LeaveCriticalSection ((CRITICAL_SECTION
*) * priv
);
197 #endif /* WIN32_LOCKS */
199 #ifdef HAVE_PTHREAD_LOCKS
202 gnutls_system_mutex_init (void **priv
)
204 pthread_mutex_t
*lock
= malloc (sizeof (pthread_mutex_t
));
208 return GNUTLS_E_MEMORY_ERROR
;
210 ret
= pthread_mutex_init (lock
, NULL
);
215 return GNUTLS_E_LOCKING_ERROR
;
224 gnutls_system_mutex_deinit (void **priv
)
226 pthread_mutex_destroy ((pthread_mutex_t
*) * priv
);
232 gnutls_system_mutex_lock (void **priv
)
234 if (pthread_mutex_lock ((pthread_mutex_t
*) * priv
))
237 return GNUTLS_E_LOCKING_ERROR
;
244 gnutls_system_mutex_unlock (void **priv
)
246 if (pthread_mutex_unlock ((pthread_mutex_t
*) * priv
))
249 return GNUTLS_E_LOCKING_ERROR
;
255 #endif /* PTHREAD_LOCKS */
260 gnutls_system_mutex_init (void **priv
)
266 gnutls_system_mutex_deinit (void **priv
)
272 gnutls_system_mutex_lock (void **priv
)
278 gnutls_system_mutex_unlock (void **priv
)
283 #endif /* NO_LOCKS */
285 gnutls_time_func gnutls_time
= time
;
286 mutex_init_func gnutls_mutex_init
= gnutls_system_mutex_init
;
287 mutex_deinit_func gnutls_mutex_deinit
= gnutls_system_mutex_deinit
;
288 mutex_lock_func gnutls_mutex_lock
= gnutls_system_mutex_lock
;
289 mutex_unlock_func gnutls_mutex_unlock
= gnutls_system_mutex_unlock
;
291 #define CONFIG_PATH ".gnutls"
293 /* Returns a path to store user-specific configuration
296 int _gnutls_find_config_path(char* path
, size_t max_size
)
298 char tmp_home_dir
[1024];
299 const char *home_dir
= getenv ("HOME");
302 if (home_dir
== NULL
|| home_dir
[0] == '\0')
304 const char *home_drive
= getenv ("HOMEDRIVE");
305 const char *home_path
= getenv ("HOMEPATH");
307 if (home_drive
!= NULL
&& home_path
!= NULL
)
309 snprintf(tmp_home_dir
, sizeof(tmp_home_dir
), "%s%s", home_drive
, home_path
);
316 home_dir
= tmp_home_dir
;
318 #elif defined(HAVE_GETPWUID_R)
319 if (home_dir
== NULL
|| home_dir
[0] == '\0')
325 getpwuid_r(getuid(), &_pwd
, buf
, sizeof(buf
), &pwd
);
328 snprintf(tmp_home_dir
, sizeof(tmp_home_dir
), "%s", pwd
->pw_dir
);
335 home_dir
= tmp_home_dir
;
338 if (home_dir
== NULL
|| home_dir
[0] == '\0')
341 home_dir
= tmp_home_dir
;
345 if (home_dir
== NULL
|| home_dir
[0] == 0)
348 snprintf(path
, max_size
, "%s/"CONFIG_PATH
, home_dir
);