summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2017-01-10 14:35:13 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2017-01-10 14:35:13 (GMT)
commit211801be532da7c72b73cf0311dc07eaef32aac5 (patch)
treec75195c0e09450101b9aabe6f16dc009a0c0c0aa
parent087ee7ed0d134cda28132343b258eee2afc60261 (diff)
downloadtcl-211801be532da7c72b73cf0311dc07eaef32aac5.zip
tcl-211801be532da7c72b73cf0311dc07eaef32aac5.tar.gz
tcl-211801be532da7c72b73cf0311dc07eaef32aac5.tar.bz2
Further experimental follow-up: Add internal function TclOpenTcpClientEx(), as companion to Tcl_OpenTcpServerEx(). Should be exported through new TIP.tip_456
-rw-r--r--generic/tclIOCmd.c19
-rw-r--r--generic/tclInt.h4
-rw-r--r--unix/tclUnixSock.c29
-rw-r--r--win/tclWinSock.c26
4 files changed, 48 insertions, 30 deletions
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index 1bd3fe7..a5038b7 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -1492,10 +1492,10 @@ Tcl_SocketObjCmd(
SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT,
SKT_SERVER
};
- int optionIndex, a, server = 0, myport = 0, async = 0, reusep = -1,
+ int optionIndex, a, server = 0, async = 0, reusep = -1,
reusea = -1;
unsigned int flags = 0;
- const char *host, *port, *myaddr = NULL;
+ const char *host, *port, *myaddr = NULL, *myport = NULL;
Tcl_Obj *script = NULL;
Tcl_Channel chan;
@@ -1532,18 +1532,13 @@ Tcl_SocketObjCmd(
myaddr = TclGetString(objv[a]);
break;
case SKT_MYPORT: {
- const char *myPortName;
-
a++;
if (a >= objc) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"no argument given for -myport option", -1));
return TCL_ERROR;
}
- myPortName = TclGetString(objv[a]);
- if (TclSockGetPort(interp, myPortName, "tcp", &myport) != TCL_OK) {
- return TCL_ERROR;
- }
+ myport = TclGetString(objv[a]);
break;
}
case SKT_SERVER:
@@ -1670,13 +1665,7 @@ Tcl_SocketObjCmd(
Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr);
} else {
- int portNum;
-
- if (TclSockGetPort(interp, port, "tcp", &portNum) != TCL_OK) {
- return TCL_ERROR;
- }
-
- chan = Tcl_OpenTcpClient(interp, portNum, host, myaddr, myport, async);
+ chan = TclOpenTcpClientEx(interp, port, host, myaddr, myport, async);
if (chan == NULL) {
return TCL_ERROR;
}
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 5faa275..e42bcfb 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -3070,6 +3070,10 @@ MODULE_SCOPE int TclCreateSocketAddress(Tcl_Interp *interp,
struct addrinfo **addrlist,
const char *host, const char *service, int willBind,
const char **errorMsgPtr);
+Tcl_Channel TclOpenTcpClientEx(Tcl_Interp *interp,
+ const char *service, const char *host,
+ const char *myaddr, const char *myservice,
+ unsigned int flags);
MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr,
Tcl_ThreadCreateProc *proc, ClientData clientData,
int stackSize, int flags);
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c
index 63bccae..50452e9 100644
--- a/unix/tclUnixSock.c
+++ b/unix/tclUnixSock.c
@@ -1283,19 +1283,30 @@ Tcl_OpenTcpClient(
* connect. Otherwise we do a blocking
* connect. */
{
- TcpState *statePtr;
- const char *errorMsg = NULL;
- struct addrinfo *addrlist = NULL, *myaddrlist = NULL;
- char channelName[SOCK_CHAN_LENGTH];
char service[TCL_INTEGER_SPACE], myservice[TCL_INTEGER_SPACE];
- /*
- * Do the name lookups for the local and remote addresses.
- */
-
TclFormatInt(service, port);
TclFormatInt(myservice, myport);
+ return TclOpenTcpClientEx(interp, service, host, myaddr, myservice, async!=0);
+}
+
+Tcl_Channel
+TclOpenTcpClientEx(
+ Tcl_Interp *interp, /* For error reporting; can be NULL. */
+ const char *service, /* Port number to open. */
+ const char *host, /* Host on which to open port. */
+ const char *myaddr, /* Client-side address */
+ const char *myservice, /* Client-side port */
+ unsigned int flags) /* If nonzero, attempt to do an asynchronous
+ * connect. Otherwise we do a blocking
+ * connect. */
+{
+ TcpState *statePtr;
+ const char *errorMsg = NULL;
+ struct addrinfo *addrlist = NULL, *myaddrlist = NULL;
+ char channelName[SOCK_CHAN_LENGTH];
+
if (!TclCreateSocketAddress(interp, &addrlist, host, service, 0, &errorMsg)
|| !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myservice, 1,
&errorMsg)) {
@@ -1314,7 +1325,7 @@ Tcl_OpenTcpClient(
*/
statePtr = ckalloc(sizeof(TcpState));
memset(statePtr, 0, sizeof(TcpState));
- statePtr->flags = async ? TCP_ASYNC_CONNECT : 0;
+ statePtr->flags = (flags&1) ? TCP_ASYNC_CONNECT : 0;
statePtr->cachedBlocking = TCL_MODE_BLOCKING;
statePtr->addrlist = addrlist;
statePtr->myaddrlist = myaddrlist;
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index b2d77a1..8545cdd 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -1873,7 +1873,7 @@ out:
/*
*----------------------------------------------------------------------
*
- * Tcl_OpenTcpClient --
+ * Tcl_OpenTcpClient, TclOpenTcpClientEx --
*
* Opens a TCP client socket and creates a channel around it.
*
@@ -1898,15 +1898,29 @@ Tcl_OpenTcpClient(
* connect. Otherwise we do a blocking
* connect. */
{
- TcpState *statePtr;
- const char *errorMsg = NULL;
- struct addrinfo *addrlist = NULL, *myaddrlist = NULL;
- char channelName[SOCK_CHAN_LENGTH];
char service[TCL_INTEGER_SPACE], myservice[TCL_INTEGER_SPACE];
TclFormatInt(service, port);
TclFormatInt(myservice, myport);
+ return TclOpenTcpClientEx(interp, service, host, myaddr, myservice, async!=0);
+}
+
+Tcl_Channel
+TclOpenTcpClientEx(
+ Tcl_Interp *interp, /* For error reporting; can be NULL. */
+ const char *service, /* Port number to open. */
+ const char *host, /* Host on which to open port. */
+ const char *myaddr, /* Client-side address */
+ const char *myservice, /* Client-side port */
+ unsigned int flags) /* If nonzero, attempt to do an asynchronous
+ * connect. Otherwise we do a blocking
+ * connect. */
+{
+ TcpState *statePtr;
+ const char *errorMsg = NULL;
+ struct addrinfo *addrlist = NULL, *myaddrlist = NULL;
+ char channelName[SOCK_CHAN_LENGTH];
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
@@ -1942,7 +1956,7 @@ Tcl_OpenTcpClient(
statePtr = NewSocketInfo(INVALID_SOCKET);
statePtr->addrlist = addrlist;
statePtr->myaddrlist = myaddrlist;
- if (async) {
+ if (flags&1) {
statePtr->flags |= TCP_ASYNC_CONNECT;
}