Merge.
authorfrederic.urbani@inria.fr
Mon, 16 Jul 2012 13:56:16 +0200
changeset 258 4c90fdff71a0
parent 257 c7fee225d919 (current diff)
parent 254 92860e84c41d (diff)
child 259 8229b566699d
Merge.
model/dce-fd.cc
model/dce-manager.cc
--- a/model/dce-fd.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce-fd.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -372,11 +372,30 @@
       current->err = EMFILE;
       return -1;
     }
+  if (!socket)
+    return -1;
   socket->IncFdCount ();
   current->process->openFiles[fd] = new FileUsage (fd, socket);
 
   return fd;
 }
+int dce_socketpair (int domain, int type, int protocol, int sv[2])
+{
+  sv[0] = dce_socket (domain, type, protocol);
+  if (sv[0] < 0)
+    {
+      return -1;
+    }
+
+  sv[1] = dce_socket (domain, type, protocol);
+  if (sv[1] < 0)
+    {
+      return -1;
+    }
+
+  return 0;
+}
+
 int dce_bind (int fd, const struct sockaddr *my_addr, socklen_t addrlen)
 {
   Thread *current = Current ();
--- a/model/dce-manager.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce-manager.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -1145,6 +1145,22 @@
           libpthread_setup = (void (*)(const struct Libc *))(symbol);
           libpthread_setup (libc);
 
+          h = ld->Load ("librt-ns3.so", RTLD_GLOBAL);
+          if (h == 0)
+            {
+              err = ENOMEM;
+              return 0;
+            }
+          symbol = ld->Lookup (h, "librt_setup");
+          if (symbol == 0)
+            {
+              NS_FATAL_ERROR ("This is not our fake librt !");
+            }
+          // construct librt now
+          void (*librt_setup)(const struct Libc *fn);
+          librt_setup = (void (*)(const struct Libc *))(symbol);
+          librt_setup (libc);
+
           // finally, call into 'main'.
           h = ld->Load (filename, RTLD_GLOBAL);
 
--- a/model/dce-poll.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce-poll.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -180,7 +180,12 @@
         }
     }
   nfds = eventByFd.size ();
-  if (nfds == 0)
+
+  // select(2): 
+  // Some  code  calls  select() with all three sets empty, nfds zero, and a
+  // non-NULL timeout as a fairly portable way to sleep with subsecond 
+  // precision.
+  if (nfds == 0 && !timeout)
     {
       current->err = EINVAL;
       return -1;
--- a/model/dce-signal.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce-signal.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -1,6 +1,7 @@
 #include "dce-signal.h"
 #include "utils.h"
 #include "process.h"
+#include "dce-manager.h"
 #include "ns3/log.h"
 #include "ns3/assert.h"
 #include <vector>
@@ -98,6 +99,21 @@
 
   return 0;
 }
+
+int dce_sigwait (const sigset_t *set, int *sig)
+{
+  Thread *current = Current ();
+  NS_LOG_FUNCTION (current << UtilsGetNodeId () << set << sig);
+  NS_ASSERT (current != 0);
+
+  int ret = 0;
+  // NEED TO WORK!!
+  // XXX: we need to add signal num notiifcation
+  current->process->manager->Wait ();
+  //  sigdelset (&current->pendingSignals, numnum);
+
+  return ret;
+}
 int dce_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
 {
   Thread *current = Current ();
--- a/model/dce-signal.h	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce-signal.h	Mon Jul 16 13:56:16 2012 +0200
@@ -17,6 +17,7 @@
 int dce_pthread_kill (pthread_t thread, int sig);
 void dce_abort ();
 int dce_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
+int dce_sigwait (const sigset_t *set, int *sig);
 
 #ifdef __cplusplus
 }
--- a/model/dce-time.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce-time.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -54,3 +54,12 @@
 
   return asctime_r (tm, Current ()->process->asctime_result);
 }
+
+int dce_clock_gettime(clockid_t which_clock, struct timespec *tp)
+{
+  NS_LOG_FUNCTION (Current () << UtilsGetNodeId ());
+  NS_ASSERT (Current () != 0);
+  NS_ASSERT (tp != 0);
+  *tp = UtilsTimeToTimespec (UtilsSimulationTimeToTime (Now ()));
+  return 0;
+}
--- a/model/dce-time.h	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce-time.h	Mon Jul 16 13:56:16 2012 +0200
@@ -3,6 +3,7 @@
 
 #include "sys/dce-time.h"
 #include <time.h>
+#include <sys/sysinfo.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -13,6 +14,8 @@
 struct tm *dce_localtime(const time_t *timep);
 char *dce_ctime(const time_t *timep);
 char *dce_asctime(const struct tm *tm);
+int dce_clock_gettime(clockid_t which_clock, struct timespec *tp);
+int dce_sysinfo (struct sysinfo *info);
 	
 #ifdef __cplusplus
 }
--- a/model/dce.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/dce.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -22,6 +22,8 @@
 #include <getopt.h>
 #include <limits.h>
 #include <fcntl.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
 #include "dce-random.h"
 #include "net/dce-if.h"
 #include "ns3/node.h"
@@ -30,6 +32,7 @@
 #include "ns3/names.h"
 #include "ns3/random-variable.h"
 #include "ns3/ipv4-l3-protocol.h"
+#include "socket-fd-factory.h"
 
 NS_LOG_COMPONENT_DEFINE ("Dce");
 
@@ -639,20 +642,60 @@
 }
 unsigned dce_if_nametoindex (const char *ifname)
 {
-  int index = 0;
-  Ptr<Node> node = Current ()->process->manager->GetObject<Node> ();
-  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Thread *current = Current ();
+  Ptr<SocketFdFactory> factory = 0;
+  factory = current->process->manager->GetObject<SocketFdFactory> ();
 
-  for (uint32_t i = 0; i < node->GetNDevices (); ++i)
+  if (factory->GetInstanceTypeId () == TypeId::LookupByName ("ns3::LinuxSocketFdFactory"))
+    {
+      struct ifreq ifr;
+      int fd = dce_socket (AF_INET, SOCK_DGRAM, 0);
+      if (fd < 0)
+        {
+          return 0;
+        }
+
+      strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+      if (dce_ioctl (fd, SIOCGIFINDEX, (char *)&ifr) < 0)
+        {
+          current->err = errno;
+          return -1;
+        }
+      return ifr.ifr_ifindex;
+    }
+  else
     {
-      Ptr<NetDevice> dev = node->GetDevice (i);
-      if (ifname == Names::FindName (dev))
+      int index = 0;
+      Ptr<Node> node = Current ()->process->manager->GetObject<Node> ();
+      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+
+      for (uint32_t i = 0; i < node->GetNDevices (); ++i)
         {
-          index = ipv4->GetInterfaceForDevice (dev);
-          return index;
+          Ptr<NetDevice> dev = node->GetDevice (i);
+          if (ifname == Names::FindName (dev))
+            {
+              index = ipv4->GetInterfaceForDevice (dev);
+              return index;
+            }
         }
+      return 0;
     }
-  return 0;
+}
+char *dce_if_indextoname (unsigned ifindex, char *ifname)
+{
+  struct ifreq ifr;
+  int fd = dce_socket (AF_INET, SOCK_DGRAM, 0);
+  if (fd < 0)
+    {
+      return 0;
+    }
+
+  ifr.ifr_ifindex = ifindex;
+  if (dce_ioctl (fd, SIOCGIFNAME, (char *)&ifr) < 0)
+    {
+      return 0;
+    }
+  return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
 }
 pid_t dce_fork (void)
 {
@@ -849,6 +892,21 @@
   static char loc[] = "";
   return loc;
 }
+int dce_sysinfo (struct sysinfo *info)
+{
+  Thread *current = Current ();
+  NS_LOG_FUNCTION (current << UtilsGetNodeId ());
+  NS_ASSERT (current != 0);
+  if (!info)
+    {
+      current->err = ENAMETOOLONG;
+      return -1;
+    }
+
+  info->uptime = (long)UtilsSimulationTimeToTime (Now ()).GetSeconds ();
+  // XXX
+  return 0;
+}
 #ifdef HAVE_GETCPUFEATURES
 extern "C"
 {
--- a/model/elf-cache.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/elf-cache.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -26,6 +26,9 @@
   overriden.from = "libpthread.so.0";
   overriden.to = "libpthread-ns3.so";
   m_overriden.push_back (overriden);
+  overriden.from = "librt.so.1";
+  overriden.to = "librt-ns3.so";
+  m_overriden.push_back (overriden);
 }
 
 std::string
--- a/model/libc-dce.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/libc-dce.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -141,6 +141,7 @@
 
 #define DCE(name) (*libc)->name ## _fn = (func_t)(__typeof(&name))dce_ ## name;
 #define DCET(rtype,name) DCE(name)
+#define DCE_EXPLICIT(name,rtype,...) (*libc)->name ## _fn = dce_ ## name;
 
 #define NATIVE(name)							\
   (*libc)->name ## _fn = (func_t)name;
--- a/model/libc-ns3.h	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/libc-ns3.h	Mon Jul 16 13:56:16 2012 +0200
@@ -124,7 +124,7 @@
 NATIVE (strcspn)
 NATIVE (strspn)
 NATIVE_EXPLICIT (strchr, char* (*) (char *, int))
-NATIVE_EXPLICIT (strrchr, char * (*) (char *, int))
+NATIVE_EXPLICIT (strrchr, const char * (*) (const char *, int))
 NATIVE (strcasecmp)
 NATIVE (strncasecmp)
 DCE_WITH_ALIAS (strdup) // because C++ defines both const and non-const functions
@@ -149,6 +149,7 @@
 NATIVE (htons)
 NATIVE (ntohl)
 NATIVE (ntohs)
+NATIVE (lockf)
 NATIVE (inet_aton)
 NATIVE (inet_addr)
 NATIVE (inet_network)
@@ -158,9 +159,11 @@
 NATIVE (inet_netof)
 DCE (inet_ntop)
 NATIVE (inet_pton)
+NATIVE (inet6_opt_find)
 
 // SYS/SOCKET.H
 DCE (socket)
+DCE (socketpair)
 DCE (getsockname)
 DCE (getpeername)
 DCE (bind)
@@ -313,7 +316,7 @@
 NATIVE_WITH_ALIAS2 (gmtime_r, localtime_r)
 NATIVE (mktime)
 NATIVE (strftime)
-NATIVE_WITH_ALIAS2 (clock_gettime, __vdso_clock_gettime) // this is wrong. clock should be changed to DCE implementation
+DCE_EXPLICIT (clock_gettime, int, clockid_t, struct timespec *)
 
 // SYS/TIME.H
 DCE (gettimeofday)
@@ -321,6 +324,8 @@
 DCE (setitimer)
 DCE (getitimer)
 
+DCE (sysinfo)
+
 // SYS/MAP.H
 DCE (mmap)
 DCE (mmap64)
@@ -348,6 +353,7 @@
 NATIVE (sigdelset)
 NATIVE (sigismember)
 DCE (sigprocmask)
+DCE    (sigwait)
 
 // PTHREAD.H
 DCE (pthread_create)
@@ -360,8 +366,8 @@
 DCE (pthread_key_delete)
 DCE (pthread_mutex_destroy)
 DCE (pthread_mutex_init)
-DCE (pthread_mutex_lock)
-DCE (pthread_mutex_unlock)
+DCE_EXPLICIT (pthread_mutex_lock, int, pthread_mutex_t *)
+DCE_EXPLICIT (pthread_mutex_unlock, int, pthread_mutex_t *)
 DCE (pthread_mutex_trylock)
 DCE (pthread_mutexattr_init)
 DCE (pthread_mutexattr_destroy)
@@ -374,10 +380,17 @@
 DCE (pthread_cond_init)
 DCE (pthread_cond_broadcast)
 DCE (pthread_cond_signal)
-DCE (pthread_cond_timedwait)
-DCE (pthread_cond_wait)
+DCE_EXPLICIT (pthread_cond_timedwait, int, pthread_cond_t*, pthread_mutex_t*, const struct timespec *)
+DCE_EXPLICIT (pthread_cond_wait, int, pthread_cond_t*, pthread_mutex_t*)
 DCE (pthread_condattr_destroy)
 DCE (pthread_condattr_init)
+NATIVE (pthread_rwlock_init)
+NATIVE (pthread_rwlock_unlock)
+NATIVE (pthread_rwlock_wrlock)
+NATIVE (pthread_rwlock_rdlock)
+NATIVE (pthread_rwlock_destroy)
+NATIVE (pthread_setcancelstate)
+NATIVE (pthread_sigmask)
 
 // SEMAPHORE.H
 DCE (sem_init)
@@ -421,6 +434,7 @@
 
 // NET/IF.H
 DCE (if_nametoindex)
+DCE (if_indextoname)
 
 // DIRENT.H
 DCE (opendir)
@@ -480,6 +494,7 @@
 
 // NETINET/ETHER.H
 NATIVE (ether_aton_r)
+NATIVE (ether_aton)
 
 // SEARCH.H
 NATIVE (tsearch)
@@ -521,6 +536,7 @@
 
 #undef DCE
 #undef DCET
+#undef DCE_EXPLICIT
 #undef NATIVE
 #undef NATIVE_WITH_ALIAS
 #undef NATIVE_WITH_ALIAS2
--- a/model/libc.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/libc.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -38,6 +38,38 @@
 #define DCET(rtype,name)                                                               \
         GCC_BUILTIN_APPLYT(rtype,name,name)
 
+/* From gcc/testsuite/gcc.dg/cpp/vararg2.c */
+/* C99 __VA_ARGS__ versions */
+#define c99_count(...)    _c99_count1 ( , ##__VA_ARGS__)/* If only ## worked.*/
+#define _c99_count1(...)  _c99_count2 (__VA_ARGS__,10,9,8,7,6,5,4,3,2,1,0)
+#define _c99_count2(_,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,n,...) n
+
+#define FULL_ARGS_0()
+#define FULL_ARGS_1(X0)  X0 a0
+#define FULL_ARGS_2(X0,X1)  X0 a0, X1 a1
+#define FULL_ARGS_3(X0,X1,X2)  X0 a0, X1 a1, X2 a2
+#define FULL_ARGS_4(X0,X1,X2,X3)  X0 a0, X1 a1, X2 a2, X3 a3
+#define FULL_ARGS_5(X0,X1,X2,X3,X4)  X0 a0, X1 a1, X2 a2, X3 a3, X4 a4
+
+#define _ARGS_0()
+#define _ARGS_1(X0)  a0
+#define _ARGS_2(X0,X1)   a0, a1
+#define _ARGS_3(X0,X1,X2)  a0, a1, a2
+#define _ARGS_4(X0,X1,X2,X3)  a0, a1, a2, a3
+#define _ARGS_5(X0,X1,X2,X3,X4) a0, a1, a2, a3, a4
+
+#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
+#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
+  
+#define  FULL_ARGS(...) CAT(FULL_ARGS_,c99_count (__VA_ARGS__))(__VA_ARGS__)
+#define  ARGS(...) CAT(_ARGS_,c99_count (__VA_ARGS__))(__VA_ARGS__)
+
+
+#define DCE_EXPLICIT(name,rtype,...)                                    \
+  rtype name (FULL_ARGS(__VA_ARGS__))    \
+  {                                                             \
+    return g_libc.name ## _fn (ARGS(__VA_ARGS__));              \
+  }
 
 #define DCE_WITH_ALIAS(name)					\
 	GCC_BUILTIN_APPLY(__ ## name,name)			\
--- a/model/libc.h	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/libc.h	Mon Jul 16 13:56:16 2012 +0200
@@ -1,6 +1,10 @@
 #ifndef LIBC_H
 #define LIBC_H
 
+#define _SYS_SELECT_H
+#include <sys/types.h>
+#undef _SYS_SELECT_H
+
 struct Libc
 {
 
@@ -8,6 +12,7 @@
 
 #define DCET(rtype, name) DCE(name)
 
+#define DCE_EXPLICIT(name,rtype,...) rtype (*name ## _fn)(__VA_ARGS__);
 #include "libc-ns3.h"
 
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/librt-ns3.version	Mon Jul 16 13:56:16 2012 +0200
@@ -0,0 +1,4 @@
+NS3 {
+global:
+	librt_setup;
+};
--- a/model/linux-socket-fd-factory.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/linux-socket-fd-factory.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -466,6 +466,7 @@
 void
 LinuxSocketFdFactory::SetTask (std::string path, std::string value)
 {
+  NS_LOG_FUNCTION (path << value);
   std::vector<std::pair<std::string,struct SimSysFile *> > files = GetSysFileList ();
   for (uint32_t i = 0; i < files.size (); i++)
     {
@@ -539,6 +540,7 @@
                                                       this));
   Set (".net.ipv4.conf.all.forwarding", "1");
   Set (".net.ipv4.conf.all.log_martians", "1");
+  Set (".net.ipv6.conf.all.forwarding", "0");
 
   while (!m_earlySysfs.empty ())
     {
--- a/model/net/dce-if.h	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/net/dce-if.h	Mon Jul 16 13:56:16 2012 +0200
@@ -7,6 +7,7 @@
 #endif
 
 unsigned dce_if_nametoindex (const char *ifname);
+char *dce_if_indextoname (unsigned ifindex, char *ifname);
 
 
 #ifdef __cplusplus
--- a/model/ns3-socket-fd-factory.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/ns3-socket-fd-factory.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -166,6 +166,7 @@
   else
     {
       NS_FATAL_ERROR ("unsupported domain");
+      return 0;
     }
 
   return socket;
--- a/model/sys/dce-socket.h	Mon Jul 16 13:45:42 2012 +0200
+++ b/model/sys/dce-socket.h	Mon Jul 16 13:56:16 2012 +0200
@@ -28,6 +28,7 @@
 ssize_t dce_sendmsg(int s, const struct msghdr *msg, int flags);
 int dce_getsockname(int s, struct sockaddr *name, socklen_t *namelen);
 int dce_getpeername(int s, struct sockaddr *name, socklen_t *namelen);
+int dce_socketpair (int domain, int type, int protocol, int sv[2]);
 
 #ifdef __cplusplus
 }
--- a/test/dce-manager-test.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/test/dce-manager-test.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -174,6 +174,7 @@
       {  "test-socket", 30, "" , true},
       {  "test-bug-multi-select", 30, "" , true},
       {  "test-tsearch", 0, "" , false},
+      // XXX: not completely tested      {  "test-signal", 30, "" , false},
   };
 
   // Prepare directories and files for test-stdio
--- a/test/test-nanosleep.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/test/test-nanosleep.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -4,7 +4,7 @@
 #include "test-macros.h"
 #include <sys/time.h>
 #include <signal.h>
-
+#include <sys/sysinfo.h>
 
 void sigresp (int) {return; }
 
@@ -27,6 +27,39 @@
     TEST_ASSERT_EQUAL (end.tv_usec-start.tv_usec, 5);
   }
 
+  // Simple nanolseep() without interruption: clock_gettime () version
+  {
+    timespec req = {1, 5000};
+    timespec rem;
+
+    timespec start;
+    timespec end;
+
+    clock_gettime (CLOCK_REALTIME, &start);
+    int result = nanosleep (&req, &rem);
+    clock_gettime (CLOCK_REALTIME, &end);
+
+    TEST_ASSERT_EQUAL (result, 0);
+    TEST_ASSERT_EQUAL (end.tv_sec-start.tv_sec, 1);
+    TEST_ASSERT_EQUAL (end.tv_nsec-start.tv_nsec, 5000);
+  }
+
+  // Simple nanolseep() without interruption: sysinfo (): uptime version
+  {
+    timespec req = {1, 5000};
+    timespec rem;
+
+    struct sysinfo start;
+    struct sysinfo end;
+
+    sysinfo (&start);
+    int result = nanosleep (&req, &rem);
+    sysinfo (&end);
+
+    TEST_ASSERT_EQUAL (result, 0);
+    TEST_ASSERT_EQUAL (end.uptime - start.uptime, 1);
+  }
+
   // Test with nanosleep() interrupted by SIGALRM fired by itimer
   {
     signal (SIGALRM, sigresp);
--- a/test/test-select.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/test/test-select.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -43,9 +43,20 @@
   struct timeval timeout =
   { 0, 0 };
   int nfds = select (timerfd + 1, &fds, NULL, NULL, &timeout);
-  close (timerfd);
   // no fds must be ready and select() should complete without errors
   TEST_ASSERT_EQUAL (nfds, 0);
+
+  timeout.tv_sec = 1;
+  timeout.tv_usec = 0;
+  // select(2): 
+  // Some  code  calls  select() with all three sets empty, nfds zero, and a
+  // non-NULL timeout as a fairly portable way to sleep with subsecond 
+  // precision.
+  nfds = select (0, &fds, NULL, NULL, &timeout);
+  // no fds must be ready and select() should complete without errors
+  TEST_ASSERT_EQUAL (nfds, 0);
+
+  close (timerfd);
 }
 
 static bool
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test-signal.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "test-macros.h"
+#include <sys/time.h>
+#include <errno.h>
+#include <signal.h>
+
+int 
+main (int argc, char *argv[])
+{
+  sigset_t sigcatch;
+  int ret = 1;
+  int signum;
+  sigemptyset(&sigcatch);
+  sigaddset(&sigcatch, SIGALRM);
+
+  {
+    struct itimerval it;
+    memset (&it, 0, sizeof (it));
+    it.it_value.tv_sec = 1;
+    it.it_value.tv_usec = 500000;
+
+    timespec req = {3, 0};
+    timespec rem;
+
+    setitimer (ITIMER_REAL, &it, NULL);
+    while (1)
+      {
+        sigwait(&sigcatch, &signum);
+        switch (signum) 
+          {
+          case SIGALRM:
+            printf ("SIG rcvd\n");
+            return 0;
+            break;
+          default:
+            break;
+          }
+        break;
+      }
+  }
+  // never reached
+  TEST_ASSERT (0);
+  return 0;
+}
--- a/test/test-socket.cc	Mon Jul 16 13:45:42 2012 +0200
+++ b/test/test-socket.cc	Mon Jul 16 13:56:16 2012 +0200
@@ -288,15 +288,15 @@
 
 void test_tcp (void)
 {
-  int sock, tx_sock;
+  int socks[2];
   const char buf[12] = "0123456789\0";
   static struct sockaddr_in dst;
   int ret;
   pthread_t thread;
 
   // TCP Sock
-  sock = socket (AF_INET, SOCK_STREAM, 0);
-  TEST_ASSERT_UNEQUAL (sock, -1);
+  ret = socketpair (AF_INET, SOCK_STREAM, 0, socks);
+  TEST_ASSERT_UNEQUAL (ret, -1);
 
   memset (&dst, 0, sizeof (dst));
   dst.sin_family = AF_INET;
@@ -304,27 +304,24 @@
   dst.sin_port = htons (30);
 
   // bind
-  ret = bind (sock, (struct sockaddr *)&dst, sizeof (dst));
+  ret = bind (socks[0], (struct sockaddr *)&dst, sizeof (dst));
   TEST_ASSERT_UNEQUAL (ret, -1);
 
   // listen
-  ret = listen (sock, 5);
+  ret = listen (socks[0], 5);
   TEST_ASSERT_UNEQUAL (ret, -1);
 
   // recv thread
   ret = pthread_create (&thread, NULL, 
                         &thread_recv,
-                        (void*)&sock);
+                        (void*)&socks[0]);
 
-  // tx sock
-  tx_sock = socket (AF_INET, SOCK_STREAM, 0);
-  TEST_ASSERT_UNEQUAL (tx_sock, -1);
   // connect
-  ret = connect (tx_sock, (struct sockaddr *)&dst, sizeof (dst));
+  ret = connect (socks[1], (struct sockaddr *)&dst, sizeof (dst));
   TEST_ASSERT_UNEQUAL (ret, -1);
 
   // send
-  ret = send (tx_sock, &buf, sizeof (buf), 0);
+  ret = send (socks[1], &buf, sizeof (buf), 0);
   TEST_ASSERT_EQUAL (ret, sizeof (buf));
   OUTPUT ("TCP send ret = " << ret);
 
@@ -332,10 +329,10 @@
   ret = pthread_join (thread, &return_value);
 
   // close
-  close (sock);
-  TEST_ASSERT_UNEQUAL (sock, -1);
-  close (tx_sock);
-  TEST_ASSERT_UNEQUAL (tx_sock, -1);
+  close (socks[0]);
+  TEST_ASSERT_UNEQUAL (socks[0], -1);
+  close (socks[1]);
+  TEST_ASSERT_UNEQUAL (socks[1], -1);
 }
 
 void test_netlink (void)
--- a/wscript	Mon Jul 16 13:45:42 2012 +0200
+++ b/wscript	Mon Jul 16 13:56:16 2012 +0200
@@ -74,6 +74,19 @@
         conf.end_msg(libpthread, True)
     conf.env['LIBPTHREAD_FILE'] = libpthread
 
+    conf.start_msg('Searching rt library')
+    librt = search_file ([
+            '/lib64/librt.so.1',
+            '/lib/librt.so.1',
+            '/lib/x86_64-linux-gnu/librt.so.1',
+            '/lib/i386-linux-gnu/librt.so.1',
+            ])
+    if librt is None:
+        conf.fatal('not found')
+    else:
+        conf.end_msg(librt, True)
+    conf.env['LIBRT_FILE'] = librt
+
     conf.find_program('readversiondef', var='READVERSIONDEF', mandatory=True)
 
     if Options.options.kernel_stack is not None and os.path.isdir(Options.options.kernel_stack):
@@ -130,7 +143,7 @@
     debug_dl = []
     d['cxxflags'] = d.get('cxxflags', []) + ['-fpie'] + mcmodel + nofortify
     d['cflags'] = d.get('cflags', []) + ['-fpie'] + mcmodel + nofortify
-    d['linkflags'] = d.get('linkflags', []) + ['-pie'] + debug_dl
+    d['linkflags'] = d.get('linkflags', []) + ['-pie'] + ['-lrt'] + debug_dl
     return d
 
 def build_dce_tests(module, kern):
@@ -179,6 +192,7 @@
              ['test-socket', []],
              ['test-bug-multi-select', []],
              ['test-tsearch', []],
+             ['test-signal', []],
              ]
     for name,uselib in tests:
         module.add_test(**dce_kw(target='bin_dce/' + name, source = ['test/' + name + '.cc'],
@@ -442,6 +456,11 @@
         rule='%s %s | cat ${SRC[0].abspath()} - > ${TGT}' %
         (bld.env['READVERSIONDEF'], bld.env['LIBPTHREAD_FILE']))
 
+    bld(source=['model/librt-ns3.version'],
+        target='model/librt.version',
+        rule='%s %s | cat ${SRC[0].abspath()} - > ${TGT}' %
+        (bld.env['READVERSIONDEF'], bld.env['LIBRT_FILE']))
+
     bld.add_group('dce_use_version_files')
 
     # The very small libc used to replace the glibc
@@ -461,5 +480,15 @@
               linkflags=['-nostdlib', '-lc',
                          '-Wl,--version-script=' + os.path.join('model', 'libpthread.version'),
                          '-Wl,-soname=libpthread.so.0'])
+
+    # The very small librt used to replace the glibc
+    # and forward to the dce_* code
+    bld.shlib(source = ['model/libc.cc', 'model/libc-setup.cc'],
+              target='lib/rt-ns3', cflags=['-g'],
+              defines=['LIBSETUP=librt_setup'],
+              linkflags=['-nostdlib', '-lc',
+                         '-Wl,--version-script=' + os.path.join('model', 'librt.version'),
+                         '-Wl,-soname=librt.so.1'])
+
     if bld.env['ENABLE_VDL']:                     
         bld.add_subdirs(['utils'])