From: Zoran V. <vas...@us...> - 2005-03-17 18:25:03
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18176 Modified Files: conn.c Log Message: Added ns_conn channel as per RFE #1156141 Index: conn.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/conn.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** conn.c 8 Mar 2005 04:59:39 -0000 1.3 --- conn.c 17 Mar 2005 18:24:54 -0000 1.4 *************** *** 42,45 **** --- 42,46 ---- static int GetIndices(Tcl_Interp *interp, Conn *connPtr, Tcl_Obj **objv, int *offPtr, int *lenPtr); + static int MakeConnChan(Tcl_Interp *interp, Ns_Conn *conn); *************** *** 841,845 **** "outputheaders", "peeraddr", "peerport", "port", "protocol", "query", "request", "server", "sock", "start", "status", ! "url", "urlc", "urlencoding", "urlv", "version", "write_encoded", NULL }; enum ISubCmdIdx { --- 842,847 ---- "outputheaders", "peeraddr", "peerport", "port", "protocol", "query", "request", "server", "sock", "start", "status", ! "url", "urlc", "urlencoding", "urlv", "version", "write_encoded", ! "channel", NULL }; enum ISubCmdIdx { *************** *** 851,855 **** CPeerPortIdx, CPortIdx, CProtocolIdx, CQueryIdx, CRequestIdx, CServerIdx, CSockIdx, CStartIdx, CStatusIdx, CUrlIdx, ! CUrlcIdx, CUrlEncodingIdx, CUrlvIdx, CVersionIdx, CWriteEncodedIdx } opt; --- 853,858 ---- CPeerPortIdx, CPortIdx, CProtocolIdx, CQueryIdx, CRequestIdx, CServerIdx, CSockIdx, CStartIdx, CStatusIdx, CUrlIdx, ! CUrlcIdx, CUrlEncodingIdx, CUrlvIdx, CVersionIdx, CWriteEncodedIdx, ! CChannelIdx } opt; *************** *** 1160,1164 **** } break; ! } --- 1163,1172 ---- } break; ! ! case CChannelIdx: ! if (MakeConnChan(interp, conn) != TCL_OK) { ! return TCL_ERROR; ! } ! break; } *************** *** 1383,1384 **** --- 1391,1448 ---- return TCL_OK; } + + /*---------------------------------------------------------------------------- + * MakeConnChan -- + * + * Wraps a Tcl channel arround the current connection socket + * and returns the channel handle to the caller. + * + * Result: + * A standard Tcl result. + * + * Side Effects: + * New channel registered in the current interpreter. The channel + * is set to blocking mode. + * + *---------------------------------------------------------------------------- + */ + static int + MakeConnChan(Tcl_Interp *interp, Ns_Conn *conn) + { + int sock; + Tcl_Channel chan; + + /* + * Flush the connection, so we can safely make a dup + * of the connection socket. Without this, we may + * dup some unwanted data in socket buffers which may + * confuse the receiving side. + */ + + Ns_WriteConn(conn, NULL, 0); + + /* + * Wrap the connection in channel and register it. + * Note we must duplicate the connection socket + * since the Tcl channel driver will try to close + * it when we tear down the channel. + */ + + sock = ns_sockdup(Ns_ConnSock(conn)); + if (sock == INVALID_SOCKET) { + Tcl_AppendResult(interp, Tcl_PosixError(interp), NULL); + return TCL_ERROR; + } + + chan = Tcl_MakeTcpClientChannel((ClientData)sock); + if (chan == NULL) { + Tcl_SetResult(interp, "can't wrap connection socket", TCL_STATIC); + return TCL_ERROR; + } + + Ns_SockSetBlocking(sock); + Tcl_RegisterChannel(interp, chan); + Tcl_SetResult(interp, Tcl_GetChannelName(chan), TCL_STATIC); + + return TCL_OK; + } |