summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tcl.decls8
-rw-r--r--generic/tclDecls.h12
-rw-r--r--generic/tclIOCmd.c19
-rw-r--r--generic/tclIOSock.c13
-rw-r--r--generic/tclInt.h2
-rw-r--r--generic/tclStubInit.c1
-rw-r--r--unix/tclUnixSock.c33
-rw-r--r--win/tclWinSock.c31
8 files changed, 77 insertions, 42 deletions
diff --git a/generic/tcl.decls b/generic/tcl.decls
index 9aac4e7..fd504f6 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -2323,7 +2323,7 @@ declare 630 {
# ----- BASELINE -- FOR -- 8.6.0 ----- #
-# TIP #456
+# TIP #456/#468
declare 631 {
Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, const char *service,
const char *host, unsigned int flags, int backlog,
@@ -2345,6 +2345,12 @@ declare 635 {
int TclZipfs_MountBuffer(Tcl_Interp *interp, const char *mountPoint,
unsigned char *data, size_t datalen, int copy)
}
+# TIP #468
+declare 636 {
+ Tcl_Channel Tcl_OpenTcpClientEx(Tcl_Interp *interp, const char *service,
+ const char *host, const char *myaddr, const char *myservice,
+ unsigned int flags)
+}
# ----- BASELINE -- FOR -- 8.7.0 ----- #
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index e20782e..8dcbac7 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -1859,7 +1859,7 @@ EXTERN void Tcl_ZlibStreamSetCompressionDictionary(
/* 631 */
EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp,
const char *service, const char *host,
- unsigned int flags,
+ unsigned int flags, int backlog,
Tcl_TcpAcceptProc *acceptProc,
ClientData callbackData);
/* 632 */
@@ -1875,6 +1875,11 @@ EXTERN Tcl_Obj * TclZipfs_TclLibrary(void);
EXTERN int TclZipfs_MountBuffer(Tcl_Interp *interp,
const char *mountPoint, unsigned char *data,
size_t datalen, int copy);
+/* 636 */
+EXTERN Tcl_Channel Tcl_OpenTcpClientEx(Tcl_Interp *interp,
+ const char *service, const char *host,
+ const char *myaddr, const char *myservice,
+ unsigned int flags);
typedef struct {
const struct TclPlatStubs *tclPlatStubs;
@@ -2541,11 +2546,12 @@ typedef struct TclStubs {
void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */
int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */
void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */
- Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */
+ Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, int backlog, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */
int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mountPoint, const char *zipname, const char *passwd); /* 632 */
int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *mountPoint); /* 633 */
Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */
int (*tclZipfs_MountBuffer) (Tcl_Interp *interp, const char *mountPoint, unsigned char *data, size_t datalen, int copy); /* 635 */
+ Tcl_Channel (*tcl_OpenTcpClientEx) (Tcl_Interp *interp, const char *service, const char *host, const char *myaddr, const char *myservice, unsigned int flags); /* 636 */
} TclStubs;
extern const TclStubs *tclStubsPtr;
@@ -3848,6 +3854,8 @@ extern const TclStubs *tclStubsPtr;
(tclStubsPtr->tclZipfs_TclLibrary) /* 634 */
#define TclZipfs_MountBuffer \
(tclStubsPtr->tclZipfs_MountBuffer) /* 635 */
+#define Tcl_OpenTcpClientEx \
+ (tclStubsPtr->tcl_OpenTcpClientEx) /* 636 */
#endif /* defined(USE_TCL_STUBS) */
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index 6c640e5..ff7af3a 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -1491,10 +1491,10 @@ Tcl_SocketObjCmd(
SKT_ASYNC, SKT_BACKLOG, 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, backlog = -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;
@@ -1531,18 +1531,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:
@@ -1694,13 +1689,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 = Tcl_OpenTcpClientEx(interp, port, host, myaddr, myport, async);
if (chan == NULL) {
return TCL_ERROR;
}
diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c
index d46b6d0..23df9da 100644
--- a/generic/tclIOSock.c
+++ b/generic/tclIOSock.c
@@ -163,7 +163,7 @@ TclCreateSocketAddress(
* family */
struct addrinfo **addrlist, /* Socket address list */
const char *host, /* Host. NULL implies INADDR_ANY */
- int port, /* Port number */
+ const char *service, /* Service */
int willBind, /* Is this an address to bind() to or to
* connect() to? */
const char **errorMsgPtr) /* Place to store the error message detail, if
@@ -173,7 +173,7 @@ TclCreateSocketAddress(
struct addrinfo *p;
struct addrinfo *v4head = NULL, *v4ptr = NULL;
struct addrinfo *v6head = NULL, *v6ptr = NULL;
- char *native = NULL, portbuf[TCL_INTEGER_SPACE], *portstring;
+ char *native = NULL;
const char *family = NULL;
Tcl_DString ds;
int result;
@@ -187,11 +187,8 @@ TclCreateSocketAddress(
* when the loopback device is the only available network interface.
*/
- if (host != NULL && port == 0) {
- portstring = NULL;
- } else {
- TclFormatInt(portbuf, port);
- portstring = portbuf;
+ if (host != NULL && service != NULL && !strcmp(service, "0")) {
+ service = NULL;
}
(void) memset(&hints, 0, sizeof(hints));
@@ -236,7 +233,7 @@ TclCreateSocketAddress(
hints.ai_flags |= AI_PASSIVE;
}
- result = getaddrinfo(native, portstring, &hints, addrlist);
+ result = getaddrinfo(native, service, &hints, addrlist);
if (host != NULL) {
Tcl_DStringFree(&ds);
diff --git a/generic/tclInt.h b/generic/tclInt.h
index abf6c83..f9e98e2 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -3142,7 +3142,7 @@ MODULE_SCOPE void TclpFinalizePipes(void);
MODULE_SCOPE void TclpFinalizeSockets(void);
MODULE_SCOPE int TclCreateSocketAddress(Tcl_Interp *interp,
struct addrinfo **addrlist,
- const char *host, int port, int willBind,
+ const char *host, const char *service, int willBind,
const char **errorMsgPtr);
MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr,
Tcl_ThreadCreateProc *proc, ClientData clientData,
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 6a4eabc..330be74 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -1581,6 +1581,7 @@ const TclStubs tclStubs = {
TclZipfs_Unmount, /* 633 */
TclZipfs_TclLibrary, /* 634 */
TclZipfs_MountBuffer, /* 635 */
+ Tcl_OpenTcpClientEx, /* 636 */
};
/* !END!: Do not edit above this line. */
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c
index c9a4188..ae6c717 100644
--- a/unix/tclUnixSock.c
+++ b/unix/tclUnixSock.c
@@ -1370,17 +1370,32 @@ Tcl_OpenTcpClient(
* connect. Otherwise we do a blocking
* connect. */
{
+ char service[TCL_INTEGER_SPACE], myservice[TCL_INTEGER_SPACE];
+
+ TclFormatInt(service, port);
+ TclFormatInt(myservice, myport);
+
+ return Tcl_OpenTcpClientEx(interp, service, host, myaddr, myservice, async!=0);
+}
+
+Tcl_Channel
+Tcl_OpenTcpClientEx(
+ 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];
- /*
- * Do the name lookups for the local and remote addresses.
- */
-
- if (!TclCreateSocketAddress(interp, &addrlist, host, port, 0, &errorMsg)
- || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1,
+ if (!TclCreateSocketAddress(interp, &addrlist, host, service, 0, &errorMsg)
+ || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myservice, 1,
&errorMsg)) {
if (addrlist != NULL) {
freeaddrinfo(addrlist);
@@ -1398,7 +1413,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;
@@ -1573,8 +1588,8 @@ Tcl_OpenTcpServerEx(
goto error;
}
- if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1,
- &errorMsg)) {
+ if (!TclCreateSocketAddress(interp, &addrlist, myHost, service, 1,
+ &errorMsg)) {
my_errno = errno;
goto error;
}
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index 80588ef..b18c763 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -2029,7 +2029,7 @@ TcpConnect(
/*
*----------------------------------------------------------------------
*
- * Tcl_OpenTcpClient --
+ * Tcl_OpenTcpClient, Tcl_OpenTcpClientEx --
*
* Opens a TCP client socket and creates a channel around it.
*
@@ -2054,6 +2054,25 @@ Tcl_OpenTcpClient(
* connect. Otherwise we do a blocking
* connect. */
{
+ char service[TCL_INTEGER_SPACE], myservice[TCL_INTEGER_SPACE];
+
+ TclFormatInt(service, port);
+ TclFormatInt(myservice, myport);
+
+ return Tcl_OpenTcpClientEx(interp, service, host, myaddr, myservice, async!=0);
+}
+
+Tcl_Channel
+Tcl_OpenTcpClientEx(
+ 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;
@@ -2077,8 +2096,8 @@ Tcl_OpenTcpClient(
* Do the name lookups for the local and remote addresses.
*/
- if (!TclCreateSocketAddress(interp, &addrlist, host, port, 0, &errorMsg)
- || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1,
+ if (!TclCreateSocketAddress(interp, &addrlist, host, service, 0, &errorMsg)
+ || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myservice, 1,
&errorMsg)) {
if (addrlist != NULL) {
freeaddrinfo(addrlist);
@@ -2093,7 +2112,7 @@ Tcl_OpenTcpClient(
statePtr = NewSocketInfo(INVALID_SOCKET);
statePtr->addrlist = addrlist;
statePtr->myaddrlist = myaddrlist;
- if (async) {
+ if (flags&1) {
SET_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
}
@@ -2236,8 +2255,8 @@ Tcl_OpenTcpServerEx(
goto error;
}
- if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1,
- &errorMsg)) {
+ if (!TclCreateSocketAddress(interp, &addrlist, myHost, service, 1,
+ &errorMsg)) {
goto error;
}