diff options
| -rw-r--r-- | generic/tcl.decls | 8 | ||||
| -rw-r--r-- | generic/tclDecls.h | 12 | ||||
| -rw-r--r-- | generic/tclIOCmd.c | 19 | ||||
| -rw-r--r-- | generic/tclIOSock.c | 13 | ||||
| -rw-r--r-- | generic/tclInt.h | 2 | ||||
| -rw-r--r-- | generic/tclStubInit.c | 1 | ||||
| -rw-r--r-- | unix/tclUnixSock.c | 33 | ||||
| -rw-r--r-- | win/tclWinSock.c | 31 |
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; } |
