src/liboping.c: Fix an incorrect assertion in `ping_timeval_add'.
[liboping.git] / src / liboping.c
index 0371f15..02125e2 100644 (file)
@@ -25,6 +25,8 @@
 # include <stdlib.h>
 # include <stdio.h>
 # include <string.h>
+# include <stdint.h>
+# include <inttypes.h>
 # include <errno.h>
 # include <assert.h>
 #else
@@ -109,6 +111,7 @@ struct pinghost
        int                      sequence;
        struct timeval          *timer;
        double                   latency;
+       uint32_t                 dropped;
        char                    *data;
 
        void                    *context;
@@ -159,7 +162,6 @@ static int ping_timeval_add (struct timeval *tv1, struct timeval *tv2,
 static int ping_timeval_sub (struct timeval *tv1, struct timeval *tv2,
                struct timeval *res)
 {
-
        if ((tv1->tv_sec < tv2->tv_sec)
                        || ((tv1->tv_sec == tv2->tv_sec)
                                && (tv1->tv_usec < tv2->tv_usec)))
@@ -168,7 +170,7 @@ static int ping_timeval_sub (struct timeval *tv1, struct timeval *tv2,
        res->tv_sec  = tv1->tv_sec  - tv2->tv_sec;
        res->tv_usec = tv1->tv_usec - tv2->tv_usec;
 
-       assert ((res->tv_sec > 0) || ((res->tv_sec == 0) && (res->tv_usec > 0)));
+       assert ((res->tv_sec > 0) || ((res->tv_sec == 0) && (res->tv_usec >= 0)));
 
        while (res->tv_usec < 0)
        {
@@ -523,6 +525,9 @@ static int ping_receive_all (pingobj_t *obj)
                else if (status == 0)
                {
                        dprintf ("select timed out\n");
+                       for (ptr = ph; ptr != NULL; ptr = ptr->next)
+                               if (ptr->latency < 0.0)
+                                       ptr->dropped++;
                        break;
                }
 
@@ -799,6 +804,7 @@ static pinghost_t *ping_alloc (void)
        ph->addrlen = sizeof (struct sockaddr_storage);
        ph->fd      = -1;
        ph->latency = -1.0;
+       ph->dropped = 0;
        ph->ident   = ping_get_ident () & 0xFFFF;
 
        return (ph);
@@ -941,9 +947,11 @@ int ping_setopt (pingobj_t *obj, int option, void *value)
                        if (status != 0)
                        {
                                ping_set_error (obj, "getaddrinfo",
-                                               status == EAI_SYSTEM
-                                               ? strerror (errno)
-                                               : gai_strerror (status));
+#if defined(EAI_SYSTEM)
+                                               (status == EAI_SYSTEM)
+                                               ? strerror (errno) :
+#endif
+                                               gai_strerror (status));
                                ret = -1;
                                break;
                        }
@@ -1073,9 +1081,11 @@ int ping_host_add (pingobj_t *obj, const char *host)
        {
                dprintf ("getaddrinfo failed\n");
                ping_set_error (obj, "getaddrinfo",
-                               (ai_return == EAI_SYSTEM)
-                               ? strerror (errno)
-                               : gai_strerror (ai_return));
+#if defined(EAI_SYSTEM)
+                                               (ai_return == EAI_SYSTEM)
+                                               ? strerror (errno) :
+#endif
+                               gai_strerror (ai_return));
                ping_free (ph);
                return (-1);
        }
@@ -1306,8 +1316,10 @@ int ping_iterator_get_info (pingobj_iter_t *iter, int info,
 #endif
                                   )
                                        ret = ENOMEM;
+#if defined(EAI_SYSTEM)
                                else if (ret == EAI_SYSTEM)
                                        ret = errno;
+#endif
                                else
                                        ret = EINVAL;
                        }
@@ -1331,6 +1343,15 @@ int ping_iterator_get_info (pingobj_iter_t *iter, int info,
                        ret = 0;
                        break;
 
+               case PING_INFO_DROPPED:
+                       ret = ENOMEM;
+                       *buffer_len = sizeof (uint32_t);
+                       if (orig_buffer_len < sizeof (uint32_t))
+                               break;
+                       *((uint32_t *) buffer) = iter->dropped;
+                       ret = 0;
+                       break;
+
                case PING_INFO_SEQUENCE:
                        ret = ENOMEM;
                        *buffer_len = sizeof (unsigned int);
@@ -1360,7 +1381,7 @@ int ping_iterator_get_info (pingobj_iter_t *iter, int info,
        }
 
        return (ret);
-}
+} /* ping_iterator_get_info */
 
 void *ping_iterator_get_context (pingobj_iter_t *iter)
 {