Commit 6e6e2602a9c49b5cead4839adc4b91a03ca728a2
1 parent
629dc1d7
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.
Showing
3 changed files
with
48 additions
and
22 deletions
NEWS
| ... | ... | @@ -7,8 +7,10 @@ libmodbus 2.2.0 (2009-05-01) |
| 7 | 7 | - modbus_param_t is smaller (2 int removed) |
| 8 | 8 | - Better error management |
| 9 | 9 | - Faster |
| 10 | -- Fix #333455 reported by Jeff Laughlin | |
| 10 | +- Fix #333455 reported by Jeff Laughlin and Yishin Li. | |
| 11 | 11 | Cygwin IPTOS_LOWDELAY not supported on cygwin |
| 12 | +- Fix #375926 - modbus.c:164: error: `MSG_DONTWAIT' undeclared | |
| 13 | + Reported and tested by Yishin Li. | |
| 12 | 14 | |
| 13 | 15 | libmodbus 2.0.3 (2009-03-22) |
| 14 | 16 | ============================ | ... | ... |
configure.ac
| ... | ... | @@ -26,9 +26,10 @@ AC_HEADER_TIME |
| 26 | 26 | AC_TYPE_UINT16_T |
| 27 | 27 | AC_TYPE_UINT32_T |
| 28 | 28 | AC_TYPE_UINT8_T |
| 29 | -AC_CHECK_DECLS([IPTOS_LOWDELAY], | |
| 30 | - [have_iptos_lowdelay=yes], [have_iptos_lowdelay=no], | |
| 31 | - [#include <netinet/ip.h>]) | |
| 29 | + | |
| 30 | +# Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's necessary to | |
| 31 | +# workaround that problem and Cygwin doesn't define MSG_DONTWAIT. | |
| 32 | +AC_CHECK_DECLS([__CYGWIN__]) | |
| 32 | 33 | |
| 33 | 34 | # Checks for library functions. |
| 34 | 35 | AC_FUNC_FORK | ... | ... |
src/modbus.c
| ... | ... | @@ -152,23 +152,6 @@ static const int TAB_MAX_ADU_LENGTH[2] = { |
| 152 | 152 | MAX_ADU_LENGTH_TCP, |
| 153 | 153 | }; |
| 154 | 154 | |
| 155 | -void modbus_flush(modbus_param_t *mb_param) | |
| 156 | -{ | |
| 157 | - if (mb_param->type_com == RTU) { | |
| 158 | - tcflush(mb_param->fd, TCIOFLUSH); | |
| 159 | - } else { | |
| 160 | - int ret; | |
| 161 | - do { | |
| 162 | - /* Extract the garbage from the socket */ | |
| 163 | - char devnull[MAX_ADU_LENGTH_TCP]; | |
| 164 | - ret = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, MSG_DONTWAIT); | |
| 165 | - if (mb_param->debug && ret > 0) { | |
| 166 | - printf("%d bytes flushed\n", ret); | |
| 167 | - } | |
| 168 | - } while (ret > 0); | |
| 169 | - } | |
| 170 | -} | |
| 171 | - | |
| 172 | 155 | /* Treats errors and flush or close connection if necessary */ |
| 173 | 156 | static void error_treat(modbus_param_t *mb_param, int code, const char *string) |
| 174 | 157 | { |
| ... | ... | @@ -194,6 +177,42 @@ static void error_treat(modbus_param_t *mb_param, int code, const char *string) |
| 194 | 177 | } |
| 195 | 178 | } |
| 196 | 179 | |
| 180 | +void modbus_flush(modbus_param_t *mb_param) | |
| 181 | +{ | |
| 182 | + if (mb_param->type_com == RTU) { | |
| 183 | + tcflush(mb_param->fd, TCIOFLUSH); | |
| 184 | + } else { | |
| 185 | + int ret; | |
| 186 | + do { | |
| 187 | + /* Extract the garbage from the socket */ | |
| 188 | + char devnull[MAX_ADU_LENGTH_TCP]; | |
| 189 | +#if (!HAVE_DECL___CYGWIN__) | |
| 190 | + ret = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, MSG_DONTWAIT); | |
| 191 | +#else | |
| 192 | + /* On Cygwin, it's a bit more complicated to not wait */ | |
| 193 | + fd_set rfds; | |
| 194 | + struct timeval tv; | |
| 195 | + | |
| 196 | + tv.tv_sec = 0; | |
| 197 | + tv.tv_usec = 0; | |
| 198 | + FD_ZERO(&rfds); | |
| 199 | + FD_SET(mb_param->fd, &rfds); | |
| 200 | + ret = select(mb_param->fd+1, &rfds, NULL, NULL, &tv); | |
| 201 | + if (ret > 0) { | |
| 202 | + ret = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, 0); | |
| 203 | + } else if (ret == -1) { | |
| 204 | + /* error_treat() doesn't call modbus_flush() in | |
| 205 | + this case (avoid infinite loop) */ | |
| 206 | + error_treat(mb_param, SELECT_FAILURE, "Select failure"); | |
| 207 | + } | |
| 208 | +#endif | |
| 209 | + if (mb_param->debug && ret > 0) { | |
| 210 | + printf("%d bytes flushed\n", ret); | |
| 211 | + } | |
| 212 | + } while (ret > 0); | |
| 213 | + } | |
| 214 | +} | |
| 215 | + | |
| 197 | 216 | /* Computes the length of the expected response */ |
| 198 | 217 | static unsigned int compute_response_length(modbus_param_t *mb_param, |
| 199 | 218 | uint8_t *query) |
| ... | ... | @@ -1686,7 +1705,11 @@ static int modbus_connect_tcp(modbus_param_t *mb_param) |
| 1686 | 1705 | return ret; |
| 1687 | 1706 | } |
| 1688 | 1707 | |
| 1689 | -#ifdef HAVE_DECL_IPTOS_LOWDELAY | |
| 1708 | +#if (!HAVE_DECL___CYGWIN__) | |
| 1709 | + /** | |
| 1710 | + * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's | |
| 1711 | + * necessary to workaround that problem. | |
| 1712 | + **/ | |
| 1690 | 1713 | /* Set the IP low delay option */ |
| 1691 | 1714 | option = IPTOS_LOWDELAY; |
| 1692 | 1715 | ret = setsockopt(mb_param->fd, IPPROTO_TCP, IP_TOS, | ... | ... |