Procházet zdrojové kódy

Fix #375926 - modbus.c:164: error: `MSG_DONTWAIT' undeclared
Reported and tested by Yishin Li.

Real fix #333455 - IPTOS_LOWDELAY not supported on cygwin
Thank to Yishin Li for the better problem description.

Stéphane Raimbault před 16 roky
rodič
revize
6e6e2602a9
3 změnil soubory, kde provedl 48 přidání a 22 odebrání
  1. 3 1
      NEWS
  2. 4 3
      configure.ac
  3. 41 18
      src/modbus.c

+ 3 - 1
NEWS

@@ -7,8 +7,10 @@ libmodbus 2.2.0 (2009-05-01)
 - modbus_param_t is smaller (2 int removed)
 - Better error management
 - Faster
-- Fix #333455 reported by Jeff Laughlin
+- Fix #333455 reported by Jeff Laughlin and Yishin Li.
   Cygwin IPTOS_LOWDELAY not supported on cygwin
+- Fix #375926 - modbus.c:164: error: `MSG_DONTWAIT' undeclared
+  Reported and tested by Yishin Li.
 
 libmodbus 2.0.3 (2009-03-22)
 ============================

+ 4 - 3
configure.ac

@@ -26,9 +26,10 @@ AC_HEADER_TIME
 AC_TYPE_UINT16_T
 AC_TYPE_UINT32_T
 AC_TYPE_UINT8_T
-AC_CHECK_DECLS([IPTOS_LOWDELAY],
-               [have_iptos_lowdelay=yes], [have_iptos_lowdelay=no],
-               [#include <netinet/ip.h>])
+
+# Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's necessary to
+# workaround that problem and Cygwin doesn't define MSG_DONTWAIT.
+AC_CHECK_DECLS([__CYGWIN__])
 
 # Checks for library functions.
 AC_FUNC_FORK

+ 41 - 18
src/modbus.c

@@ -152,23 +152,6 @@ static const int TAB_MAX_ADU_LENGTH[2] = {
         MAX_ADU_LENGTH_TCP,
 };
 
-void modbus_flush(modbus_param_t *mb_param)
-{
-        if (mb_param->type_com == RTU) {
-                tcflush(mb_param->fd, TCIOFLUSH);
-        } else {
-                int ret;
-                do {
-                        /* Extract the garbage from the socket */
-                        char devnull[MAX_ADU_LENGTH_TCP];
-                        ret = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, MSG_DONTWAIT);
-                        if (mb_param->debug && ret > 0) {
-                                printf("%d bytes flushed\n", ret);
-                        }
-                } while (ret > 0);
-        }
-}
-
 /* Treats errors and flush or close connection if necessary */
 static void error_treat(modbus_param_t *mb_param, int code, const char *string)
 {
@@ -194,6 +177,42 @@ static void error_treat(modbus_param_t *mb_param, int code, const char *string)
         }
 }
 
+void modbus_flush(modbus_param_t *mb_param)
+{
+        if (mb_param->type_com == RTU) {
+                tcflush(mb_param->fd, TCIOFLUSH);
+        } else {
+                int ret;
+                do {
+                        /* Extract the garbage from the socket */
+                        char devnull[MAX_ADU_LENGTH_TCP];
+#if (!HAVE_DECL___CYGWIN__)
+                        ret = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, MSG_DONTWAIT);
+#else
+                        /* On Cygwin, it's a bit more complicated to not wait */
+                        fd_set rfds;
+                        struct timeval tv;
+
+                        tv.tv_sec = 0;
+                        tv.tv_usec = 0;
+                        FD_ZERO(&rfds);
+                        FD_SET(mb_param->fd, &rfds);
+                        ret = select(mb_param->fd+1, &rfds, NULL, NULL, &tv);
+                        if (ret > 0) {
+                                ret = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, 0);
+                        } else if (ret == -1) {
+                                /* error_treat() doesn't call modbus_flush() in
+                                   this case (avoid infinite loop) */
+                                error_treat(mb_param, SELECT_FAILURE, "Select failure");
+                        }
+#endif
+                        if (mb_param->debug && ret > 0) {
+                                printf("%d bytes flushed\n", ret);
+                        }
+                } while (ret > 0);
+        }
+}
+
 /* Computes the length of the expected response */
 static unsigned int compute_response_length(modbus_param_t *mb_param,
                                             uint8_t *query)
@@ -1686,7 +1705,11 @@ static int modbus_connect_tcp(modbus_param_t *mb_param)
                 return ret;
         }
 
-#ifdef HAVE_DECL_IPTOS_LOWDELAY
+#if (!HAVE_DECL___CYGWIN__)
+        /**
+         * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's
+         * necessary to workaround that problem.
+         **/
         /* Set the IP low delay option */
         option = IPTOS_LOWDELAY;
         ret = setsockopt(mb_param->fd, IPPROTO_TCP, IP_TOS,