Tcl Source Code

Artifact [50bf63f055]
Login

Artifact 50bf63f05507412a5fbd4695dd2e8b22305c8c83:

Attachment "halfclosesock.patch" to ticket [219159ffff] added by ferrieux 2008-11-17 05:10:56.
Index: win/tclWinSock.c
===================================================================
RCS file: /cvsroot/tcl/tcl/win/tclWinSock.c,v
retrieving revision 1.63
diff -u -r1.63 tclWinSock.c
--- win/tclWinSock.c	26 Oct 2008 18:43:27 -0000	1.63
+++ win/tclWinSock.c	16 Nov 2008 22:05:24 -0000
@@ -168,6 +168,7 @@
 static Tcl_EventSetupProc	SocketSetupProc;
 static Tcl_DriverBlockModeProc	TcpBlockProc;
 static Tcl_DriverCloseProc	TcpCloseProc;
+static Tcl_DriverClose2Proc	TcpClose2Proc;
 static Tcl_DriverSetOptionProc	TcpSetOptionProc;
 static Tcl_DriverGetOptionProc	TcpGetOptionProc;
 static Tcl_DriverInputProc	TcpInputProc;
@@ -191,7 +192,7 @@
     TcpGetOptionProc,	    /* Get option proc. */
     TcpWatchProc,	    /* Set up notifier to watch this channel. */
     TcpGetHandleProc,	    /* Get an OS handle from channel. */
-    NULL,		    /* close2proc. */
+    TcpClose2Proc,	    /* Close2proc. */
     TcpBlockProc,	    /* Set socket into (non-)blocking mode. */
     NULL,		    /* flush proc. */
     NULL,		    /* handler proc. */
@@ -818,6 +819,58 @@
 /*
  *----------------------------------------------------------------------
  *
+ * TcpClose2Proc --
+ *
+ *	This function is called by the generic IO level to perform the channel
+ *	type specific part of a half-close: namely, a shutdown() on a socket.
+ *
+ * Results:
+ *	0 if successful, the value of errno if failed.
+ *
+ * Side effects:
+ *	Shuts down one side of the socket.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TcpClose2Proc(
+    ClientData instanceData,	/* The socket to close. */
+    Tcl_Interp *interp,		/* For error reporting. */
+    int flags)			/* Flags that indicate which side to close. */
+{
+    SocketInfo *infoPtr = (SocketInfo *) instanceData;
+    int errorCode = 0;
+    int sd;
+
+    /*
+     * Shutdown the OS socket handle.
+     */
+    switch(flags)
+	{
+	case TCL_CLOSE_READ:
+	    sd=SD_RECEIVE;
+	    break;
+	case TCL_CLOSE_WRITE:
+	    sd=SD_SEND;
+	    break;
+	default:
+	    if (interp) {
+		Tcl_AppendResult(interp, "Socket close2proc called bidirectionally", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+    if (shutdown(infoPtr->socket,sd) == SOCKET_ERROR) {
+	TclWinConvertWSAError((DWORD) WSAGetLastError());
+	errorCode = Tcl_GetErrno();
+    }
+
+    return errorCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
  * NewSocketInfo --
  *
  *	This function allocates and initializes a new SocketInfo structure.
Index: unix/tclUnixChan.c
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/tclUnixChan.c,v
retrieving revision 1.96
diff -u -r1.96 tclUnixChan.c
--- unix/tclUnixChan.c	26 Oct 2008 12:45:04 -0000	1.96
+++ unix/tclUnixChan.c	16 Nov 2008 22:05:28 -0000
@@ -218,6 +218,9 @@
 static int		TcpBlockModeProc(ClientData data, int mode);
 static int		TcpCloseProc(ClientData instanceData,
 			    Tcl_Interp *interp);
+static int		TcpClose2Proc(ClientData instanceData,
+				      Tcl_Interp *interp,
+				      int flags);
 static int		TcpGetHandleProc(ClientData instanceData,
 			    int direction, ClientData *handlePtr);
 static int		TcpGetOptionProc(ClientData instanceData,
@@ -318,7 +321,7 @@
     TcpGetOptionProc,		/* Get option proc. */
     TcpWatchProc,		/* Initialize notifier. */
     TcpGetHandleProc,		/* Get OS handles out of channel. */
-    NULL,			/* close2proc. */
+    TcpClose2Proc,		/* Close2 proc. */
     TcpBlockModeProc,		/* Set blocking or non-blocking mode.*/
     NULL,			/* flush proc. */
     NULL,			/* handler proc. */
@@ -2018,6 +2021,57 @@
 /*
  *----------------------------------------------------------------------
  *
+ * TcpClose2Proc --
+ *
+ *	This function is called by the generic IO level to perform the channel
+ *	type specific part of a half-close: namely, a shutdown() on a socket.
+ *
+ * Results:
+ *	0 if successful, the value of errno if failed.
+ *
+ * Side effects:
+ *	Shuts down one side of the socket.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TcpClose2Proc(
+    ClientData instanceData,	/* The socket to close. */
+    Tcl_Interp *interp,		/* For error reporting. */
+    int flags)			/* Flags that indicate which side to close. */
+{
+    TcpState *statePtr = (TcpState *) instanceData;
+    int errorCode = 0;
+    int sd;
+
+    /*
+     * Shutdown the OS socket handle.
+     */
+    switch(flags)
+	{
+	case TCL_CLOSE_READ:
+	    sd=SD_RECEIVE;
+	    break;
+	case TCL_CLOSE_WRITE:
+	    sd=SD_SEND;
+	    break;
+	default:
+	    if (interp) {
+		Tcl_AppendResult(interp, "Socket close2proc called bidirectionally", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+    if (shutdown(statePtr->fd,sd)<0) {
+	errorCode = errno;
+    }
+
+    return errorCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
  * TcpGetOptionProc --
  *
  *	Computes an option value for a TCP socket based channel, or a list of