summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils/utils.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2014-07-11 07:23:31 +0200
committerYves-Alexis Perez <corsac@debian.org>2014-07-11 07:23:31 +0200
commit81c63b0eed39432878f78727f60a1e7499645199 (patch)
tree82387d8fecd1c20788fd8bd784a9b0bde091fb6b /src/libstrongswan/utils/utils.c
parentc5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9 (diff)
downloadvyos-strongswan-81c63b0eed39432878f78727f60a1e7499645199.tar.gz
vyos-strongswan-81c63b0eed39432878f78727f60a1e7499645199.zip
Imported Upstream version 5.2.0
Diffstat (limited to 'src/libstrongswan/utils/utils.c')
-rw-r--r--src/libstrongswan/utils/utils.c279
1 files changed, 240 insertions, 39 deletions
diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c
index fe80edb82..02a720945 100644
--- a/src/libstrongswan/utils/utils.c
+++ b/src/libstrongswan/utils/utils.c
@@ -15,6 +15,13 @@
*/
#define _GNU_SOURCE /* for memrchr */
+#ifdef WIN32
+/* for GetTickCount64, Windows 7 */
+# define _WIN32_WINNT 0x0601
+#endif
+
+#include "utils.h"
+
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
@@ -24,13 +31,17 @@
#include <limits.h>
#include <dirent.h>
#include <time.h>
-#include <pthread.h>
-
-#include "utils.h"
-
-#include "collections/enumerator.h"
-#include "utils/debug.h"
-#include "utils/chunk.h"
+#ifndef WIN32
+# include <signal.h>
+#endif
+
+#include <library.h>
+#include <utils/debug.h>
+#include <utils/chunk.h>
+#include <collections/enumerator.h>
+#include <threading/spinlock.h>
+#include <threading/mutex.h>
+#include <threading/condvar.h>
ENUM(status_names, SUCCESS, NEED_MORE,
"SUCCESS",
@@ -216,6 +227,84 @@ char* strreplace(const char *str, const char *search, const char *replace)
return res;
}
+#ifdef WIN32
+
+/**
+ * Flag to indicate signaled wait_sigint()
+ */
+static bool sigint_signaled = FALSE;
+
+/**
+ * Condvar to wait in wait_sigint()
+ */
+static condvar_t *sigint_cond;
+
+/**
+ * Mutex to check signaling()
+ */
+static mutex_t *sigint_mutex;
+
+/**
+ * Control handler to catch ^C
+ */
+static BOOL WINAPI handler(DWORD dwCtrlType)
+{
+ switch (dwCtrlType)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ sigint_mutex->lock(sigint_mutex);
+ sigint_signaled = TRUE;
+ sigint_cond->signal(sigint_cond);
+ sigint_mutex->unlock(sigint_mutex);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Windows variant
+ */
+void wait_sigint()
+{
+ SetConsoleCtrlHandler(handler, TRUE);
+
+ sigint_mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ sigint_cond = condvar_create(CONDVAR_TYPE_DEFAULT);
+
+ sigint_mutex->lock(sigint_mutex);
+ while (!sigint_signaled)
+ {
+ sigint_cond->wait(sigint_cond, sigint_mutex);
+ }
+ sigint_mutex->unlock(sigint_mutex);
+
+ sigint_mutex->destroy(sigint_mutex);
+ sigint_cond->destroy(sigint_cond);
+}
+
+#else /* !WIN32 */
+
+/**
+ * Unix variant
+ */
+void wait_sigint()
+{
+ sigset_t set;
+ int sig;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGTERM);
+
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ sigwait(&set, &sig);
+}
+
+#endif
+
/**
* Described in header.
*/
@@ -223,21 +312,30 @@ char* path_dirname(const char *path)
{
char *pos;
- pos = path ? strrchr(path, '/') : NULL;
+ pos = path ? strrchr(path, DIRECTORY_SEPARATOR[0]) : NULL;
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
- while (pos > path && *pos == '/')
+ while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip trailing slashes */
pos--;
}
- pos = memrchr(path, '/', pos - path + 1);
+ pos = memrchr(path, DIRECTORY_SEPARATOR[0], pos - path + 1);
}
if (!pos)
{
+#ifdef WIN32
+ if (path && strlen(path))
+ {
+ if ((isalpha(path[0]) && path[1] == ':'))
+ { /* if just a drive letter given, return that as dirname */
+ return chunk_clone(chunk_from_chars(path[0], ':', 0)).ptr;
+ }
+ }
+#endif
return strdup(".");
}
- while (pos > path && *pos == '/')
+ while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip superfluous slashes */
pos--;
}
@@ -255,19 +353,19 @@ char* path_basename(const char *path)
{
return strdup(".");
}
- pos = strrchr(path, '/');
+ pos = strrchr(path, DIRECTORY_SEPARATOR[0]);
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
- while (pos > path && *pos == '/')
+ while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip trailing slashes */
pos--;
}
- if (pos == path && *pos == '/')
+ if (pos == path && *pos == DIRECTORY_SEPARATOR[0])
{ /* contains only slashes */
- return strdup("/");
+ return strdup(DIRECTORY_SEPARATOR);
}
trail = pos + 1;
- pos = memrchr(path, '/', trail - path);
+ pos = memrchr(path, DIRECTORY_SEPARATOR[0], trail - path);
}
pos = pos ? pos + 1 : (char*)path;
return trail ? strndup(pos, trail - pos) : strdup(pos);
@@ -276,6 +374,33 @@ char* path_basename(const char *path)
/**
* Described in header.
*/
+bool path_absolute(const char *path)
+{
+ if (!path)
+ {
+ return FALSE;
+ }
+#ifdef WIN32
+ if (strpfx(path, "\\\\"))
+ { /* UNC */
+ return TRUE;
+ }
+ if (strlen(path) && isalpha(path[0]) && path[1] == ':')
+ { /* drive letter */
+ return TRUE;
+ }
+#else /* !WIN32 */
+ if (path[0] == DIRECTORY_SEPARATOR[0])
+ {
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+/**
+ * Described in header.
+ */
bool mkdir_p(const char *path, mode_t mode)
{
int len;
@@ -307,7 +432,11 @@ bool mkdir_p(const char *path, mode_t mode)
*pos = '\0';
if (access(full, F_OK) < 0)
{
+#ifdef WIN32
+ if (_mkdir(full) < 0)
+#else
if (mkdir(full, mode) < 0)
+#endif
{
DBG1(DBG_LIB, "failed to create directory %s", full);
return FALSE;
@@ -359,6 +488,9 @@ char* tty_escape_get(int fd, tty_escape_t escape)
case TTY_BOLD:
case TTY_UNDERLINE:
case TTY_BLINKING:
+#ifdef WIN32
+ return "";
+#endif
case TTY_FG_BLACK:
case TTY_FG_RED:
case TTY_FG_GREEN:
@@ -378,7 +510,7 @@ char* tty_escape_get(int fd, tty_escape_t escape)
case TTY_BG_WHITE:
case TTY_BG_DEF:
return enum_to_name(tty_color_names, escape);
- /* warn if a excape code is missing */
+ /* warn if a escape code is missing */
}
return "";
}
@@ -414,7 +546,11 @@ void closefrom(int lowfd)
}
/* ...fall back to closing all fds otherwise */
+#ifdef WIN32
+ maxfd = _getmaxstdio();
+#else
maxfd = (int)sysconf(_SC_OPEN_MAX);
+#endif
if (maxfd < 0)
{
maxfd = 256;
@@ -431,6 +567,19 @@ void closefrom(int lowfd)
*/
time_t time_monotonic(timeval_t *tv)
{
+#ifdef WIN32
+ ULONGLONG ms;
+ time_t s;
+
+ ms = GetTickCount64();
+ s = ms / 1000;
+ if (tv)
+ {
+ tv->tv_sec = s;
+ tv->tv_usec = (ms - (s * 1000)) * 1000;
+ }
+ return s;
+#else /* !WIN32 */
#if defined(HAVE_CLOCK_GETTIME) && \
(defined(HAVE_CONDATTR_CLOCK_MONOTONIC) || \
defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC))
@@ -462,6 +611,7 @@ time_t time_monotonic(timeval_t *tv)
return -1;
}
return tv->tv_sec;
+#endif /* !WIN32 */
}
/**
@@ -511,12 +661,12 @@ void nop()
{
}
-#ifndef HAVE_GCC_ATOMIC_OPERATIONS
+#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
/**
- * We use a single mutex for all refcount variables.
+ * Spinlock for ref_get/put
*/
-static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+static spinlock_t *ref_lock;
/**
* Increase refcount
@@ -525,9 +675,9 @@ refcount_t ref_get(refcount_t *ref)
{
refcount_t current;
- pthread_mutex_lock(&ref_mutex);
+ ref_lock->lock(ref_lock);
current = ++(*ref);
- pthread_mutex_unlock(&ref_mutex);
+ ref_lock->unlock(ref_lock);
return current;
}
@@ -539,16 +689,30 @@ bool ref_put(refcount_t *ref)
{
bool more_refs;
- pthread_mutex_lock(&ref_mutex);
+ ref_lock->lock(ref_lock);
more_refs = --(*ref) > 0;
- pthread_mutex_unlock(&ref_mutex);
+ ref_lock->unlock(ref_lock);
return !more_refs;
}
/**
- * Single mutex for all compare and swap operations.
+ * Current refcount
+ */
+refcount_t ref_cur(refcount_t *ref)
+{
+ refcount_t current;
+
+ ref_lock->lock(ref_lock);
+ current = *ref;
+ ref_lock->unlock(ref_lock);
+
+ return current;
+}
+
+/**
+ * Spinlock for all compare and swap operations.
*/
-static pthread_mutex_t cas_mutex = PTHREAD_MUTEX_INITIALIZER;
+static spinlock_t *cas_lock;
/**
* Compare and swap if equal to old value
@@ -557,16 +721,16 @@ static pthread_mutex_t cas_mutex = PTHREAD_MUTEX_INITIALIZER;
bool cas_##name(type *ptr, type oldval, type newval) \
{ \
bool swapped; \
- pthread_mutex_lock(&cas_mutex); \
+ cas_lock->lock(cas_lock); \
if ((swapped = (*ptr == oldval))) { *ptr = newval; } \
- pthread_mutex_unlock(&cas_mutex); \
+ cas_lock->unlock(cas_lock); \
return swapped; \
}
_cas_impl(bool, bool)
_cas_impl(ptr, void*)
-#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
+#endif /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */
#ifdef HAVE_FMEMOPEN_FALLBACK
@@ -614,6 +778,40 @@ FILE *fmemopen(void *buf, size_t size, const char *mode)
#endif /* FMEMOPEN fallback*/
/**
+ * See header
+ */
+void utils_init()
+{
+#ifdef WIN32
+ windows_init();
+#endif
+
+#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
+ ref_lock = spinlock_create();
+ cas_lock = spinlock_create();
+#endif
+
+ strerror_init();
+}
+
+/**
+ * See header
+ */
+void utils_deinit()
+{
+#ifdef WIN32
+ windows_deinit();
+#endif
+
+#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
+ ref_lock->destroy(ref_lock);
+ cas_lock->destroy(cas_lock);
+#endif
+
+ strerror_deinit();
+}
+
+/**
* Described in header.
*/
int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
@@ -625,20 +823,23 @@ int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
};
time_t *time = *((time_t**)(args[0]));
bool utc = *((int*)(args[1]));
- struct tm t;
+ struct tm t, *ret = NULL;
- if (*time == UNDEFINED_TIME)
+ if (*time != UNDEFINED_TIME)
{
- return print_in_hook(data, "--- -- --:--:--%s----",
- utc ? " UTC " : " ");
- }
- if (utc)
- {
- gmtime_r(time, &t);
+ if (utc)
+ {
+ ret = gmtime_r(time, &t);
+ }
+ else
+ {
+ ret = localtime_r(time, &t);
+ }
}
- else
+ if (ret == NULL)
{
- localtime_r(time, &t);
+ return print_in_hook(data, "--- -- --:--:--%s----",
+ utc ? " UTC " : " ");
}
return print_in_hook(data, "%s %02d %02d:%02d:%02d%s%04d",
months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,