Attachment "patch.txt" to
ticket [557488ffff]
added by
davygrvy
2002-05-18 05:50:18.
Index: tclWinSock.c
===================================================================
RCS file: /cvsroot/tcl/tcl/win/tclWinSock.c,v
retrieving revision 1.25
diff -c -r1.25 tclWinSock.c
*** tclWinSock.c 24 Jan 2002 01:34:16 -0000 1.25
--- tclWinSock.c 17 May 2002 22:48:09 -0000
***************
*** 194,199 ****
--- 194,200 ----
int mode));
static int TcpCloseProc _ANSI_ARGS_((ClientData instanceData,
Tcl_Interp *interp));
+ static Tcl_DriverSetOptionProc TcpSetOptionProc;
static int TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,
Tcl_Interp *interp, CONST char *optionName,
Tcl_DString *optionValue));
***************
*** 221,227 ****
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
NULL, /* Seek proc. */
! NULL, /* Set option proc. */
TcpGetOptionProc, /* Get option proc. */
TcpWatchProc, /* Set up notifier to watch this channel. */
TcpGetHandleProc, /* Get an OS handle from channel. */
--- 222,228 ----
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
NULL, /* Seek proc. */
! TcpSetOptionProc, /* Set option proc. */
TcpGetOptionProc, /* Get option proc. */
TcpWatchProc, /* Set up notifier to watch this channel. */
TcpGetHandleProc, /* Get an OS handle from channel. */
***************
*** 1859,1864 ****
--- 1860,1929 ----
/*
*----------------------------------------------------------------------
*
+ * TcpSetOptionProc --
+ *
+ * Sets Tcp channel specific options.
+ *
+ * Results:
+ * ...
+ *
+ * Side effects:
+ * ...
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static int
+ TcpSetOptionProc (
+ ClientData instanceData, /* Socket state. */
+ Tcl_Interp *interp, /* For error reporting - can be NULL. */
+ CONST char *optionName, /* Name of the option to set. */
+ CONST char *value) /* New value for option. */
+ {
+ SocketInfo *infoPtr;
+ SOCKET sock;
+ BOOL val = FALSE;
+ int boolVar, rtn;
+
+ /*
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
+ */
+
+ if (!SocketsEnabled()) {
+ if (interp) {
+ Tcl_AppendResult(interp, "winsock is not initialized", NULL);
+ }
+ return TCL_ERROR;
+ }
+
+ infoPtr = (SocketInfo *) instanceData;
+ sock = infoPtr->socket;
+
+ if (!stricmp(optionName, "-keepalive")) {
+ if (Tcl_GetBoolean(interp, value, &boolVar) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (boolVar) val = TRUE;
+ rtn = winSock.setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+ (const char *) &val, sizeof(BOOL));
+ if (rtn != 0) {
+ TclWinConvertWSAError(winSock.WSAGetLastError());
+ if (interp) {
+ Tcl_AppendResult(interp, "couldn't set socket option: ",
+ Tcl_PosixError(interp), NULL);
+ }
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
* TcpGetOptionProc --
*
* Computes an option value for a TCP socket based channel, or a
***************
*** 2028,2035 ****
}
}
if (len > 0) {
! return Tcl_BadChannelOption(interp, optionName, "peername sockname");
}
return TCL_OK;
--- 2093,2119 ----
}
}
+ if ((len == 0) ||
+ ((len > 1) && (optionName[1] == 'k') &&
+ (strncmp(optionName, "-keepalive", len) == 0))) {
+ int optlen;
+ BOOL ka;
+
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-keepalive");
+ }
+ optlen = sizeof(BOOL);
+ winSock.getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&ka,
+ &optlen);
+ if (ka) {
+ Tcl_DStringAppendElement(dsPtr, "1");
+ } else {
+ Tcl_DStringAppendElement(dsPtr, "0");
+ }
+ }
+
if (len > 0) {
! return Tcl_BadChannelOption(interp, optionName, "peername sockname keepalive");
}
return TCL_OK;