Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Further experimental follow-up: Add internal function TclOpenTcpClientEx(), as companion to Tcl_OpenTcpServerEx(). Should be exported through new TIP. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | tip-456 |
Files: | files | file ages | folders |
SHA1: |
78d4429e3b090e8f2e0b2d275f1e0dba |
User & Date: | jan.nijtmans 2017-01-10 14:35:13.522 |
Context
2017-04-10
| ||
11:01 | Merge "tip-468" branch. Add new function Tcl_OpenTcpClientEx() with same change as Tcl_OpenTcpServer... Leaf check-in: 97a181d1d6 user: jan.nijtmans tags: tip-468-bis | |
2017-01-10
| ||
14:35 | Further experimental follow-up: Add internal function TclOpenTcpClientEx(), as companion to Tcl_Open... Closed-Leaf check-in: 78d4429e3b user: jan.nijtmans tags: tip-456 | |
13:56 | Experimental follow-up: Change internal TclCreateSocketAddress() signature, from using "int port" to... check-in: 3b3fac1cee user: jan.nijtmans tags: tip-456 | |
Changes
Changes to generic/tclIOCmd.c.
︙ | ︙ | |||
1488 1489 1490 1491 1492 1493 1494 | "-async", "-myaddr", "-myport", "-reuseaddr", "-reuseport", "-server", NULL }; enum socketOptions { SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT, SKT_SERVER }; | | | | 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 | "-async", "-myaddr", "-myport", "-reuseaddr", "-reuseport", "-server", NULL }; enum socketOptions { SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT, SKT_SERVER }; int optionIndex, a, server = 0, async = 0, reusep = -1, reusea = -1; unsigned int flags = 0; const char *host, *port, *myaddr = NULL, *myport = NULL; Tcl_Obj *script = NULL; Tcl_Channel chan; if (TclpHasSockets(interp) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
1528 1529 1530 1531 1532 1533 1534 | Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -myaddr option", -1)); return TCL_ERROR; } myaddr = TclGetString(objv[a]); break; case SKT_MYPORT: { | < < | < < < | 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 | Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -myaddr option", -1)); return TCL_ERROR; } myaddr = TclGetString(objv[a]); break; case SKT_MYPORT: { a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -myport option", -1)); return TCL_ERROR; } myport = TclGetString(objv[a]); break; } case SKT_SERVER: if (async == 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot set -async option for server sockets", -1)); return TCL_ERROR; |
︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 | * Register a close callback. This callback will inform the * interpreter (if it still exists) that this channel does not need to * be informed when the interpreter is deleted. */ Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr); } else { | < < < < < < | | 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 | * Register a close callback. This callback will inform the * interpreter (if it still exists) that this channel does not need to * be informed when the interpreter is deleted. */ Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr); } else { chan = TclOpenTcpClientEx(interp, port, host, myaddr, myport, async); if (chan == NULL) { return TCL_ERROR; } } Tcl_RegisterChannel(interp, chan); Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1)); |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 | MODULE_SCOPE void TclpFinalizeMutex(Tcl_Mutex *mutexPtr); MODULE_SCOPE void TclpFinalizePipes(void); MODULE_SCOPE void TclpFinalizeSockets(void); MODULE_SCOPE int TclCreateSocketAddress(Tcl_Interp *interp, struct addrinfo **addrlist, const char *host, const char *service, int willBind, const char **errorMsgPtr); MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, ClientData clientData, int stackSize, int flags); MODULE_SCOPE int TclpFindVariable(const char *name, int *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); | > > > > | 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 | MODULE_SCOPE void TclpFinalizeMutex(Tcl_Mutex *mutexPtr); MODULE_SCOPE void TclpFinalizePipes(void); MODULE_SCOPE void TclpFinalizeSockets(void); 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); MODULE_SCOPE int TclpFindVariable(const char *name, int *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); |
︙ | ︙ |
Changes to unix/tclUnixSock.c.
︙ | ︙ | |||
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 | int port, /* Port number to open. */ const char *host, /* Host on which to open port. */ const char *myaddr, /* Client-side address */ int myport, /* Client-side port */ int async) /* 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]; | > > > > > > > > > > > > > > > > > > > < < < < < < < < | | 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 | int port, /* Port number to open. */ const char *host, /* Host on which to open port. */ const char *myaddr, /* Client-side address */ int myport, /* Client-side port */ int async) /* If nonzero, attempt to do an asynchronous * connect. Otherwise we do a blocking * connect. */ { 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 (!TclCreateSocketAddress(interp, &addrlist, host, service, 0, &errorMsg) || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myservice, 1, &errorMsg)) { if (addrlist != NULL) { freeaddrinfo(addrlist); } if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open socket: %s", errorMsg)); } return NULL; } /* * Allocate a new TcpState for this socket. */ statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->flags = (flags&1) ? TCP_ASYNC_CONNECT : 0; statePtr->cachedBlocking = TCL_MODE_BLOCKING; statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; statePtr->fds.fd = -1; /* * Create a new client socket and wrap it in a channel. |
︙ | ︙ |
Changes to win/tclWinSock.c.
︙ | ︙ | |||
1869 1870 1871 1872 1873 1874 1875 | } return TCL_OK; } /* *---------------------------------------------------------------------- * | | | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 | } return TCL_OK; } /* *---------------------------------------------------------------------- * * Tcl_OpenTcpClient, TclOpenTcpClientEx -- * * Opens a TCP client socket and creates a channel around it. * * Results: * The channel or NULL if failed. An error message is returned in the * interpreter on failure. * |
︙ | ︙ | |||
1894 1895 1896 1897 1898 1899 1900 | const char *host, /* Host on which to open port. */ const char *myaddr, /* Client-side address */ int myport, /* Client-side port */ int async) /* If nonzero, attempt to do an asynchronous * connect. Otherwise we do a blocking * connect. */ { | < < < < > > > > > > > > > > > > > > > > > > | 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 | const char *host, /* Host on which to open port. */ const char *myaddr, /* Client-side address */ int myport, /* Client-side port */ int async) /* If nonzero, attempt to do an asynchronous * connect. Otherwise we do a blocking * connect. */ { 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; } /* * Check that WinSock is initialized; do not call it if not, to prevent |
︙ | ︙ | |||
1938 1939 1940 1941 1942 1943 1944 | } return NULL; } statePtr = NewSocketInfo(INVALID_SOCKET); statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; | | | 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 | } return NULL; } statePtr = NewSocketInfo(INVALID_SOCKET); statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; if (flags&1) { statePtr->flags |= TCP_ASYNC_CONNECT; } /* * Create a new client socket and wrap it in a channel. */ if (TcpConnect(interp, statePtr) != TCL_OK) { |
︙ | ︙ |