Add support for Solaris 2.6 on sun4m builds

It is an excellent platform for catching bugs: big-endian, slow enough
that a context switch in the middle of an operation becomes a regular
occurrence, and all that on a SMP box.  Or: I just wanted to see if it
would work.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-07-05 23:15:41 +02:00 committed by eboasson
parent 47920df65c
commit fda285e2f5
52 changed files with 1266 additions and 4197 deletions

View file

@ -150,10 +150,10 @@ foreach(feature atomics cdtors environ heap ifaddrs random rusage
sockets string sync threads time md5 process)
if(EXISTS "${include_path}/dds/ddsrt/${feature}.h")
list(APPEND headers "${include_path}/dds/ddsrt/${feature}.h")
file(GLOB
file(GLOB_RECURSE
files
CONFIGURE_DEPENDS
"${include_path}/dds/ddsrt/${feature}/**.h")
"${include_path}/dds/ddsrt/${feature}/*.h")
list(APPEND headers ${files})
# Do not add any sources if a feature is not offered by the target. The
@ -193,20 +193,20 @@ foreach(feature atomics cdtors environ heap ifaddrs random rusage
# Headers that must remain private but are required by other runtime
# source files must be located in src/<feature>/dds/ddsrt.
if(IS_DIRECTORY "${source_path}/${feature}/include")
file(GLOB
file(GLOB_RECURSE
files
CONFIGURE_DEPENDS
"${source_path}/${feature}/include/**.h")
list(APPEND sources ${files})
"${source_path}/${feature}/include/*.h")
list(APPEND headers ${files})
target_include_directories(
ddsrt INTERFACE
"$<BUILD_INTERFACE:${source_path}/${feature}/include/>")
endif()
if(IS_DIRECTORY "${source_path}/${feature}/${system}")
file(GLOB
file(GLOB_RECURSE
files
CONFIGURE_DEPENDS
"${source_path}/${feature}/${system}/**.c")
"${source_path}/${feature}/${system}/*.c")
list(APPEND sources ${files})
set(system_exists TRUE)
endif()

View file

@ -16,12 +16,12 @@
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#else
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#endif
#if defined(__cplusplus)
@ -37,19 +37,32 @@ typedef int ddsrt_socket_t;
# define DDSRT_HAVE_IPV6 1
# endif
# if LWIP_DNS && LWIP_SOCKET
# define DDSRT_HAVE_DNS DDSRT_WITH_DNS
# define DDSRT_HAVE_DNS DDSRT_WITH_DNS
# define DDSRT_HAVE_GETADDRINFO DDSRT_WITH_DNS
# endif
# define DDSRT_HAVE_SSM 0
# define DDSRT_HAVE_SSM 0
# define DDSRT_HAVE_INET_NTOP 1
# define DDSRT_HAVE_INET_PTON 1
# define IFF_UP 0x1
# define IFF_BROADCAST 0x2
# define IFF_LOOPBACK 0x8
# define IFF_POINTOPOINT 0x10
# define IFF_UP 0x1
# define IFF_BROADCAST 0x2
# define IFF_LOOPBACK 0x8
# define IFF_POINTOPOINT 0x10
# define IFF_MULTICAST 0x1000
#elif __SunOS_5_6
# define DDSRT_HAVE_IPV6 0
# define DDSRT_HAVE_DNS DDSRT_WITH_DNS
# define DDSRT_HAVE_GETADDRINFO 0
# define DDSRT_HAVE_SSM 0
# define DDSRT_HAVE_INET_NTOP 0
# define DDSRT_HAVE_INET_PTON 0
#else /* LWIP_SOCKET */
# define DDSRT_HAVE_IPV6 1
# define DDSRT_HAVE_DNS DDSRT_WITH_DNS
# define DDSRT_HAVE_SSM 1
# define DDSRT_HAVE_IPV6 1
# define DDSRT_HAVE_DNS DDSRT_WITH_DNS
# define DDSRT_HAVE_GETADDRINFO DDSRT_WITH_DNS
# define DDSRT_HAVE_SSM 1
# define DDSRT_HAVE_INET_NTOP 1
# define DDSRT_HAVE_INET_PTON 1
#endif /* LWIP_SOCKET */
typedef struct iovec ddsrt_iovec_t;

View file

@ -12,8 +12,11 @@ typedef SOCKET ddsrt_socket_t;
#define DDSRT_INVALID_SOCKET (INVALID_SOCKET)
#define PRIdSOCK PRIuPTR
#define DDSRT_HAVE_IPV6 1
#define DDSRT_HAVE_DNS DDSRT_WITH_DNS
#define DDSRT_HAVE_IPV6 1
#define DDSRT_HAVE_DNS DDSRT_WITH_DNS
#define DDSRT_HAVE_GETADDRINFO DDSRT_WITH_DNS
#define DDSRT_HAVE_INET_NTOP 1
#define DDSRT_HAVE_INET_PTON 1
#if defined(NTDDI_VERSION) && \
defined(_WIN32_WINNT_WS03) && \

View file

@ -22,6 +22,8 @@
#include "dds/ddsrt/sync/freertos.h"
#elif _WIN32
#include "dds/ddsrt/sync/windows.h"
#elif __SunOS_5_6
#include "dds/ddsrt/sync/solaris2.6.h"
#else
#include "dds/ddsrt/sync/posix.h"
#endif

View file

@ -0,0 +1,44 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifndef DDSRT_POSIX_SYNC_H
#define DDSRT_POSIX_SYNC_H
#include <stdint.h>
#include <pthread.h>
#if HAVE_LKST
#include "lkst.h"
#endif
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct {
pthread_cond_t cond;
} ddsrt_cond_t;
typedef struct {
pthread_mutex_t mutex;
} ddsrt_mutex_t;
typedef struct {
pthread_mutex_t rwlock;
} ddsrt_rwlock_t;
typedef pthread_once_t ddsrt_once_t;
#define DDSRT_ONCE_INIT PTHREAD_ONCE_INIT
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_POSIX_SYNC_H */

View file

@ -165,22 +165,30 @@ void ddsrt_atomic_lifo_pushmany (ddsrt_atomic_lifo_t *head, void *first, void *l
}
#endif
#if DDSRT_HAVE_ATOMIC64
void ddsrt_atomics_init (void)
{
}
/* On platforms that don't provide 64-bit atomic operations, emulate them by hashing
the variable's address to a small set of mutexes.
void ddsrt_atomics_fini (void)
{
}
This also defines the GCC builtins on SPARCv8 for 32-bit operations. It would be
more appropriate to simply define the ddsrt_atomic_... functions properly in that
case and avoid squatting in the __sync_... namespace, but SPARCv8 support really
is just for fun and it doesn't seem worth the bother right now */
#if DDSRT_HAVE_ATOMIC64
void ddsrt_atomics_init (void) { }
void ddsrt_atomics_fini (void) { }
#else
/* Emulation by hashing the variable's address to a small set of mutexes. */
#include "dds/ddsrt/sync.h"
/* SPARCv8 depends on these mutexes already for one-shot initialisation of the ddsrt
code. Using PTHREAD_MUTEX_INITIALIZER guarantees they are properly initialized.
Once a platform shows up that defines that macro where we don't used pthread mutexes
something else will have to be done. */
#define N_MUTEXES_LG2 4
#define N_MUTEXES (1 << N_MUTEXES_LG2)
#ifndef PTHREAD_MUTEX_INITIALIZER
static ddsrt_mutex_t mutexes[N_MUTEXES];
void ddsrt_atomics_init (void)
@ -194,6 +202,20 @@ void ddsrt_atomics_fini (void)
for (int i = 0; i < N_MUTEXES; i++)
ddsrt_mutex_destroy (&mutexes[i]);
}
#else
static ddsrt_mutex_t mutexes[N_MUTEXES] = {
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }
};
void ddsrt_atomics_init (void) { }
void ddsrt_atomics_fini (void) { }
#endif
static uint32_t atomic64_lock_index (const volatile ddsrt_atomic_uint64_t *x)
{
@ -219,7 +241,25 @@ int ddsrt_atomic_cas64 (volatile ddsrt_atomic_uint64_t *x, uint64_t exp, uint64_
}
}
uint64_t ddsrt_atomic_ld64(const volatile ddsrt_atomic_uint64_t *x)
#define DDSRT_FAKE_ATOMIC64(name, oper, ret) \
uint64_t ddsrt_atomic_##name##64_##ret (volatile ddsrt_atomic_uint64_t *x, uint64_t v) \
{ \
const uint64_t idx = atomic64_lock_index (x); \
ddsrt_mutex_lock (&mutexes[idx]); \
const uint64_t ov = x->v; \
const uint64_t nv = ov oper v; \
x->v = nv; \
ddsrt_mutex_unlock (&mutexes[idx]); \
return ret; \
}
#define DDSRT_FAKE_ATOMIC64_TRIPLET(name, oper) \
DDSRT_FAKE_ATOMIC64(name, oper, nv) \
DDSRT_FAKE_ATOMIC64(name, oper, ov) \
void ddsrt_atomic_##name##64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) { \
(void) ddsrt_atomic_##name##64_ov (x, v); \
}
uint64_t ddsrt_atomic_ld64 (const volatile ddsrt_atomic_uint64_t *x)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
@ -228,7 +268,7 @@ uint64_t ddsrt_atomic_ld64(const volatile ddsrt_atomic_uint64_t *x)
return v;
}
void ddsrt_atomic_st64(volatile ddsrt_atomic_uint64_t *x, uint64_t v)
void ddsrt_atomic_st64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
@ -236,136 +276,70 @@ void ddsrt_atomic_st64(volatile ddsrt_atomic_uint64_t *x, uint64_t v)
ddsrt_mutex_unlock (&mutexes[idx]);
}
void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
++x->v;
ddsrt_mutex_unlock (&mutexes[idx]);
DDSRT_FAKE_ATOMIC64_TRIPLET(add, +)
DDSRT_FAKE_ATOMIC64_TRIPLET(sub, -)
DDSRT_FAKE_ATOMIC64_TRIPLET(or, |)
DDSRT_FAKE_ATOMIC64_TRIPLET(and, &)
void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) {
ddsrt_atomic_add64 (x, 1);
}
uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x) {
return ddsrt_atomic_add64_nv (x, 1);
}
void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x) {
ddsrt_atomic_sub64 (x, 1);
}
uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x) {
return ddsrt_atomic_sub64_nv (x, 1);
}
uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x)
#undef DDSRT_FAKE_ATOMIC64_TRIPLET
#undef DDSRT_FAKE_ATOMIC64
/* SPARCv8 doesn't support any atomic operations beyond a simple atomic exchange. GCC happily
compiles the __sync_* functions into library calls, and implementing them as such will do
the trick. The rarity of SPARCv8 machines (EOL'd 2 decades ago) */
#ifdef __sparc_v8__
#define DDSRT_FAKE_SYNC(name, size, oper, ret) \
unsigned __sync_##name##_##size (volatile unsigned *x, unsigned v) \
{ \
const uint32_t idx = atomic64_lock_index ((const volatile ddsrt_atomic_uint64_t *) x); \
ddsrt_mutex_lock (&mutexes[idx]); \
const uint32_t ov = *x; \
const uint32_t nv = ov oper v; \
*x = nv; \
ddsrt_mutex_unlock (&mutexes[idx]); \
return ret; \
}
#define DDSRT_FAKE_SYNC_PAIR(name, size, oper) \
DDSRT_FAKE_SYNC(name##_and_fetch, size, oper, nv) \
DDSRT_FAKE_SYNC(fetch_and_##name, size, oper, ov)
DDSRT_FAKE_SYNC_PAIR (add, 4, +)
DDSRT_FAKE_SYNC_PAIR (sub, 4, -)
DDSRT_FAKE_SYNC_PAIR (or, 4, |)
DDSRT_FAKE_SYNC_PAIR (and, 4, &)
bool __sync_bool_compare_and_swap_4 (volatile unsigned *x, unsigned exp, unsigned des)
{
const uint32_t idx = atomic64_lock_index (x);
const uint32_t idx = atomic64_lock_index ((const volatile ddsrt_atomic_uint64_t *) x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t nv = ++x->v;
ddsrt_mutex_unlock (&mutexes[idx]);
return nv;
if (*x == exp)
{
*x = des;
ddsrt_mutex_unlock (&mutexes[idx]);
return true;
}
else
{
ddsrt_mutex_unlock (&mutexes[idx]);
return false;
}
}
void ddsrt_atomic_dec64 (volatile ddsrt_atomic_uint64_t *x)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
--x->v;
ddsrt_mutex_unlock (&mutexes[idx]);
}
uint64_t ddsrt_atomic_dec64_nv (volatile ddsrt_atomic_uint64_t *x)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t nv = --x->v;
ddsrt_mutex_unlock (&mutexes[idx]);
return nv;
}
void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
x->v += v;
ddsrt_mutex_unlock (&mutexes[idx]);
}
uint64_t ddsrt_atomic_add64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t ov = x->v;
const uint64_t nv = ov + v;
x->v = nv;
ddsrt_mutex_unlock (&mutexes[idx]);
return nv;
}
void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
x->v -= v;
ddsrt_mutex_unlock (&mutexes[idx]);
}
uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t ov = x->v;
const uint64_t nv = ov - v;
x->v = nv;
ddsrt_mutex_unlock (&mutexes[idx]);
return nv;
}
void ddsrt_atomic_and64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
x->v &= v;
ddsrt_mutex_unlock (&mutexes[idx]);
}
uint64_t ddsrt_atomic_and64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t ov = x->v;
const uint64_t nv = ov & v;
x->v = nv;
ddsrt_mutex_unlock (&mutexes[idx]);
return ov;
}
uint64_t ddsrt_atomic_and64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t ov = x->v;
const uint64_t nv = ov & v;
x->v = nv;
ddsrt_mutex_unlock (&mutexes[idx]);
return nv;
}
void ddsrt_atomic_or64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
x->v |= v;
ddsrt_mutex_unlock (&mutexes[idx]);
}
uint64_t ddsrt_atomic_or64_ov (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t ov = x->v;
const uint64_t nv = ov | v;
x->v = nv;
ddsrt_mutex_unlock (&mutexes[idx]);
return ov;
}
uint64_t ddsrt_atomic_or64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v)
{
const uint32_t idx = atomic64_lock_index (x);
ddsrt_mutex_lock (&mutexes[idx]);
const uint64_t ov = x->v;
const uint64_t nv = ov | v;
x->v = nv;
ddsrt_mutex_unlock (&mutexes[idx]);
return nv;
}
#undef DDSRT_FAKE_SYNC_PAIR
#undef DDSRT_FAKE_SYNC
#endif /* SPARCv8 hack */
#endif /* DDSRT_HAVE_ATOMIC64 */

View file

@ -0,0 +1,100 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "dds/ddsrt/environ.h"
#include "dds/ddsrt/retcode.h"
extern char **environ;
static int
isenvvar(const char *name)
{
return (*name == '\0' || strchr(name, '=') != NULL) == 0;
}
dds_return_t
ddsrt_getenv(const char *name, char **value)
{
char *env;
assert(name != NULL);
assert(value != NULL);
if (!isenvvar(name))
return DDS_RETCODE_BAD_PARAMETER;
if ((env = getenv(name)) != NULL) {
*value = env;
return DDS_RETCODE_OK;
}
return DDS_RETCODE_NOT_FOUND;
}
dds_return_t
ddsrt_setenv(const char *name, const char *value)
{
/* Not MT-Safe -- but it is only used in a tests to set
CYCLONEDDS_URI, so for Solaris 2.6 support it is not worth the
bother to do a better job. Same for a bit of leakage. */
assert(name != NULL);
assert(value != NULL);
if (strlen(value) == 0)
return ddsrt_unsetenv(name);
if (!isenvvar(name))
return DDS_RETCODE_BAD_PARAMETER;
const size_t namelen = strlen (name);
const size_t entrysize = namelen + 1 + strlen (value) + 1;
char *entry = malloc (entrysize);
snprintf (entry, entrysize, "%s=%s", name, value);
size_t n = 0;
while (environ[n] != NULL)
{
if (strncmp (environ[n], name, namelen) == 0 && environ[n][namelen] == '=')
{
environ[n] = entry;
return DDS_RETCODE_OK;
}
n++;
}
environ = realloc (environ, (n + 2) * sizeof (*environ));
environ[n] = entry;
environ[n+1] = NULL;
return DDS_RETCODE_OK;
}
dds_return_t
ddsrt_unsetenv(const char *name)
{
/* Same considerations as setenv. */
assert(name != NULL);
if (!isenvvar(name))
return DDS_RETCODE_BAD_PARAMETER;
const size_t namelen = strlen (name);
size_t n = 0, idx = SIZE_MAX;
while (environ[n] != NULL)
{
if (idx > n && strncmp (environ[n], name, namelen) == 0 && environ[n][namelen] == '=')
idx = n;
n++;
}
if (idx < n)
memmove (&environ[idx], &environ[idx + 1], (n - idx) * sizeof (*environ));
return DDS_RETCODE_OK;
}

View file

@ -0,0 +1,84 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include "dds/ddsrt/ifaddrs.h"
#include <string.h>
#include <stdio.h>
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/string.h"
extern const int *const os_supp_afs;
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/sockio.h>
#include <stdlib.h>
dds_return_t
ddsrt_getifaddrs(
ddsrt_ifaddrs_t **ret_ifap,
const int *afs)
{
int sock;
char *buf;
int32_t n;
struct ifconf ifc;
struct ifreq *ifr;
/* get interfaces */
buf = ddsrt_malloc (8192);
memset (&ifc, 0, sizeof (ifc));
ifc.ifc_len = 8192;
ifc.ifc_buf = buf;
sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ioctl (sock, SIOCGIFCONF, (char *) &ifc) < 0)
{
perror ("ioctl (SIOCGIFCONF)");
exit (77);
}
ddsrt_ifaddrs_t **ifap, *ifa_root;
ifap = &ifa_root; ifa_root = NULL;
ifr = ifc.ifc_req;
for (n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++)
{
ddsrt_ifaddrs_t *ifa;
if (ifr->ifr_name[0] == '\0')
continue; /* Forget about anonymous network devices */
if (ifr->ifr_addr.sa_family != AF_INET) {
printf ("%s: not INET\n", ifr->ifr_name);
continue;
}
ifa = ddsrt_malloc (sizeof (*ifa));
memset (ifa, 0, sizeof (*ifa));
ifa->index = (int) (ifr - ifc.ifc_req);
ifa->flags = IFF_UP | ((strcmp(ifr->ifr_name, "lo0")==0) ? IFF_LOOPBACK : IFF_MULTICAST);
ifa->name = strdup (ifr->ifr_name);
ifa->addr = ddsrt_memdup (&ifr->ifr_addr, sizeof (struct sockaddr_in));
ifa->netmask = ddsrt_memdup (&ifr->ifr_addr, sizeof (struct sockaddr_in));
((struct sockaddr_in *) ifa->netmask)->sin_addr.s_addr = htonl (0xffffff00);
ifa->broadaddr = NULL;
ifa->next = NULL;
*ifap = ifa;
ifap = &ifa->next;
}
ddsrt_free (buf);
close (sock);
*ret_ifap = ifa_root;
return DDS_RETCODE_OK;
}

View file

@ -186,13 +186,19 @@ ddsrt_sockaddrfromstr(int af, const char *str, void *sa)
switch (af) {
case AF_INET: {
struct in_addr buf;
#if DDSRT_HAVE_INET_PTON
if (inet_pton(af, str, &buf) != 1) {
return DDS_RETCODE_BAD_PARAMETER;
} else {
memset(sa, 0, sizeof(struct sockaddr_in));
((struct sockaddr_in *)sa)->sin_family = AF_INET;
memcpy(&((struct sockaddr_in *)sa)->sin_addr, &buf, sizeof(buf));
}
#else
buf.s_addr = inet_addr (str);
if (buf.s_addr == (in_addr_t)-1) {
return DDS_RETCODE_BAD_PARAMETER;
}
#endif
memset(sa, 0, sizeof(struct sockaddr_in));
((struct sockaddr_in *)sa)->sin_family = AF_INET;
memcpy(&((struct sockaddr_in *)sa)->sin_addr, &buf, sizeof(buf));
} break;
#if DDSRT_HAVE_IPV6
case AF_INET6: {
@ -225,8 +231,16 @@ DDSRT_WARNING_GNUC_OFF(sign-conversion)
#endif
switch (((struct sockaddr *)sa)->sa_family) {
case AF_INET:
#if DDSRT_HAVE_INET_NTOP
ptr = inet_ntop(
AF_INET, &((struct sockaddr_in *)sa)->sin_addr, buf, (socklen_t)size);
#else
{
in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
snprintf(buf,size,"%u.%u.%u.%u",(x>>24),(x>>16)&0xff,(x>>8)&0xff,x&0xff);
ptr = buf;
}
#endif
break;
#if DDSRT_HAVE_IPV6
case AF_INET6:
@ -249,6 +263,7 @@ DDSRT_WARNING_GNUC_ON(sign-conversion)
}
#if DDSRT_HAVE_DNS
#if DDSRT_HAVE_GETADDRINFO
dds_return_t
ddsrt_gethostbyname(const char *name, int af, ddsrt_hostent_t **hentp)
{
@ -363,4 +378,23 @@ ddsrt_gethostbyname(const char *name, int af, ddsrt_hostent_t **hentp)
*hentp = hent;
return DDS_RETCODE_OK;
}
#else
dds_return_t
ddsrt_gethostbyname(const char *name, int af, ddsrt_hostent_t **hentp)
{
struct hostent hest, *he;
char buf[256];
int err;
he = gethostbyname_r (name, &hest, buf, sizeof (buf), &err);
if (he == NULL) {
return DDS_RETCODE_HOST_NOT_FOUND;
} else {
size_t size = sizeof(**hentp) + (1 * sizeof((*hentp)->addrs[0]));
*hentp = ddsrt_calloc_s(1, size);
(*hentp)->naddrs = 1;
memcpy(&(*hentp)->addrs[0], he->h_addr, he->h_length);
return DDS_RETCODE_OK;
}
}
#endif /* DDSRT_HAVE_GETADDRINFO */
#endif /* DDSRT_HAVE_DNS */

View file

@ -27,7 +27,6 @@ typedef long ddsrt_tv_sec_t;
typedef long ddsrt_tv_usec_t;
#else
typedef time_t ddsrt_tv_sec_t;
typedef suseconds_t ddsrt_tv_usec_t;
#endif
#define DDSRT_TIME_T_MAX \
@ -62,7 +61,7 @@ ddsrt_duration_to_timeval_ceil(dds_duration_t reltime, struct timeval *tv)
if (reltime < (max_nsecs - DDS_NSECS_IN_USEC - 1)) {
reltime += (DDS_NSECS_IN_USEC - 1);
tv->tv_sec = (ddsrt_tv_sec_t)(reltime / DDS_NSECS_IN_SEC);
tv->tv_usec = (ddsrt_tv_usec_t)((reltime % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_USEC);
tv->tv_usec = (int)((reltime % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_USEC);
} else {
tv->tv_sec = DDSRT_TIME_T_MAX;
tv->tv_usec = 999999;

View file

@ -45,6 +45,10 @@ ddsrt_gethostname(
return DDS_RETCODE_OK;
}
#else
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif
dds_return_t
ddsrt_gethostname(
char *name,

View file

@ -0,0 +1,34 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
/* Make sure we get the XSI compliant version of strerror_r */
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
#undef _GNU_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "dds/ddsrt/string.h"
dds_return_t
ddsrt_strerror_r(int errnum, char *buf, size_t buflen)
{
assert(buf != NULL);
assert(buflen > 0);
if (snprintf (buf, buflen, "errno=%d", errnum) >= buflen)
return DDS_RETCODE_NOT_ENOUGH_SPACE;
else
return DDS_RETCODE_OK;
}

View file

@ -0,0 +1,236 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h"
void ddsrt_mutex_init (ddsrt_mutex_t *mutex)
{
int shared;
assert (mutex != NULL);
pthread_mutex_init (&mutex->mutex, NULL);
(void)shared;
}
void ddsrt_mutex_destroy (ddsrt_mutex_t *mutex)
{
assert (mutex != NULL);
if (pthread_mutex_destroy (&mutex->mutex) != 0)
abort();
}
void ddsrt_mutex_lock (ddsrt_mutex_t *mutex)
{
assert (mutex != NULL);
if (pthread_mutex_lock (&mutex->mutex) != 0)
abort();
}
bool
ddsrt_mutex_trylock (ddsrt_mutex_t *mutex)
{
int err;
assert (mutex != NULL);
err = pthread_mutex_trylock (&mutex->mutex);
if (err != 0 && err != EBUSY)
abort();
return (err == 0);
}
void
ddsrt_mutex_unlock (ddsrt_mutex_t *mutex)
{
assert (mutex != NULL);
if (pthread_mutex_unlock (&mutex->mutex) != 0)
abort();
}
void
ddsrt_cond_init (ddsrt_cond_t *cond)
{
assert (cond != NULL);
pthread_cond_init (&cond->cond, NULL);
}
void
ddsrt_cond_destroy (ddsrt_cond_t *cond)
{
assert (cond != NULL);
if (pthread_cond_destroy (&cond->cond) != 0)
abort();
}
void
ddsrt_cond_wait (ddsrt_cond_t *cond, ddsrt_mutex_t *mutex)
{
assert (cond != NULL);
assert (mutex != NULL);
if (pthread_cond_wait (&cond->cond, &mutex->mutex) != 0)
abort();
}
bool
ddsrt_cond_waituntil(
ddsrt_cond_t *cond,
ddsrt_mutex_t *mutex,
dds_time_t abstime)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
assert(cond != NULL);
assert(mutex != NULL);
if (abstime == DDS_NEVER) {
ddsrt_cond_wait(cond, mutex);
return true;
}
if (abstime > 0) {
ts.tv_sec = abstime / DDS_NSECS_IN_SEC;
ts.tv_nsec = abstime % DDS_NSECS_IN_SEC;
}
switch (pthread_cond_timedwait(&cond->cond, &mutex->mutex, &ts)) {
case 0:
return true;
case ETIMEDOUT:
return false;
default:
break;
}
abort();
}
bool
ddsrt_cond_waitfor(
ddsrt_cond_t *cond,
ddsrt_mutex_t *mutex,
dds_duration_t reltime)
{
assert(cond != NULL);
assert(mutex != NULL);
return ddsrt_cond_waituntil(
cond, mutex, ddsrt_time_add_duration(dds_time(), reltime));
}
void
ddsrt_cond_signal (ddsrt_cond_t *cond)
{
assert (cond != NULL);
if (pthread_cond_signal (&cond->cond) != 0)
abort();
}
void
ddsrt_cond_broadcast (ddsrt_cond_t *cond)
{
assert (cond != NULL);
if (pthread_cond_broadcast (&cond->cond) != 0)
abort();
}
void
ddsrt_rwlock_init (ddsrt_rwlock_t *rwlock)
{
int err = 0;
assert(rwlock != NULL);
/* process-shared attribute is set to PTHREAD_PROCESS_PRIVATE by default */
if ((err = pthread_mutex_init(&rwlock->rwlock, NULL)) != 0)
abort();
}
void
ddsrt_rwlock_destroy (ddsrt_rwlock_t *rwlock)
{
int err;
assert(rwlock != NULL);
if ((err = pthread_mutex_destroy (&rwlock->rwlock)) != 0)
abort();
}
void ddsrt_rwlock_read (ddsrt_rwlock_t *rwlock)
{
int err;
assert(rwlock != NULL);
err = pthread_mutex_lock(&rwlock->rwlock);
assert(err == 0);
(void)err;
}
void ddsrt_rwlock_write (ddsrt_rwlock_t *rwlock)
{
int err;
assert(rwlock != NULL);
err = pthread_mutex_lock (&rwlock->rwlock);
assert(err == 0);
(void)err;
}
bool ddsrt_rwlock_tryread (ddsrt_rwlock_t *rwlock)
{
int err;
assert(rwlock != NULL);
err = pthread_mutex_trylock(&rwlock->rwlock);
assert(err == 0 || err == EBUSY);
return err == 0;
}
bool ddsrt_rwlock_trywrite (ddsrt_rwlock_t *rwlock)
{
int err;
assert(rwlock != NULL);
err = pthread_mutex_trylock(&rwlock->rwlock);
assert(err == 0 || err == EBUSY);
return err == 0;
}
void ddsrt_rwlock_unlock (ddsrt_rwlock_t *rwlock)
{
int err;
assert(rwlock != NULL);
err = pthread_mutex_unlock(&rwlock->rwlock);
assert(err == 0);
(void)err;
}
void ddsrt_once (ddsrt_once_t *control, ddsrt_once_fn init_fn)
{
/* There are no defined errors that can be returned by pthread_once */
(void)pthread_once(control, init_fn);
}

View file

@ -80,7 +80,11 @@ ddsrt_thread_getname(char *str, size_t size)
(void)pthread_get_name_np(pthread_self(), buf, sizeof(buf));
cnt = ddsrt_strlcpy(str, buf, size);
#elif defined(__sun)
#if !(__SunOS_5_6 || __SunOS_5_7 || __SunOS_5_8 || __SunOS_5_9 || __SunOS_5_10)
(void)pthread_getname_np(pthread_self(), buf, sizeof(buf));
#else
buf[0] = 0;
#endif
cnt = ddsrt_strlcpy(str, buf, size);
#elif defined(__VXWORKS__)
{
@ -125,7 +129,9 @@ ddsrt_thread_setname(const char *__restrict name)
#elif defined(__sun)
/* Thread names are limited to 31 bytes on Solaris. Excess bytes are
silently truncated. */
#if !(__SunOS_5_6 || __SunOS_5_7 || __SunOS_5_8 || __SunOS_5_9 || __SunOS_5_10)
(void)pthread_setname_np(pthread_self(), name);
#endif
#else
/* VxWorks does not support the task name to be set after a task is created.
Setting the name of a task can be done through pthread_attr_setname. */

View file

@ -47,7 +47,12 @@ size_t
ddsrt_ctime(dds_time_t n, char *str, size_t size)
{
struct tm tm;
#if __SunOS_5_6
/* Solaris 2.6 doesn't recognize %z so we just leave it out */
static const char fmt[] = "%Y-%m-%d %H:%M:%S";
#else
static const char fmt[] = "%Y-%m-%d %H:%M:%S%z";
#endif
char buf[] = "YYYY-mm-dd HH:MM:SS.hh:mm"; /* RFC 3339 */
size_t cnt;
time_t sec = (time_t)(n / DDS_NSECS_IN_SEC);
@ -61,12 +66,14 @@ ddsrt_ctime(dds_time_t n, char *str, size_t size)
#endif /* _WIN32 */
cnt = strftime(buf, sizeof(buf), fmt, &tm);
#if ! __SunOS_5_6
/* %z is without a separator between hours and minutes, fixup */
assert(cnt == (sizeof(buf) - 2 /* ':' + '\0' */));
buf[sizeof(buf) - 1] = '\0';
buf[sizeof(buf) - 2] = buf[sizeof(buf) - 3];
buf[sizeof(buf) - 3] = buf[sizeof(buf) - 4];
buf[sizeof(buf) - 4] = ':';
#endif
(void)cnt;
return ddsrt_strlcpy(str, buf, size);

View file

@ -0,0 +1,38 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include "dds/ddsrt/time.h"
dds_time_t dds_time(void)
{
struct timespec ts;
(void)clock_gettime(CLOCK_REALTIME, &ts);
return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec;
}
dds_time_t ddsrt_time_monotonic(void)
{
return gethrtime ();
}
dds_time_t ddsrt_time_elapsed(void)
{
/* Elapsed time clock not worth the bother for now. */
return ddsrt_time_monotonic();
}