From 63c0e375eb5ccf65fbcd5a16dd24c3fc395ec0c5 Mon Sep 17 00:00:00 2001 From: patthoyts Date: Tue, 10 Apr 2007 12:25:57 +0000 Subject: [PATCH] * 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. --- ChangeLog | 7 +++++++ Makefile.in | 4 ++-- generic/udp_tcl.c | 41 ++++++++++++++++++++++++++++++++++------- win/makefile.vc | 2 +- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1674cab..e333386 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-04-10 Pat Thoyts + + * 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 * generic/udp_tcl.c: Added support for IP_MULTICAST_LOOP for diff --git a/Makefile.in b/Makefile.in index 9ec6714..4b1a875 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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: diff --git a/generic/udp_tcl.c b/generic/udp_tcl.c index 1a04aee..44a82bc 100644 --- a/generic/udp_tcl.c +++ b/generic/udp_tcl.c @@ -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; } diff --git a/win/makefile.vc b/win/makefile.vc index 7857b0d..a1e00c4 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -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 -- 2.23.0