Use -1 as file descriptor "not open" value instead of 0
[debian/gnuradio] / gnuradio-core / src / lib / io / gr_udp_sink.cc
index a9cb87a21e323db842371b423650a8c28847093c..2ee16b79f21020d45583fac12b5b489f2e973c60 100755 (executable)
 #include <string.h>
 #if defined(HAVE_NETDB_H)
 #include <netdb.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>  //usually included by <netdb.h>?
+#endif
 typedef void* optval_t;
 #elif defined(HAVE_WINDOWS_H)
 // if not posix, assume winsock
@@ -92,7 +97,7 @@ gr_udp_sink::gr_udp_sink (size_t itemsize,
                   gr_make_io_signature (1, 1, itemsize),
                   gr_make_io_signature (0, 0, 0)),
     d_itemsize (itemsize), d_payload_size(payload_size), d_eof(eof),
-    d_connected(false)
+    d_socket(-1), d_connected(false)
 {
 #if defined(USING_WINSOCK) // for Windows (with MinGW)
   // initialize winsock DLL
@@ -140,14 +145,14 @@ gr_udp_sink::~gr_udp_sink ()
   if (d_connected)
     disconnect();
 
-  if (d_socket){
+  if (d_socket != -1){
     shutdown(d_socket, SHUT_RDWR);
 #if defined(USING_WINSOCK)
     closesocket(d_socket);
 #else
     ::close(d_socket);
 #endif
-    d_socket = 0;
+    d_socket = -1;
   }
 
 #if defined(USING_WINSOCK) // for Windows (with MinGW)
@@ -251,6 +256,31 @@ void gr_udp_sink::disconnect()
       (void) send( d_socket, NULL, 0, 0 );  // ignore errors
   }
 
+  // Sending EOF can produce ERRCONNREFUSED errors that won't show up
+  //  until the next send or recv, which might confuse us if it happens
+  //  on a new connection.  The following does a nonblocking recv to
+  //  clear any such errors.
+  timeval timeout;
+  timeout.tv_sec = 0;    // zero time for immediate return
+  timeout.tv_usec = 0;
+  fd_set readfds;
+  FD_ZERO(&readfds);
+  FD_SET(d_socket, &readfds);
+  int r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+  if(r < 0) {
+      #if SNK_VERBOSE
+      report_error("udp_sink/select",NULL);
+      #endif
+  }
+  else if(r > 0) {  // call recv() to get error return
+    r = recv(d_socket, (char*)&readfds, sizeof(readfds), 0);
+    if(r < 0) {
+       #if SNK_VERBOSE
+       report_error("udp_sink/recv",NULL);
+       #endif
+    }
+  }
+
   // Since I can't find any way to disconnect a datagram socket in Cygwin,
   // we just leave it connected but disable sending.
 #if 0