mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
Merge branch 'dirname'
Fixes the incorrect usage of dirname(3) in settings_t and stroke_cred_t, and adds thread-safe variants of dirname(3) and basename(3).
This commit is contained in:
commit
625fc60154
@ -81,7 +81,7 @@ static bool load_configs(char *suite_file, char *test_file)
|
||||
}
|
||||
conftest->test = settings_create(suite_file);
|
||||
conftest->test->load_files(conftest->test, test_file, TRUE);
|
||||
conftest->suite_dir = strdup(dirname(suite_file));
|
||||
conftest->suite_dir = path_dirname(suite_file);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
@ -1158,8 +1157,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
|
||||
}
|
||||
else
|
||||
{ /* use directory of current file if relative */
|
||||
dir = strdup(file);
|
||||
dir = dirname(dir);
|
||||
dir = path_dirname(file);
|
||||
|
||||
if (line.len + 1 + strlen(dir) + 1 > sizeof(pattern))
|
||||
{
|
||||
|
@ -266,19 +266,20 @@ static void do_args(int argc, char *argv[])
|
||||
continue;
|
||||
case 'F':
|
||||
{
|
||||
char *path = strdup(optarg);
|
||||
char *dir = dirname(path);
|
||||
char *file = basename(optarg);
|
||||
char *dir = path_dirname(optarg);
|
||||
char *file = path_basename(optarg);
|
||||
|
||||
if (*dir != '.')
|
||||
{
|
||||
if (!attest->set_directory(attest, dir, op == OP_ADD))
|
||||
{
|
||||
free(path);
|
||||
free(file);
|
||||
free(dir);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
free(path);
|
||||
free(file);
|
||||
free(dir);
|
||||
if (!attest->set_file(attest, file, op == OP_ADD))
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -627,7 +627,7 @@ METHOD(pts_t, get_metadata, pts_file_meta_t*,
|
||||
metadata->destroy(metadata);
|
||||
return NULL;
|
||||
}
|
||||
entry->filename = strdup(basename(pathname));
|
||||
entry->filename = path_basename(pathname);
|
||||
metadata->add(metadata, entry);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ METHOD(pts_database_t, check_file_measurement, status_t,
|
||||
enumerator_t *e;
|
||||
chunk_t hash;
|
||||
status_t status = NOT_FOUND;
|
||||
char *path, *dir, *file;
|
||||
char *dir, *file;
|
||||
|
||||
if (strlen(filename) < 1)
|
||||
{
|
||||
@ -257,9 +257,8 @@ METHOD(pts_database_t, check_file_measurement, status_t,
|
||||
}
|
||||
|
||||
/* separate filename into directory and basename components */
|
||||
path = strdup(filename);
|
||||
dir = dirname(path);
|
||||
file = basename(filename);
|
||||
dir = path_dirname(filename);
|
||||
file = path_basename(filename);
|
||||
|
||||
if (*dir == '.')
|
||||
{ /* relative pathname */
|
||||
@ -281,7 +280,8 @@ METHOD(pts_database_t, check_file_measurement, status_t,
|
||||
DB_TEXT, dir, DB_INT);
|
||||
if (!e)
|
||||
{
|
||||
free(path);
|
||||
free(file);
|
||||
free(dir);
|
||||
return FAILED;
|
||||
}
|
||||
dir_found = e->enumerate(e, &did);
|
||||
@ -289,7 +289,8 @@ METHOD(pts_database_t, check_file_measurement, status_t,
|
||||
|
||||
if (!dir_found)
|
||||
{
|
||||
free(path);
|
||||
free(file);
|
||||
free(dir);
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
@ -301,7 +302,8 @@ METHOD(pts_database_t, check_file_measurement, status_t,
|
||||
DB_TEXT, product, DB_INT, did, DB_TEXT, file, DB_INT, algo,
|
||||
DB_BLOB);
|
||||
}
|
||||
free(path);
|
||||
free(file);
|
||||
free(dir);
|
||||
|
||||
if (!e)
|
||||
{
|
||||
|
@ -341,9 +341,10 @@ pts_file_meas_t *pts_file_meas_create_from_path(u_int16_t request_id,
|
||||
success = FALSE;
|
||||
goto end;
|
||||
}
|
||||
filename = use_rel_name ? basename(pathname) : pathname;
|
||||
filename = use_rel_name ? path_basename(pathname) : strdup(pathname);
|
||||
DBG2(DBG_PTS, " %#B for '%s'", &measurement, filename);
|
||||
add(this, filename, measurement);
|
||||
free(filename);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -36,7 +36,8 @@ selectors/traffic_selector.c threading/thread.c threading/thread_value.c \
|
||||
threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \
|
||||
utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
|
||||
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
|
||||
utils/printf_hook/printf_hook_builtin.c utils/settings.c utils/test.c
|
||||
utils/printf_hook/printf_hook_builtin.c utils/settings.c utils/test.c \
|
||||
utils/utils/strerror.c
|
||||
|
||||
# adding the plugin source files
|
||||
|
||||
|
@ -34,7 +34,8 @@ selectors/traffic_selector.c threading/thread.c threading/thread_value.c \
|
||||
threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \
|
||||
utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
|
||||
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
|
||||
utils/settings.c utils/test.c
|
||||
utils/settings.c utils/test.c \
|
||||
utils/utils/strerror.c
|
||||
|
||||
if USE_DEV_HEADERS
|
||||
strongswan_includedir = ${dev_headers}
|
||||
@ -82,7 +83,8 @@ utils/utils.h utils/chunk.h utils/debug.h utils/enum.h utils/identification.h \
|
||||
utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
|
||||
utils/leak_detective.h utils/printf_hook/printf_hook.h \
|
||||
utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
|
||||
utils/settings.h utils/test.h utils/integrity_checker.h
|
||||
utils/settings.h utils/test.h utils/integrity_checker.h \
|
||||
utils/utils/strerror.h
|
||||
endif
|
||||
|
||||
library.lo : $(top_builddir)/config.status
|
||||
|
@ -467,6 +467,57 @@ START_TEST(test_strreplace)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* path_dirname/basename
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *path;
|
||||
char *dir;
|
||||
char *base;
|
||||
} path_data[] = {
|
||||
{NULL, ".", "."},
|
||||
{"", ".", "."},
|
||||
{".", ".", "."},
|
||||
{"..", ".", ".."},
|
||||
{"/", "/", "/"},
|
||||
{"//", "/", "/"},
|
||||
{"foo", ".", "foo"},
|
||||
{"f/", ".", "f"},
|
||||
{"foo/", ".", "foo"},
|
||||
{"foo//", ".", "foo"},
|
||||
{"/f", "/", "f"},
|
||||
{"/f/", "/", "f"},
|
||||
{"/foo", "/", "foo"},
|
||||
{"/foo/", "/", "foo"},
|
||||
{"//foo/", "/", "foo"},
|
||||
{"foo/bar", "foo", "bar"},
|
||||
{"foo//bar", "foo", "bar"},
|
||||
{"/foo/bar", "/foo", "bar"},
|
||||
{"/foo/bar/", "/foo", "bar"},
|
||||
{"/foo/bar/baz", "/foo/bar", "baz"},
|
||||
};
|
||||
|
||||
START_TEST(test_path_dirname)
|
||||
{
|
||||
char *dir;
|
||||
|
||||
dir = path_dirname(path_data[_i].path);
|
||||
ck_assert_str_eq(path_data[_i].dir, dir);
|
||||
free(dir);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_path_basename)
|
||||
{
|
||||
char *base;
|
||||
|
||||
base = path_basename(path_data[_i].path);
|
||||
ck_assert_str_eq(path_data[_i].base, base);
|
||||
free(base);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* time_printf_hook
|
||||
*/
|
||||
@ -630,6 +681,11 @@ Suite *utils_suite_create()
|
||||
tcase_add_loop_test(tc, test_strreplace, 0, countof(strreplace_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("path_dirname/basename");
|
||||
tcase_add_loop_test(tc, test_path_dirname, 0, countof(path_data));
|
||||
tcase_add_loop_test(tc, test_path_basename, 0, countof(path_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("printf_hooks");
|
||||
tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
|
||||
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
|
||||
|
@ -499,7 +499,7 @@ static bool register_hooks()
|
||||
char *whitelist[] = {
|
||||
/* backtraces, including own */
|
||||
"backtrace_create",
|
||||
"safe_strerror",
|
||||
"strerror_safe",
|
||||
/* pthread stuff */
|
||||
"pthread_create",
|
||||
"pthread_setspecific",
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@ -1302,8 +1301,7 @@ static bool parse_files(linked_list_t *contents, char *file, int level,
|
||||
}
|
||||
else
|
||||
{ /* base relative paths to the directory of the current file */
|
||||
char *dir = strdup(file);
|
||||
dir = dirname(dir);
|
||||
char *dir = path_dirname(file);
|
||||
if (snprintf(pat, sizeof(pat), "%s/%s", dir, pattern) >= sizeof(pat))
|
||||
{
|
||||
DBG1(DBG_LIB, "include pattern too long, ignored");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2013 Tobias Brunner
|
||||
* Copyright (C) 2008-2014 Tobias Brunner
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@ -14,8 +14,7 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define _GNU_SOURCE /* for memrchr */
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -27,6 +26,8 @@
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "collections/enumerator.h"
|
||||
#include "utils/debug.h"
|
||||
#include "utils/chunk.h"
|
||||
@ -193,6 +194,63 @@ char* strreplace(const char *str, const char *search, const char *replace)
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
char* path_dirname(const char *path)
|
||||
{
|
||||
char *pos;
|
||||
|
||||
pos = path ? strrchr(path, '/') : NULL;
|
||||
|
||||
if (pos && !pos[1])
|
||||
{ /* if path ends with slashes we have to look beyond them */
|
||||
while (pos > path && *pos == '/')
|
||||
{ /* skip trailing slashes */
|
||||
pos--;
|
||||
}
|
||||
pos = memrchr(path, '/', pos - path + 1);
|
||||
}
|
||||
if (!pos)
|
||||
{
|
||||
return strdup(".");
|
||||
}
|
||||
while (pos > path && *pos == '/')
|
||||
{ /* skip superfluous slashes */
|
||||
pos--;
|
||||
}
|
||||
return strndup(path, pos - path + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
char* path_basename(const char *path)
|
||||
{
|
||||
char *pos, *trail = NULL;
|
||||
|
||||
if (!path || !*path)
|
||||
{
|
||||
return strdup(".");
|
||||
}
|
||||
pos = strrchr(path, '/');
|
||||
if (pos && !pos[1])
|
||||
{ /* if path ends with slashes we have to look beyond them */
|
||||
while (pos > path && *pos == '/')
|
||||
{ /* skip trailing slashes */
|
||||
pos--;
|
||||
}
|
||||
if (pos == path && *pos == '/')
|
||||
{ /* contains only slashes */
|
||||
return strdup("/");
|
||||
}
|
||||
trail = pos + 1;
|
||||
pos = memrchr(path, '/', trail - path);
|
||||
}
|
||||
pos = pos ? pos + 1 : (char*)path;
|
||||
return trail ? strndup(pos, trail - pos) : strdup(pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
@ -303,84 +361,6 @@ char* tty_escape_get(int fd, tty_escape_t escape)
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the thread-specific error buffer
|
||||
*/
|
||||
#define STRERROR_BUF_LEN 256
|
||||
|
||||
/**
|
||||
* Key to store thread-specific error buffer
|
||||
*/
|
||||
static pthread_key_t strerror_buf_key;
|
||||
|
||||
/**
|
||||
* Only initialize the key above once
|
||||
*/
|
||||
static pthread_once_t strerror_buf_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
/**
|
||||
* Create the key used for the thread-specific error buffer
|
||||
*/
|
||||
static void create_strerror_buf_key()
|
||||
{
|
||||
pthread_key_create(&strerror_buf_key, free);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the error buffer assigned to the current thread (or create it)
|
||||
*/
|
||||
static inline char *get_strerror_buf()
|
||||
{
|
||||
char *buf;
|
||||
|
||||
pthread_once(&strerror_buf_key_once, create_strerror_buf_key);
|
||||
buf = pthread_getspecific(strerror_buf_key);
|
||||
if (!buf)
|
||||
{
|
||||
buf = malloc(STRERROR_BUF_LEN);
|
||||
pthread_setspecific(strerror_buf_key, buf);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRERROR_R
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
const char *safe_strerror(int errnum)
|
||||
{
|
||||
char *buf = get_strerror_buf(), *msg;
|
||||
|
||||
#ifdef STRERROR_R_CHAR_P
|
||||
/* char* version which may or may not return the original buffer */
|
||||
msg = strerror_r(errnum, buf, STRERROR_BUF_LEN);
|
||||
#else
|
||||
/* int version returns 0 on success */
|
||||
msg = strerror_r(errnum, buf, STRERROR_BUF_LEN) ? "Unknown error" : buf;
|
||||
#endif
|
||||
return msg;
|
||||
}
|
||||
#else /* HAVE_STRERROR_R */
|
||||
/* we actually wan't to call strerror(3) below */
|
||||
#undef strerror
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
const char *safe_strerror(int errnum)
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
char *buf = get_strerror_buf();
|
||||
|
||||
/* use a mutex to ensure calling strerror(3) is thread-safe */
|
||||
pthread_mutex_lock(&mutex);
|
||||
strncpy(buf, strerror(errnum), STRERROR_BUF_LEN);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
buf[STRERROR_BUF_LEN - 1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
#endif /* HAVE_STRERROR_R */
|
||||
|
||||
|
||||
#ifndef HAVE_CLOSEFROM
|
||||
/**
|
||||
* Described in header.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2013 Tobias Brunner
|
||||
* Copyright (C) 2008-2014 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@ -30,6 +30,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "enum.h"
|
||||
#include "utils/strerror.h"
|
||||
|
||||
/**
|
||||
* strongSwan program return codes
|
||||
@ -485,6 +486,32 @@ char *translate(char *str, const char *from, const char *to);
|
||||
*/
|
||||
char *strreplace(const char *str, const char *search, const char *replace);
|
||||
|
||||
/**
|
||||
* Like dirname(3) returns the directory part of the given null-terminated
|
||||
* pathname, up to but not including the final '/' (or '.' if no '/' is found).
|
||||
* Trailing '/' are not counted as part of the pathname.
|
||||
*
|
||||
* The difference is that it does this in a thread-safe manner (i.e. it does not
|
||||
* use static buffers) and does not modify the original path.
|
||||
*
|
||||
* @param path original pathname
|
||||
* @return allocated directory component
|
||||
*/
|
||||
char *path_dirname(const char *path);
|
||||
|
||||
/**
|
||||
* Like basename(3) returns the filename part of the given null-terminated path,
|
||||
* i.e. the part following the final '/' (or '.' if path is empty or NULL).
|
||||
* Trailing '/' are not counted as part of the pathname.
|
||||
*
|
||||
* The difference is that it does this in a thread-safe manner (i.e. it does not
|
||||
* use static buffers) and does not modify the original path.
|
||||
*
|
||||
* @param path original pathname
|
||||
* @return allocated filename component
|
||||
*/
|
||||
char *path_basename(const char *path);
|
||||
|
||||
/**
|
||||
* Creates a directory and all required parent directories.
|
||||
*
|
||||
@ -494,23 +521,6 @@ char *strreplace(const char *str, const char *search, const char *replace);
|
||||
*/
|
||||
bool mkdir_p(const char *path, mode_t mode);
|
||||
|
||||
/**
|
||||
* Thread-safe wrapper around strerror and strerror_r.
|
||||
*
|
||||
* This is required because the first is not thread-safe (on some platforms)
|
||||
* and the second uses two different signatures (POSIX/GNU) and is impractical
|
||||
* to use anyway.
|
||||
*
|
||||
* @param errnum error code (i.e. errno)
|
||||
* @return error message
|
||||
*/
|
||||
const char *safe_strerror(int errnum);
|
||||
|
||||
/**
|
||||
* Replace usages of strerror(3) with thread-safe variant.
|
||||
*/
|
||||
#define strerror(errnum) safe_strerror(errnum)
|
||||
|
||||
#ifndef HAVE_CLOSEFROM
|
||||
/**
|
||||
* Close open file descriptors greater than or equal to lowfd.
|
||||
|
97
src/libstrongswan/utils/utils/strerror.c
Normal file
97
src/libstrongswan/utils/utils/strerror.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "strerror.h"
|
||||
|
||||
/**
|
||||
* The size of the thread-specific error buffer
|
||||
*/
|
||||
#define STRERROR_BUF_LEN 256
|
||||
|
||||
/**
|
||||
* Key to store thread-specific error buffer
|
||||
*/
|
||||
static pthread_key_t strerror_buf_key;
|
||||
|
||||
/**
|
||||
* Only initialize the key above once
|
||||
*/
|
||||
static pthread_once_t strerror_buf_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
/**
|
||||
* Create the key used for the thread-specific error buffer
|
||||
*/
|
||||
static void create_strerror_buf_key()
|
||||
{
|
||||
pthread_key_create(&strerror_buf_key, free);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the error buffer assigned to the current thread (or create it)
|
||||
*/
|
||||
static inline char *get_strerror_buf()
|
||||
{
|
||||
char *buf;
|
||||
|
||||
pthread_once(&strerror_buf_key_once, create_strerror_buf_key);
|
||||
buf = pthread_getspecific(strerror_buf_key);
|
||||
if (!buf)
|
||||
{
|
||||
buf = malloc(STRERROR_BUF_LEN);
|
||||
pthread_setspecific(strerror_buf_key, buf);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRERROR_R
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
const char *strerror_safe(int errnum)
|
||||
{
|
||||
char *buf = get_strerror_buf(), *msg;
|
||||
|
||||
#ifdef STRERROR_R_CHAR_P
|
||||
/* char* version which may or may not return the original buffer */
|
||||
msg = strerror_r(errnum, buf, STRERROR_BUF_LEN);
|
||||
#else
|
||||
/* int version returns 0 on success */
|
||||
msg = strerror_r(errnum, buf, STRERROR_BUF_LEN) ? "Unknown error" : buf;
|
||||
#endif
|
||||
return msg;
|
||||
}
|
||||
#else /* HAVE_STRERROR_R */
|
||||
/* we actually wan't to call strerror(3) below */
|
||||
#undef strerror
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
const char *strerror_safe(int errnum)
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
char *buf = get_strerror_buf();
|
||||
|
||||
/* use a mutex to ensure calling strerror(3) is thread-safe */
|
||||
pthread_mutex_lock(&mutex);
|
||||
strncpy(buf, strerror(errnum), STRERROR_BUF_LEN);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
buf[STRERROR_BUF_LEN - 1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
#endif /* HAVE_STRERROR_R */
|
40
src/libstrongswan/utils/utils/strerror.h
Normal file
40
src/libstrongswan/utils/utils/strerror.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{ @ingroup utils
|
||||
*/
|
||||
|
||||
#ifndef STRERROR_H_
|
||||
#define STRERROR_H_
|
||||
|
||||
/**
|
||||
* Thread-safe wrapper around strerror and strerror_r.
|
||||
*
|
||||
* This is required because the first is not thread-safe (on some platforms)
|
||||
* and the second uses two different signatures (POSIX/GNU) and is impractical
|
||||
* to use anyway.
|
||||
*
|
||||
* @param errnum error code (i.e. errno)
|
||||
* @return error message
|
||||
*/
|
||||
const char *strerror_safe(int errnum);
|
||||
|
||||
/**
|
||||
* Replace usages of strerror(3) with thread-safe variant.
|
||||
*/
|
||||
#define strerror(errnum) strerror_safe(errnum)
|
||||
|
||||
#endif /** STRERROR_H_ @}*/
|
Loading…
x
Reference in New Issue
Block a user