* generic/udp_tcl.c: Applied patch 1693037 from Uwe Klein to
authorpatthoyts <patthoyts>
Tue, 10 Apr 2007 12:25:57 +0000 (12:25 +0000)
committerpatthoyts <patthoyts>
Tue, 10 Apr 2007 12:25:57 +0000 (12:25 +0000)
enable setting the SO_REUSEADDR socket option when creating a new
udp socket.
Improved error reporting on Windows.

ChangeLog
Makefile.in
generic/udp_tcl.c
win/makefile.vc

index 1674cab3828e2c1b74e1f25d673f0ee6bc724869..e333386da5283263e61abb23a04c480695bbb53a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-04-10  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * generic/udp_tcl.c: Applied patch 1693037 from Uwe Klein to
+       enable setting the SO_REUSEADDR socket option when creating a new
+       udp socket.
+       Improved error reporting on Windows.
+
 2007-03-30  Pat Thoyts  <patthoyts@users.sourceforge.net>
 
        * generic/udp_tcl.c: Added support for IP_MULTICAST_LOOP for
index 9ec6714e3acf504f4673f96f4a129d687fad6352..4b1a875a42a448db483908be882cdd1ea3150992 100644 (file)
@@ -235,10 +235,10 @@ test: binaries libraries
        $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
 
 shell: binaries libraries
-       echo "load $(PKG_LIB_FILE);set argv $(SCRIPT)" | $(TCLSH)
+       @$(TCLSH) $(SCRIPT)
 
 gdb:
-       $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+       @$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
 
 depend:
 
index 1a04aee7203f3c0965e302742c63af52e1de6d23..44a82bc37fa0b1cf81b2003855faec178ffc20ca 100644 (file)
@@ -237,6 +237,7 @@ udpOpen(ClientData clientData, Tcl_Interp *interp,
     char channelName[20];
     UdpState *statePtr;
     uint16_t localport = 0;
+    int reuse = 0;
 #ifdef SIPC_IPV6
     struct sockaddr_in6  addr, sockaddr;
 #else
@@ -246,6 +247,10 @@ udpOpen(ClientData clientData, Tcl_Interp *interp,
     socklen_t len;
     
     if (argc >= 2) {
+        if ((argc >= 3) && (0 == strncmp("reuse", argv[2], 6))) {
+            fprintf(stderr,"sock reuse!\n");
+            reuse = 1;
+        }
         if (udpGetService(interp, argv[1], &localport) != TCL_OK)
             return TCL_ERROR;
     }
@@ -289,12 +294,20 @@ udpOpen(ClientData clientData, Tcl_Interp *interp,
     addr.sin_addr.s_addr = 0;
     addr.sin_port = localport;
 #endif
+    if (reuse) {
+        int one = 1;
+        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+                       (const char *)&one, sizeof(one)) < 0) {
+            Tcl_SetObjResult(interp, 
+                             ErrorToObj("error setting socket option"));
+            closesocket(sock);
+            return TCL_ERROR;
+        }
+    }
     if (bind(sock,(struct sockaddr *)&addr, sizeof(addr)) < 0) {
-        snprintf(errBuf, 255, "failed to bind socket to port %u",
-            ntohs(localport));
-        errBuf[255] = 0;
-        UDPTRACE("%s\n");
-        Tcl_AppendResult(interp, errBuf, (char *)NULL);
+        Tcl_SetObjResult(interp, 
+                         ErrorToObj("failed to bind socket to port"));
+        closesocket(sock);
         return TCL_ERROR;
     }
 
@@ -1458,9 +1471,23 @@ udpSetOption(ClientData instanceData, Tcl_Interp *interp,
 static Tcl_Obj *
 ErrorToObj(const char * prefix)
 {
+    Tcl_Obj *errObj;
+#ifdef WIN32
+    LPVOID sMsg;
+    DWORD len = 0;
+    len = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
+                         | FORMAT_MESSAGE_FROM_SYSTEM
+                         | FORMAT_MESSAGE_IGNORE_INSERTS,
+                         NULL, GetLastError(),
+                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                         (LPWSTR)&sMsg, 0, NULL);
+    errObj = Tcl_NewStringObj(prefix, -1);
+    Tcl_AppendToObj(errObj, ": ", -1);
+    Tcl_AppendUnicodeToObj(errObj, (LPWSTR)sMsg, len - 1);
+    LocalFree(sMsg);
+#elif defined(HAVE_STRERROR)
     extern int errno;
     Tcl_Obj *errObj = Tcl_NewStringObj(prefix, -1);
-#ifdef HAVE_STRERROR
     Tcl_AppendStringsToObj(errObj, ": ", strerror(errno), NULL);
 #endif
     return errObj;
@@ -1511,7 +1538,7 @@ udpGetService(Tcl_Interp *interp, const char *service,
 {
     int port = 0;
     int r = UdpSockGetPort(interp, service, "udp", &port);
-    *servicePort = htons(port);
+    *servicePort = htons((short)port);
     return r;
 }
 
index 7857b0d7b2aa5f48f477156f1339c31b7ddc6155..a1e00c439e704524b575f47891c1a6b5ef3dd604 100644 (file)
@@ -156,7 +156,7 @@ Please `cd` to its location first.
 PROJECT = udp
 !include "rules.vc"
 
-DOTVERSION      = 1.0.8
+DOTVERSION      = 1.0.9
 VERSION         = $(DOTVERSION:.=)
 STUBPREFIX      = $(PROJECT)stub