Blame common/compat.h

Packit ce73f7
/*
Packit ce73f7
 * Copyright (c) 2011 Collabora Ltd.
Packit ce73f7
 *
Packit ce73f7
 * Redistribution and use in source and binary forms, with or without
Packit ce73f7
 * modification, are permitted provided that the following conditions
Packit ce73f7
 * are met:
Packit ce73f7
 *
Packit ce73f7
 *     * Redistributions of source code must retain the above
Packit ce73f7
 *       copyright notice, this list of conditions and the
Packit ce73f7
 *       following disclaimer.
Packit ce73f7
 *     * Redistributions in binary form must reproduce the
Packit ce73f7
 *       above copyright notice, this list of conditions and
Packit ce73f7
 *       the following disclaimer in the documentation and/or
Packit ce73f7
 *       other materials provided with the distribution.
Packit ce73f7
 *     * The names of contributors to this software may not be
Packit ce73f7
 *       used to endorse or promote products derived from this
Packit ce73f7
 *       software without specific prior written permission.
Packit ce73f7
 *
Packit ce73f7
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit ce73f7
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit ce73f7
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
Packit ce73f7
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
Packit ce73f7
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit ce73f7
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
Packit ce73f7
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
Packit ce73f7
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
Packit ce73f7
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit ce73f7
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
Packit ce73f7
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
Packit ce73f7
 * DAMAGE.
Packit ce73f7
 *
Packit ce73f7
 * Author: Stef Walter <stefw@collabora.co.uk>
Packit ce73f7
 */
Packit ce73f7
Packit ce73f7
#ifndef __COMPAT_H__
Packit ce73f7
#define __COMPAT_H__
Packit ce73f7
Packit ce73f7
#include "config.h"
Packit ce73f7
Packit ce73f7
#include <sys/types.h>
Packit ce73f7
#include <sys/stat.h>
Packit ce73f7
Packit ce73f7
#if !defined(__cplusplus) && (__GNUC__ > 2)
Packit ce73f7
#define GNUC_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
Packit ce73f7
#else
Packit ce73f7
#define GNUC_PRINTF(x, y)
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#if __GNUC__ >= 4
Packit ce73f7
#define GNUC_NULL_TERMINATED __attribute__((__sentinel__))
Packit ce73f7
#else
Packit ce73f7
#define GNUC_NULL_TERMINATED
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
/* For detecting clang features */
Packit ce73f7
#ifndef __has_feature
Packit ce73f7
#define __has_feature(x) 0
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#ifndef CLANG_ANALYZER_NORETURN
Packit ce73f7
#if __has_feature(attribute_analyzer_noreturn)
Packit ce73f7
#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
Packit ce73f7
#else
Packit ce73f7
#define CLANG_ANALYZER_NORETURN
Packit ce73f7
#endif
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#ifndef O_BINARY
Packit ce73f7
#define O_BINARY 0
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#ifndef O_CLOEXEC
Packit ce73f7
#define O_CLOEXEC 0
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#ifndef HAVE_GETPROGNAME
Packit ce73f7
const char * getprogname (void);
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#ifndef HAVE_MKSTEMP
Packit ce73f7
Packit ce73f7
int          mkstemp     (char *template);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_MKSTEMP */
Packit ce73f7
Packit ce73f7
#ifndef HAVE_MKDTEMP
Packit ce73f7
Packit ce73f7
char *       mkdtemp     (char *template);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_MKDTEMP */
Packit ce73f7
Packit ce73f7
char *       strdup_path_mangle (const char *template);
Packit ce73f7
Packit ce73f7
void         p11_dl_close       (void * dl);
Packit ce73f7
Packit ce73f7
/* -----------------------------------------------------------------------------
Packit ce73f7
 * WIN32
Packit ce73f7
 */
Packit ce73f7
Packit ce73f7
#ifdef OS_WIN32
Packit ce73f7
Packit ce73f7
#ifndef _WIN32_WINNT
Packit ce73f7
#define _WIN32_WINNT 0x500
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#ifndef _WIN32_IE
Packit ce73f7
#define _WIN32_IE 0x500
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#define WIN32_LEAN_AND_MEAN 1
Packit ce73f7
#include <windows.h>
Packit ce73f7
Packit ce73f7
#include <io.h>
Packit ce73f7
Packit ce73f7
/* Oh ... my ... god */
Packit ce73f7
#undef CreateMutex
Packit ce73f7
Packit ce73f7
typedef CRITICAL_SECTION p11_mutex_t;
Packit ce73f7
Packit ce73f7
typedef HANDLE p11_thread_t;
Packit ce73f7
Packit ce73f7
typedef DWORD p11_thread_id_t;
Packit ce73f7
Packit ce73f7
#define P11_RECURSIVE_MUTEX_INIT(m) \
Packit ce73f7
	(InitializeCriticalSection (&m))
Packit ce73f7
#define p11_mutex_init(m) \
Packit ce73f7
	(InitializeCriticalSection (m))
Packit ce73f7
#define p11_mutex_lock(m) \
Packit ce73f7
	(EnterCriticalSection (m))
Packit ce73f7
#define p11_mutex_unlock(m) \
Packit ce73f7
	(LeaveCriticalSection (m))
Packit ce73f7
#define p11_mutex_uninit(m) \
Packit ce73f7
	(DeleteCriticalSection (m))
Packit ce73f7
Packit ce73f7
typedef void * (*p11_thread_routine) (void *arg);
Packit ce73f7
Packit ce73f7
int p11_thread_create (p11_thread_t *thread, p11_thread_routine, void *arg);
Packit ce73f7
Packit ce73f7
int p11_thread_join (p11_thread_t thread);
Packit ce73f7
Packit ce73f7
/* Returns a thread_id_t */
Packit ce73f7
#define p11_thread_id_self() \
Packit ce73f7
	(GetCurrentThreadId ())
Packit ce73f7
Packit ce73f7
typedef HMODULE dl_module_t;
Packit ce73f7
Packit ce73f7
#define p11_dl_open(f) \
Packit ce73f7
	(LoadLibrary (f))
Packit ce73f7
#define p11_dl_symbol(d, s) \
Packit ce73f7
	((void *)GetProcAddress ((d), (s)))
Packit ce73f7
Packit ce73f7
char *    p11_dl_error       (void);
Packit ce73f7
Packit ce73f7
#define p11_sleep_ms(ms) \
Packit ce73f7
	(Sleep (ms))
Packit ce73f7
Packit ce73f7
typedef struct _p11_mmap p11_mmap;
Packit ce73f7
Packit ce73f7
p11_mmap *  p11_mmap_open   (const char *path,
Packit ce73f7
                             struct stat *sb,
Packit ce73f7
                             void **data,
Packit ce73f7
                             size_t *size);
Packit ce73f7
Packit ce73f7
void        p11_mmap_close  (p11_mmap *map);
Packit ce73f7
Packit ce73f7
#ifndef HAVE_SETENV
Packit ce73f7
#define setenv(n, v, z) _putenv_s(n, v)
Packit ce73f7
#endif /* HAVE_SETENV */
Packit ce73f7
Packit ce73f7
#endif /* OS_WIN32 */
Packit ce73f7
Packit ce73f7
/* ----------------------------------------------------------------------------
Packit ce73f7
 * UNIX
Packit ce73f7
 */
Packit ce73f7
Packit ce73f7
#ifdef OS_UNIX
Packit ce73f7
Packit ce73f7
#include <pthread.h>
Packit ce73f7
#include <dlfcn.h>
Packit ce73f7
#include <time.h>
Packit ce73f7
#include <unistd.h>
Packit ce73f7
Packit ce73f7
typedef pthread_mutex_t p11_mutex_t;
Packit ce73f7
Packit ce73f7
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
Packit ce73f7
Packit ce73f7
/* No implementation, because done by static initializer */
Packit ce73f7
#define P11_RECURSIVE_MUTEX_INIT(mutex)
Packit ce73f7
Packit ce73f7
#else
Packit ce73f7
Packit ce73f7
#define P11_RECURSIVE_MUTEX_INIT(mutex) \
Packit ce73f7
	(p11_recursive_mutex_init (&(mutex)))
Packit ce73f7
Packit ce73f7
void        p11_recursive_mutex_init          (p11_mutex_t *mutex);
Packit ce73f7
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#define p11_mutex_init(m) \
Packit ce73f7
	(pthread_mutex_init (m, NULL))
Packit ce73f7
#define p11_mutex_lock(m) \
Packit ce73f7
	(pthread_mutex_lock (m))
Packit ce73f7
#define p11_mutex_unlock(m) \
Packit ce73f7
	(pthread_mutex_unlock (m))
Packit ce73f7
#define p11_mutex_uninit(m) \
Packit ce73f7
	(pthread_mutex_destroy(m))
Packit ce73f7
Packit ce73f7
typedef pthread_t p11_thread_t;
Packit ce73f7
Packit ce73f7
typedef pthread_t p11_thread_id_t;
Packit ce73f7
Packit ce73f7
typedef void * (*p11_thread_routine) (void *arg);
Packit ce73f7
Packit ce73f7
#define p11_thread_create(t, r, a) \
Packit ce73f7
	(pthread_create ((t), NULL, (r), (a)))
Packit ce73f7
#define p11_thread_join(t) \
Packit ce73f7
	(pthread_join ((t), NULL))
Packit ce73f7
#define p11_thread_id_self(m) \
Packit ce73f7
	(pthread_self ())
Packit ce73f7
Packit ce73f7
typedef void * dl_module_t;
Packit ce73f7
Packit ce73f7
#define p11_dl_open(f) \
Packit ce73f7
	(dlopen ((f), RTLD_LOCAL | RTLD_NOW))
Packit ce73f7
#define p11_dl_symbol(d, s) \
Packit ce73f7
	(dlsym ((d), (s)))
Packit ce73f7
Packit ce73f7
char * p11_dl_error (void);
Packit ce73f7
Packit ce73f7
#define p11_sleep_ms(ms) \
Packit ce73f7
	do { int _ms = (ms); \
Packit ce73f7
	struct timespec _ts = { _ms / 1000, (_ms % 1000) * 1000 * 1000 }; \
Packit ce73f7
	nanosleep (&_ts, NULL); \
Packit ce73f7
	} while(0)
Packit ce73f7
Packit ce73f7
typedef struct _p11_mmap p11_mmap;
Packit ce73f7
Packit ce73f7
p11_mmap *  p11_mmap_open   (const char *path,
Packit ce73f7
                             struct stat *sb,
Packit ce73f7
                             void **data,
Packit ce73f7
                             size_t *size);
Packit ce73f7
Packit ce73f7
void        p11_mmap_close  (p11_mmap *map);
Packit ce73f7
Packit ce73f7
#endif /* OS_UNIX */
Packit ce73f7
Packit ce73f7
/* ----------------------------------------------------------------------------
Packit ce73f7
 * MORE COMPAT
Packit ce73f7
 */
Packit ce73f7
Packit ce73f7
#ifdef	HAVE_ERRNO_H
Packit ce73f7
#include <errno.h>
Packit ce73f7
#endif	/* HAVE_ERRNO_H */
Packit ce73f7
Packit ce73f7
#ifndef HAVE_STRNSTR
Packit ce73f7
Packit ce73f7
char *     strnstr          (const char *s,
Packit ce73f7
                             const char *find,
Packit ce73f7
                             size_t slen);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_STRNSTR */
Packit ce73f7
Packit ce73f7
#ifndef HAVE_MEMDUP
Packit ce73f7
Packit ce73f7
void *     memdup           (const void *data,
Packit ce73f7
                             size_t length);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_MEMDUP */
Packit ce73f7
Packit ce73f7
#ifndef HAVE_STRNDUP
Packit ce73f7
Packit ce73f7
char *     strndup          (const char *data,
Packit ce73f7
                             size_t length);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_STRDUP */
Packit ce73f7
Packit ce73f7
#if defined HAVE_DECL_REALLOCARRAY && !HAVE_DECL_REALLOCARRAY
Packit ce73f7
Packit ce73f7
void *     reallocarray     (void *ptr,
Packit ce73f7
                             size_t nmemb,
Packit ce73f7
                             size_t size);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_REALLOCARRAY */
Packit ce73f7
Packit ce73f7
#ifdef HAVE_STDBOOL_H
Packit ce73f7
#include <stdbool.h>
Packit ce73f7
#else
Packit ce73f7
typedef enum { false, true } bool;
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
#ifndef HAVE_STRCONCAT
Packit ce73f7
Packit ce73f7
char *     strconcat        (const char *first,
Packit ce73f7
                             ...) GNUC_NULL_TERMINATED;
Packit ce73f7
Packit ce73f7
#endif /* HAVE_STRCONCAT */
Packit ce73f7
Packit ce73f7
#if defined HAVE_DECL_ASPRINTF && !HAVE_DECL_ASPRINTF
Packit ce73f7
Packit ce73f7
int        asprintf         (char **strp,
Packit ce73f7
                             const char *fmt,
Packit ce73f7
                             ...);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_ASPRINTF */
Packit ce73f7
Packit ce73f7
#if defined HAVE_DECL_VASPRINTF && !HAVE_DECL_VASPRINTF
Packit ce73f7
#include <stdarg.h>
Packit ce73f7
Packit ce73f7
int        vasprintf        (char **strp,
Packit ce73f7
                             const char *fmt,
Packit ce73f7
                             va_list ap);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_DECL_VASPRINTF */
Packit ce73f7
Packit ce73f7
#ifndef HAVE_GMTIME_R
Packit ce73f7
#include <time.h>
Packit ce73f7
Packit ce73f7
struct tm * gmtime_r        (const time_t *timep,
Packit ce73f7
                             struct tm *result);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_GMTIME_R */
Packit ce73f7
Packit ce73f7
#ifndef HAVE_TIMEGM
Packit ce73f7
#include <time.h>
Packit ce73f7
Packit ce73f7
time_t      timegm          (struct tm *tm);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_TIMEGM */
Packit ce73f7
Packit ce73f7
#ifdef HAVE_GETAUXVAL
Packit ce73f7
Packit ce73f7
#include <sys/auxv.h>
Packit ce73f7
Packit ce73f7
#else /* !HAVE_GETAUXVAL */
Packit ce73f7
Packit ce73f7
unsigned long     getauxval (unsigned long type);
Packit ce73f7
Packit ce73f7
#define AT_SECURE 23
Packit ce73f7
Packit ce73f7
#endif /* !HAVE_GETAUXVAL */
Packit ce73f7
Packit ce73f7
char *            secure_getenv (const char *name);
Packit ce73f7
Packit ce73f7
#ifndef HAVE_STRERROR_R
Packit ce73f7
Packit ce73f7
int         strerror_r      (int errnum,
Packit ce73f7
                             char *buf,
Packit ce73f7
                             size_t buflen);
Packit ce73f7
Packit ce73f7
#endif /* HAVE_STRERROR_R */
Packit ce73f7
Packit ce73f7
#ifndef HAVE_FDWALK
Packit ce73f7
Packit ce73f7
int        fdwalk           (int (* cb) (void *data, int fd),
Packit ce73f7
                             void *data);
Packit ce73f7
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
/* If either locale_t or newlocale() is not available, strerror_l()
Packit ce73f7
 * cannot be used */
Packit ce73f7
#if !defined(HAVE_LOCALE_T) || !defined(HAVE_NEWLOCALE)
Packit ce73f7
#undef HAVE_STRERROR_L
Packit ce73f7
#endif
Packit ce73f7
Packit ce73f7
int        p11_ascii_tolower (int c);
Packit ce73f7
int        p11_ascii_toupper (int c);
Packit ce73f7
Packit ce73f7
#endif /* __COMPAT_H__ */