Merge some portability changes from the mingw branch

Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
Angus Salkeld 2011-12-21 13:38:24 +11:00
parent 3554d145fc
commit ab3dc60f7f
23 changed files with 639 additions and 597 deletions

View File

@ -58,6 +58,7 @@ AC_PROG_CXX
AC_PROG_AWK
AC_PROG_CC
AC_PROG_CPP
AM_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
@ -115,10 +116,11 @@ fi
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h netinet/in.h stdint.h \
time.h sys/time.h stdlib.h string.h strings.h sys/types.h sys/stat.h \
sys/param.h sys/socket.h sys/time.h sys/timerfd.h sys/epoll.h \
sys/sockio.h sys/un.h syslog.h errno.h unistd.h])
AC_CHECK_HEADERS([arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h stdint.h \
dlfcn.h time.h sys/time.h stdlib.h string.h strings.h sys/types.h sys/stat.h \
sys/param.h sys/socket.h sys/time.h sys/timerfd.h sys/poll.h sys/epoll.h sys/uio.h \
sys/sockio.h sys/un.h sys/resource.h syslog.h errno.h unistd.h sys/mman.h \
sys/sem.h sys/ipc.h sys/msg.h mqueue.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
@ -141,19 +143,19 @@ AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_MMAP
AC_FUNC_REALLOC
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday localtime_r memset munmap \
socket strchr strdup strerror strrchr strstr \
epoll_create epoll_create1 \
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday localtime localtime_r \
memset munmap socket strchr strrchr strchrnul strdup strerror strstr \
poll epoll_create epoll_create1 random rand getrlimit sysconf \
pthread_spin_lock timerfd_create pthread_setschedparam \
sched_get_priority_max sched_setscheduler])
## local defines
PACKAGE_FEATURES=""
if test $ac_cv_func_timerfd_create = yes; then
if test x$ac_cv_func_timerfd_create = xyes; then
PACKAGE_FEATURES="$PACKAGE_FEATURES timerfd"
fi
if test $ac_cv_func_epoll_create = yes; then
if test x$ac_cv_func_epoll_create = xyes; then
PACKAGE_FEATURES="$PACKAGE_FEATURES epoll"
fi
@ -207,6 +209,8 @@ fi
# THIS SECTION MUST DIE!
CP=cp
LIB_RT=-lrt
supports_sysv_mq="yes"
supports_posix_mq="yes"
AC_MSG_CHECKING([for os in ${host_os}])
case "$host_os" in
*linux*)
@ -219,6 +223,8 @@ case "$host_os" in
[Compiling for Darwin platform])
CP=rsync
LIB_RT=
supports_sysv_mq="no"
supports_posix_mq="no"
ac_cv_link_attribute_section=no
dnl Attribute section appears to work here but fails later with:
dnl cc1: error in backend: Global variable 'descriptor.4902' has an invalid section specifier '__verbose': mach-o section specifier requires a segment and section separated by a comma
@ -245,7 +251,7 @@ case "$host_os" in
[Compiling for FreeBSD >= 8 platform])
;;
esac
AC_MSG_RESULT([BSB])
AC_MSG_RESULT([BSD])
;;
*solaris*)
AC_DEFINE_UNQUOTED([QB_SOLARIS], [1],
@ -262,42 +268,50 @@ case "$host_os" in
;;
esac
# Check for atomic support
gcc_has_builtin_atomic_operations=no
if test x"$GCC" = xyes; then
AC_MSG_CHECKING([whether GCC supports build-in atomic intrinsics])
AC_TRY_LINK([],
[int i;
__sync_synchronize ();
__sync_bool_compare_and_swap (&i, 0, 1);
__sync_fetch_and_add (&i, 1);
],
[gcc_has_builtin_atomic_operations=yes],
[gcc_has_builtin_atomic_operations=no])
AC_MSG_CHECKING([whether GCC supports build-in atomic intrinsics])
if test -z "$gcc_has_builtin_atomic_operations"; then
gcc_has_builtin_atomic_operations=no
if test x"$GCC" = xyes && test x$have_mingw != xyes; then
AC_TRY_LINK([],
[int i;
__sync_synchronize ();
__sync_bool_compare_and_swap (&i, 0, 1);
__sync_fetch_and_add (&i, 1);
],
[gcc_has_builtin_atomic_operations=yes],
[gcc_has_builtin_atomic_operations=no])
fi
fi
AC_MSG_RESULT($gcc_has_builtin_atomic_operations)
AM_CONDITIONAL(HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS,
[test "x$gcc_has_builtin_atomic_operations" = xyes])
AC_MSG_RESULT($gcc_has_builtin_atomic_operations)
if test $gcc_has_builtin_atomic_operations = yes; then
if test "x$gcc_has_builtin_atomic_operations" = xyes; then
AC_DEFINE_UNQUOTED(HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS, 1,
[have builtin atomic operations])
fi
AC_MSG_CHECKING([whether atomics need memory barrier])
if test -n "$ac_cv_atomic_need_memory_barrier"; then
memory_barrier_needed=$ac_cv_atomic_need_memory_barrier
else
if test x$gcc_has_builtin_atomic_operations = xyes; then
memory_barrier_needed=yes
PACKAGE_FEATURES="$PACKAGE_FEATURES gcc__sync"
PACKAGE_FEATURES="$PACKAGE_FEATURES gcc__sync"
else
if test $nongcc_memory_barrier_needed = yes; then
memory_barrier_needed=yes
fi
memory_barrier_needed=$nongcc_memory_barrier_needed
AC_MSG_WARN([-----------------------------])
AC_MSG_WARN([You have gcc but not __sync_bool_compare_and_swap])
AC_MSG_WARN([try CFLAGS="-march=<your arch> -mtune=native" ./configure])
AC_MSG_WARN([-----------------------------])
fi
fi
AC_MSG_RESULT($memory_barrier_needed)
if test x"$memory_barrier_needed" != xno; then
AC_DEFINE_UNQUOTED(QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED, 1,
[need atomic memory barrier])
fi
AM_CONDITIONAL(HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS,
[test $gcc_has_builtin_atomic_operations = yes])
fi
LINT_FLAGS="-weak -unrecog +posixlib +ignoresigns -fcnuse \
-badflag -D__gnuc_va_list=va_list -D__attribute\(x\)= \
@ -393,12 +407,33 @@ else
COVERAGE_LDFLAGS=""
fi
if test "x${enable_slow_tests}" = xyes ; then
AC_DEFINE([HAVE_SLOW_TESTS], 1,[have slow tests])
AC_MSG_NOTICE([Enabling Slow tests])
fi
AM_CONDITIONAL(HAVE_SLOW_TESTS, [test "x$enable_slow_tests" = xyes])
AM_CONDITIONAL(HAVE_SLOW_TESTS, [test "x${enable_slow_tests}" = xyes])
if test -n "$ac_cv_supports_sysv_mq"; then
supports_sysv_mq=$ac_cv_supports_sysv_mq
fi
if test "x${supports_sysv_mq}" = xyes ; then
AC_DEFINE([HAVE_SYSV_MQ], [1],
[have sysv message queues])
PACKAGE_FEATURES="$PACKAGE_FEATURES sysv_mq"
AC_MSG_NOTICE([Enabling SYSV Message Queues])
fi
AM_CONDITIONAL(HAVE_SYSV_MQ, [test "x${supports_sysv_mq}" = xyes])
if test -n "$ac_cv_supports_posix_mq"; then
supports_posix_mq=$ac_cv_supports_posix_mq
fi
if test "x${supports_posix_mq}" = xyes ; then
AC_DEFINE([HAVE_POSIX_MQ], [1],
[have posix message queues])
PACKAGE_FEATURES="$PACKAGE_FEATURES posix_mq"
AC_MSG_NOTICE([Enabling POSIX Message Queues])
fi
AM_CONDITIONAL(HAVE_POSIX_MQ, [test "x${supports_posix_mq}" = xyes])
AM_CONDITIONAL(USE_TIMERFD, [test "x$ac_cv_func_timerfd_create" = xyes])

View File

@ -37,7 +37,9 @@
#include <sys/types.h>
#endif /* HAVE_SYS_TYPES_H */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif /* HAVE_SYS_UIO_H */
#ifdef HAVE_STDINT_H
#include <stdint.h>

View File

@ -27,6 +27,8 @@ extern "C" {
#endif
/* *INDENT-ON* */
#include <qb/qbconfig.h>
#include <pthread.h>
#include <sys/poll.h>
#include <sys/socket.h>

View File

@ -26,6 +26,8 @@ extern "C" {
#endif
/* *INDENT-ON* */
#include <pthread.h>
#include <stdint.h>
#ifndef S_SPLINT_S
#include <unistd.h>

View File

@ -40,21 +40,25 @@ libqb_la_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
libqb_la_LDFLAGS = -version-info 7:0:7
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \
loop.c loop_poll.c loop_job.c \
ipcc.c ipcs.c ipc_posix_mq.c ipc_sysv_mq.c ipc_shm.c ipc_us.c \
ipcc.c ipcs.c ipc_shm.c ipc_us.c \
log.c log_thread.c log_blackbox.c log_file.c \
log_syslog.c log_dcs.c log_format.c \
map.c skiplist.c hashtable.c trie.c
libqb_la_SOURCES = $(source_to_lint)
libqb_la_SOURCES = $(source_to_lint) unix.c
if HAVE_SYSV_MQ
libqb_la_SOURCES+=ipc_sysv_mq.c
endif
if HAVE_POSIX_MQ
libqb_la_SOURCES+=ipc_posix_mq.c
endif
if USE_TIMERFD
else
libqb_la_SOURCES+=loop_timerlist.c
endif
if HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS
libqb_la_SOURCES+=atomic_gcc.c
else
libqb_la_SOURCES+=atomic_lock.c
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libqb.pc

View File

@ -1,88 +0,0 @@
/*
* Copyright (C) 2009 Hiroyuki Ikezoe
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copied from the glib code base (glib/gatomic-gcc.c) and namespaced
* for libqb.
*/
#include "config.h"
#include <qb/qbatomic.h>
void
qb_atomic_init(void)
{
}
int32_t
qb_atomic_int_exchange_and_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t val)
{
return __sync_fetch_and_add(atomic, val);
}
void
qb_atomic_int_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic, int32_t val)
{
__sync_fetch_and_add(atomic, val);
}
int32_t
qb_atomic_int_compare_and_exchange(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t oldval, int32_t newval)
{
return __sync_bool_compare_and_swap(atomic, oldval, newval);
}
int32_t
qb_atomic_pointer_compare_and_exchange(volatile void *QB_GNUC_MAY_ALIAS *
atomic, void *oldval, void *newval)
{
return __sync_bool_compare_and_swap(atomic, oldval, newval);
}
int32_t
(qb_atomic_int_get) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic)
{
__sync_synchronize();
return *atomic;
}
void
(qb_atomic_int_set) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t newval)
{
*atomic = newval;
__sync_synchronize();
}
void *
(qb_atomic_pointer_get) (volatile void *QB_GNUC_MAY_ALIAS * atomic)
{
__sync_synchronize();
return (void *)*atomic;
}
void
(qb_atomic_pointer_set) (volatile void *QB_GNUC_MAY_ALIAS * atomic,
void *newval)
{
*atomic = newval;
__sync_synchronize();
}

View File

@ -1,214 +0,0 @@
/*
* Copyright (C) 2003 Sebastian Wilhelmi
* Copyright (C) 2007 Nokia Corporation
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copied basic locking backup method from the glib code base
* (glib/gatomic.c) and namespaced for libqb.
*/
#include "os_base.h"
#include <qb/qbatomic.h>
#include <qb/qbutil.h>
#ifdef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED
#if defined (QB_ARCH_SPARC)
#define QB_ATOMIC_MEMORY_BARRIER \
__asm__ __volatile__ ("membar #LoadLoad | #LoadStore" \
" | #StoreLoad | #StoreStore" : : : "memory")
#elif defined (QB_ARCH_ALPHA)
#define QB_ATOMIC_MEMORY_BARRIER __asm__ ("mb" : : : "memory")
#elif defined (QB_ARCH_POWERPC)
#define QB_ATOMIC_MEMORY_BARRIER __asm__ ("sync" : : : "memory")
#elif defined (QB_ARCH_IA64)
#define QB_ATOMIC_MEMORY_BARRIER __sync_synchronize ()
#endif /* arch */
#endif /* QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
/* We have to use the slow, but safe locking method */
static qb_thread_lock_t *qb_atomic_mutex = NULL;
void
qb_atomic_init(void)
{
if (qb_atomic_mutex == NULL) {
qb_atomic_mutex = qb_thread_lock_create(QB_THREAD_LOCK_SHORT);
}
assert(qb_atomic_mutex);
}
int32_t
qb_atomic_int_exchange_and_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t val)
{
int32_t result;
qb_thread_lock(qb_atomic_mutex);
result = *atomic;
*atomic += val;
qb_thread_unlock(qb_atomic_mutex);
return result;
}
void
qb_atomic_int_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic, int32_t val)
{
qb_thread_lock(qb_atomic_mutex);
*atomic += val;
qb_thread_unlock(qb_atomic_mutex);
}
int32_t
qb_atomic_int_compare_and_exchange(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t oldval, int32_t newval)
{
int32_t result;
qb_thread_lock(qb_atomic_mutex);
if (*atomic == oldval) {
result = QB_TRUE;
*atomic = newval;
} else {
result = QB_FALSE;
}
qb_thread_unlock(qb_atomic_mutex);
return result;
}
int32_t
qb_atomic_pointer_compare_and_exchange(volatile void *QB_GNUC_MAY_ALIAS *
atomic, void *oldval, void *newval)
{
int32_t result;
qb_thread_lock(qb_atomic_mutex);
if (*atomic == oldval) {
result = QB_TRUE;
*atomic = newval;
} else {
result = QB_FALSE;
}
qb_thread_unlock(qb_atomic_mutex);
return result;
}
#ifdef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED
int32_t(qb_atomic_int_get) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic) {
int32_t result;
qb_thread_lock(qb_atomic_mutex);
result = *atomic;
qb_thread_unlock(qb_atomic_mutex);
return result;
}
void
(qb_atomic_int_set) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t newval)
{
qb_thread_lock(qb_atomic_mutex);
*atomic = newval;
qb_thread_unlock(qb_atomic_mutex);
}
void *
(qb_atomic_pointer_get) (volatile void *QB_GNUC_MAY_ALIAS * atomic)
{
void *result;
qb_thread_lock(qb_atomic_mutex);
result = *atomic;
qb_thread_unlock(qb_atomic_mutex);
return result;
}
void
(qb_atomic_pointer_set) (volatile void *QB_GNUC_MAY_ALIAS * atomic,
void *newval)
{
qb_thread_lock(qb_atomic_mutex);
*atomic = newval;
qb_thread_unlock(qb_atomic_mutex);
}
int32_t
(qb_atomic_int_get) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic)
{
QB_ATOMIC_MEMORY_BARRIER;
return *atomic;
}
void
(qb_atomic_int_set) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t newval)
{
*atomic = newval;
QB_ATOMIC_MEMORY_BARRIER;
}
void *
(qb_atomic_pointer_get) (volatile void *QB_GNUC_MAY_ALIAS * atomic)
{
QB_ATOMIC_MEMORY_BARRIER;
return *atomic;
}
void
(qb_atomic_pointer_set) (volatile void *QB_GNUC_MAY_ALIAS * atomic,
void *newval)
{
*atomic = newval;
QB_ATOMIC_MEMORY_BARRIER;
}
#endif /* QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
#ifndef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED
int32_t
(qb_atomic_int_get) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic)
{
return qb_atomic_int_get(atomic);
}
void
(qb_atomic_int_set) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t newval)
{
qb_atomic_int_set(atomic, newval);
}
void *
(qb_atomic_pointer_get) (volatile void *QB_GNUC_MAY_ALIAS * atomic) {
return qb_atomic_pointer_get(atomic);
}
void
(qb_atomic_pointer_set) (volatile void *QB_GNUC_MAY_ALIAS * atomic,
void *newval)
{
qb_atomic_pointer_set(atomic, newval);
}
#endif /* QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED */

View File

@ -25,9 +25,9 @@
#include "os_base.h"
#include <dirent.h>
#ifndef QB_DARWIN
# include <mqueue.h>
#endif
#ifdef HAVE_MQUEUE_H
#include <mqueue.h>
#endif /* HAVE_MQUEUE_H */
#include <qb/qblist.h>
#include <qb/qbloop.h>
#include <qb/qbipcc.h>
@ -77,7 +77,7 @@ struct qb_ipc_one_way {
void* shared_data;
char shared_file_name[NAME_MAX];
} us;
#ifndef QB_DARWIN
#ifdef HAVE_MQUEUE_H
struct {
mqd_t q;
char name[NAME_MAX];

View File

@ -19,7 +19,6 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#ifndef QB_DARWIN
#include <mqueue.h>
#include <sys/resource.h>
@ -417,4 +416,3 @@ qb_ipcs_pmq_init(struct qb_ipcs_service *s)
s->needs_sock_for_poll = QB_TRUE;
#endif
}
#endif

View File

@ -20,8 +20,12 @@
*/
#include "os_base.h"
#ifdef HAVE_SYS_IPC_H
#include <sys/ipc.h>
#endif
#ifdef HAVE_SYS_MSG_H
#include <sys/msg.h>
#endif
#include <qb/qbdefs.h>
#include <qb/qbloop.h>

View File

@ -19,6 +19,7 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#if defined(HAVE_GETPEERUCRED)
#include <ucred.h>
#endif
@ -29,7 +30,9 @@
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <qb/qbatomic.h>
#include <qb/qbipcs.h>
@ -267,7 +270,7 @@ qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_pt)
#ifdef SO_NOSIGPIPE
socket_nosigpipe(request_fd);
#endif /* SO_NOSIGPIPE */
res = qb_util_fd_nonblock_cloexec_set(request_fd);
res = qb_sys_fd_nonblock_cloexec_set(request_fd);
if (res < 0) {
goto error_connect;
}
@ -371,8 +374,8 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c,
c->response.u.us.sock = c->setup.u.us.sock;
c->setup.u.us.sock = -1;
fd_hdr = qb_util_mmap_file_open(path, r->request,
sizeof(struct ipc_us_control), O_RDWR);
fd_hdr = qb_sys_mmap_file_open(path, r->request,
sizeof(struct ipc_us_control), O_RDWR);
if (fd_hdr < 0) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't open file for mmap");
@ -444,7 +447,7 @@ qb_ipcs_us_publish(struct qb_ipcs_service * s)
return res;
}
res = qb_util_fd_nonblock_cloexec_set(s->server_sock);
res = qb_sys_fd_nonblock_cloexec_set(s->server_sock);
if (res < 0) {
goto error_close;
}
@ -779,7 +782,7 @@ retry_accept:
return 0;
}
res = qb_util_fd_nonblock_cloexec_set(new_fd);
res = qb_sys_fd_nonblock_cloexec_set(new_fd);
if (res < 0) {
close(new_fd);
/* This is an error, but -1 would indicate disconnect
@ -822,9 +825,9 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s,
snprintf(r->request, NAME_MAX, "qb-%s-control-%d-%d",
s->name, c->pid, c->setup.u.us.sock);
fd_hdr = qb_util_mmap_file_open(path, r->request,
sizeof(struct ipc_us_control),
O_CREAT | O_TRUNC | O_RDWR);
fd_hdr = qb_sys_mmap_file_open(path, r->request,
sizeof(struct ipc_us_control),
O_CREAT | O_TRUNC | O_RDWR);
if (fd_hdr < 0) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't create file for mmap");

View File

@ -20,6 +20,9 @@
*/
#include "os_base.h"
#ifdef HAVE_MQUEUE_H
#include <mqueue.h>
#endif /* HAVE_MQUEUE_H */
#include "ipc_int.h"
#include "util_int.h"
#include <qb/qbdefs.h>
@ -59,10 +62,18 @@ qb_ipcc_connect(const char *name, size_t max_msg_size)
res = qb_ipcc_shm_connect(c, &response);
break;
case QB_IPC_POSIX_MQ:
#ifdef HAVE_POSIX_MQ
res = qb_ipcc_pmq_connect(c, &response);
#else
res = -ENOTSUP;
#endif /* HAVE_POSIX_MQ */
break;
case QB_IPC_SYSV_MQ:
#ifdef HAVE_SYSV_MQ
res = qb_ipcc_smq_connect(c, &response);
#else
res = -ENOTSUP;
#endif /* HAVE_SYSV_MQ */
break;
case QB_IPC_SOCKET:
res = qb_ipcc_us_connect(c, &response);

View File

@ -78,8 +78,7 @@ qb_ipcs_poll_handlers_set(struct qb_ipcs_service *s,
int32_t
qb_ipcs_run(struct qb_ipcs_service *s)
{
int32_t res;
int32_t res = 0;
if (s->poll_fns.dispatch_add == NULL ||
s->poll_fns.dispatch_mod == NULL ||
@ -95,15 +94,27 @@ qb_ipcs_run(struct qb_ipcs_service *s)
qb_ipcs_shm_init((struct qb_ipcs_service *)s);
break;
case QB_IPC_POSIX_MQ:
#ifdef HAVE_POSIX_MQ
qb_ipcs_pmq_init((struct qb_ipcs_service *)s);
#else
res = -ENOTSUP;
#endif /* HAVE_POSIX_MQ */
break;
case QB_IPC_SYSV_MQ:
#ifdef HAVE_SYSV_MQ
qb_ipcs_smq_init((struct qb_ipcs_service *)s);
#else
res = -ENOTSUP;
#endif /* HAVE_SYSV_MQ */
break;
default:
res = -EINVAL;
break;
}
if (res < 0) {
qb_ipcs_unref(s);
return res;
}
res = qb_ipcs_us_publish(s);
if (res < 0) {
(void)qb_ipcs_us_withdraw(s);
@ -121,12 +132,12 @@ _modify_dispatch_descriptor_(struct qb_ipcs_connection *c)
if (c->service->type == QB_IPC_POSIX_MQ
&& !c->service->needs_sock_for_poll) {
#ifndef QB_DARWIN
#ifdef HAVE_MQUEUE_H
return disp_mod(c->service->poll_priority,
(int32_t) c->request.u.pmq.q,
c->poll_events, c,
qb_ipcs_dispatch_service_request);
#endif
#endif /* HAVE_MQUEUE_H */
} else if (c->service->type == QB_IPC_SOCKET) {
return disp_mod(c->service->poll_priority,
c->event.u.us.sock,

View File

@ -20,12 +20,14 @@
*/
#include "os_base.h"
#include <ctype.h>
#ifndef QB_DARWIN
#ifdef HAVE_LINK_H
#include <link.h>
#endif
#endif /* HAVE_LINK_H */
#include <stdarg.h>
#include <pthread.h>
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif /* HAVE_DLFCN_H */
#include <stdarg.h>
#include <qb/qbdefs.h>

View File

@ -20,8 +20,8 @@
*/
#include "os_base.h"
#include <ctype.h>
#ifndef QB_DARWIN
# include <link.h>
#ifdef HAVE_LINK_H
#include <link.h>
#endif
#include <stdarg.h>

View File

@ -19,7 +19,10 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif /* HAVE_SYSLOG_H */
#include "log_int.h"
static void

View File

@ -20,11 +20,16 @@
*/
#include "os_base.h"
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_EPOLL_H
#include <sys/epoll.h>
#endif /* HAVE_SYS_EPOLL_H */
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif /* HAVE_SYS_POLL_H */
#ifndef S_SPLINT_S
#ifdef HAVE_SYS_TIMERFD_H
#include <sys/timerfd.h>
@ -924,8 +929,8 @@ qb_loop_signals_create(struct qb_loop *l)
qb_util_perror(LOG_ERR, "Can't light pipe");
goto error_exit;
}
(void)qb_util_fd_nonblock_cloexec_set(pipe_fds[0]);
(void)qb_util_fd_nonblock_cloexec_set(pipe_fds[1]);
(void)qb_sys_fd_nonblock_cloexec_set(pipe_fds[0]);
(void)qb_sys_fd_nonblock_cloexec_set(pipe_fds[1]);
res = _poll_add_(l, QB_LOOP_HIGH,
pipe_fds[0], POLLIN, NULL, &pe);

View File

@ -120,8 +120,8 @@ qb_rb_open(const char *name, size_t size, uint32_t flags,
* Create a shared_hdr memory segment for the header.
*/
snprintf(filename, PATH_MAX, "qb-%s-header", name);
fd_hdr = qb_util_mmap_file_open(path, filename,
shared_size, file_flags);
fd_hdr = qb_sys_mmap_file_open(path, filename,
shared_size, file_flags);
if (fd_hdr < 0) {
error = fd_hdr;
qb_util_log(LOG_ERR, "couldn't create file for mmap");
@ -162,14 +162,14 @@ qb_rb_open(const char *name, size_t size, uint32_t flags,
*/
if (flags & QB_RB_FLAG_CREATE) {
snprintf(filename, PATH_MAX, "qb-%s-data", name);
fd_data = qb_util_mmap_file_open(path,
filename,
real_size, file_flags);
fd_data = qb_sys_mmap_file_open(path,
filename,
real_size, file_flags);
strncpy(rb->shared_hdr->data_path, path, PATH_MAX);
} else {
fd_data = qb_util_mmap_file_open(path,
rb->shared_hdr->data_path,
real_size, file_flags);
fd_data = qb_sys_mmap_file_open(path,
rb->shared_hdr->data_path,
real_size, file_flags);
}
if (fd_data < 0) {
error = fd_data;
@ -181,7 +181,7 @@ qb_rb_open(const char *name, size_t size, uint32_t flags,
"shm size:%zd; real_size:%zd; rb->size:%d", size,
real_size, rb->shared_hdr->size);
error = qb_util_circular_mmap(fd_data, &shm_addr, real_size);
error = qb_sys_circular_mmap(fd_data, &shm_addr, real_size);
rb->shared_data = shm_addr;
if (error != 0) {
qb_util_log(LOG_ERR, "couldn't create circular mmap on %s",

View File

@ -23,9 +23,15 @@
#include "os_base.h"
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif /* HAVE_SYS_MMAN_H */
#ifdef HAVE_SYS_SEM_H
#include <sys/sem.h>
#endif
#ifdef HAVE_SYS_IPC_H
#include <sys/ipc.h>
#endif
#include <pthread.h>
#include <semaphore.h>

465
lib/unix.c Normal file
View File

@ -0,0 +1,465 @@
/*
* Copyright (C) 2011 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Angus Salkeld <asalkeld@redhat.com>
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#ifdef HAVE_SYS_SHM_H
#include <sys/shm.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include "util_int.h"
#include <qb/qbdefs.h>
#include <qb/qbutil.h>
#include <qb/qbatomic.h>
char *
qb_strerror_r(int errnum, char *buf, size_t buflen)
{
#ifdef QB_LINUX
return strerror_r(errnum, buf, buflen);
#else
char *out_buf;
if (strerror_r(errnum, buf, buflen) == 0) {
out_buf = buf;
} else {
out_buf = (char*)"";
}
return out_buf;
#endif /* QB_LINUX */
}
#ifndef HAVE_STRCHRNUL
/* Find the first occurrence of C in S or the final NUL byte.
*/
char *
qb_sys_strchrnul(const char *s, int c_in)
{
char c = c_in;
while (*s && (*s != c))
s++;
return (char *) s;
}
#endif /* HAVE_STRCHRNUL */
static int32_t
open_mmap_file(char *path, uint32_t file_flags)
{
if (strstr(path, "XXXXXX") != NULL) {
return mkstemp(path);
}
return open(path, file_flags, 0600);
}
int32_t
qb_sys_mmap_file_open(char *path, const char *file, size_t bytes,
uint32_t file_flags)
{
int32_t fd;
int32_t i;
int32_t res = 0;
ssize_t written;
char *buffer = NULL;
char *is_absolute = strchr(file, '/');;
if (is_absolute) {
strcpy(path, file);
} else {
snprintf(path, PATH_MAX, "/dev/shm/%s", file);
}
fd = open_mmap_file(path, file_flags);
if (fd < 0 && !is_absolute) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't open file %s", path);
snprintf(path, PATH_MAX, LOCALSTATEDIR "/run/%s", file);
fd = open_mmap_file(path, file_flags);
if (fd < 0) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't open file %s", path);
return res;
}
}
if (ftruncate(fd, bytes) == -1) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't truncate file %s", path);
goto unlink_exit;
}
if (file_flags & O_CREAT) {
long page_size = sysconf(_SC_PAGESIZE);
if (page_size < 0) {
res = -errno;
goto unlink_exit;
}
buffer = calloc(1, page_size);
if (buffer == NULL) {
res = -ENOMEM;
goto unlink_exit;
}
for (i = 0; i < (bytes / page_size); i++) {
retry_write:
written = write(fd, buffer, page_size);
if (written == -1 && errno == EINTR) {
goto retry_write;
}
if (written != page_size) {
res = -ENOSPC;
free(buffer);
goto unlink_exit;
}
}
free(buffer);
}
return fd;
unlink_exit:
unlink(path);
if (fd > 0) {
close(fd);
}
return res;
}
int32_t
qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes)
{
void *addr_orig = NULL;
void *addr;
void *addr_next;
int32_t res;
int flags = MAP_ANONYMOUS;
#ifdef QB_FORCE_SHM_ALIGN
/* On a number of arches any fixed and shared mmap() mapping address
* must be aligned to 16k. If the first mmap() below is not shared then
* the first mmap() will succeed because these restrictions do not apply to
* private mappings. The second mmap() wants a shared memory mapping but
* the address returned by the first one is only page-aligned and not
* aligned to 16k.
*/
flags |= MAP_SHARED;
#else
flags |= MAP_PRIVATE;
#endif /* QB_FORCE_SHM_ALIGN */
addr_orig = mmap(NULL, bytes << 1, PROT_NONE, flags, -1, 0);
if (addr_orig == MAP_FAILED) {
return -errno;
}
addr = mmap(addr_orig, bytes, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, fd, 0);
if (addr != addr_orig) {
res = -errno;
goto cleanup_fail;
}
#ifdef QB_BSD
madvise(addr_orig, bytes, MADV_NOSYNC);
#endif
addr_next = ((char *)addr_orig) + bytes;
addr = mmap(addr_next,
bytes, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, fd, 0);
if (addr != addr_next) {
res = -errno;
goto cleanup_fail;
}
#ifdef QB_BSD
madvise(((char *)addr_orig) + bytes, bytes, MADV_NOSYNC);
#endif
res = close(fd);
if (res) {
goto cleanup_fail;
}
*buf = addr_orig;
return 0;
cleanup_fail:
if (addr_orig) {
munmap(addr_orig, bytes << 1);
}
close(fd);
return res;
}
int32_t
qb_sys_fd_nonblock_cloexec_set(int32_t fd)
{
int32_t res = 0;
int32_t oldflags = fcntl(fd, F_GETFD, 0);
if (oldflags < 0) {
oldflags = 0;
}
oldflags |= FD_CLOEXEC;
res = fcntl(fd, F_SETFD, oldflags);
if (res == -1) {
res = -errno;
qb_util_perror(LOG_ERR,
"Could not set close-on-exit on fd:%d", fd);
return res;
}
res = fcntl(fd, F_SETFL, O_NONBLOCK);
if (res == -1) {
res = -errno;
qb_util_log(LOG_ERR, "Could not set non-blocking on fd:%d", fd);
}
return res;
}
/*
* atomic operations
* --------------------------------------------------------------------------
*/
#ifndef HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS
/*
* We have to use the slow, but safe locking method
*/
static qb_thread_lock_t *qb_atomic_mutex = NULL;
void
qb_atomic_init(void)
{
if (qb_atomic_mutex == NULL) {
qb_atomic_mutex = qb_thread_lock_create(QB_THREAD_LOCK_SHORT);
}
assert(qb_atomic_mutex);
}
int32_t
qb_atomic_int_exchange_and_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t val)
{
int32_t result;
qb_thread_lock(qb_atomic_mutex);
result = *atomic;
*atomic += val;
qb_thread_unlock(qb_atomic_mutex);
return result;
}
void
qb_atomic_int_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic, int32_t val)
{
qb_thread_lock(qb_atomic_mutex);
*atomic += val;
qb_thread_unlock(qb_atomic_mutex);
}
int32_t
qb_atomic_int_compare_and_exchange(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t oldval, int32_t newval)
{
int32_t result;
qb_thread_lock(qb_atomic_mutex);
if (*atomic == oldval) {
result = QB_TRUE;
*atomic = newval;
} else {
result = QB_FALSE;
}
qb_thread_unlock(qb_atomic_mutex);
return result;
}
int32_t
qb_atomic_pointer_compare_and_exchange(volatile void *QB_GNUC_MAY_ALIAS *
atomic, void *oldval, void *newval)
{
int32_t result;
qb_thread_lock(qb_atomic_mutex);
if (*atomic == oldval) {
result = QB_TRUE;
*atomic = newval;
} else {
result = QB_FALSE;
}
qb_thread_unlock(qb_atomic_mutex);
return result;
}
#ifdef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED
int32_t
(qb_atomic_int_get) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic)
{
int32_t result;
qb_thread_lock(qb_atomic_mutex);
result = *atomic;
qb_thread_unlock(qb_atomic_mutex);
return result;
}
void
(qb_atomic_int_set) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t newval)
{
qb_thread_lock(qb_atomic_mutex);
*atomic = newval;
qb_thread_unlock(qb_atomic_mutex);
}
void *
(qb_atomic_pointer_get) (volatile void *QB_GNUC_MAY_ALIAS * atomic)
{
void *result;
qb_thread_lock(qb_atomic_mutex);
result = (void*)*atomic;
qb_thread_unlock(qb_atomic_mutex);
return result;
}
void
(qb_atomic_pointer_set) (volatile void *QB_GNUC_MAY_ALIAS * atomic,
void *newval)
{
qb_thread_lock(qb_atomic_mutex);
*atomic = newval;
qb_thread_unlock(qb_atomic_mutex);
}
#endif /* QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
#else
/*
* gcc built-ins
*/
void
qb_atomic_init(void)
{
}
int32_t
qb_atomic_int_exchange_and_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t val)
{
return __sync_fetch_and_add(atomic, val);
}
void
qb_atomic_int_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic, int32_t val)
{
__sync_fetch_and_add(atomic, val);
}
int32_t
qb_atomic_int_compare_and_exchange(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t oldval, int32_t newval)
{
return __sync_bool_compare_and_swap(atomic, oldval, newval);
}
int32_t
qb_atomic_pointer_compare_and_exchange(volatile void *QB_GNUC_MAY_ALIAS *
atomic, void *oldval, void *newval)
{
return __sync_bool_compare_and_swap(atomic, oldval, newval);
}
#ifdef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED
#define QB_ATOMIC_MEMORY_BARRIER __sync_synchronize ()
int32_t
(qb_atomic_int_get) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic)
{
QB_ATOMIC_MEMORY_BARRIER;
return *atomic;
}
void
(qb_atomic_int_set) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t newval)
{
*atomic = newval;
QB_ATOMIC_MEMORY_BARRIER;
}
void *
(qb_atomic_pointer_get) (volatile void *QB_GNUC_MAY_ALIAS * atomic)
{
QB_ATOMIC_MEMORY_BARRIER;
return (void*)*atomic;
}
void
(qb_atomic_pointer_set) (volatile void *QB_GNUC_MAY_ALIAS * atomic,
void *newval)
{
*atomic = newval;
QB_ATOMIC_MEMORY_BARRIER;
}
#endif /* QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
#endif /* HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS */
#ifndef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED
int32_t
(qb_atomic_int_get) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic)
{
return qb_atomic_int_get(atomic);
}
void
(qb_atomic_int_set) (volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
int32_t newval)
{
qb_atomic_int_set(atomic, newval);
}
void *
(qb_atomic_pointer_get) (volatile void *QB_GNUC_MAY_ALIAS * atomic)
{
return qb_atomic_pointer_get(atomic);
}
void
(qb_atomic_pointer_set) (volatile void *QB_GNUC_MAY_ALIAS * atomic,
void *newval)
{
qb_atomic_pointer_set(atomic, newval);
}
#endif /* !QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED */

View File

@ -21,8 +21,6 @@
#include "os_base.h"
#include "util_int.h"
#include <sys/shm.h>
#include <sys/mman.h>
#include <pthread.h>
#include <sys/stat.h>
#include <qb/qbdefs.h>
@ -220,7 +218,7 @@ qb_util_nano_from_epoch_get(void)
return (nano_from_epoch);
}
#endif
#endif /* HAVE_MONOTONIC_CLOCK */
struct qb_util_stopwatch {
uint64_t started;
@ -231,9 +229,7 @@ qb_util_stopwatch_t *
qb_util_stopwatch_create(void)
{
struct qb_util_stopwatch *sw;
sw = (struct qb_util_stopwatch *)calloc(1,
sizeof(struct
qb_util_stopwatch));
sw = (struct qb_util_stopwatch *)calloc(1, sizeof(struct qb_util_stopwatch));
return sw;
}
@ -276,213 +272,3 @@ qb_util_stopwatch_sec_elapsed_get(qb_util_stopwatch_t * sw)
return ((float)e6 / (float)QB_TIME_US_IN_SEC);
}
static int32_t
open_mmap_file(char *path, uint32_t file_flags)
{
if (strstr(path, "XXXXXX") != NULL) {
return mkstemp(path);
}
return open(path, file_flags, 0600);
}
/*
* ---------------------------------------------------
* shared memory functions.
*/
int32_t
qb_util_mmap_file_open(char *path, const char *file, size_t bytes,
uint32_t file_flags)
{
int32_t fd;
int32_t i;
int32_t res = 0;
ssize_t written;
char *buffer = NULL;
char *is_absolute = strchr(file, '/');;
if (is_absolute) {
strcpy(path, file);
} else {
snprintf(path, PATH_MAX, "/dev/shm/%s", file);
}
fd = open_mmap_file(path, file_flags);
if (fd < 0 && !is_absolute) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't open file %s", path);
snprintf(path, PATH_MAX, LOCALSTATEDIR "/run/%s", file);
fd = open_mmap_file(path, file_flags);
if (fd < 0) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't open file %s", path);
return res;
}
}
if (ftruncate(fd, bytes) == -1) {
res = -errno;
qb_util_perror(LOG_ERR, "couldn't truncate file %s", path);
goto unlink_exit;
}
if (file_flags & O_CREAT) {
long page_size = sysconf(_SC_PAGESIZE);
if (page_size < 0) {
res = -errno;
goto unlink_exit;
}
buffer = calloc(1, page_size);
if (buffer == NULL) {
res = -ENOMEM;
goto unlink_exit;
}
for (i = 0; i < (bytes / page_size); i++) {
retry_write:
written = write(fd, buffer, page_size);
if (written == -1 && errno == EINTR) {
goto retry_write;
}
if (written != page_size) {
res = -ENOSPC;
free(buffer);
goto unlink_exit;
}
}
free(buffer);
}
return fd;
unlink_exit:
unlink(path);
if (fd > 0) {
close(fd);
}
return res;
}
int32_t
qb_util_circular_mmap(int32_t fd, void **buf, size_t bytes)
{
void *addr_orig = NULL;
void *addr;
void *addr_next;
int32_t res;
int flags = MAP_ANONYMOUS;
#ifdef QB_FORCE_SHM_ALIGN
/* On a number of arches any fixed and shared mmap() mapping address
* must be aligned to 16k. If the first mmap() below is not shared then
* the first mmap() will succeed because these restrictions do not apply to
* private mappings. The second mmap() wants a shared memory mapping but
* the address returned by the first one is only page-aligned and not
* aligned to 16k.
*/
flags |= MAP_SHARED;
#else
flags |= MAP_PRIVATE;
#endif /* QB_FORCE_SHM_ALIGN */
addr_orig = mmap(NULL, bytes << 1, PROT_NONE, flags, -1, 0);
if (addr_orig == MAP_FAILED) {
return -errno;
}
addr = mmap(addr_orig, bytes, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, fd, 0);
if (addr != addr_orig) {
res = -errno;
goto cleanup_fail;
}
#ifdef QB_BSD
madvise(addr_orig, bytes, MADV_NOSYNC);
#endif
addr_next = ((char *)addr_orig) + bytes;
addr = mmap(addr_next,
bytes, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, fd, 0);
if (addr != addr_next) {
res = -errno;
goto cleanup_fail;
}
#ifdef QB_BSD
madvise(((char *)addr_orig) + bytes, bytes, MADV_NOSYNC);
#endif
res = close(fd);
if (res) {
goto cleanup_fail;
}
*buf = addr_orig;
return 0;
cleanup_fail:
if (addr_orig) {
munmap(addr_orig, bytes << 1);
}
close(fd);
return res;
}
int32_t
qb_util_fd_nonblock_cloexec_set(int32_t fd)
{
int32_t res;
int32_t oldflags = fcntl(fd, F_GETFD, 0);
if (oldflags < 0) {
oldflags = 0;
}
oldflags |= FD_CLOEXEC;
res = fcntl(fd, F_SETFD, oldflags);
if (res == -1) {
res = -errno;
qb_util_perror(LOG_ERR,
"Could not set close-on-exit on fd:%d", fd);
return res;
}
res = fcntl(fd, F_SETFL, O_NONBLOCK);
if (res == -1) {
res = -errno;
qb_util_log(LOG_ERR, "Could not set non-blocking on fd:%d", fd);
}
return res;
}
char *
qb_strerror_r(int errnum, char *buf, size_t buflen)
{
#ifdef QB_LINUX
return strerror_r(errnum, buf, buflen);
#else
char *out_buf;
if (strerror_r(errnum, buf, buflen) == 0) {
out_buf = buf;
} else {
out_buf = (char*)"";
}
return out_buf;
#endif /* QB_LINUX */
}
#ifdef QB_DARWIN
/* Borrowed from gnulib's strchrnul.c under GLPv2+ */
#include <string.h>
/* Find the first occurrence of C in S or the final NUL byte. */
char *
strchrnul (const char *s, int c_in)
{
char c = c_in;
while (*s && (*s != c))
s++;
return (char *) s;
}
#endif

View File

@ -20,6 +20,7 @@
#ifndef QB_UTIL_INT_H_DEFINED
#define QB_UTIL_INT_H_DEFINED
#include "os_base.h"
#include <qb/qblog.h>
#if !defined (va_copy)
@ -61,7 +62,7 @@
* @param file_flags same as passed into open()
* @return 0 (success) or -errno
*/
int32_t qb_util_mmap_file_open(char *path, const char *file, size_t bytes,
int32_t qb_sys_mmap_file_open(char *path, const char *file, size_t bytes,
uint32_t file_flags);
/**
@ -72,7 +73,7 @@ int32_t qb_util_mmap_file_open(char *path, const char *file, size_t bytes,
* @param bytes the size of the shared memory.
* @return 0 (success) or -errno
*/
int32_t qb_util_circular_mmap(int32_t fd, void **buf, size_t bytes);
int32_t qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes);
/**
@ -80,6 +81,10 @@ int32_t qb_util_circular_mmap(int32_t fd, void **buf, size_t bytes);
* @param fd the file descriptor.
* @return 0 (success) or -errno
*/
int32_t qb_util_fd_nonblock_cloexec_set(int32_t fd);
int32_t qb_sys_fd_nonblock_cloexec_set(int32_t fd);
#ifndef HAVE_STRCHRNUL
#define strchrnul(s, c_in) qb_sys_strchrnul(s, c_in)
char * qb_sys_strchrnul(const char *s, int c_in);
#endif /* !HAVE_STRCHRNUL */
#endif /* QB_UTIL_INT_H_DEFINED */

View File

@ -73,7 +73,7 @@ bench_log_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
if HAVE_CHECK
EXTRA_DIST += resources.test
TESTS = array.test map.test rb.test log.test loop.test ipc.test resources.test map.test
TESTS = array.test map.test rb.test log.test loop.test ipc.test resources.test
resources.log: rb.log log.log ipc.log