From 467b6eeb8e37745e3e02deb72d0833995109cc50 Mon Sep 17 00:00:00 2001
From: limeboy <that.lemon+tcl@gmai.com>
Date: Thu, 24 Nov 2016 21:01:43 +0000
Subject: Allow a boolean argument to be passed.

---
 generic/tclIOCmd.c | 42 +++++++++++++++++++++++++++++++++++-------
 tests/socket.test  | 18 +++++++++---------
 unix/tclUnixSock.c |  3 ++-
 3 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index b4696fd..49c7c06 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -1485,14 +1485,14 @@ Tcl_SocketObjCmd(
     Tcl_Obj *const objv[])	/* Argument objects. */
 {
     static const char *const socketOptions[] = {
-	"-async", "-myaddr", "-myport", "-server", "-reuseaddr", "-reuseport",
+	"-async", "-myaddr", "-myport", "-reuseaddr", "-reuseport", "server",
 	NULL
     };
     enum socketOptions {
-	SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER, SKT_REUSEADDR,
-	SKT_REUSEPORT
+	SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT,
+	SKT_SERVER
     };
-    int optionIndex, a, server = 0, port, myport = 0, async = 0;
+    int optionIndex, a, server = 0, port, myport = 0, async = 0, boolTmp;
     unsigned int flags = 0;
     const char *host, *myaddr = NULL;
     Tcl_Obj *script = NULL;
@@ -1552,6 +1552,7 @@ Tcl_SocketObjCmd(
 		return TCL_ERROR;
 	    }
 	    server = 1;
+	    flags = TCL_TCPSERVER_REUSEADDR;
 	    a++;
 	    if (a >= objc) {
 		Tcl_SetObjResult(interp, Tcl_NewStringObj(
@@ -1561,10 +1562,36 @@ Tcl_SocketObjCmd(
 	    script = objv[a];
 	    break;
 	case SKT_REUSEADDR:
-	    flags |= TCL_TCPSERVER_REUSEADDR;
+	    a++;
+	    if (a >= objc) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"no argument given for -reuseaddr option", -1));
+		return TCL_ERROR;
+	    }
+	    if (Tcl_GetBooleanFromObj(interp, objv[a], &boolTmp) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (boolTmp) {
+		flags |= TCL_TCPSERVER_REUSEADDR;
+	    } else {
+		flags &= ~TCL_TCPSERVER_REUSEADDR;
+	    }
 	    break;
 	case SKT_REUSEPORT:
-	    flags |= TCL_TCPSERVER_REUSEPORT;
+	    a++;
+	    if (a >= objc) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"no argument given for -reuseport option", -1));
+		return TCL_ERROR;
+	    }
+	    if (Tcl_GetBooleanFromObj(interp, objv[a], &boolTmp) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (boolTmp) {
+		flags |= TCL_TCPSERVER_REUSEPORT;
+	    } else {
+		flags &= ~TCL_TCPSERVER_REUSEPORT;
+	    }
 	    break;
 	default:
 	    Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions");
@@ -1589,7 +1616,8 @@ Tcl_SocketObjCmd(
 		"?-myaddr addr? ?-myport myport? ?-async? host port");
 	iPtr->flags |= INTERP_ALTERNATE_WRONG_ARGS;
 	Tcl_WrongNumArgs(interp, 1, objv,
-		"-server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port");
+		"-server command ?-reuseaddr boolean? ?-reuseport boolean? "
+		"?-myaddr addr? port");
 	return TCL_ERROR;
     }
 
diff --git a/tests/socket.test b/tests/socket.test
index 82dc800..387e08e 100644
--- a/tests/socket.test
+++ b/tests/socket.test
@@ -265,13 +265,13 @@ test socket_$af-1.1 {arg parsing for socket command} -constraints [list socket s
 } -returnCodes error -result {no argument given for -server option}
 test socket_$af-1.2 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket -server foo
-} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"}
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"}
 test socket_$af-1.3 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket -myaddr
 } -returnCodes error -result {no argument given for -myaddr option}
 test socket_$af-1.4 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket -myaddr $localhost
-} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"}
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"}
 test socket_$af-1.5 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket -myport
 } -returnCodes error -result {no argument given for -myport option}
@@ -280,7 +280,7 @@ test socket_$af-1.6 {arg parsing for socket command} -constraints [list socket s
 } -returnCodes error -result {expected integer but got "xxxx"}
 test socket_$af-1.7 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket -myport 2522
-} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"}
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"}
 test socket_$af-1.8 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket -froboz
 } -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, -server, -reuseaddr, or -reuseport}
@@ -289,10 +289,10 @@ test socket_$af-1.9 {arg parsing for socket command} -constraints [list socket s
 } -returnCodes error -result {option -myport is not valid for servers}
 test socket_$af-1.10 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket host 2528 -junk
-} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"}
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"}
 test socket_$af-1.11 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket -server callback 2520 --
-} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"}
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"}
 test socket_$af-1.12 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
     socket foo badport
 } -returnCodes error -result {expected integer but got "badport"}
@@ -303,10 +303,10 @@ test socket_$af-1.14 {arg parsing for socket command} -constraints [list socket
     socket -server foo -async
 } -returnCodes error -result {cannot set -async option for server sockets}
 test socket_$af-1.15 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
-    socket -reuseaddr 4242
+    socket -reuseaddr yes 4242
 } -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers}
 test socket_$af-1.16 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
-    socket -reuseport 4242
+    socket -reuseport yes 4242
 } -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers}
 
 set path(script) [makeFile {} script]
@@ -2371,8 +2371,8 @@ test socket-14.19 {tip 456 -- introduce the -reuseport option} \
     -body {
         proc accept {channel address port} {}
         set port [randport]
-        set ssock1 [socket -server accept -reuseport $port]
-        set ssock2 [socket -server accept -reuseport $port]
+        set ssock1 [socket -server accept -reuseport yes $port]
+        set ssock2 [socket -server accept -reuseport yes $port]
         return ok
 } -cleanup {
     catch {close $ssock1}
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c
index bb75ed3..187c157 100644
--- a/unix/tclUnixSock.c
+++ b/unix/tclUnixSock.c
@@ -1523,10 +1523,11 @@ Tcl_OpenTcpServerEx(
 	     */
 	    errorMsg = "SO_REUSEPORT isn't supported by this platform";
 	    goto error;
-#endif
+#else
 	    optvalue = 1;
 	    (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT,
 			      (char *) &optvalue, sizeof(optvalue));
+#endif
 	}
 
         /*
-- 
cgit v0.12